dynamic change bitrate in CBR mode

dynamic change bitrate in CBR mode

Hi:
    I'm using the SDK(API 1.8 for linux) to change the target bitrate dynamically. When I use VBR mode, it seems to be OK, but when I use CBR mode, the Reset() function seems success(return MFX_WRN_INCOMPATIBLE_VIDEO_PARAM), and after call GetVideoParam(), the value of bitrate is what I set , but the streem contain the old bitrate, maybe I am missing something?

the key code is as follow:
Step1: Init param
mfxStatus sts = MFX_ERR_NONE;
m_EncExtParams.clear();
MSDK_ZERO_MEMORY(m_mfxEncParams);
MSDK_ZERO_MEMORY(m_EncResponse);
m_mfxEncParams.mfx.CodecId                 = MFX_CODEC_AVC;
m_mfxEncParams.mfx.TargetUsage             = m_h264param.usageTarget; // trade-off between quality and speed
m_mfxEncParams.mfx.TargetKbps              = m_h264param.bitrate; // in Kbps
m_mfxEncParams.mfx.RateControlMethod       = m_h264param.rctype;
m_mfxEncParams.mfx.FrameInfo.FrameRateExtN = m_h264param.frameN;
m_mfxEncParams.mfx.FrameInfo.FrameRateExtD = m_h264param.frameD;
m_mfxEncParams.mfx.EncodedOrder            = 0;
if ( SYSTEM_MEMORY == m_memType ) {
    m_mfxEncParams.IOPattern                = MFX_IOPATTERN_IN_SYSTEM_MEMORY;
} else {
    m_mfxEncParams.IOPattern               = MFX_IOPATTERN_IN_VIDEO_MEMORY;
}

m_mfxEncParams.mfx.FrameInfo.FourCC       = MFX_FOURCC_NV12;
m_mfxEncParams.mfx.FrameInfo.ChromaFormat = MFX_CHROMAFORMAT_YUV420;
m_mfxEncParams.mfx.FrameInfo.PicStruct    = m_h264param.interlace;

m_mfxEncParams.mfx.FrameInfo.Width  = MSDK_ALIGN16(m_h264param.width);
m_mfxEncParams.mfx.FrameInfo.Height = (MFX_PICSTRUCT_PROGRESSIVE == m_mfxEncParams.mfx.FrameInfo.PicStruct)?
MSDK_ALIGN16(m_h264param.height) : MSDK_ALIGN32(m_h264param.height);

printf("EncParams.FrameInfo.Width=[%d],Height=[%d]\n", m_mfxEncParams.mfx.FrameInfo.Width, m_mfxEncParams.mfx.FrameInfo.Height);

m_mfxEncParams.mfx.FrameInfo.CropX = 0;
m_mfxEncParams.mfx.FrameInfo.CropY = 0;
m_mfxEncParams.mfx.FrameInfo.CropW = m_h264param.width;
m_mfxEncParams.mfx.FrameInfo.CropH = m_h264param.height;

//mfxExtCodingOption config
// CAVLC EOF HRD
MSDK_ZERO_MEMORY(m_CodingOption);
m_CodingOption.CAVLC = MFX_CODINGOPTION_OFF;
m_CodingOption.EndOfStream = MFX_CODINGOPTION_OFF;

m_CodingOption.NalHrdConformance = MFX_CODINGOPTION_OFF;
m_mfxEncParams.mfx.RateControlMethod = MFX_RATECONTROL_VBR;
m_mfxEncParams.mfx.MaxKbps = m_mfxEncParams.mfx.TargetKbps*1.01;
//m_mfxEncParams.mfx.RateControlMethod = MFX_RATECONTROL_CBR;

m_CodingOption.Header.BufferId = MFX_EXTBUFF_CODING_OPTION;
m_CodingOption.Header.BufferSz = sizeof(m_CodingOption);
m_EncExtParams.push_back((mfxExtBuffer *)&m_CodingOption);

if (!m_EncExtParams.empty())
{
    m_mfxEncParams.ExtParam = &m_EncExtParams[0]; // vector is stored linearly in memory
    m_mfxEncParams.NumExtParam = (mfxU16)m_EncExtParams.size();
}

m_mfxEncParams.mfx.GopPicSize = 250;
m_mfxEncParams.mfx.IdrInterval = 1;

m_mfxEncParams.mfx.CodecProfile = m_h264param.profile;
if (m_h264param.profile != MFX_PROFILE_AVC_BASELINE ) {
    m_mfxEncParams.mfx.GopRefDist = m_h264param.bframes + 1;
}

m_mfxEncParams.mfx.NumRefFrame = 3;

Step2: change bitrate
mfxVideoParam oldParam;
MSDK_ZERO_MEMORY(oldParam);
mfxStatus status = m_pmfxENC->GetVideoParam(&oldParam);
oldParam.mfx.TargetKbps = bitrate_kb;
oldParam.mfx.MaxKbps = oldParam.mfx.TargetKbps*1.01; // if CBR, ignore
if (status != MFX_ERR_NONE){
    printf("+++[GetVideoParam] error status:%d [%s:%d]\n", status, __FILE__, __LINE__);
}
sts = m_pmfxENC->Reset(&oldParam);
printf("+++Reset status:%d\n", sts);
MSDK_IGNORE_MFX_STS(sts, MFX_WRN_INCOMPATIBLE_VIDEO_PARAM);
if (sts != MFX_ERR_NONE){
    printf("+++[Reset] error sts:%d [%s:%d]\n", sts, __FILE__, __LINE__);
} else {
    MSDK_ZERO_MEMORY(oldParam);
    m_pmfxENC->GetVideoParam(&oldParam);
    printf("+++After change bitrate:%dkb\n", oldParam.mfx.TargetKbps);
}

 

 

AttachmentSize
Downloadimage/png CBR mode.png28.89 KB
Downloadimage/png VBR mode.png26.88 KB
4 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.

Same problem and it's a pity there has been no comment here over the past 4.5 years, however...

… it looks like documentation does have related references, see Appendix C: Streaming and Video Conferencing Features:

If HRD conformance is not required, i.e. if application turns off NalHrdConformance option in mfxExtCodingOption structure, all bitrate control modes are available. In CBR and AVBR modes the application can change TargetKbps, in VBR mode the application can change TargetKbps and MaxKbps values. Such change in bitrate will not result in generation of a new key-frame or sequence header.

NalHrdConformance, set to ON by default, is the important one. Once disabled, it enables the SDK to reset without producing new SPS. In partcular, this enables CBR resets too.

I am new to qsv api, i also want to change bitrate on the fly using QSV with FFMPEG.

I have done same thing nvenc api and it worked but i am not code using qsv. Please help me.

Hi Jetsen,

Let me try to understand your request, so you said:

  1. When doing VBR, you can change bitrate dynamic.
  2. When doing CBR, you can not change bitrate by resetting call, and you are showing me the code example as:
    • Step1: initial configuration
    • Step2: change bitrate dynamically
  3. You validated the bitrate with bitrate viewer and attached the screen capture.

But I have a question in "Step 2", it has a comment "If CBR, ignore", what does it mean?

Are you doing "Step 2" at the end in encoding loop or outside of encoding loop?

I will check document and dev team to validate your code sequence.

During this time, could you also check if following article helps:

Common Bitrate Control Methods (BRC) in Intel® Media SDK

Advanced Bitrate Control Methods (BRC) in Intel® Media SDK

Mark

Leave a Comment

Please sign in to add a comment. Not a member? Join today