main() // 主函数
//给H264AVCEncoderTest* pcH264AVCEncoderTest分配空间,后面函数用它调用
H264AVCEncoderTest::create()
//初始化pcH264AVCEncoderTest的成员,主要是编码器的参数配置
pcH264AVCEncoderTest->init()
//给EncoderCodingParameter* m_pcEncoderCodingParameter分配空间
//它是H264AVCEncoderTest *pcH264AVCEncoderTest的成员
EncoderCodingParameter::create( m_pcEncoderCodingParameter ) //编码参数
//解析输入命令行,并把相应参数写入EncoderCodingParameter的基类CodingParameter的成员中
m_pcEncoderCodingParameter->init()
//读取配置文件
xReadFromFile( cFilename, rcBitstreamFile )
fopen( rcFilename.c_str(), "r"); encoder.cfg //先创建每个参数 m_pEncoderLines[uiParLnCount++] = new EncoderConfigLineXXX //从配置文件里读一行,重复直到文件末尾 xReadLine( f, acTags ) //查找读到的参数对应的m_pEncoderLines,更新值 fclose( f );
//从上面的配置文件读到的参数中得到有几层,和每层配置文件路径 //对每一层 setDependencyId(ui); //设置Did //读取每一层的配置文件 读到如下类中 //EncoderCodingParameter::LayerParameters m_acLayerParameters[n] xReadLayerFromFile( acLayerConfigName[ui], getLayerParameters(ui) )
//设置CGS/MGS的Dependency_Id和Quality_id //由BaseLayer更新当前Layer的ResizeParameter----------ESS |
//对每一层 rcLayer = m_pcEncoderCodingParameter->getLayerParameters( uiLayer );
//创建并打开重建输出文件
WriteYuvToFile::create( m_apcWriteYuv[uiLayer] )
m_apcWriteYuv[uiLayer]->init( rcLayer.getOutputFilename() )
//创建并打开读入的视频文件
ReadYuvFile ::create( m_apcReadYuv [uiLayer] )
m_apcReadYuv[uiLayer]->init()
//创建并打开码流文件
WriteBitstreamToFile::create ( m_pcWriteBitstreamToFile )
m_pcWriteBitstreamToFile->init ( m_cEncoderIoParameter.cBitstreamFilename )
注意: 以上三个文件都是H264AVCEncoderTest类的成员 WriteBitstreamToFile* m_pcWriteBitstreamToFile; WriteYuvToFile* m_apcWriteYuv [MAX_LAYERS]; ReadYuvFile* m_apcReadYuv [MAX_LAYERS];
也用到了辅助IO的成员 EncoderIoParameter m_cEncoderIoParameter; |
//给编码器分配空间:它是H264AVCEncoderTest *pcH264AVCEncoderTest的成员
h264::CreaterH264AVCEncoder::create( m_pcH264AVCEncoder )
ParameterSetMng ::create( m_pcParameterSetMng ) BitWriteBuffer ::create( m_pcBitWriteBuffer ) BitCounter ::create( m_pcBitCounter ) NalUnitEncoder ::create( m_pcNalUnitEncoder) SliceEncoder ::create( m_pcSliceEncoder ) UvlcWriter ::create( m_pcUvlcWriter ) UvlcWriter ::create( m_pcUvlcTester, false ) CabacWriter ::create( m_pcCabacWriter ) MbCoder ::create( m_pcMbCoder ) MbEncoder ::create( m_pcMbEncoder ) LoopFilter ::create( m_pcLoopFilter ) IntraPredictionSearch ::create( m_pcIntraPrediction ) MotionEstimationQuarterPel ::create( m_pcMotionEstimation ) H264AVCEncoder ::create( m_pcH264AVCEncoder ) ControlMngH264AVCEncoder ::create( m_pcControlMng ) ReconstructionBypass ::create( m_pcReconstructionBypass ) QuarterPelFilter ::create( m_pcQuarterPelFilter ) Transform ::create( m_pcTransform ) SampleWeighting ::create( m_pcSampleWeighting ) XDistortion ::create( m_pcXDistortion ) PicEncoder ::create( m_pcPicEncoder ) //每一层的编码器 for( UInt uiLayer = 0; uiLayer < MAX_LAYERS; uiLayer++ ) { LayerEncoder ::create( m_apcLayerEncoder [uiLayer] ) PocCalculator ::create( m_apcPocCalculator [uiLayer] ) YuvBufferCtrl ::create( m_apcYuvFullPelBufferCtrl[uiLayer] ) YuvBufferCtrl ::create( m_apcYuvHalfPelBufferCtrl[uiLayer] ) } |
//设置NAL UNIT起始码m_aucStartCodeBuffer[],绑定到H264AVCEncoderTest::BinData m_cBinDataStartCode;
//进行编码
pcH264AVCEncoderTest->go ()
//初始化编码器参数 h264::CreaterH264AVCEncoder* m_pcH264AVCEncoder; H264AVCEncoderTest成员
m_pcH264AVCEncoder->init( m_pcEncoderCodingParameter )
/* 几个参数关系 1. H264AVCEncoderTest的成员CreaterH264AVCEncoder* m_pcH264AVCEncoder调用init 2. 初始化H264AVCEncoderTest的成员EncoderCodingParameter * m_pcEncoderCodingParameter 3. 而CreaterH264AVCEncoder的成员CodingParameter* m_pcCodingParameter 被赋值传入的参数m_pcEncoderCodingParameter */
RateDistortion::create( m_pcRateDistortion ) //给率失真计算类分配空间 RateDistortion m_pcBitWriteBuffer ->init() //初始化写Packet/比特流的类 BitWriteBuffer m_pcBitCounter ->init() //初始化计算比特数类 BitCounter m_pcXDistortion ->init() //初始化计算失真所需的参数 (块行数/列数/Dist计算函数指针)XDistortion m_pcSampleWeighting ->init() //初始化加权函数 SampleWeighting
//初始化写NalUnit的类 NalUnitEncoder m_pcNalUnitEncoder->init( m_pcBitWriteBuffer, m_pcUvlcWriter, m_pcUvlcTester ) m_pcUvlcWriter ->init( m_pcBitWriteBuffer ) //关联比特流缓存和写Uvlc的类 UvlcWriter m_pcUvlcTester ->init( m_pcBitCounter ) //关联比特计数和写Uvlc的类 UvlcWriter m_pcCabacWriter ->init( m_pcBitWriteBuffer ) //初始化Cabac的缓存 CabacWriter CabacEncoder m_pcParameterSetMng ->init() //空函数 m_pcSliceEncoder->init() //关联MbEncoder、MbCoder、ControlMngH264AVCEncoder、CodingParameter、 PocCalculator和Transform 给Slice编码器 SliceEncoder m_pcReconstructionBypass ->init() //空函数 m_pcLoopFilter->init( m_pcControlMng, m_pcReconstructionBypass, true ) //关联 ControlMngH264AVCEncoder和 ReconstructionBypass给去块滤波器 LoopFilter m_pcQuarterPelFilter->init() //分配1/4像素插值滤波器 QuarterPelFilter m_pcMbEncoder->init() //关联Transform、IntraPredictionSearch、MotionEstimation、CodingParameter、 RateDistortion和XDistortion给宏块编码器 MbEncoder m_pcMotionEstimation ->init() MotionEstimation MotionCompensation::init() //初始化MC相关—1/4插值滤波、变换、加权 //设置计算失真、MV搜索参数 MotionEstimationCost::xInit() //设置RD相关 //设置跟搜索范围搜索深度有关参数 // spiral search参数
m_pcControlMng->init() //分配上面所有的编码过程类到ControlMngH264AVCEncoder类中,集中管理 //包括每层的LayerEncoder、PocCalculator和YuvBufferCtrl
m_pcPicEncoder->init() //初始化AVC编码器 m_pcH264AVCEncoder ->init() //初始化SVC编码器 分配LayerEncoder、ParameterSetMng、PocCalculator、 // NalUnitEncoder、ControlMngIf和CodingParameter //初始化LayerEncoder* m_apcLayerEncoder[MAX_LAYERS] 和AccessUnitDataList m_cAccessUnitDataList; H264AVCEncoder
//对每层 m_apcLayerEncoder[uiLayer]->init() //初始化每层编码所需的参数 //把配置文件读入的参数LayerParameter复制过来 xInitCodingOrder() // 初始化编码顺序和分层的对应关系 //初始化如ESS、LARDO等参数
//计算每层采用LARDO的情况 |
//Rate Control相关初始化,与GOP有关
//写SPS和PPS
参数: UChar aucParameterSetBuffer[1000] 作为缓存 BinData cBinData 绑定上面的缓存 ExtBinDataAccessor cExtBinDataAccessor 操纵上面的cBinData | ||
m_pcH264AVCEncoder->writeParameterSets( &cExtBinDataAccessor, pcAVCSPS, bMoreSets ) CreaterH264AVCEncoder m_pcH264AVCEncoder->writeParameterSets( pcExtBinDataAccessor, rpcAVCSPS, rbMoreSets ) H264AVCEncoder //如果是第一次调用 xInitParameterSets() //对每一层 //设置基本参数 SequenceParameterSet::create( pcSPS ) // 分配SPS空间 PictureParameterSet ::create( pcPPS ) // 分配PPS空间 //设置SPS和PPS的ID和NalUnitType
m_pcParameterSetMng->store( pcPPS ) m_pcParameterSetMng->store( pcSPS )
m_pcParameterSetMng->setActiveSPS( pcSPS->getSeqParameterSetId(), uiDQId + ui );
//设置SPS的内容 //设置subset SPS的内容 //设置PPS内容
// 初始化每层与帧分辨率有关的参数 m_pcControlMng->initParameterSets( *pcSPS, *pcPPS ) ControlMngH264AVCEncoder m_apcYuvFullPelBufferCtrl[uiLayer]->initSPS( uiAllocY, uiAllocX, YUV_Y_MARGIN, YUV_X_MARGIN) m_apcYuvHalfPelBufferCtrl[uiLayer]->initSPS( uiAllocY, uiAllocX, YUV_Y_MARGIN, YUV_X_MARGIN, 1 ) m_apcLayerEncoder [uiLayer]->initParameterSets( rcSPS, rcPPS )
//从ParameterSetMng类中的SPS和PPS缓存m_cSPSBuf和m_cPPSBuf读取并保存到 //std::list<SequenceParameterSet*> m_cUnWrittenSPS 和 std::list<PictureParameterSet*> m_cUnWrittenPPS; m_pcParameterSetMng->setParamterSetList( m_cUnWrittenSPS, m_cUnWrittenPPS )
// 写SEI相关信息
//m_cUnWrittenSPS和m_cUnWrittenPPS非空,则 m_pcNalUnitEncoder->initNalUnit( pcExtBinDataAccessor ) //初始化写Nalunit的类 m_pcBitWriteBuffer->initPacket( (UInt*)(m_pucTempBuffer), m_uiPacketLength-1 ) //初始化写比特流的类 //读取SPS/PPS m_pcNalUnitEncoder->write( rcSPS ) rcSPS.write( m_pcHeaderSymbolWriteIf ) //由m_pcHeaderSymbolWriteIf写NalUnit m_pcNalUnitEncoder->closeNalUnit( uiBits ) xWriteTrailingBits() //写1000…补齐 m_pcBitWriteBuffer->flushBuffer() //把拖尾等最后的数据写入并计算bit convertRBSPToPayload(…) //加上0x03
m_pcWriteBitstreamToFile->writePacket ( &m_cBinDataStartCode ) //先写starcode 0x00000001 区分NALUNIT m_pcWriteBitstreamToFile->writePacket ( &cExtBinDataAccessor ) //再写实际NAL内容 |
//计算每层图像宽高、Crop信息和luma与chroma的Offset等
//对每个Frame ==============================START===============================
//对每一层 XXXXXXXXXXXXXXX START
本函数的重要参数:在H264AVCEndoderTest::go()函数里 PicBuffer* apcOriginalPicBuffer [MAX_LAYERS]; //原始图像list PicBuffer* apcReconstructPicBuffer [MAX_LAYERS]; //重建图像list PicBufferList acPicBufferOutputList [MAX_LAYERS]; //输出图像list PicBufferList acPicBufferUnusedList [MAX_LAYERS]; ExtBinDataAccessorList cOutExtBinDataAccessorList; //输出NalUnit的list |
//从PicBufferList m_acUnusedPicBufferList [MAX_LAYERS] 中弹出一个PicBuffer
//并存入PicBufferList m_acActivePicBufferList [MAX_LAYERS];
xGetNewPicBuffer( apcReconstructPicBuffer [uiLayer], uiLayer, auiPicSize[uiLayer] ) //重建帧
xGetNewPicBuffer( apcOriginalPicBuffer [uiLayer], uiLayer, auiPicSize[uiLayer] ) //原始帧
m_apcReadYuv[uiLayer]->readFrame(…) // 读取一帧到apcOriginalPicBuffer [uiLayer]
XXXXXXXXXXXXXXX END
//处理一帧,所有Layer都处理,数据写入cOutExtBinDataAccessorList CreaterH264AVCEncoder调用
m_pcH264AVCEncoder->process(cOutExtBinDataAccessorList,apcOriginalPicBuffer,
apcReconstructPicBuffer, acPicBufferOutputList, acPicBufferUnusedList )
àm_pcH264AVCEncoder->process( rcExtBinDataAccessorList, H264AVCEncoder调用
apcOriginalPicBuffer,
apcReconstructPicBuffer,
apcPicBufferOutputList,
apcPicBufferUnusedList )
xWrite ( cOutExtBinDataAccessorList, uiBytesUsed ) //把编码一帧后的NALUNIT写到比特流中
//重复,直到cOutExtBinDataAccessorList为空
m_pcWriteBitstreamToFile->writePacket( &m_cBinDataStartCode ) //写起始码
m_pcWriteBitstreamToFile->writePacket( rcList.front() ) //写NalUnit
//对每层
xWrite ( acPicBufferOutputList[uiLayer], uiLayer ) //把输出图像(重建文件)写到文件中
//从list中弹出一个图像
m_apcWriteYuv[uiLayer]->writeFrame()
m_cFile.write( pucSrc, uiWidth ) //重复调用此函数写重建图像
xRelease( acPicBufferUnusedList[uiLayer], uiLayer )
xRemovePicBuffer( rcPicBufferList, uiLayer ) //删除未使用的图像
//从m_acActivePicBufferList中找到acPicBufferUnusedList中每一帧
//从m_acActivePicBufferList中删除,添加到m_acUnusedPicBufferList中
==============================END===============================
m_pcH264AVCEncoder->finish(…)
m_pcH264AVCEncoder->finish(…)
//把不足GOP数量剩下的帧进行编码
xProcessGOP( apcPicBufferOutputList, apcPicBufferUnusedList )
//从AccessUnitDataList m_cAccessUnitDataList的成员std::list<AccessUnitData>m_cAccessUnitDataList
//取出编码后的NalUnit到cOutExtBinDataAccessorList
m_cAccessUnitDataList.emptyNALULists( rcExtBinDataAccessorList )
m_apcLayerEncoder[uiLayer]->finish() //输出每层的编码信息,如比特数和PSNR等
xWrite ( cOutExtBinDataAccessorList, uiWrittenBytes ) //把cOutExtBinDataAccessorList中的Nal写到比特流
//对每一层
xWrite ( acPicBufferOutputList[uiLayer], uiLayer ) //把输出图像(重建文件)写到文件中
xRelease( acPicBufferUnusedList[uiLayer], uiLayer ) //删除未使用的图像
//写SEI信息
m_pcH264AVCEncoder->writeParameterSets( &cExtBinDataAccessor, pcAVCSPS, bMoreSets )
m_pcWriteBitstreamToFile->writePacket ( &m_cBinDataStartCode )
m_pcWriteBitstreamToFile->writePacket ( &cExtBinDataAccessor )
m_pcWriteBitstreamToFile->uninit() //关闭比特流文件
m_pcWriteBitstreamToFile->destroy() //释放空间
ScalableDealing() //把临时的比特流文件转成Scalable比特流
//结束函数
pcH264AVCEncoderTest->destroy()
//释放m_cBinDataStartCode、m_pcH264AVCEncoder、读写文件、m_pcEncoderCodingParameter和一些List的空间