i have a problem with a H.264 encoding stream.
I need an output stream like this
I P P P I P P P I P P P ...
but only the I-Frames should be used as reference frames. Each P-Frame should be predicted from the last I-Frame, NOT from the previous P-Frame.
For this i set
m_mfxEncParams.mfx.EncodedOrder=1; // use encoded order, NOT display order
m_mfxEncParams.mfx.NumRefFrame = 1; // only one reference frame
m_mfxEncParams.mfx.GopPicSize = 15; // 15 frames
m_mfxEncParams.mfx.GopRefDist = 1; // no Bs
m_mfxEncParams.mfx.GopOptFlag = MFX_GOP_CLOSED | MFX_GOP_STRICT;
(As far as I understood, are are the GoP settings "dont care", because we are in EncodedOrder mode)
and during encoding I specify the FrameType for each frame like this
((frameCtr & 3) == 0) ?
m_ctrl.FrameType = MFX_FRAMETYPE_I | MFX_FRAMETYPE_IDR | MFX_FRAMETYPE_REF :
m_ctrl.FrameType = MFX_FRAMETYPE_P;
pSurf->Data.FrameOrder = frameCtr;
sts = m_pmfxENC->EncodeFrameAsync(&m_ctrl, &m_pEncSurfaces[nEncSurfIdx], &pCurrentTask->mfxBS, &pCurrentTask->EncSyncP);
but the result is still a "normal" stream IPPP IPPP... where each Frame is predicted from the previous one. The SDK still marks all P-Frames as reference frames. :(
Is this a bug in the SDK? Or is there a solution? Or where is my fault?
Indeed, it should work with the mfxExtAVCRefListCtrl and the RejectedRefList, but this seems to be to complicated for my easy problem , because i just want to tell the SDK, that it should NOT take P-Frames as reference frames
Thnx for your help/ideas
The Media SDK encoder default behavior is always to use previous P-frame as reference.
For complete control of reference pattern you need to use the mfxExtAVCRefListCtrl extended buffer attached to mfxEncodeCtrl for each call to EncodeFrameAsync.
"sample_videoconf" sample provides an example on how to setup and use the available reference list types during encode.
So it is a BUG in the SDK.
If the encoder marks every P as a reference frame, and i need to modify the the ref frame list LATER with the mfxExtAVCRefListCtrl, the P will still be marked with nal_ref_idc!!! For this the decoder allways needs a 2 frame reference buffer!!! One for the I and another for the P. I cant tell the decoder that i will throw away the P later -> :(
And why can i specify the frametype
m_ctrl.FrameType = MFX_FRAMETYPE_P;
without MFX_FRAMETYPE_REF if the encoder don't cares about??????
Say what you want..IT'S A BUG. Please tell it the core team, to fix it FAST!!!
Since mfxExtAVCRefListCtrl is used in mfxEncodeCtrl as an input to EncodeFrameAsync there is no need to modify ref list "later". Not sure what you mean.
For what I think you want to acomplish I do not think you need to set frame type explicitly. Instead, just set EncodedOrder to 0 and specify the desired GOP pattern. Then use ref list (Preferred and Rejected) to control the exact frame reference pattern. One thing to keep in mind is that the FrameOrder parameter must also be set in encoder input surface when using reference lists. (as illustrated in sample_videoconf).
However, I do see your point regarding P-frames having a non-zero "nal_ref_idc" value even though they are not referenced. I do observe this on my side also. I will discuss this with the codec experts and get back to you.
first, thnx for your quick answers!
With "later" i mean, that the encoder will allways encode the P as a reference frame (as you said) and then later (after the frame is allready encoded with nal_ref_idc=1) i tell the encode (by using the mfxExtAVCRefListCtrl ) that he does not use this frame anymore as a reference frame.
But from the decoders point of view (which does not know about it) it requirees allways two refeerence frames in memory. But i need a stream where only the I and so only one reference is needed for decoding.
Right, I made the wrong assessment regarding the required order of things. The correct approach would be to use EncodedOrder=1 to explicitly specify the frame type and reference pattern.
However, after some internal discussions it is clear that the current Media SDK encoder implementation does not support encoding P-frames as non referenced using this approach. It's been identified as a limitation and something we may address in future Media SDK release.
As a workaround you may explore uisng the Media SDK AVC temporal layer feature instead (P-frames from highest temporal layer will have nal_ref_idc = 0).