HEVC参考软件平台HM中,在进入正式编码之前需要做一些初始化的工作。这些工作主要在encmain.cpp、TAppEncTop.cpp和TEncTop.cpp中。
1、encmain.cpp
int main(int argc, char* argv[]) { TAppEncTop cTAppEncTop; // print information fprintf( stdout, "\n" ); fprintf( stdout, "HM software: Encoder Version [%s]", NV_VERSION ); fprintf( stdout, NVM_ONOS ); fprintf( stdout, NVM_COMPILEDBY ); fprintf( stdout, NVM_BITS ); fprintf( stdout, "\n" ); // create application encoder class cTAppEncTop.create(); // parse configuration try { if(!cTAppEncTop.parseCfg( argc, argv )) { cTAppEncTop.destroy(); return 1; } } catch (po::ParseFailure& e) { cerr << "Error parsing option \""<< e.arg <<"\" with argument \""<< e.val <<"\"." << endl; return 1; } // starting time double dResult; long lBefore = clock(); // call encoding function cTAppEncTop.encode(); // ending time dResult = (double)(clock()-lBefore) / CLOCKS_PER_SEC; printf("\n Total Time: %12.3f sec.\n", dResult); // destroy application encoder class cTAppEncTop.destroy(); return 0; }
该部分的大致工作流程如下图所示:
2、TAppEncTop.cpp
Void TAppEncTop::encode() { fstream bitstreamFile(m_pchBitstreamFile, fstream::binary | fstream::out);//m_pchBitstreamFile:output bitstream file(以二进制的形式打开/读取一个可写入文件) if (!bitstreamFile) { fprintf(stderr, "\nfailed to open bitstream file `%s' for writing\n", m_pchBitstreamFile); exit(EXIT_FAILURE); } TComPicYuv* pcPicYuvOrg = new TComPicYuv;//使用new在运行阶段分配未命名的内存来存储值 TComPicYuv* pcPicYuvRec = NULL; // initialize internal class & member variables xInitLibCfg(); xCreateLib(); xInitLib(m_isField); // main encoder loop Int iNumEncoded = 0; Bool bEos = false; list<AccessUnit> outputAccessUnits; ///< list of access units to write out. is populated by the encoding process // allocate original YUV buffer if( m_isField ) { pcPicYuvOrg->create( m_iSourceWidth, m_iSourceHeightOrg, m_uiMaxCUWidth, m_uiMaxCUHeight, m_uiMaxCUDepth ); } else { pcPicYuvOrg->create( m_iSourceWidth, m_iSourceHeight, m_uiMaxCUWidth, m_uiMaxCUHeight, m_uiMaxCUDepth ); } while ( !bEos ) { // get buffers xGetBuffer(pcPicYuvRec); // read input YUV file m_cTVideoIOYuvInputFile.read( pcPicYuvOrg, m_aiPad ); // increase number of received frames m_iFrameRcvd++; bEos = (m_isField && (m_iFrameRcvd == (m_framesToBeEncoded >> 1) )) || ( !m_isField && (m_iFrameRcvd == m_framesToBeEncoded) ); Bool flush = 0; // if end of file (which is only detected on a read failure) flush the encoder of any queued pictures if (m_cTVideoIOYuvInputFile.isEof()) { flush = true; bEos = true; m_iFrameRcvd--; m_cTEncTop.setFramesToBeEncoded(m_iFrameRcvd); } // call encoding function for one frame if ( m_isField ) { m_cTEncTop.encode( bEos, flush ? 0 : pcPicYuvOrg, m_cListPicYuvRec, outputAccessUnits, iNumEncoded, m_isTopFieldFirst); } else { m_cTEncTop.encode( bEos, flush ? 0 : pcPicYuvOrg, m_cListPicYuvRec, outputAccessUnits, iNumEncoded ); } // write bistream to file if necessary if ( iNumEncoded > 0 ) { xWriteOutput(bitstreamFile, iNumEncoded, outputAccessUnits); outputAccessUnits.clear(); } } m_cTEncTop.printSummary(m_isField); // delete original YUV buffer pcPicYuvOrg->destroy(); delete pcPicYuvOrg;//使用delete释放内存(只能用delete来释放使用new分配的内存) pcPicYuvOrg = NULL; // delete used buffers in encoder class m_cTEncTop.deletePicBuffer(); // delete buffers & classes xDeleteBuffer(); xDestroyLib(); printRateSummary(); return; }
该部分的大致工作流程如下图所示:
Void TEncTop::encode(Bool flush, TComPicYuv* pcPicYuvOrg, TComList<TComPicYuv*>& rcListPicYuvRecOut, std::list<AccessUnit>& accessUnitsOut, Int& iNumEncoded ) { if (pcPicYuvOrg) { // get original YUV TComPic* pcPicCurr = NULL; xGetNewPicBuffer( pcPicCurr ); pcPicYuvOrg->copyToPic( pcPicCurr->getPicYuvOrg() ); // compute image characteristics if ( getUseAdaptiveQP() ) { m_cPreanalyzer.xPreanalyze( dynamic_cast<TEncPic*>( pcPicCurr ) ); } } if (!m_iNumPicRcvd || (!flush && m_iPOCLast != 0 && m_iNumPicRcvd != m_iGOPSize && m_iGOPSize)) { iNumEncoded = 0; return; } if ( m_RCEnableRateControl ) { m_cRateCtrl.initRCGOP( m_iNumPicRcvd ); } // compress GOP m_cGOPEncoder.compressGOP(m_iPOCLast, m_iNumPicRcvd, m_cListPic, rcListPicYuvRecOut, accessUnitsOut, false, false); if ( m_RCEnableRateControl ) { m_cRateCtrl.destroyRCGOP(); } iNumEncoded = m_iNumPicRcvd; m_iNumPicRcvd = 0; m_uiNumAllPicCoded += iNumEncoded; }
该部分的大致工作流程如下图所示:
以上只是粗略的流程图,特此说明。