这边博客主要记录在预研quick sync中涉及到的一些性能质量相关的关键参数设置。
github: https://github.com/MarkRepo/qsve
1. VPP处理过程伪代码:
MFXVideoVPP_QueryIOSurf(session, &init_param, response); allocate_pool_of_surfaces(in_pool, response[0].NumFrameSuggested); allocate_pool_of_surfaces(out_pool, response[1].NumFrameSuggested); MFXVideoVPP_Init(session, &init_param); in=find_unlocked_surface_and_fill_content(in_pool); out=find_unlocked_surface_from_the_pool(out_pool); for (;;) { sts=MFXVideoVPP_RunFrameVPPAsync(session,in,out,aux,&syncp); if (sts==MFX_ERR_MORE_SURFACE || sts==MFX_ERR_NONE) { MFXVideoCore_SyncOperation(session,syncp,INFINITE); process_output_frame(out); out=find_unlocked_surface_from_the_pool(out_pool); } if (sts==MFX_ERR_MORE_DATA && in==NULL) break; if (sts==MFX_ERR_NONE || sts==MFX_ERR_MORE_DATA) { in=find_unlocked_surface(in_pool); fill_content_for_video_processing(in); if (end_of_input_sequence()) in=NULL; } } MFXVideoVPP_Close(session); free_pool_of_surfaces(in_pool); free_pool_of_surfaces(out_pool);
2.Encoder处理过程伪代码:
MFXVideoENCODE_QueryIOSurf(session, &init_param, &request); allocate_pool_of_frame_surfaces(request.NumFrameSuggested); MFXVideoENCODE_Init(session, &init_param); sts=MFX_ERR_MORE_DATA; for (;;) { if (sts==MFX_ERR_MORE_DATA && !end_of_stream()) { find_unlocked_surface_from_the_pool(&surface); fill_content_for_encoding(surface); } surface2=end_of_stream()?NULL:surface; sts=MFXVideoENCODE_EncodeFrameAsync(session,NULL,surface2,bits,&syncp); if (end_of_stream() && sts==MFX_ERR_MORE_DATA) break; … // other error handling if (sts==MFX_ERR_NONE) { MFXVideoCORE_SyncOperation(session, syncp, INFINITE); do_something_with_encoded_bits(bits); } }
MFXVideoENCODE_Close(); free_pool_of_frame_surfaces();
3. Lowlatency 低延时参数设置:
//Encoder参数设置: m_mfxEncParams.mfx.GopRefDist = 1;
m_mfxEncParams.AsyncDepth = 1; m_mfxEncParams.mfx.NumRefFrame = 1; //Vpp参数设置: m_mfxVppParams.AsyncDepth = 1;
4. Quality 编码质量相关参数:
m_mfxEncParams.mfx.TargetKbps // 码率越高,质量越好, 流量越大 m_mfxEncParams.mfx.TargetUsage // 1~7 质量从高到低, 流量几乎不变,质量变化不明显
5.SPS PPS信息(开始一个新的编码序列)
//获取当前参数设置 mfxVideoParam par; memset(&par, 0, sizeof(p ar)); sts = m_pMfxEnc->GetVideoParam(&par); MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts); //设置编码器扩展选项,开始一个新序列 mfxExtEncoderResetOption resetOption; memset(&resetOption, 0, sizeof(resetOption)); resetOption.Header.BufferId = MFX_EXTBUFF_ENCODER_RESET_OPTION; resetOption.Header.BufferSz = sizeof(resetOption); resetOption.StartNewSequence = MFX_CODINGOPTION_ON; mfxExtBuffer* extendedBuffers[1]; extendedBuffers[0] = (mfxExtBuffer*) & resetOption; par.NumExtParam = 1; par.ExtParam = extendedBuffers; sts = m_pMfxEnc->Reset(&par); MSDK_CHECK_RESULT(sts,MFX_ERR_NONE,sts); //手动设置编码参数 mfxEncodeCtrl curEncCtrl; memset(&curEncCtrl, 0, sizeof(curEncCtrl)); curEncCtrl.FrameType = MFX_FRAMETYPE_I | MFX_FRAMETYPE_REF | MFX_FRAMETYPE_IDR; sts = m_pMfxEnc->EncodeFrameAsync(&curEncCtrl, &m_pVPPSurfacesVPPOutEnc[nEncSurfIdx], &m_mfxBS, &syncpEnc);
6. 运行环境依赖的rpm
libdrm, libdrm-devel, libva, intel-linux-media, kmod-ukmd(内核模块), libippcc.so, libippcore.so,(libippcc.so 会根据cpu型号依赖不同的动态库,如E3 1275 依赖libippccl9.so, i5 6400 依赖libippccy8.so)
7. 剩下的细节参考github上的源代码,稍后把代码放到github上管理起来。