1、openRtComm 系统的解码主要依靠如下函数:
int doDecodeVideo( QY_TRANSFORM * pTransform, MIS_MSGU * pMsgBuf )
2、那么这个函数里主要实现了那些东西呢
下面这段代码就是整个doDecodeVideo()函数中最核心的地方,判断使用哪中方式来解码,这里列出mediaSdk、amf、vp8,nv(N卡的方式目前还不可用)等方式解码:
switch ( uiModuleType_toDec ) { case CONST_moduleType_mediaSdk_dec: return doDecodeVideo_mediaSdk( pTransform, index_pMems_from, index_activeMems_from, pMsgBuf ); break; case CONST_moduleType_dec_nv: // 2014/06/25 return doDecodeVideo_nv( pTransform, index_pMems_from, index_activeMems_from, pMsgBuf ); break; case CONST_moduleType_dec_amf: // 2015/05/06 return doDecodeVideo_amf( pTransform, index_pMems_from, pMsgBuf ); break; case CONST_moduleType_dec_vp8: return doDecodeVideo_vp8( pTransform, index_pMems_from, index_activeMems_from, pMsgBuf ); break; default: break; }
3、这里我们拿出来已经实现的doDecodeVideo_mediaSdk()函数深度解析一下:
这段代码中执行了initTaskAvFrom_video() ,这是先执行一下初始化解压缩
if ( initTaskAvFrom_video( pProcInfo, pActiveMem_from, index_activeMems_from, pTransform->iTaskId, uiModuleType_suggested, bUseDecTool, pTransform ) ) goto errLabel;
4、这里再查看下initTaskAvFrom_video()的内部,发现其中执行了qf_qdcInitDecompressVideo(),这个函数就是执行了 解码初始化
if ( !pModule || !pModule->compress.pf_qdcInitDecompressVideo ) {
5、返回到doDecodeVideo_mediaSdk()函数,接着往下看,发现这段代码中,执行了一个pf_qdcDecompressVideoRun()函数(异步的方式执行的压缩),它就是解码函数 进入一循环,每循环都读取压缩包:
if ( pCusModules->pMediaSdk_dec->compress.pf_qdcDecompressVideoRun( &pTransform->video.u.qoi.myQoi.common ) ) goto errLabel;
6、经过pf_qdcDecompressVideoRun()函数中,内部是通过压缩解压缩模块hdDec中的CMYSmplBitstreamReader::ReadNextDrame()函数处理h264流输入对象 ,
通过调用pf_transformGetSpsPps来获取输入数据。
再次调用辅助函数ReadNextFrame_func()获取输入数据。
mfxStatus CMySmplBitstreamReader::ReadNextFrame( mfxBitstream *pBS) { ... ... if ( !pObj->common.bInited2 ) { int nSize = pBS->MaxLength - pBS->DataLength; if ( pQdcObjInfo->cfg.v.pf_transformGetSpsPps( pQdcObjInfo->cfg.v.uiTransformType_pParent, pQdcObjInfo->cfg.v.pParent_transform, pQdcObjInfo->cfg.v.iDecParam_index_pMems_from, ( char * )(pBS->Data + pBS->DataLength), ( unsigned int * )&nSize ) ) return MFX_ERR_UNKNOWN; pBS->DataLength += nSize; #if 0 _sntprintf( tBuf, mycountof( tBuf ), _T( "Decline: spsPpsLen %d" ), nSize ); tmp_showInfo( tBuf ); #endif } sts = this->ReadNextFrame_func( pBS ); //再次调用辅助函数 return sts; }
7、接着看下h264的输出,压缩解压缩模块hdDec中的CMySmplYUVWrite::WriteNextFrame()函数处理h264流输出对象
通过调用三个辅助函数将解压缩输出图像输出。
mfxStatus CMySmplYUVWriter::WriteNextFrame(mfxFrameSurface1 *pSurface) { mfxStatus sts = MFX_ERR_UNKNOWN; if ( this->WriteNextFrame_pre( ) ) goto errLabel; //调用预处理函数 if ( this->WriteNextFrame0( pSurface ) ) goto errLabel; //调用辅助函数0 if ( this->WriteNextFrame1( ) ) goto errLabel; //调用辅助函数1 sts = MFX_ERR_NONE; errLabel: return MFX_ERR_NONE; // sts; }
8、回到doDecodeVideo_mediaSdk()函数,到最后执行了exitTaskAvFrom_video()函数,它是做编码清理。
exitTaskAvFrom_video( pProcInfo, pTransform );
以上就是openRtComm系统中解码的核心步骤,做N卡解压缩的朋友需要在解码上实现以上列出的函数。
有一篇文章也是详细介绍了这解码的函数中的参数详解:https://bbs.qycx.com/index/jie/194.html
hdDec模块下载地址:https://bbs.qycx.com/index/jie/193.html