VTM3.0代码阅读:decompressSlice函数

decompressSlice函数是解码端解码ctu数据的统领函数。其中调用coding_tree_unit函数实现ctu数据的解码,调用decompressCtu函数实现ctu数据和像素信息的解析恢复。

大致流程可以总结为:
当前帧picture.cs的各种数据的初始化,方便ctu各种数据的解码和存储;
读取到每个ctu的编码信息数据流,每个sub数据流可以解码得到一个ctu的数据;
for循环逐个处理一帧中的所有ctu:确定ctu位置和区域,初始化cabac解码器,读取sub数据流并调用coding_tree_unit函数解码一个ctu,调用decompressCtu函数实现ctu数据和像素信息的解析恢复。直到一帧中的所有ctu解码完成,解码剩余bit。

由于宏HEVC_TILES_WPP等关闭,所以删掉了一些无用的代码。函数流程和VTM1中差别不大,只是在每一行Ctu解码开始时,重置HMVP列表。

void DecSlice::decompressSlice( Slice* slice, InputBitstream* bitstream )
{
  //-- For time output for each slice
  slice->startProcessingTimer();		//开启计时

  const SPS*     sps          = slice->getSPS();
  Picture*       pic          = slice->getPic();	//当前需要解码的一帧picture
#if HEVC_TILES_WPP
  const TileMap& tileMap      = *pic->tileMap;
#endif
  CABACReader&   cabacReader  = *m_CABACDecoder->getCABACReader( 0 );	//新建一个CABAC解码器

  // setup coding structure
  CodingStructure& cs = *pic->cs;		//当前解码picture的cs,进行各种数据的初始化,以便接下里ctu的解码
  cs.slice            = slice;
  cs.sps              = sps;
  cs.pps              = slice->getPPS();
#if HEVC_VPS
  cs.vps              = slice->getVPS();
#endif
  cs.pcv              = slice->getPPS()->pcv;
  cs.chromaQpAdj      = 0;

  cs.picture->resizeSAO(cs.pcv->sizeInCtus, 0);

  cs.picture->resizeAlfCtuEnableFlag( cs.pcv->sizeInCtus );

  const unsigned numSubstreams = slice->getNumberOfSubstreamSizes() + 1;	//sub数据流的个数

  // init each couple {EntropyDecoder, Substream}
  // Table of extracted substreams.
  std::vector<InputBitstream*> ppcSubstreams( numSubstreams );
  for( unsigned idx = 0; idx < numSubstreams; idx++ )			//将每个sub数据流存储到ppcSubstreams,用于接下来每个ctu的解码
  {
    ppcSubstreams[idx] = bitstream->extractSubstream( idx+1 < numSubstreams ? ( slice->getSubstreamSize(idx) << 3 ) : bitstream->getNumBitsLeft() );
  }

#if HEVC_DEPENDENT_SLICES
  const int       startCtuTsAddr          = slice->getSliceSegmentCurStartCtuTsAddr();
#else
  const int       startCtuTsAddr          = slice->getSliceCurStartCtuTsAddr();	//CTU的起始ts扫描地址,即0
#endif

  const unsigned  numCtusInFrame          = cs.pcv->sizeInCtus;			//当前帧的ctu个数
  const unsigned  widthInCtus             = cs.pcv->widthInCtus;		//当前帧一行有多少个ctu

  cabacReader.initBitstream( ppcSubstreams[0] );		//初始化cabac解码器
  cabacReader.initCtxModels( *slice );

  // Quantization parameter
#if HEVC_DEPENDENT_SLICES
  if(!slice->getDependentSliceSegmentFlag())
  {
#endif
    pic->m_prevQP[0] = pic->m_prevQP[1] = slice->getSliceQp();	//量化系数qp
#if HEVC_DEPENDENT_SLICES
  }
#endif
  CHECK( pic->m_prevQP[0] == std::numeric_limits<int>::max(), "Invalid previous QP" );

  DTRACE( g_trace_ctx, D_HEADER, "=========== POC: %d ===========\n", slice->getPOC() );

  // The first CTU of the slice is the first coded substream, but the global substream number, as calculated by getSubstreamForCtuAddr may be higher.
  // This calculates the common offset for all substreams in this slice.

  // for every CTU in the slice segment...
  bool isLastCtuOfSliceSegment = false;			//当前解码的ctu是否为当前帧的最后一个ctu
  for( unsigned ctuTsAddr = startCtuTsAddr; !isLastCtuOfSliceSegment && ctuTsAddr < numCtusInFrame; ctuTsAddr++ )
  {																//ctu loop,对一帧中的所有ctu进行解码
    const unsigned  ctuRsAddr             = ctuTsAddr;

    const unsigned  ctuXPosInCtus         = ctuRsAddr % widthInCtus;	//计算当前解码ctu的pos,area等信息
    const unsigned  ctuYPosInCtus         = ctuRsAddr / widthInCtus;
#if HEVC_TILES_WPP
    const unsigned  subStrmId             = tileMap.getSubstreamForCtuAddr( ctuRsAddr, true, slice ) - subStreamOffset;
#else
    const unsigned  subStrmId             = 0;
#endif
    const unsigned  maxCUSize             = sps->getMaxCUWidth();
    Position pos( ctuXPosInCtus*maxCUSize, ctuYPosInCtus*maxCUSize) ;	//解码ctu的pos
    UnitArea ctuArea(cs.area.chromaFormat, Area( pos.x, pos.y, maxCUSize, maxCUSize ) );	//解码ctu的area

    DTRACE_UPDATE( g_trace_ctx, std::make_pair( "ctu", ctuRsAddr ) );

    cabacReader.initBitstream( ppcSubstreams[subStrmId] );	//CABAC解码器读取当前ctu的sub数据流,开始解码

#if JVET_L0646_GBI			//广义Bi
    bool updateGbiCodingOrder = cs.slice->getSliceType() == B_SLICE && ctuTsAddr == startCtuTsAddr;
    if(updateGbiCodingOrder)
    {
      resetGbiCodingOrder(true, cs);
    }
#endif

#if JVET_L0158_L0106_RESET_BUFFER	//HMVP
    if (cs.slice->getSliceType() != I_SLICE && ctuXPosInCtus == 0)
    {
      cs.slice->resetMotionLUTs();		//每一行CTU开始时重置HMVP列表
    }
#endif
														//coding_tree_unit 解码ctu数据
    isLastCtuOfSliceSegment = cabacReader.coding_tree_unit( cs, ctuArea, pic->m_prevQP, ctuRsAddr );

    m_pcCuDecoder->decompressCtu( cs, ctuArea );		//decompressCtu	解析恢复ctu数据和像素信息


    if( isLastCtuOfSliceSegment )		//当前ctu为一帧的最后一个ctu
    {
#if DECODER_CHECK_SUBSTREAM_AND_SLICE_TRAILING_BYTES
      cabacReader.remaining_bytes( false );		//读取完剩余bit
#endif
	
	  slice->setSliceCurEndCtuTsAddr( ctuTsAddr+1 );
    }
  }///ctu loop结束,一帧解码完成
  
  CHECK( !isLastCtuOfSliceSegment, "Last CTU of slice segment not signalled as such" );

#if HEVC_DEPENDENT_SLICES
  if( depSliceSegmentsEnabled )
  {
    m_lastSliceSegmentEndContextState = cabacReader.getCtx();  //ctx end of dep.slice
  }
#endif
  // deallocate all created substreams, including internal buffers.
  for( auto substr: ppcSubstreams )		//一帧解码完成,存储的编码信息数据流delete	
  {
    delete substr;
  }
  slice->stopProcessingTimer();		//停止计时
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
智慧校园整体解决方案是响应国家教育信息化政策,结合教育改革和技术创新的产物。该方案以物联网、大数据、人工智能和移动互联技术为基础,旨在打造一个安全、高效、互动且环保的教育环境。方案强调从数字化校园向智慧校园的转变,通过自动数据采集、智能分析和按需服务,实现校园业务的智能化管理。 方案的总体设计原则包括应用至上、分层设计和互联互通,确保系统能够满足不同用户角色的需求,并实现数据和资源的整合与共享。框架设计涵盖了校园安全、管理、教学、环境等多个方面,构建了一个全面的校园应用生态系统。这包括智慧安全系统、校园身份识别、智能排课及选课系统、智慧学习系统、精品录播教室方案等,以支持个性化学习和教学评估。 建设内容突出了智慧安全和智慧管理的重要性。智慧安全管理通过分布式录播系统和紧急预案一键启动功能,增强校园安全预警和事件响应能力。智慧管理系统则利用物联网技术,实现人员和设备的智能管理,提高校园运营效率。 智慧教学部分,方案提供了智慧学习系统和精品录播教室方案,支持专业级学习硬件和智能化网络管理,促进个性化学习和教学资源的高效利用。同时,教学质量评估中心和资源应用平台的建设,旨在提升教学评估的科学性和教育资源的共享性。 智慧环境建设则侧重于基于物联网的设备管理,通过智慧教室管理系统实现教室环境的智能控制和能效管理,打造绿色、节能的校园环境。电子班牌和校园信息发布系统的建设,将作为智慧校园的核心和入口,提供教务、一卡通、图书馆等系统的集成信息。 总体而言,智慧校园整体解决方案通过集成先进技术,不仅提升了校园的信息化水平,而且优化了教学和管理流程,为学生、教师和家长提供了更加便捷、个性化的教育体验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值