Community
cancel
Showing results for 
Search instead for 
Did you mean: 
cedronius__anders
New Contributor I
115 Views

MFX_PICSTRUCT_FIELD_TFF breaks my encoder

Hi,

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.

 

/Anders

 

 // 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;
        return;
    }
    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.IOPattern = MFX_IOPATTERN_IN_SYSTEM_MEMORY;
    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;
        return;
    }
    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;
        return;
    }
    std::cout << "QSV Video encoder accepted encoding parameters." << std::endl;

 

0 Kudos
1 Reply
Dmitry_E_Intel
Employee
115 Views

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.

https://github.com/Intel-Media-SDK/MediaSDK/blob/1e7b8c287346065a31da94fa500bd18af70d988b/_studio/mf...

 

Regards,

Dmitry

Reply