网站开发项目延期说明,中铁建设集团有限公司基础设施事业部,建筑网课回放,深州网站在TAppDecTop.cpp ,最重要的是decode 函数#xff0c;下面将对其进行分析#xff0c;是解码上层的一个重要函数。
代码如下#xff0c;代码后将进行分析。 Void TAppDecTop::decode()
{Int poc;TComListTComPic** pcListPic NULL;ifstream bits…在TAppDecTop.cpp ,最重要的是decode 函数下面将对其进行分析是解码上层的一个重要函数。
代码如下代码后将进行分析。 Void TAppDecTop::decode()
{Int poc;TComListTComPic** pcListPic NULL;ifstream bitstreamFile(m_pchBitstreamFile, ifstream::in | ifstream::binary);if (!bitstreamFile){fprintf(stderr, \nfailed to open bitstream file %s for reading\n, m_pchBitstreamFile);exit(EXIT_FAILURE);}InputByteStream bytestream(bitstreamFile);// create initialize internal classesxCreateDecLib();xInitDecLib ();m_iPOCLastDisplay m_iSkipFrame; // set the last displayed POC correctly for skip forward.// main decoder loopBool recon_opened false; // reconstruction file not yet opened. (must be performed after SPS is seen)while (!!bitstreamFile){/* location serves to work around a design fault in the decoder, whereby* the process of reading a new slice that is the first slice of a new frame* requires the TDecTop::decode() method to be called again with the same* nal unit. */streampos location bitstreamFile.tellg();AnnexBStats stats AnnexBStats();Bool bPreviousPictureDecoded false;vectoruint8_t nalUnit;InputNALUnit nalu;byteStreamNALUnit(bytestream, nalUnit, stats);// call actual decoding functionBool bNewPicture false;if (nalUnit.empty()){/* this can happen if the following occur:* - empty input file* - two back-to-back start_code_prefixes* - start_code_prefix immediately followed by EOF*/fprintf(stderr, Warning: Attempt to decode an empty NAL unit\n);}else{read(nalu, nalUnit);if( (m_iMaxTemporalLayer 0 nalu.m_temporalId m_iMaxTemporalLayer) || !isNaluWithinTargetDecLayerIdSet(nalu) ){if(bPreviousPictureDecoded){bNewPicture true;bPreviousPictureDecoded false;}else{bNewPicture false;}}else{bNewPicture m_cTDecTop.decode(nalu, m_iSkipFrame, m_iPOCLastDisplay);if (bNewPicture){bitstreamFile.clear();/* location points to the current nalunit payload[1] due to the* need for the annexB parser to read three extra bytes.* [1] except for the first NAL unit in the file* (but bNewPicture doesnt happen then) */bitstreamFile.seekg(location-streamoff(3));bytestream.reset();}bPreviousPictureDecoded true; }}if (bNewPicture || !bitstreamFile){m_cTDecTop.executeLoopFilters(poc, pcListPic);printf(\npoc %d\n,poc);}if( pcListPic ){printf(\nnaluType %d\n,nalu.m_nalUnitType);if ( m_pchReconFile !recon_opened ){if (!m_outputBitDepthY) { m_outputBitDepthY g_bitDepthY; }if (!m_outputBitDepthC) { m_outputBitDepthC g_bitDepthC; }m_cTVideoIOYuvReconFile.open( m_pchReconFile, true, m_outputBitDepthY, m_outputBitDepthC, g_bitDepthY, g_bitDepthC ); // write moderecon_opened true;}if ( bNewPicture ( nalu.m_nalUnitType NAL_UNIT_CODED_SLICE_IDR|| nalu.m_nalUnitType NAL_UNIT_CODED_SLICE_IDR_N_LP|| nalu.m_nalUnitType NAL_UNIT_CODED_SLICE_BLA_N_LP|| nalu.m_nalUnitType NAL_UNIT_CODED_SLICE_BLANT|| nalu.m_nalUnitType NAL_UNIT_CODED_SLICE_BLA ) ){xFlushOutput( pcListPic );}// write reconstruction to fileif(bNewPicture){xWriteOutput( pcListPic, nalu.m_temporalId );}}}xFlushOutput( pcListPic );// delete buffersm_cTDecTop.deletePicBuffer();// destroy internal classesxDestroyDecLib();
} 代码xCreateDecLib 和 xInitDecLib 重要是初始化四叉树和解码需要的全局变量和申请内存。
当提供一个码流文件的文件名后进行ifstream bitstreamFile(m_pchBitstreamFile, ifstream::in | ifstream::binary); 以二进制方式打开文件名码流以字节方式InputByteStream bytestream(bitstreamFile);进行读操作。 我们都知道HEVC/H265 是以NAL方式组织数据的解析VPS,SPS,PPS,SEI,SEI_SUFFIX 后其他的是一个个slice的NAL数据而Deblocking SAO Filters 等滤波是对整个picuture进行滤波操作出现从第二帧开始每帧的第一个slice两次进行解析这是参考软件的一个bug或不好的地方其实完全可以知道是否是最后一个slice不必进行两次打开。
所以出现
bitstreamFile.clear();
bitstreamFile.seekg(location-streamoff(3)); bytestream.reset(); 大家有兴趣可以先增加一个变量判断是否是最后一个slice就不需要执行上面代码了。 如下代码是从来不会执行因为HEVC/H265没有cavlc也就不会有slice part A slice part Bslice part C 是现实的编解码告诉了设计者slice part A slice part Bslice part C 没有人使用就被抛弃了实际的编解码从来没有实现slice part A slice part Bslice part C 等编解码的。 if( (m_iMaxTemporalLayer 0 nalu.m_temporalId m_iMaxTemporalLayer) || !isNaluWithinTargetDecLayerIdSet(nalu) ) { if(bPreviousPictureDecoded) { bNewPicture true; bPreviousPictureDecoded false; } else { bNewPicture false; } } 解码和滤波后当然就是输出重构数据xWriteOutput( pcListPic, nalu.m_temporalId ) 如果slice是NAL_UNIT_CODED_SLICE_IDRNAL_UNIT_CODED_SLICE_IDR_N_LPNAL_UNIT_CODED_SLICE_BLA_N_LPNAL_UNIT_CODED_SLICE_BLANTNAL_UNIT_CODED_SLICE_BLA中的一种将解码产生的picture全部清空没有任何参考帧相当于一个新的sequence进行解码了。 其他的代码很简单请自己分析。