Media (Intel® oneAPI Video Processing Library, Intel Media SDK)
Access community support with transcoding, decoding, and encoding in applications using media tools from Intel. This includes Intel® oneAPI Video Processing Library and Intel® Media SDK.
This community is designed for sharing of public information. Please do not share Intel or third-party confidential information here.

MFX_PICSTRUCT_FIELD_TFF breaks my encoder

New Contributor I


I'm trying to initialise my encoder for field/interlace encoding. The only parameter I change is PicStruct from MFX_PICSTRUCT_PROGRESSIVE to MFX_PICSTRUCT_FIELD_TFF, however doing that results in mfxENC->Query returning MFX_WRN_INCOMPATIBLE_VIDEO_PARAM. But setting the PicStruct to progressive works just fine.

What apart from setting PicStruct to MFX_PICSTRUCT_FIELD_TFF do I need to configure for QSV to accept my settings?

Is there a simpler way of setting the parameters, or any helper methods that I can use?..

See my code below and thanks for helping.




 // Initialize encoder parameters
    mfxVideoParam mfxEncParams;
    memset(&mfxEncParams, 0, sizeof (mfxEncParams));
    if (encParamFieldCount == 1) {
        mfxEncParams.mfx.FrameInfo.PicStruct = MFX_PICSTRUCT_PROGRESSIVE;
    } else if (encParamFieldCount == 2) {
        mfxEncParams.mfx.FrameInfo.PicStruct = MFX_PICSTRUCT_FIELD_TFF;
    } else {
        std::cout << "Failed init.. Encoding field structure unknown." << std::endl;
    mfxU16 adjustedVideoWidth = MSDK_ALIGN16(videoWidth);
    mfxU16 adjustedVideoHeight = (MFX_PICSTRUCT_PROGRESSIVE == mfxEncParams.mfx.FrameInfo.PicStruct) ? MSDK_ALIGN16(videoHeight) : MSDK_ALIGN32(videoHeight);
    mfxEncParams.mfx.FrameInfo.Width = adjustedVideoWidth;
    mfxEncParams.mfx.FrameInfo.Height = adjustedVideoHeight;
    mfxEncParams.mfx.CodecId = MFX_CODEC_AVC;
    mfxEncParams.mfx.CodecProfile = MFX_PROFILE_AVC_HIGH;
    mfxEncParams.mfx.CodecLevel = MFX_LEVEL_AVC_42;
    mfxEncParams.mfx.GopPicSize = videoFPS;
    mfxEncParams.mfx.GopRefDist = 1; //I and P frames only
    mfxEncParams.mfx.TargetUsage = MFX_TARGETUSAGE_BEST_SPEED; //TODO test quality and see if speed is at all changed
    mfxEncParams.mfx.TargetKbps = 4000;
    mfxEncParams.mfx.RateControlMethod = MFX_RATECONTROL_CBR;
    mfxEncParams.mfx.FrameInfo.FrameRateExtN = videoFPS;
    mfxEncParams.mfx.FrameInfo.FrameRateExtD = 1;
    mfxEncParams.mfx.FrameInfo.FourCC = MFX_FOURCC_NV12;
    mfxEncParams.mfx.FrameInfo.ChromaFormat = MFX_CHROMAFORMAT_YUV420;
    mfxEncParams.mfx.FrameInfo.CropX = 0;
    mfxEncParams.mfx.FrameInfo.CropY = 0;
    mfxEncParams.mfx.FrameInfo.CropW = videoWidth;
    mfxEncParams.mfx.FrameInfo.CropH = videoHeight;
    mfxEncParams.mfx.FrameInfo.BitDepthLuma = 8;
    mfxEncParams.mfx.FrameInfo.BitDepthChroma = 8;
    mfxEncParams.mfx.FrameInfo.Shift = 0;
    mfxEncParams.AsyncDepth = 1;

    mfxExtCodingOption extendedCodingOptions;
    memset(&extendedCodingOptions, 0, sizeof (extendedCodingOptions));
    extendedCodingOptions.Header.BufferId = MFX_EXTBUFF_CODING_OPTION;
    extendedCodingOptions.Header.BufferSz = sizeof (extendedCodingOptions);
    extendedCodingOptions.MaxDecFrameBuffering = 1;
    mfxExtBuffer * extendedBuffers[1];
    extendedBuffers[0] = (mfxExtBuffer*) & extendedCodingOptions;
    mfxEncParams.ExtParam = extendedBuffers;
    mfxEncParams.NumExtParam = 1;

    // Create Media SDK encoder
    // MFXVideoENCODE* mfxENC = new MFXVideoENCODE(mfxSES);

    mfxENC = std::shared_ptr<MFXVideoENCODE>(new MFXVideoENCODE(mfxSES));
    if (mfxENC == nullptr) {
        std::cout << "Creating a MFXVideoENCODE returned nullptr." << std::endl;
    std::cout << "QSV Video encoder created." << std::endl;

    //Probe to see if the encoder parameters are valid
    sts = mfxENC->Query(&mfxEncParams, &mfxEncParams);
    if (sts != MFX_ERR_NONE) {
        std::cout << __LINE__ << ": QSV Got error " << sts << std::endl;
    std::cout << "QSV Video encoder accepted encoding parameters." << std::endl;


0 Kudos
1 Reply

Hi Anders,


This is expected. Table A-4 of AVC spec says that for levels >=4.2 frame_mbs_only flag must be 1, on other words levels >=4.2 don't support interlace encode (without spec violation of course) . 
If app specifies level 4.2, MSDK detects incompatibility and forces PicStruct to MFX_PICSTRUCT_PROGRESSIVE to give a priority to the level, not to PicStruct. 
If application didn't specify particular level (4.2 in our case), then MSDK would calculate minimal possible level from Init params and would encode steam as interlace.