TI中文支持网
TI专业的中文技术问题搜集分享网站

dm365平台, 720P解码h264文件, 图像质量问题

专家好, 我遇到如下问题: 

软件架构为ipnc2.6, 在dm365平台实现解码功能,视频文件为 720P, 25fps,  发现仅有关键帧(I-frame) 解出的图像是很好质量的,其他帧(p-frame, b-frame) 解出来的帧是有马赛克的。

视频文件来源于本机自身。解码库已经更新到最新的了: dm365_h264dec_02_00_00_13_production.

该视频文件在电脑端用 ffplay 检查,发现是可以正常播放的,不存在马赛克现象。

我阅读了相关资料,觉得 p-frame 和 b-frame解出来的图像应该是依赖于 I-frame的(为了达到高压缩比率),猜测是通过某种方式叠加到之前的 I-frame去,但是具体怎么实现还没有头绪。不清楚是需要手工叠加还是解码库已经做了这个功能?

关键帧 (225帧): 

非关键帧(224帧): 

Ricky Xian:

代码: ( 已经根据网上其他资料修改过.)

//———– create —————————————————

void *ALG_vidDecCreate(ALG_VidDecCreate *create){ ALG_VidDecObj *pObj;

pObj = OSA_memAlloc(sizeof(ALG_VidDecObj));

if(pObj==NULL) return NULL;

memset(pObj, 0, sizeof(*pObj));

memcpy(&pObj->createPrm, create, sizeof(pObj->createPrm));

switch(create->codec) { case ALG_VID_CODEC_H264: strcpy(pObj->algName, ALG_VID_CODEC_H264_DEC_NAME); break; case ALG_VID_CODEC_MPEG4: strcpy(pObj->algName, ALG_VID_CODEC_MPEG4_DEC_NAME); break; case ALG_VID_CODEC_MJPEG: { ALG_JpgDecCreate jpgDecCreate;

jpgDecCreate.dataFormat = create->dataFormat; jpgDecCreate.maxWidth = create->maxWidth; jpgDecCreate.maxHeight = create->maxHeight;

pObj->hJpgDecode = ALG_jpgDecCreate(&jpgDecCreate);

if(pObj->hJpgDecode==NULL) return NULL;

return pObj; } break; default: OSA_memFree(pObj); return NULL; }

memcpy(&pObj->h264Params, &IH264VDEC_PARAMS, sizeof(pObj->h264Params)); pObj->params.size = sizeof(VIDDEC2_Params); pObj->params.maxHeight = create->maxHeight; pObj->params.maxWidth = create->maxWidth; pObj->params.maxFrameRate = 30000; //0 pObj->params.maxBitRate = ALG_VID_DEC_MAX_BITRATE; pObj->params.dataEndianness = XDM_BYTE; //pObj->params.forceChromaFormat = 9; pObj->params.forceChromaFormat = XDM_YUV_420SP;

pObj->h264Params.displayDelay = 0; pObj->h264Params.hdvicpHandle = NULL;// pObj->h264Params.resetHDVICPeveryFrame = TRUE; pObj->h264Params.disableHDVICPeveryFrame = 0; pObj->h264Params.frame_closedloop_flag = 1; pObj->h264Params.inputDataMode = 1; pObj->h264Params.sliceFormat = 1; pObj->h264Params.viddecParams = pObj->params; pObj->h264Params.viddecParams.size = sizeof(pObj->h264Params);

/* Create video decoder instance */ pObj->hDecode = VIDDEC2_create(gALG_hEngine, pObj->algName, &pObj->h264Params); if (pObj->hDecode == NULL) { OSA_ERROR("Failed to open video decode algorithm (%s)\n", pObj->algName); OSA_memFree(pObj); return NULL; }

return (void*)pObj;}

Ricky Xian:

//————-解压功能

int ALG_vidDecRun(void *hndl, ALG_VidDecRunPrm *prm, ALG_VidDecRunStatus *runStatus){ VIDDEC2_InArgs inArgs; VIDDEC2_OutArgs outArgs; XDM1_BufDesc inBufDesc; XDM_BufDesc outBufDesc; XDAS_Int32 outBufSizeArray[2]; XDAS_Int32 status; XDAS_Int8 *outBufPtrs[2]; ALG_VidDecObj *pObj; IH264VDEC_DynamicParams h264DynParams; pObj = (ALG_VidDecObj *)hndl;

if(pObj==NULL) return OSA_EFAIL;

if(pObj->createPrm.codec == ALG_VID_CODEC_MJPEG) {

ALG_JpgDecRunPrm jpgDecRun; ALG_JpgDecRunStatus jpgDecStatus;

jpgDecRun.inAddr = prm->inAddr; jpgDecRun.inDataSize = prm->inDataSize; jpgDecRun.outAddr = prm->outAddr; jpgDecRun.outOffsetH = prm->outOffsetH; jpgDecRun.outOffsetV = prm->outOffsetV; jpgDecRun.outStartX = 0; jpgDecRun.outStartY = 0;

status = ALG_jpgDecRun(pObj->hJpgDecode, &jpgDecRun, &jpgDecStatus); if(status!=OSA_SOK) return OSA_EFAIL;

runStatus->bytesUsed = jpgDecStatus.bytesUsed; runStatus->isKeyFrame = TRUE; runStatus->frameWidth = jpgDecStatus.frameWidth; runStatus->frameHeight= jpgDecStatus.frameHeight; runStatus->outputBufId= prm->inputBufId; runStatus->freeBufId = prm->inputBufId; runStatus->outStartX = jpgDecRun.outStartX; runStatus->outStartY = jpgDecRun.outStartY; runStatus->outOffsetH = jpgDecRun.outOffsetH; runStatus->outOffsetV = jpgDecRun.outOffsetV;

return OSA_SOK; }

if(pObj->hDecode==NULL) return OSA_EFAIL;

if(pObj->curFrameNum==0) { pObj->dynamicParams.size = sizeof(VIDDEC2_DynamicParams); pObj->dynamicParams.decodeHeader = XDM_DECODE_AU; pObj->dynamicParams.displayWidth = prm->outOffsetH; pObj->dynamicParams.frameSkipMode = IVIDEO_NO_SKIP;

// ricky: from web: // http://e2e.ti.com/support/embedded/multimedia_software_codecs/f/356/t/63637.aspx pObj->dynamicParams.frameOrder = IVIDDEC2_DECODE_ORDER;

pObj->decStatus.size = sizeof(VIDDEC2_Status); pObj->decStatus.data.buf = NULL; h264DynParams.viddecDynamicParams = pObj->dynamicParams; h264DynParams.viddecDynamicParams.size = sizeof(h264DynParams); h264DynParams.resetHDVICPeveryFrame = 1; h264DynParams.dataSyncHandle = NULL; h264DynParams.getDataFxn = NULL; status = VIDDEC2_control(pObj->hDecode, XDM_SETPARAMS, &h264DynParams, &pObj->decStatus); if (status != VIDDEC2_EOK) { OSA_ERROR("XDM_SETPARAMS failed, status=%ld\n", status); return OSA_EFAIL; }

/* Get buffer information from video decoder */ pObj->decStatus.size = sizeof(VIDDEC2_Status); pObj->decStatus.data.buf = NULL;

pObj->dynamicParams.size = sizeof(VIDDEC2_DynamicParams); status = VIDDEC2_control(pObj->hDecode, XDM_GETBUFINFO, &pObj->dynamicParams, &pObj->decStatus); if (status != VIDDEC2_EOK) { OSA_ERROR("XDM_GETBUFINFO failed, status=%ld\n", status); return OSA_EFAIL; }

#ifdef ALG_VID_DEC_TEST_DEBUG OSA_printf(" ALG: VidDec: XDM_GETBUFINFO: min out bufs:%ld,size:%ld %ld\n",pObj->decStatus.bufInfo.minNumOutBufs,pObj->decStatus.bufInfo.minOutBufSize[0], pObj->decStatus.bufInfo.minOutBufSize[1]); #endif }

pObj->dynamicParams.size = sizeof(VIDDEC2_DynamicParams); pObj->decStatus.size = sizeof(VIDDEC2_Status); pObj->decStatus.data.buf = NULL;

outBufSizeArray[0] = (prm->outOffsetH)*(prm->outOffsetV); outBufSizeArray[1] = outBufSizeArray[0]/2;

inBufDesc.descs[0].bufSize = prm->inDataSize; inBufDesc.descs[0].buf = (XDAS_Int8 *)prm->inAddr; inBufDesc.numBufs = 1;

outBufPtrs[0] = (XDAS_Int8 *)prm->outAddr; outBufPtrs[1] = (XDAS_Int8 *)(prm->outAddr + outBufSizeArray[0]) ;

outBufDesc.bufSizes = outBufSizeArray; outBufDesc.bufs = (XDAS_Int8 **) &outBufPtrs; outBufDesc.numBufs = 2;

inArgs.size = sizeof(VIDDEC2_InArgs); inArgs.numBytes = prm->inDataSize; inArgs.inputID = prm->inputBufId+1; // must be greater than 0

outArgs.size = sizeof(VIDDEC2_OutArgs); outArgs.outBufsInUseFlag=0; status = VIDDEC2_process(pObj->hDecode, &inBufDesc, &outBufDesc, &inArgs, &outArgs);

status = VIDDEC2_control(pObj->hDecode, XDM_GETSTATUS, &pObj->dynamicParams, &pObj->decStatus); if (status != VIDDEC2_EOK) { OSA_ERROR("XDM_GETSTATUS failed, status=%ld\n", status); return OSA_EFAIL; }

runStatus->bytesUsed = outArgs.bytesConsumed;

if (status != VIDDEC2_EOK) { OSA_ERROR("status=%ld\n", status); return OSA_EFAIL; }

switch (outArgs.displayBufs[0].frameType) { case IVIDEO_I_FRAME: runStatus->isKeyFrame = TRUE; break; case IVIDEO_P_FRAME: runStatus->isKeyFrame = FALSE; break; case IVIDEO_B_FRAME: runStatus->isKeyFrame = FALSE; break; case IVIDEO_IDR_FRAME: runStatus->isKeyFrame = TRUE; break; case IVIDEO_II_FRAME: runStatus->isKeyFrame = TRUE; break; case IVIDEO_PP_FRAME: runStatus->isKeyFrame = FALSE; break; default: runStatus->isKeyFrame = FALSE; break; }

runStatus->frameWidth = pObj->decStatus.outputWidth; runStatus->frameHeight = pObj->decStatus.outputHeight;

if(outArgs.outBufsInUseFlag == 1){ inBufDesc.descs[0].buf = (XDAS_Int8 *)prm->inAddr + runStatus->bytesUsed;

status = VIDDEC2_process(pObj->hDecode, &inBufDesc, &outBufDesc, &inArgs, &outArgs);

runStatus->bytesUsed += outArgs.bytesConsumed; if (status != VIDDEC2_EOK) { OSA_ERROR("status=%ld\n", status);// return OSA_EFAIL; }

VIDDEC2_control(pObj->hDecode, XDM_GETSTATUS, &pObj->dynamicParams, &pObj->decStatus); if (status != VIDDEC2_EOK) { OSA_ERROR("XDM_GETSTATUS failed with error code = 0x%x , status=%ld\n", pObj->decStatus.extendedError,status);// OSA_fileWriteFile("InputBitstream.dat", (XDAS_Int8 *)prm->inAddr, prm->inDataSize); OSA_printf("\r\n Bytes Consumed so far = %d ",runStatus->bytesUsed); return OSA_EFAIL; }} if(outArgs.displayBufs[0].bufDesc[0].buf == NULL) { return OSA_EFAIL; } else { runStatus->outputBufId = outArgs.outputID[0]-1; // to adjust for +1 done in inputID runStatus->freeBufId = outArgs.freeBufID[0]-1;

if(pObj->curFrameNum==0) { pObj->outStartY = ((Uint32)outArgs.displayBufs[0].bufDesc[0].buf – (Uint32)prm->outAddr)/prm->outOffsetH; pObj->outStartX = ((Uint32)outArgs.displayBufs[0].bufDesc[0].buf – (Uint32)prm->outAddr)%prm->outOffsetH; } runStatus->outStartX = pObj->outStartX; runStatus->outStartY = pObj->outStartY; runStatus->outOffsetH= prm->outOffsetH; runStatus->outOffsetV= prm->outOffsetV; } pObj->curFrameNum++; return OSA_SOK;}

Feng Dong:

解码的文件是什么编码得来的,解365的编码文件怎样?

Ricky Xian:

Hi Feng Dong,

这个264文件就是dm365本机自身编码过来的.

赞(0)
未经允许不得转载:TI中文支持网 » dm365平台, 720P解码h264文件, 图像质量问题
分享到: 更多 (0)