1 // Copyright (c) 2017-2020 Intel Corporation
2 //
3 // Permission is hereby granted, free of charge, to any person obtaining a copy
4 // of this software and associated documentation files (the "Software"), to deal
5 // in the Software without restriction, including without limitation the rights
6 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 // copies of the Software, and to permit persons to whom the Software is
8 // furnished to do so, subject to the following conditions:
9 //
10 // The above copyright notice and this permission notice shall be included in all
11 // copies or substantial portions of the Software.
12 //
13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19 // SOFTWARE.
20 
21 #include "mfx_common.h"
22 
23 #if defined (MFX_ENABLE_MPEG2_VIDEO_ENCODE)
24 
25 #include "mfx_enc_common.h"
26 #include "mfx_mpeg2_encode_utils_hw.h"
27 #include "mfx_brc_common.h"
28 #include "mfx_mpeg2_enc_common.h"
29 #include "umc_mpeg2_brc.h"
30 #include "mfx_task.h"
31 #include "libmfx_core.h"
32 
33 // temporary defines
34 #define CHECK_VERSION(ver) /*ver.Major==0;*/
35 #define CHECK_CODEC_ID(id, myid) /*id==myid;*/
36 
37 #define RANGE_TO_F_CODE(range, fcode) { \
38     int32_t fc = 1;                        \
39     while((4<<fc) < range && fc <= 15)    \
40     fc++;                               \
41     fcode = fc;                           \
42 }
43 namespace MPEG2EncoderHW
44 {
CheckHwCaps(VideoCORE * core,mfxVideoParam const * par,mfxExtCodingOption const * ext,ENCODE_CAPS * pCaps)45     mfxStatus CheckHwCaps(VideoCORE* core, mfxVideoParam const * par, mfxExtCodingOption const * ext, ENCODE_CAPS*  pCaps)
46     {
47         ENCODE_CAPS hwCaps {};
48 
49         mfxU16 codecProfile = MFX_PROFILE_MPEG2_MAIN;
50         if (par->mfx.CodecProfile != MFX_PROFILE_UNKNOWN)
51             codecProfile = par->mfx.CodecProfile;
52         mfxStatus sts = MfxHwMpeg2Encode::QueryHwCaps(core, hwCaps, codecProfile);
53         MFX_CHECK_STS(sts);
54 
55         if (par->mfx.FrameInfo.Width  > hwCaps.MaxPicWidth ||
56             par->mfx.FrameInfo.Height > hwCaps.MaxPicHeight)
57             return MFX_WRN_PARTIAL_ACCELERATION;
58 
59         if (par->mfx.FrameInfo.PicStruct != MFX_PICSTRUCT_PROGRESSIVE)
60         {
61             if (ext == 0)
62                 ext = GetExtCodingOptions(par->ExtParam, par->NumExtParam);
63 
64             if (ext != 0 && ext->FramePicture == MFX_CODINGOPTION_OFF)
65                 return MFX_WRN_PARTIAL_ACCELERATION;
66         }
67         if (!hwCaps.EncodeFunc && !hwCaps.EncFunc)
68         {
69             return MFX_WRN_PARTIAL_ACCELERATION;
70         }
71         if( pCaps )
72         {
73             *pCaps = hwCaps;
74         }
75 
76         return MFX_ERR_NONE;
77     }
GetHwEncodeMode(ENCODE_CAPS & caps)78     HW_MODE GetHwEncodeMode(ENCODE_CAPS &caps)
79     {
80         if( caps.EncodeFunc )
81         {
82             return FULL_ENCODE;
83         }
84         else if(caps.EncFunc)
85         {
86             return HYBRID_ENCODE;
87         }
88         else
89         {
90             return UNSUPPORTED;
91         }
92     }
ApplyTargetUsage(mfxVideoParamEx_MPEG2 * par)93     mfxStatus ApplyTargetUsage (mfxVideoParamEx_MPEG2* par)
94     {
95         if (par->mfxVideoParams.mfx.CodecProfile == MFX_PROFILE_MPEG2_SIMPLE)
96         {
97             par->mfxVideoParams.mfx.GopRefDist = 1;
98         }
99 
100         if (par->mfxVideoParams.mfx.GopRefDist == 0)
101         {
102             par->mfxVideoParams.mfx.GopRefDist = 3;
103         }
104         if (par->mfxVideoParams.mfx.GopPicSize == 0)
105         {
106             par->mfxVideoParams.mfx.GopPicSize = 24;
107         }
108         if (par->mfxVideoParams.mfx.GopRefDist > par->mfxVideoParams.mfx.GopPicSize)
109         {
110             par->mfxVideoParams.mfx.GopRefDist = par->mfxVideoParams.mfx.GopPicSize;
111         }
112         if (par->MVRangeP[0] == 0 ||  par->MVRangeP[1] == 0 )
113         {
114             mfxU32 FrameW = par->mfxVideoParams.mfx.FrameInfo.Width;
115 
116             par->MVRangeP[0] = FrameW < 200 ? 32 /*3*/ : FrameW < 500 ? 64 /*4*/  : FrameW < 1400 ? 128 /*5*/ : 256/*6*/;             // 200, 500, 1400 are horizontal resolution
117             par->MVRangeP[1] = par->MVRangeP[0] > 128 /*5*/ ? 128 /*5*/ : par->MVRangeP[0];
118         }
119         par->MVRangeB[0][0] =  par->MVRangeP[0];
120         par->MVRangeB[0][1] =  par->MVRangeP[1];
121         par->MVRangeB[1][0] =  par->MVRangeP[0];
122         par->MVRangeB[1][1] =  par->MVRangeP[1];
123 
124         par->bAllowFieldPrediction = 1;
125         par->bAllowFieldDCT        = 1;
126 
127         return MFX_ERR_NONE;
128     }
129 
GetExtCodingOptionsSPSPPS(mfxExtBuffer ** ebuffers,mfxU32 nbuffers)130     mfxExtCodingOptionSPSPPS* GetExtCodingOptionsSPSPPS(mfxExtBuffer** ebuffers,
131         mfxU32 nbuffers)
132     {
133         for(mfxU32 i=0; i<nbuffers; i++)
134         {
135             if((0 != (*ebuffers+i)) && ((*ebuffers+i)->BufferId == MFX_EXTBUFF_CODING_OPTION_SPSPPS))
136             {
137                 return (mfxExtCodingOptionSPSPPS*)(*ebuffers+i);
138             }
139         }
140         return 0;
141     }
142 
CheckExtendedBuffers(mfxVideoParam * par)143     mfxStatus CheckExtendedBuffers (mfxVideoParam* par)
144     {
145         mfxU32 supported_buffers[] = {
146             MFX_EXTBUFF_CODING_OPTION
147             ,MFX_EXTBUFF_CODING_OPTION_SPSPPS
148             ,MFX_EXTBUFF_OPAQUE_SURFACE_ALLOCATION
149             ,MFX_EXTBUFF_VIDEO_SIGNAL_INFO
150             ,MFX_EXTBUFF_CODING_OPTION2
151             ,MFX_EXTBUFF_CODING_OPTION3
152         };
153         mfxU32 num_supported = 0;
154 
155         if (par->NumExtParam == 0 || par->ExtParam == 0)
156         {
157             return MFX_ERR_NONE;
158         }
159         for (mfxU32 n_buf=0; n_buf < sizeof(supported_buffers)/sizeof(mfxU32); n_buf++)
160         {
161             mfxU32 num = 0;
162             for (mfxU32 i=0; i < par->NumExtParam; i++)
163             {
164                 if (par->ExtParam[i] == NULL)
165                 {
166                     return MFX_ERR_NULL_PTR;
167                 }
168                 if (par->ExtParam[i]->BufferId == supported_buffers[n_buf])
169                 {
170                     num ++;
171                 }
172             }
173             if (num > 1)
174             {
175                 return MFX_ERR_UNDEFINED_BEHAVIOR;
176             }
177             num_supported += num;
178 
179         }
180         return (num_supported == par->NumExtParam) ? MFX_ERR_NONE : MFX_ERR_UNSUPPORTED;
181     }
182 
183     /*static mfxU16 GetBufferSizeInKB (mfxU16 TargetKbps, double frame_rate, bool bMin = false)
184     {
185     mfxU32 numFrames = (bMin)? 2:10;
186     if (TargetKbps==0 || frame_rate == 0.0)
187     {
188     return 0;
189     }
190     return (mfxU16)((numFrames*TargetKbps)/(frame_rate*8));
191     }
192     static mfxU16 GetBitRate(mfxU16 w, mfxU16 h, double frame_rate, bool bIntraFrames ,bool bMin = false)
193     {
194     double coeff = 0;
195     if (bIntraFrames)
196     {
197     coeff = (bMin)? 30.0:15.0;
198     }
199     else
200     {
201     coeff = (bMin)? 250.0:25.0;
202     }
203     return (mfxU16)(frame_rate*(double)(w*h*3/2)*8.0/1000.0/coeff);
204     }*/
FillMFXFrameParams(mfxFrameParamMPEG2 * pFrameParams,mfxU8 frameType,mfxVideoParamEx_MPEG2 * pExParams,mfxU16 inputPictStruct,bool bBackwOnly,bool bFwdOnly)205     mfxStatus FillMFXFrameParams(mfxFrameParamMPEG2*     pFrameParams,
206                                 mfxU8 frameType,
207                                 mfxVideoParamEx_MPEG2 *pExParams,
208                                 mfxU16 inputPictStruct,
209                                 bool bBackwOnly,
210                                 bool bFwdOnly)
211     {
212         mfxU16                  seqPicStruct = pExParams->mfxVideoParams.mfx.FrameInfo.PicStruct & 0x0F;
213         bool                    bField = false;
214 
215         pFrameParams->FrameType    = frameType;
216 
217         mfxU16 curPicStruct = 0;
218         switch (seqPicStruct)
219         {
220         case MFX_PICSTRUCT_PROGRESSIVE:
221             curPicStruct = mfxU16(MFX_PICSTRUCT_PROGRESSIVE | (inputPictStruct &0xF0)); break;
222         case MFX_PICSTRUCT_FIELD_TFF:
223             curPicStruct = mfxU16(MFX_PICSTRUCT_FIELD_TFF | (inputPictStruct & (~MFX_PICSTRUCT_FIELD_BFF) & 0x0F)); break;
224         case MFX_PICSTRUCT_FIELD_BFF:
225             curPicStruct = mfxU16(MFX_PICSTRUCT_FIELD_BFF | (inputPictStruct & (~MFX_PICSTRUCT_FIELD_TFF) & 0x0F)); break;
226         case MFX_PICSTRUCT_UNKNOWN:
227         default:
228             curPicStruct = mfxU16((inputPictStruct == MFX_PICSTRUCT_UNKNOWN) ? MFX_PICSTRUCT_PROGRESSIVE : inputPictStruct); break;
229         }
230 
231         pFrameParams->CodecFlags  = 0;
232         pFrameParams->BitStreamPCEelement = 0;
233 
234         if(curPicStruct & MFX_PICSTRUCT_PROGRESSIVE)  {
235 
236             if (!(seqPicStruct & MFX_PICSTRUCT_PROGRESSIVE)) /*progressive frame in not progressive sequence*/
237             {
238                 pFrameParams->TopFieldFirst       = (curPicStruct & MFX_PICSTRUCT_FIELD_BFF)? 0:1;
239                 pFrameParams->RepeatFirstField    = (curPicStruct & MFX_PICSTRUCT_FIELD_REPEATED)? 1:0;
240             }
241             else /*progressive frame in progressive sequence*/
242             {
243                 if (curPicStruct & MFX_PICSTRUCT_FRAME_DOUBLING)
244                 {
245                     pFrameParams->RepeatFirstField = 1;
246                 }
247                 else if (curPicStruct & MFX_PICSTRUCT_FRAME_TRIPLING)
248                 {
249                     pFrameParams->RepeatFirstField  = 1;
250                     pFrameParams->TopFieldFirst     = 1;
251                 }
252             }
253             pFrameParams->PicStructure        = MFX_MPEG2_FRAME_PICTURE;
254             pFrameParams->ProgressiveFrame    = 1;
255             pFrameParams->FrameMbsOnlyFlag    = 1;
256             pFrameParams->FrameDCTprediction  = 1;
257         }
258         else if(curPicStruct & MFX_PICSTRUCT_FIELD_TFF)
259         {
260             pFrameParams->TopFieldFirst     = 1;
261 
262             if (pExParams->bFieldCoding)
263             {
264                 pFrameParams->PicStructure        = MFX_MPEG2_TOP_FIELD;
265                 pFrameParams->FieldPicFlag        = 1;
266                 bField  = true;
267             }
268             else
269             {
270                 pFrameParams->PicStructure        = MFX_MPEG2_FRAME_PICTURE;
271                 pFrameParams->InterlacedFrameFlag = 1;
272                 pFrameParams->FrameDCTprediction  = 0;
273                 pFrameParams->FrameMbsOnlyFlag    = 0;
274             }
275         }
276         else if(curPicStruct & MFX_PICSTRUCT_FIELD_BFF)
277         {
278 
279             if (pExParams->bFieldCoding)
280             {
281                 pFrameParams->PicStructure       = MFX_MPEG2_BOTTOM_FIELD;
282                 pFrameParams->BottomFieldFlag    = 1;
283                 pFrameParams->FieldPicFlag       = 1;
284                 bField  = true;
285             }
286             else
287             {
288                 pFrameParams->PicStructure        = MFX_MPEG2_FRAME_PICTURE;
289                 pFrameParams->InterlacedFrameFlag = 1;
290                 pFrameParams->FrameDCTprediction  = 0;
291                 pFrameParams->FrameMbsOnlyFlag    = 0;
292 
293             }
294         }
295         else
296         {
297             pFrameParams->PicStructure      = MFX_MPEG2_FRAME_PICTURE;
298             pFrameParams->TopFieldFirst     = 1;
299             pFrameParams->ProgressiveFrame  = 1;
300             pFrameParams->FrameMbsOnlyFlag  = 1;
301             pFrameParams->FrameDCTprediction= 1;
302         }
303 
304         pFrameParams->Chroma420type       = 1;
305         pFrameParams->ChromaFormatIdc     = MFX_CHROMAFORMAT_YUV420;
306         pFrameParams->FrameHinMbMinus1    = (pExParams->mfxVideoParams.mfx.FrameInfo.Height)>>4;
307         pFrameParams->FrameWinMbMinus1    = (pExParams->mfxVideoParams.mfx.FrameInfo.Width )>>4;
308         if (bField)
309         {
310             pFrameParams->FrameHinMbMinus1 = (pFrameParams->FrameHinMbMinus1>>1);
311         }
312 
313         MFX_CHECK(pFrameParams->FrameHinMbMinus1>=1 &&pFrameParams->FrameWinMbMinus1>=1, MFX_ERR_UNSUPPORTED);
314 
315         pFrameParams->NumMb            = pFrameParams->FrameHinMbMinus1*pFrameParams->FrameWinMbMinus1;
316         pFrameParams->FrameHinMbMinus1 = pFrameParams->FrameHinMbMinus1 - 1;
317         pFrameParams->FrameWinMbMinus1 = pFrameParams->FrameWinMbMinus1 - 1;
318         pFrameParams->CloseEntryFlag   = !!(pExParams->mfxVideoParams.mfx.GopOptFlag & MFX_GOP_CLOSED);
319 
320         if (pFrameParams->FrameType & MFX_FRAMETYPE_I)
321         {
322             pFrameParams->RefPicFlag        = 1;
323             pFrameParams->BackwardPredFlag  = 0;
324             pFrameParams->IntraPicFlag      = 1;
325             pFrameParams->ForwardPredFlag   = 0;
326             pFrameParams->NumRefFrame       = 0;
327         }
328         else if (pFrameParams->FrameType & MFX_FRAMETYPE_P)
329         {
330             pFrameParams->RefPicFlag        = 1;
331             pFrameParams->BackwardPredFlag  = 0;
332             pFrameParams->IntraPicFlag      = 0;
333             pFrameParams->ForwardPredFlag   = 1;
334             pFrameParams->NumRefFrame       = 1;
335         }
336         else if (pFrameParams->FrameType & MFX_FRAMETYPE_B)
337         {
338             pFrameParams->RefPicFlag       = 0;
339             pFrameParams->BackwardPredFlag = (bFwdOnly)   ? 0 : 1;
340             pFrameParams->ForwardPredFlag  = (bBackwOnly) ? 0 : 1;
341             pFrameParams->IntraPicFlag     = 0;
342             pFrameParams->NumRefFrame      = (bBackwOnly || bFwdOnly) ? 1 : 2;
343         }
344         else
345         {
346             return MFX_ERR_UNSUPPORTED;
347         }
348         pFrameParams->BSConcealmentNeed     = 0;
349         pFrameParams->BSConcealmentMethod   = 0;
350         pFrameParams->MvGridAndChroma       = 0;
351         pFrameParams->BitStreamFcodes       = 0;
352         pFrameParams->IntraDCprecision      = 1;
353 
354         if (pFrameParams->IntraPicFlag)
355         {
356             pFrameParams->BitStreamFcodes = 0xffff;
357         }
358         else if (pFrameParams->RefPicFlag)
359         {
360             pFrameParams->BitStreamFcodes = 0xff;
361 
362             mfxU32 fcode=0;
363             RANGE_TO_F_CODE (((mfxI32)pExParams->MVRangeP[0]),fcode);
364             pFrameParams->BitStreamFcodes |= (fcode & 0x0f)<<12;
365 
366             fcode=0;
367             RANGE_TO_F_CODE (((mfxI32)pExParams->MVRangeP[1]), fcode);
368             pFrameParams->BitStreamFcodes |= (fcode & 0x0f)<<8;
369 
370         }
371         else
372         {
373             mfxU32 fcode=0;
374             RANGE_TO_F_CODE ((mfxI32)pExParams->MVRangeB[0][0],fcode);
375             pFrameParams->BitStreamFcodes |= (fcode & 0x0f)<<12;
376 
377             fcode=0;
378             RANGE_TO_F_CODE ((mfxI32)pExParams->MVRangeB[0][1], fcode);
379             pFrameParams->BitStreamFcodes |= (fcode & 0x0f)<<8;
380 
381             fcode=0;
382             RANGE_TO_F_CODE ((mfxI32)pExParams->MVRangeB[1][0],fcode);
383             pFrameParams->BitStreamFcodes |= (fcode & 0x0f)<<4;
384 
385             fcode=0;
386             RANGE_TO_F_CODE ((mfxI32)pExParams->MVRangeB[1][1], fcode);
387             pFrameParams->BitStreamFcodes |= (fcode & 0x0f)<<0;
388         }
389         return MFX_ERR_NONE;
390 
391     }
AVBR_via_CBR(mfxVideoParam * par)392     bool AVBR_via_CBR (mfxVideoParam *par)
393     {
394        if (par->mfx.RateControlMethod != MFX_RATECONTROL_AVBR)
395            return false;
396        par->mfx.RateControlMethod = MFX_RATECONTROL_CBR;
397        par->mfx.MaxKbps = par->mfx.TargetKbps;
398        par->mfx.InitialDelayInKB = par->mfx.BufferSizeInKB = 0;
399        return true;
400     }
401 
FramesSet()402     FramesSet::FramesSet()
403     {
404         Reset();
405     }
Reset()406     void FramesSet::Reset()
407     {
408         m_pInputFrame = 0;
409         m_pRefFrame[0] = m_pRefFrame[1] = 0;
410         m_pRawFrame[0] = m_pRawFrame[1] = 0;
411         m_pRecFrame = 0;
412         m_nFrame = 0;
413         m_nRefFrame[0] = m_nRefFrame[1] = 0;
414         m_nLastRefBeforeIntra = -1;
415         m_nLastRef = -1;
416     }
ReleaseFrames(VideoCORE * pCore)417     mfxStatus FramesSet::ReleaseFrames(VideoCORE* pCore)
418     {
419         mfxStatus sts = MFX_ERR_NONE;
420         if (m_pInputFrame)
421         {
422             sts = pCore->DecreaseReference(&m_pInputFrame->Data);
423             MFX_CHECK_STS(sts);
424             m_pInputFrame = 0;
425         }
426         if (m_pRecFrame)
427         {
428             sts = pCore->DecreaseReference(&m_pRecFrame->Data);
429             MFX_CHECK_STS(sts);
430             m_pRecFrame = 0;
431         }
432         if (m_pRefFrame[0])
433         {
434             sts = pCore->DecreaseReference(&m_pRefFrame[0]->Data);
435             MFX_CHECK_STS(sts);
436             m_pRefFrame[0] = 0;
437         }
438         if (m_pRefFrame[1])
439         {
440             sts = pCore->DecreaseReference(&m_pRefFrame[1]->Data);
441             MFX_CHECK_STS(sts);
442             m_pRefFrame[1] = 0;
443         }
444         if (m_pRawFrame[0])
445         {
446             sts = pCore->DecreaseReference(&m_pRawFrame[0]->Data);
447             MFX_CHECK_STS(sts);
448             m_pRawFrame[0] = 0;
449         }
450         if (m_pRawFrame[1])
451         {
452             sts = pCore->DecreaseReference(&m_pRawFrame[1]->Data);
453             MFX_CHECK_STS(sts);
454             m_pRawFrame[1] = 0;
455         }
456         return sts;
457     }
LockRefFrames(VideoCORE * pCore)458     mfxStatus FramesSet::LockRefFrames(VideoCORE* pCore)
459     {
460         mfxStatus sts = MFX_ERR_NONE;
461 
462         if (m_pRefFrame[0])
463         {
464             sts = pCore->IncreaseReference(&m_pRefFrame[0]->Data);
465             MFX_CHECK_STS(sts);
466         }
467         if (m_pRefFrame[1])
468         {
469             sts = pCore->IncreaseReference(&m_pRefFrame[1]->Data);
470             MFX_CHECK_STS(sts);
471         }
472         if (m_pRawFrame[0])
473         {
474             sts = pCore->IncreaseReference(&m_pRawFrame[0]->Data);
475             MFX_CHECK_STS(sts);
476         }
477         if (m_pRawFrame[1])
478         {
479             sts = pCore->IncreaseReference(&m_pRawFrame[1]->Data);
480             MFX_CHECK_STS(sts);
481         }
482         return sts;
483     }
484 
Query(VideoCORE * core,mfxVideoParam * in,mfxVideoParam * out,bool bAVBR_WA)485     mfxStatus ControllerBase::Query(VideoCORE * core, mfxVideoParam *in, mfxVideoParam *out, bool bAVBR_WA)
486     {
487         MFX_AUTO_LTRACE(MFX_TRACE_LEVEL_HOTSPOTS, "ControllerBase::Query");
488         MFX_CHECK_NULL_PTR1(out);
489         if(in==0)
490         {
491             memset(&out->mfx, 0, sizeof(mfxInfoMFX));
492             out->mfx.FrameInfo.FourCC = 1;
493             out->mfx.FrameInfo.Width = 1;
494             out->mfx.FrameInfo.Height = 1;
495             out->mfx.FrameInfo.CropX = 0;
496             out->mfx.FrameInfo.CropY = 0;
497             out->mfx.FrameInfo.CropW = 1;
498             out->mfx.FrameInfo.CropH = 1;
499             out->mfx.FrameInfo.ChromaFormat = 1;
500             out->mfx.FrameInfo.FrameRateExtN = 1;
501             out->mfx.FrameInfo.FrameRateExtD = 1;
502             out->mfx.FrameInfo.AspectRatioW = 1;
503             out->mfx.FrameInfo.AspectRatioH = 1;
504             out->mfx.FrameInfo.PicStruct = 1;
505             out->mfx.CodecProfile = 1;
506             out->mfx.CodecLevel = 1;
507             out->mfx.GopPicSize = 1;
508             out->mfx.GopRefDist = 1;
509             out->mfx.GopOptFlag = 1;
510             out->mfx.RateControlMethod = 1; // not sure, it is BRC
511             out->mfx.InitialDelayInKB = 1; // not sure, it is BRC
512             out->mfx.BufferSizeInKB = 1; // not sure, it is BRC
513             out->mfx.TargetKbps = 1;
514             out->mfx.MaxKbps = 1; // not sure, it is BRC
515             out->mfx.NumSlice = 1;
516             out->mfx.NumThread = 1;
517             out->mfx.TargetUsage = 1;
518             out->IOPattern = MFX_IOPATTERN_IN_SYSTEM_MEMORY;
519             out->AsyncDepth = 0;
520             out->Protected = 0;
521 
522             MFX_CHECK_STS (CheckExtendedBuffers(out));
523             mfxExtCodingOption* ext_out = GetExtCodingOptions(out->ExtParam,out->NumExtParam);
524             if (ext_out)
525             {
526                 mfxU32 bufOffset = sizeof(mfxExtBuffer);
527                 mfxU32 bufSize   = sizeof(mfxExtCodingOption) - bufOffset;
528 
529                 memset ((mfxU8*)(ext_out) + bufOffset,0, bufSize);
530 
531                 ext_out->EndOfSequence     = 1;
532                 ext_out->FramePicture      = 1;
533             }
534             mfxExtCodingOptionSPSPPS* pSPSPPS_out = GetExtCodingOptionsSPSPPS (out->ExtParam, out->NumExtParam);
535             if (pSPSPPS_out)
536             {
537                 pSPSPPS_out->PPSBuffer  = NULL;
538                 pSPSPPS_out->PPSBufSize = 0;
539                 pSPSPPS_out->SPSBuffer  = NULL;
540                 pSPSPPS_out->SPSBufSize = 0;
541             }
542             mfxExtVideoSignalInfo* pVideoSignal_out = GetExtVideoSignalInfo(out->ExtParam, out->NumExtParam);
543             if (pVideoSignal_out)
544             {
545                 pVideoSignal_out->VideoFormat              = 1;
546                 pVideoSignal_out->ColourDescriptionPresent = 1;
547                 pVideoSignal_out->ColourPrimaries          = 1;
548                 pVideoSignal_out->TransferCharacteristics  = 1;
549                 pVideoSignal_out->MatrixCoefficients       = 1;
550                 pVideoSignal_out->VideoFullRange           = 0;
551             }
552         }
553         else
554         {
555             bool bUnsupported = false;
556             bool bWarning = false;
557             //bool bInvalid = false;
558 
559             mfxExtCodingOptionSPSPPS* pSPSPPS_out = GetExtCodingOptionsSPSPPS (out->ExtParam, out->NumExtParam);
560             mfxExtCodingOptionSPSPPS* pSPSPPS_in  = GetExtCodingOptionsSPSPPS (in->ExtParam,  in->NumExtParam);
561 
562             if (pSPSPPS_out && pSPSPPS_in)
563             {
564                 if (pSPSPPS_in->SPSBuffer && pSPSPPS_out->SPSBuffer && pSPSPPS_out->SPSBufSize && pSPSPPS_in->SPSBufSize)
565                 {
566                     mfxU32 real_size = 0;
567                     if (SHParametersEx::CheckSHParameters (pSPSPPS_in->SPSBuffer, pSPSPPS_in->SPSBufSize, real_size, out, 0))
568                     {
569                         if (real_size <= pSPSPPS_out->SPSBufSize)
570                         {
571                             std::copy(pSPSPPS_in->SPSBuffer, pSPSPPS_in->SPSBuffer + real_size, pSPSPPS_out->SPSBuffer);
572                             memset(pSPSPPS_out->SPSBuffer + real_size, 0, pSPSPPS_out->SPSBufSize - real_size);
573                         }
574                         else
575                         {
576                             memset(pSPSPPS_out->SPSBuffer, 0, pSPSPPS_out->SPSBufSize);
577                             bUnsupported   = true;
578                         }
579 
580                     }
581                     else
582                     {
583                         memset(pSPSPPS_out->SPSBuffer, 0, pSPSPPS_out->SPSBufSize);
584                         bUnsupported   = true;
585                     }
586                 }
587                 else if (pSPSPPS_in->SPSBuffer || pSPSPPS_out->SPSBuffer || pSPSPPS_out->SPSBufSize || pSPSPPS_in->SPSBufSize)
588                 {
589                     bUnsupported   = true;
590                 }
591             }
592             else if (!(pSPSPPS_in == 0 && pSPSPPS_out ==0))
593             {
594                 bUnsupported   = true;
595             }
596 
597             out->mfx        = in->mfx;
598             out->IOPattern  = in->IOPattern;
599             out->Protected  = in->Protected;
600             out->AsyncDepth = in->AsyncDepth;
601 
602             mfxStatus stsCaps = CheckHwCaps(core, out);
603 
604             MFX_CHECK_STS (CheckExtendedBuffers(in));
605             MFX_CHECK_STS (CheckExtendedBuffers(out));
606 
607             if (out->Protected)
608             {
609                 out->Protected = 0;
610                 bUnsupported   = true;
611             }
612 
613             if (out->mfx.FrameInfo.FourCC != MFX_FOURCC_NV12 && out->mfx.FrameInfo.FourCC !=0)
614             {
615                 out->mfx.FrameInfo.FourCC = 0;
616                 bUnsupported   = true;
617             }
618 
619             mfxU16 ps = out->mfx.FrameInfo.PicStruct & (MFX_PICSTRUCT_PROGRESSIVE|MFX_PICSTRUCT_FIELD_TFF|MFX_PICSTRUCT_FIELD_BFF);
620 
621             if (ps != MFX_PICSTRUCT_PROGRESSIVE &&
622                 ps != MFX_PICSTRUCT_FIELD_TFF &&
623                 ps != MFX_PICSTRUCT_FIELD_BFF &&
624                 ps != MFX_PICSTRUCT_UNKNOWN)
625             {
626                 ps = MFX_PICSTRUCT_UNKNOWN;
627                 bWarning = true;
628             }
629             if (out->mfx.FrameInfo.PicStruct != ps)
630             {
631                 out->mfx.FrameInfo.PicStruct = ps;
632                 bWarning = true;
633             }
634 
635             mfxU16 t = (out->mfx.FrameInfo.PicStruct == MFX_PICSTRUCT_PROGRESSIVE) ? 0x0f:0x1f;
636 
637             if ((out->mfx.FrameInfo.Width !=0 && out->mfx.FrameInfo.Height==0) ||
638                 (out->mfx.FrameInfo.Width ==0 && out->mfx.FrameInfo.Height!=0))
639             {
640                 out->mfx.FrameInfo.Width = 0;
641                 out->mfx.FrameInfo.Height= 0;
642                 bUnsupported = true;
643             }
644             if (out->mfx.FrameInfo.Width > 0x1fff ||(out->mfx.FrameInfo.Width & 0x0f))
645             {
646                 out->mfx.FrameInfo.Width = 0;
647                 bUnsupported = true;
648             }
649             if (out->mfx.FrameInfo.Height > 0x1fff ||(out->mfx.FrameInfo.Height & t))
650             {
651                 out->mfx.FrameInfo.Height = 0;
652                 bUnsupported = true;
653             }
654 
655             if (out->mfx.FrameInfo.CropX != 0)
656             {
657                 out->mfx.FrameInfo.CropX = 0;
658                 bUnsupported = true;
659             }
660             if (out->mfx.FrameInfo.CropY != 0)
661             {
662                 out->mfx.FrameInfo.CropY = 0;
663                 bUnsupported = true;
664             }
665 
666             /*
667             if (out->mfx.FrameInfo.CropW > out->mfx.FrameInfo.Width)
668             {
669             out->mfx.FrameInfo.CropW = 0;
670             bUnsupported = true;
671             }
672             if (out->mfx.FrameInfo.CropH > out->mfx.FrameInfo.Height)
673             {
674             out->mfx.FrameInfo.CropH = 0;
675             bUnsupported = true;
676             }*/
677 
678             switch(out->IOPattern)
679             {
680                 case 0:
681                 case MFX_IOPATTERN_IN_VIDEO_MEMORY:
682                 case MFX_IOPATTERN_IN_SYSTEM_MEMORY:
683                 case MFX_IOPATTERN_IN_OPAQUE_MEMORY:
684                     break;
685                 default:
686                     bWarning = true;
687                     if (out->IOPattern & MFX_IOPATTERN_IN_VIDEO_MEMORY)
688                         out->IOPattern = MFX_IOPATTERN_IN_VIDEO_MEMORY;
689                     else if (in->IOPattern & MFX_IOPATTERN_IN_OPAQUE_MEMORY)
690                         out->IOPattern = MFX_IOPATTERN_IN_OPAQUE_MEMORY;
691                     else if (out->IOPattern & MFX_IOPATTERN_IN_SYSTEM_MEMORY)
692                         out->IOPattern = MFX_IOPATTERN_IN_SYSTEM_MEMORY;
693                     else
694                         out->IOPattern = MFX_IOPATTERN_IN_VIDEO_MEMORY;
695             }
696 
697             mfxExtCodingOption* ext_in  = GetExtCodingOptions(in->ExtParam, in->NumExtParam);
698             mfxExtCodingOption* ext_out = GetExtCodingOptions(out->ExtParam,out->NumExtParam);
699 
700             MFX_CHECK ((ext_in !=0 && ext_out != 0) || (ext_in == 0 && ext_out == 0),  MFX_ERR_UNDEFINED_BEHAVIOR );
701 
702             if (ext_in && ext_out)
703             {
704                 mfxExtCodingOption temp = {};
705 
706                 mfxU32 bufOffset = sizeof(mfxExtBuffer);
707                 mfxU32 bufSize   = sizeof(mfxExtCodingOption) - bufOffset;
708 
709                 temp = *ext_in;
710 
711                 memset ((mfxU8*)(ext_out) + bufOffset,0, bufSize);
712 
713                 ext_out->EndOfSequence     = temp.EndOfSequence;
714                 ext_out->FramePicture      = temp.FramePicture;
715 
716                 bWarning = bWarning || (memcmp((mfxU8*)(ext_out) + bufOffset,(mfxU8*)(&temp) + bufOffset, bufSize)!= 0);
717                 bUnsupported = bUnsupported || (temp.FieldOutput == MFX_CODINGOPTION_ON);
718             }
719 
720             mfxExtVideoSignalInfo* pVideoSignal_out = GetExtVideoSignalInfo(out->ExtParam, out->NumExtParam);
721             mfxExtVideoSignalInfo* pVideoSignal_in  = GetExtVideoSignalInfo(in->ExtParam,  in->NumExtParam);
722 
723             MFX_CHECK ((pVideoSignal_in == 0) == (pVideoSignal_out == 0),  MFX_ERR_UNDEFINED_BEHAVIOR );
724 
725             if (pVideoSignal_in && pVideoSignal_out)
726             {
727                 *pVideoSignal_out = *pVideoSignal_in;
728 
729                 if (CheckExtVideoSignalInfo(pVideoSignal_out) == MFX_WRN_INCOMPATIBLE_VIDEO_PARAM)
730                 {
731                     bWarning = true;
732                 }
733             }
734 
735             if ((out->mfx.FrameInfo.Width!= 0 && out->mfx.FrameInfo.CropW > out->mfx.FrameInfo.Width) ||
736                 (out->mfx.FrameInfo.CropW == 0 && out->mfx.FrameInfo.CropH != 0))
737             {
738                 bWarning = true;
739                 out->mfx.FrameInfo.CropW = out->mfx.FrameInfo.Width;
740             }
741 
742             if ((out->mfx.FrameInfo.Height != 0 && out->mfx.FrameInfo.CropH > out->mfx.FrameInfo.Height)||
743                 (out->mfx.FrameInfo.CropW != 0 && out->mfx.FrameInfo.CropH == 0))
744             {
745                 bWarning = true;
746                 out->mfx.FrameInfo.CropH = out->mfx.FrameInfo.Height;
747             }
748 
749             if (out->mfx.FrameInfo.CropX || out->mfx.FrameInfo.CropY)
750             {
751                 out->mfx.FrameInfo.CropX = 0;
752                 out->mfx.FrameInfo.CropY = 0;
753                 bWarning = true;
754             }
755 
756             if (out->mfx.FrameInfo.FrameRateExtN !=0 && out->mfx.FrameInfo.FrameRateExtD != 0)
757             {
758                 mfxStatus sts = CheckFrameRateMPEG2(out->mfx.FrameInfo.FrameRateExtD, out->mfx.FrameInfo.FrameRateExtN);
759                 if (sts != MFX_ERR_NONE)
760                 {
761                     bWarning = true;
762                 }
763             }
764             else
765             {
766                 if (out->mfx.FrameInfo.FrameRateExtN !=0 || out->mfx.FrameInfo.FrameRateExtD != 0)
767                 {
768                     out->mfx.FrameInfo.FrameRateExtN = 0;
769                     out->mfx.FrameInfo.FrameRateExtD = 0;
770                     bUnsupported = true;
771                 }
772             }
773 
774 
775             if ((out->mfx.TargetUsage < MFX_TARGETUSAGE_BEST_QUALITY || out->mfx.TargetUsage > MFX_TARGETUSAGE_BEST_SPEED)&&
776                 out->mfx.TargetUsage !=0)
777             {
778                 out->mfx.TargetUsage = MFX_TARGETUSAGE_UNKNOWN;
779                 bWarning = true;
780             }
781 
782 
783             if (out->mfx.FrameInfo.ChromaFormat != 0 &&
784                 out->mfx.FrameInfo.ChromaFormat != MFX_CHROMAFORMAT_YUV420)
785             {
786                 out->mfx.FrameInfo.ChromaFormat = MFX_CHROMAFORMAT_YUV420;
787                 bWarning = true;
788             }
789 
790             mfxStatus sts = CheckAspectRatioMPEG2(
791                 out->mfx.FrameInfo.AspectRatioW,
792                 out->mfx.FrameInfo.AspectRatioH,
793                 out->mfx.FrameInfo.Width,
794                 out->mfx.FrameInfo.Height,
795                 out->mfx.FrameInfo.CropW,
796                 out->mfx.FrameInfo.CropH);
797 
798             if (sts != MFX_ERR_NONE)
799             {
800                 bWarning = true;
801                 if (sts < MFX_ERR_NONE)
802                 {
803                     out->mfx.FrameInfo.AspectRatioW = 1;
804                     out->mfx.FrameInfo.AspectRatioH = 1;
805                 }
806             }
807 
808             if (out->mfx.CodecProfile != MFX_PROFILE_MPEG2_SIMPLE &&
809                 out->mfx.CodecProfile != MFX_PROFILE_MPEG2_MAIN   &&
810                 out->mfx.CodecProfile != MFX_PROFILE_MPEG2_HIGH &&
811                 out->mfx.CodecProfile != MFX_PROFILE_UNKNOWN)
812             {
813                 out->mfx.CodecProfile = MFX_PROFILE_UNKNOWN;
814                 bWarning = true;
815             }
816             if (out->mfx.CodecLevel != MFX_LEVEL_MPEG2_LOW &&
817                 out->mfx.CodecLevel != MFX_LEVEL_MPEG2_MAIN &&
818                 out->mfx.CodecLevel != MFX_LEVEL_MPEG2_HIGH1440 &&
819                 out->mfx.CodecLevel != MFX_LEVEL_MPEG2_HIGH &&
820                 out->mfx.CodecLevel != MFX_LEVEL_UNKNOWN)
821             {
822                 out->mfx.CodecLevel = MFX_LEVEL_UNKNOWN;
823                 bWarning = true;
824             }
825             if (CorrectProfileLevelMpeg2(out->mfx.CodecProfile, out->mfx.CodecLevel,
826                 out->mfx.FrameInfo.Width, out->mfx.FrameInfo.Height,
827                 CalculateUMCFramerate(out->mfx.FrameInfo.FrameRateExtN, out->mfx.FrameInfo.FrameRateExtD),
828                 out->mfx.RateControlMethod == MFX_RATECONTROL_CQP ? 0 : (mfxU32)(out->mfx.TargetKbps * out->mfx.BRCParamMultiplier * BRC_BITS_IN_KBIT),
829                 out->mfx.GopRefDist))
830             {
831                 bWarning = true;
832             }
833 
834             if (bAVBR_WA)
835             {
836                 bWarning = AVBR_via_CBR(out) ? true : bWarning;
837             }
838 
839 
840             // invalid modes
841             if (out->mfx.RateControlMethod == MFX_RATECONTROL_VCM ||
842                 out->mfx.RateControlMethod == MFX_RATECONTROL_ICQ ||
843                 out->mfx.RateControlMethod == MFX_RATECONTROL_QVBR ||
844                 out->mfx.RateControlMethod == MFX_RATECONTROL_LA ||
845                 out->mfx.RateControlMethod == MFX_RATECONTROL_LA_ICQ ||
846                 out->mfx.RateControlMethod == MFX_RATECONTROL_LA_EXT ||
847                 out->mfx.RateControlMethod == MFX_RATECONTROL_LA_HRD ||
848                 out->mfx.RateControlMethod == MFX_RATECONTROL_RESERVED1 ||
849                 out->mfx.RateControlMethod == MFX_RATECONTROL_RESERVED2 ||
850                 out->mfx.RateControlMethod == MFX_RATECONTROL_RESERVED3 ||
851                 out->mfx.RateControlMethod == MFX_RATECONTROL_RESERVED4)
852             {
853                 out->mfx.RateControlMethod = 0;
854                 bUnsupported = true;
855             }
856 
857             // unknown mode - set to VBR with warning
858             if (out->mfx.RateControlMethod != MFX_RATECONTROL_CBR  &&
859                 out->mfx.RateControlMethod != MFX_RATECONTROL_VBR  &&
860                 out->mfx.RateControlMethod != MFX_RATECONTROL_AVBR &&
861                 out->mfx.RateControlMethod != MFX_RATECONTROL_CQP  &&
862                 out->mfx.RateControlMethod != 0)
863             {
864                 out->mfx.RateControlMethod = MFX_RATECONTROL_VBR;
865                 bWarning = true;
866             }
867 
868             mfxExtCodingOption2 * extOpt2 = (mfxExtCodingOption2 *)GetExtendedBuffer(out->ExtParam, out->NumExtParam, MFX_EXTBUFF_CODING_OPTION2);
869             if (extOpt2 && extOpt2->SkipFrame)
870             {
871                 // TODO: check hwCaps
872                 if (extOpt2->SkipFrame != MFX_SKIPFRAME_INSERT_DUMMY || out->mfx.RateControlMethod != MFX_RATECONTROL_CQP)
873                 {
874                     extOpt2->SkipFrame = 0;
875                     bWarning = true;
876                 }
877             }
878 
879             mfxExtCodingOption3 * extOpt3 = (mfxExtCodingOption3 *)GetExtendedBuffer(out->ExtParam, out->NumExtParam, MFX_EXTBUFF_CODING_OPTION3);
880             if (extOpt3 && extOpt3->EnableMBQP == MFX_CODINGOPTION_ON)
881             {
882                 if (out->mfx.RateControlMethod != MFX_RATECONTROL_CQP)
883                 {
884                     extOpt3->EnableMBQP = MFX_CODINGOPTION_OFF;
885                     bWarning = true;
886                 }
887                 // MPEG2 MBQP currently only supported on Linux
888                 if (core->GetVAType() != MFX_HW_VAAPI)
889                 {
890                     extOpt3->EnableMBQP = MFX_CODINGOPTION_OFF;
891                     bUnsupported = true;
892                 }
893             }
894             if (extOpt3 && extOpt3->EnableMBQP == MFX_CODINGOPTION_UNKNOWN)
895             {
896                 extOpt3->EnableMBQP = MFX_CODINGOPTION_OFF;
897             }
898 
899             if (extOpt3 && (extOpt3->WeightedPred != MFX_WEIGHTED_PRED_UNKNOWN || extOpt3->WeightedBiPred != MFX_WEIGHTED_PRED_UNKNOWN))
900             {
901                 extOpt3->WeightedPred = 0;
902                 bUnsupported = true;
903             }
904 
905             if (extOpt3 && (extOpt3->FadeDetection == MFX_CODINGOPTION_ON))
906             {
907                 extOpt3->FadeDetection = 0;
908                 bUnsupported = true;
909             }
910 
911             mfxU16 gof = out->mfx.GopOptFlag & (MFX_GOP_CLOSED | MFX_GOP_STRICT);
912             if (out->mfx.GopOptFlag != gof)
913             {
914                 out->mfx.GopOptFlag = gof;
915                 bWarning = true;
916             }
917 
918             if (extOpt3 && extOpt3->BRCPanicMode == MFX_CODINGOPTION_OFF)
919             {
920                 // MPEG2 BRC panic mode disabling currently only supported on Linux
921                 if ((core->GetVAType() != MFX_HW_VAAPI)
922                  || (out->mfx.RateControlMethod != MFX_RATECONTROL_CBR
923                  && out->mfx.RateControlMethod != MFX_RATECONTROL_VBR
924                  && out->mfx.RateControlMethod != MFX_RATECONTROL_AVBR))
925                 {
926                     extOpt3->BRCPanicMode = MFX_CODINGOPTION_UNKNOWN;
927                     bUnsupported = true;
928                 }
929             }
930 
931             MFX_CHECK_STS(stsCaps);
932 
933             if (bUnsupported)
934             {
935                 return MFX_ERR_UNSUPPORTED;
936             }
937             /* Unreachable code is commented out
938             if(bInvalid)
939                 return MFX_ERR_INVALID_VIDEO_PARAM;*/
940             if (bWarning)
941             {
942                 return MFX_WRN_INCOMPATIBLE_VIDEO_PARAM;
943             }
944 
945         }
946         return MFX_ERR_NONE;
947     }
948 
QueryIOSurf(VideoCORE * core,mfxVideoParam * par,mfxFrameAllocRequest * request)949     mfxStatus ControllerBase::QueryIOSurf(VideoCORE * core, mfxVideoParam *par, mfxFrameAllocRequest *request)
950     {
951         MFX_AUTO_LTRACE(MFX_TRACE_LEVEL_HOTSPOTS, "ControllerBase::QueryIOSurf");
952         mfxVideoParamEx_MPEG2 videoParamEx = {};
953 
954         MFX_CHECK_NULL_PTR1(par);
955         MFX_CHECK_NULL_PTR1(request);
956         CHECK_VERSION(par->Version);
957         CHECK_CODEC_ID(par->mfx.CodecId, MFX_CODEC_MPEG2);
958         MFX_CHECK (CheckExtendedBuffers(par) == MFX_ERR_NONE, MFX_ERR_INVALID_VIDEO_PARAM);
959 
960         mfxStatus sts = core->IsGuidSupported(DXVA2_Intel_Encode_MPEG2, par, true);
961         MFX_CHECK_STS(sts);
962 
963         mfxExtCodingOption* ext = GetExtCodingOptions(par->ExtParam, par->NumExtParam);
964         mfxExtCodingOptionSPSPPS* pSPSPPS = GetExtCodingOptionsSPSPPS (par->ExtParam, par->NumExtParam);
965 
966         mfxVideoParam parFromSpsPps = {};
967 
968         mfxExtCodingOption extFromSpsPps = {};
969 
970         if (pSPSPPS)
971         {
972             parFromSpsPps = *par;
973             if (ext)
974                 extFromSpsPps = *ext;
975 
976             //mfxStatus sts = MFX_ERR_NONE;
977             mfxU32 real_len = 0;
978             MFX_CHECK(pSPSPPS->PPSBufSize == 0, MFX_ERR_INVALID_VIDEO_PARAM);
979             MFX_CHECK(!pSPSPPS->PPSBuffer, MFX_ERR_INVALID_VIDEO_PARAM);
980 
981             if (!SHParametersEx::CheckSHParameters(pSPSPPS->SPSBuffer, pSPSPPS->SPSBufSize, real_len, &parFromSpsPps, &extFromSpsPps))
982                 return MFX_ERR_INVALID_VIDEO_PARAM;
983 
984             par = &parFromSpsPps;
985             ext = &extFromSpsPps;
986         }
987 
988         ENCODE_CAPS EncCaps = {};
989 
990         sts = CheckHwCaps(core, par, ext, &EncCaps);
991         MFX_CHECK_STS(sts);
992 
993         mfxU32 mask = (par->mfx.FrameInfo.PicStruct & MFX_PICSTRUCT_PROGRESSIVE)? 0x0f:0x1f;
994         if ((par->mfx.FrameInfo.Width & 0x0f) != 0 || (par->mfx.FrameInfo.Height & mask) != 0 )
995         {
996             return MFX_ERR_INVALID_VIDEO_PARAM;
997         }
998         videoParamEx.mfxVideoParams = *par;
999         ApplyTargetUsage (&videoParamEx);
1000 
1001         if ((par->IOPattern & (MFX_IOPATTERN_IN_VIDEO_MEMORY|MFX_IOPATTERN_IN_SYSTEM_MEMORY)) == MFX_IOPATTERN_IN_VIDEO_MEMORY ||
1002             ((par->IOPattern & (MFX_IOPATTERN_IN_VIDEO_MEMORY|MFX_IOPATTERN_IN_SYSTEM_MEMORY|MFX_IOPATTERN_IN_OPAQUE_MEMORY))== MFX_IOPATTERN_IN_OPAQUE_MEMORY))
1003         {
1004             request->Info              = videoParamEx.mfxVideoParams.mfx.FrameInfo ;
1005             request->NumFrameMin       = videoParamEx.mfxVideoParams.mfx.GopRefDist + 3;
1006             request->NumFrameSuggested = request->NumFrameMin;
1007             request->Type              = (par->IOPattern & MFX_IOPATTERN_IN_OPAQUE_MEMORY)
1008                 ? MFX_MEMTYPE_FROM_ENCODE|MFX_MEMTYPE_OPAQUE_FRAME  |MFX_MEMTYPE_DXVA2_DECODER_TARGET
1009                 : MFX_MEMTYPE_FROM_ENCODE|MFX_MEMTYPE_EXTERNAL_FRAME|MFX_MEMTYPE_DXVA2_DECODER_TARGET;
1010         }
1011         else if ((par->IOPattern & (MFX_IOPATTERN_IN_VIDEO_MEMORY|MFX_IOPATTERN_IN_SYSTEM_MEMORY))==MFX_IOPATTERN_IN_SYSTEM_MEMORY)
1012         {
1013             request->Info              =  videoParamEx.mfxVideoParams.mfx.FrameInfo;
1014             request->NumFrameMin       =  videoParamEx.mfxVideoParams.mfx.GopRefDist + 3;
1015             request->NumFrameSuggested = request->NumFrameMin;
1016             request->Type              = MFX_MEMTYPE_FROM_ENCODE|MFX_MEMTYPE_EXTERNAL_FRAME|MFX_MEMTYPE_SYSTEM_MEMORY;
1017         }
1018         else
1019         {
1020             return MFX_ERR_INVALID_VIDEO_PARAM;
1021         }
1022         if (ext && (ext->EndOfSequence==MFX_CODINGOPTION_ON))
1023         {
1024             request->NumFrameMin       = request->NumFrameMin*2+1;
1025             request->NumFrameSuggested = request->NumFrameSuggested*2+1;
1026         }
1027         if (EncCaps.EncodeFunc)
1028         {
1029             request->NumFrameMin = request->NumFrameMin + videoParamEx.mfxVideoParams.AsyncDepth;
1030             request->NumFrameSuggested = request->NumFrameSuggested + videoParamEx.mfxVideoParams.AsyncDepth;
1031         }
1032 
1033         return MFX_ERR_NONE;
1034     }
1035 
UnlockFrames(MFXGOP * pGOP,MFXWaitingList * pWaitingList,VideoCORE * pcore)1036     mfxStatus  UnlockFrames (MFXGOP* pGOP, MFXWaitingList* pWaitingList, VideoCORE* pcore)
1037     {
1038         mfxStatus  sts = MFX_ERR_NONE;
1039         if (pGOP !=0)
1040         {
1041             pGOP->CloseGop(false);
1042             for (;;)
1043             {
1044                 sFrameEx  fr = {};
1045                 if (!pGOP->GetFrameExForDecoding(&fr,0,0,0))
1046                 {
1047                     break;
1048                 }
1049                 sts = pcore->DecreaseReference(&fr.m_pFrame->Data);
1050                 MFX_CHECK_STS(sts);
1051                 pGOP->ReleaseCurrentFrame();
1052             }
1053         }
1054         if (pWaitingList)
1055         {
1056             for (;;)
1057             {
1058                 sFrameEx  fr = {};
1059                 if (!pWaitingList->GetFrameEx(&fr))
1060                 {
1061                     break;
1062                 }
1063                 sts = pcore->DecreaseReference(&fr.m_pFrame->Data);
1064                 MFX_CHECK_STS(sts);
1065                 pWaitingList->MoveOnNextFrame();
1066             }
1067         }
1068         return sts;
1069     }
ControllerBase(VideoCORE * core,bool bAVBR_WA)1070     ControllerBase::ControllerBase(VideoCORE *core, bool bAVBR_WA )
1071         : m_pCore (core)
1072         , m_nEncodeCalls(0)
1073         , m_nFrameInGOP(0)
1074         , m_pGOP(0)
1075         , m_pWaitingList(0)
1076         , m_InputFrameOrder(-1)
1077         , m_OutputFrameOrder(-1)
1078         , m_BitstreamLen (0)
1079         , m_InputSurfaces(core)
1080         , m_InitWidth(0)
1081         , m_InitHeight(0)
1082         , m_bInitialized (false)
1083         , m_bAVBR_WA (bAVBR_WA)
1084     {
1085         memset (&m_VideoParamsEx, 0, sizeof(m_VideoParamsEx));
1086     }
Reset(mfxVideoParam * par,bool bAllowRawFrames)1087     mfxStatus ControllerBase::Reset(mfxVideoParam *par, bool bAllowRawFrames)
1088     {
1089         mfxStatus sts = MFX_ERR_NONE;
1090 
1091         bool bProgressiveSequence = false;
1092         mfxFrameInfo *pFrameInfo = 0;
1093         bool bCorrected = false;
1094         bool bUnsupported = false;
1095         bool bInvalid = false;
1096         eMFXHWType type = m_pCore->GetHWType();
1097 
1098 
1099         MFX_CHECK_NULL_PTR1(par);
1100         CHECK_VERSION(par->Version);
1101         CHECK_CODEC_ID(par->mfx.CodecId, MFX_CODEC_MPEG2);
1102         MFX_CHECK(CheckExtendedBuffers(par) == MFX_ERR_NONE, MFX_ERR_INVALID_VIDEO_PARAM);
1103 
1104         memset(&m_VideoParamsEx,0,sizeof(mfxVideoParamEx_MPEG2));
1105         m_VideoParamsEx.mfxVideoParams.mfx = par->mfx;
1106         m_VideoParamsEx.mfxVideoParams.IOPattern = par->IOPattern;
1107         m_VideoParamsEx.mfxVideoParams.Protected = par->Protected;
1108         m_VideoParamsEx.mfxVideoParams.AsyncDepth = par->AsyncDepth == 0 ? 2: par->AsyncDepth;
1109 
1110 
1111         if (m_VideoParamsEx.mfxVideoParams.mfx.BRCParamMultiplier == 0)
1112             m_VideoParamsEx.mfxVideoParams.mfx.BRCParamMultiplier = 1;
1113 
1114         /*-------------------Check and correct parameters:---------------------*/
1115         sts = CheckVideoParamEncoders(par, m_pCore->IsExternalFrameAllocator(), type);
1116         MFX_CHECK_STS(sts);
1117 
1118         MFX_CHECK(par->Protected == 0,MFX_ERR_INVALID_VIDEO_PARAM);
1119 
1120         mfxExtCodingOption extFromSpsPps = {};
1121         mfxExtCodingOption* ext = GetExtCodingOptions(par->ExtParam, par->NumExtParam);
1122 
1123 
1124         if (mfxExtCodingOptionSPSPPS* pSPSPPS = GetExtCodingOptionsSPSPPS (par->ExtParam, par->NumExtParam))
1125         {
1126             MFX_CHECK(pSPSPPS->PPSBufSize == 0, MFX_ERR_INVALID_VIDEO_PARAM);
1127             MFX_CHECK(!pSPSPPS->PPSBuffer, MFX_ERR_INVALID_VIDEO_PARAM);
1128 
1129             mfxU32 real_len = 0;
1130             if (ext != 0)
1131             {
1132                 extFromSpsPps = *ext;
1133             }
1134             if (!SHParametersEx::CheckSHParameters(pSPSPPS->SPSBuffer, pSPSPPS->SPSBufSize, real_len, &m_VideoParamsEx.mfxVideoParams, &extFromSpsPps))
1135                 return MFX_ERR_INCOMPATIBLE_VIDEO_PARAM;
1136 
1137             ext = &extFromSpsPps;
1138         }
1139 
1140         if (mfxExtVideoSignalInfo* pVideoSignalInfo = GetExtVideoSignalInfo(par->ExtParam, par->NumExtParam))
1141         {
1142             m_VideoParamsEx.videoSignalInfo = *pVideoSignalInfo;
1143             m_VideoParamsEx.bAddDisplayExt = true;
1144         }
1145         else
1146         {
1147             m_VideoParamsEx.bAddDisplayExt = false;
1148         }
1149 
1150 
1151         sts = CheckHwCaps(m_pCore, &m_VideoParamsEx.mfxVideoParams, ext);
1152         if (sts != MFX_ERR_NONE)
1153         {
1154             return is_initialized()
1155                 ? MFX_ERR_INVALID_VIDEO_PARAM // reset can't return partial acceleration
1156                 : MFX_WRN_PARTIAL_ACCELERATION;
1157         }
1158         m_nEncodeCalls = 0;
1159         m_nFrameInGOP  = 0;
1160 
1161         pFrameInfo = &m_VideoParamsEx.mfxVideoParams.mfx.FrameInfo;
1162 
1163         switch (pFrameInfo->PicStruct)
1164         {
1165         case MFX_PICSTRUCT_PROGRESSIVE:
1166             bProgressiveSequence = true;
1167             break;
1168         case MFX_PICSTRUCT_FIELD_TFF:
1169         case MFX_PICSTRUCT_UNKNOWN:
1170         case MFX_PICSTRUCT_FIELD_BFF:
1171             break;
1172         default:
1173             return MFX_ERR_INVALID_VIDEO_PARAM;
1174         }
1175         if (pFrameInfo->CropX!=0      || pFrameInfo->CropY!=0 ||
1176             pFrameInfo->Width > 0x1fff || pFrameInfo->Height > 0x1fff ||
1177             pFrameInfo->CropW > pFrameInfo->Width ||
1178             pFrameInfo->CropH > pFrameInfo->Height)
1179             return MFX_ERR_INVALID_VIDEO_PARAM;
1180 
1181         sts = CheckFrameRateMPEG2(pFrameInfo->FrameRateExtD,pFrameInfo->FrameRateExtN);
1182         if (sts == MFX_WRN_INCOMPATIBLE_VIDEO_PARAM)
1183         {
1184             bCorrected = true;
1185         }
1186         else if (sts == MFX_ERR_INVALID_VIDEO_PARAM)
1187         {
1188             bInvalid = true;
1189         }
1190         if ((pFrameInfo->Width & 15) != 0)
1191             return MFX_ERR_INVALID_VIDEO_PARAM;
1192 
1193         if (pFrameInfo->CropW)
1194             pFrameInfo->Width = mfx::align2_value(pFrameInfo->CropW, 16);
1195 
1196         mfxU32 heightAlignment = bProgressiveSequence ? 16 : 32;
1197 
1198         if ((pFrameInfo->Height & (heightAlignment - 1)) != 0)
1199             return MFX_ERR_INVALID_VIDEO_PARAM;
1200 
1201         if (pFrameInfo->CropH)
1202             pFrameInfo->Height = mfx::align2_value(pFrameInfo->CropH, heightAlignment);
1203 
1204         if (m_bInitialized == false)
1205         {
1206             m_InitWidth  = pFrameInfo->Width;
1207             m_InitHeight = pFrameInfo->Height;
1208         }
1209         else if (m_InitWidth < pFrameInfo->Width || m_InitHeight < pFrameInfo->Height)
1210         {
1211             return MFX_ERR_INCOMPATIBLE_VIDEO_PARAM;
1212         }
1213 
1214         if (ext)
1215         {
1216             mfxExtCodingOption temp = {};
1217 
1218             mfxU32 bufOffset = sizeof(mfxExtBuffer);
1219             mfxU32 bufSize   = sizeof(mfxExtCodingOption) - bufOffset;
1220             temp.EndOfSequence = ext->EndOfSequence;
1221             temp.FramePicture  = ext->FramePicture;
1222 
1223             bCorrected   = bCorrected || (memcmp((mfxU8*)(ext) + bufOffset,(mfxU8*)(&temp) + bufOffset, bufSize)!= 0);
1224             bUnsupported = bUnsupported || (ext->FieldOutput == MFX_CODINGOPTION_ON);
1225 
1226         }
1227         m_VideoParamsEx.bFieldCoding = false;
1228         if (!bProgressiveSequence)
1229         {
1230             m_VideoParamsEx.bFieldCoding = (ext && ext->FramePicture == MFX_CODINGOPTION_OFF)? true:false;
1231         }
1232 
1233         sts = CheckAspectRatioMPEG2(
1234             pFrameInfo->AspectRatioW,
1235             pFrameInfo->AspectRatioH,
1236             pFrameInfo->Width,
1237             pFrameInfo->Height,
1238             pFrameInfo->CropW,
1239             pFrameInfo->CropH);
1240 
1241         if (sts < 0)
1242         {
1243             if (!m_bInitialized)
1244             {
1245                 pFrameInfo->AspectRatioW = 0;
1246                 pFrameInfo->AspectRatioH = 0;
1247                 bInvalid = true;
1248             }
1249             else
1250             {
1251                 return MFX_ERR_INCOMPATIBLE_VIDEO_PARAM;
1252             }
1253         }
1254         if (m_bAVBR_WA)
1255         {
1256             bCorrected = AVBR_via_CBR(&m_VideoParamsEx.mfxVideoParams) ? true : bCorrected;
1257         }
1258 
1259         mfxU16& RateControl = m_VideoParamsEx.mfxVideoParams.mfx.RateControlMethod;
1260 
1261         // invalid modes
1262         if (RateControl == MFX_RATECONTROL_VCM ||
1263             RateControl == MFX_RATECONTROL_ICQ ||
1264             RateControl == MFX_RATECONTROL_QVBR ||
1265             RateControl == MFX_RATECONTROL_LA ||
1266             RateControl == MFX_RATECONTROL_LA_ICQ ||
1267             RateControl == MFX_RATECONTROL_LA_EXT ||
1268             RateControl == MFX_RATECONTROL_LA_HRD ||
1269             RateControl == MFX_RATECONTROL_RESERVED1 ||
1270             RateControl == MFX_RATECONTROL_RESERVED2 ||
1271             RateControl == MFX_RATECONTROL_RESERVED3 ||
1272             RateControl == MFX_RATECONTROL_RESERVED4)
1273         {
1274             return MFX_ERR_INVALID_VIDEO_PARAM;
1275         }
1276 
1277         // unknown mode - set to VBR with warning
1278         if (RateControl != MFX_RATECONTROL_CBR  &&
1279             RateControl != MFX_RATECONTROL_VBR  &&
1280             RateControl != MFX_RATECONTROL_AVBR &&
1281             RateControl != MFX_RATECONTROL_CQP)
1282         {
1283             /*if RateControlMethod was undefined MSDK have to use default one */
1284             RateControl = MFX_RATECONTROL_VBR;
1285             bCorrected = true;
1286         }
1287 
1288         mfxExtCodingOption2 * extOpt2 = (mfxExtCodingOption2 *)GetExtendedBuffer(par->ExtParam, par->NumExtParam, MFX_EXTBUFF_CODING_OPTION2);
1289         if (extOpt2 && extOpt2->SkipFrame)
1290         {
1291 
1292         }
1293 
1294         mfxExtCodingOption3 * extOpt3 = (mfxExtCodingOption3 *)GetExtendedBuffer(par->ExtParam, par->NumExtParam, MFX_EXTBUFF_CODING_OPTION3);
1295         if (extOpt3 && extOpt3->EnableMBQP == MFX_CODINGOPTION_ON)
1296         {
1297             // MPEG2 MBQP currently only supported on Linux and only valid for CQP mode
1298             if (m_pCore->GetVAType() != MFX_HW_VAAPI)
1299             {
1300                 extOpt3->EnableMBQP = MFX_CODINGOPTION_OFF;
1301                 return MFX_ERR_UNSUPPORTED;
1302             }
1303             if (m_VideoParamsEx.mfxVideoParams.mfx.RateControlMethod != MFX_RATECONTROL_CQP)
1304             {
1305                 extOpt3->EnableMBQP = MFX_CODINGOPTION_OFF;
1306                 bCorrected = true; // return MFX_ERR_INCOMPATIBLE_VIDEO_PARAM;
1307             }
1308             else
1309             {
1310                 m_VideoParamsEx.bMbqpMode = true;
1311             }
1312         }
1313 
1314         if (extOpt3 && extOpt3->BRCPanicMode == MFX_CODINGOPTION_OFF)
1315         {
1316             // MPEG2 BRC panic mode disabling currently only supported on Linux and only valid for non-CQP modes
1317             const mfxU16 selectedRateControl = m_VideoParamsEx.mfxVideoParams.mfx.RateControlMethod;
1318             if (selectedRateControl != MFX_RATECONTROL_CBR
1319              && selectedRateControl != MFX_RATECONTROL_VBR
1320              && selectedRateControl != MFX_RATECONTROL_AVBR)
1321             {
1322                 extOpt3->BRCPanicMode = MFX_CODINGOPTION_UNKNOWN;
1323                 bCorrected = true;
1324             }
1325             if (m_pCore->GetVAType() != MFX_HW_VAAPI)
1326             {
1327                 extOpt3->BRCPanicMode = MFX_CODINGOPTION_UNKNOWN;
1328                 return MFX_ERR_UNSUPPORTED;
1329             }
1330 
1331             m_VideoParamsEx.bDisablePanicMode = true;
1332         }
1333 
1334         if (extOpt3 && (extOpt3->WeightedPred != MFX_WEIGHTED_PRED_UNKNOWN || extOpt3->WeightedBiPred != MFX_WEIGHTED_PRED_UNKNOWN || extOpt3->FadeDetection == MFX_CODINGOPTION_ON))
1335         {
1336             return MFX_ERR_INVALID_VIDEO_PARAM;
1337         }
1338 
1339         double fr = CalculateUMCFramerate(m_VideoParamsEx.mfxVideoParams.mfx.FrameInfo.FrameRateExtN,
1340             m_VideoParamsEx.mfxVideoParams.mfx.FrameInfo.FrameRateExtD);
1341 
1342         if (CorrectProfileLevelMpeg2(m_VideoParamsEx.mfxVideoParams.mfx.CodecProfile,
1343             m_VideoParamsEx.mfxVideoParams.mfx.CodecLevel,
1344             m_VideoParamsEx.mfxVideoParams.mfx.FrameInfo.Width,
1345             m_VideoParamsEx.mfxVideoParams.mfx.FrameInfo.Height,
1346             fr,
1347             m_VideoParamsEx.mfxVideoParams.mfx.RateControlMethod == MFX_RATECONTROL_CQP
1348             ? 0
1349             : (mfxU32)(m_VideoParamsEx.mfxVideoParams.mfx.TargetKbps * m_VideoParamsEx.mfxVideoParams.mfx.BRCParamMultiplier * BRC_BITS_IN_KBIT),
1350             m_VideoParamsEx.mfxVideoParams.mfx.GopRefDist))
1351           bCorrected = true;;
1352 
1353         ApplyTargetUsage(&m_VideoParamsEx);
1354 
1355         m_InputFrameOrder = -1;
1356         m_OutputFrameOrder= -1;
1357         m_BitstreamLen    = 0;
1358 
1359         m_VideoParamsEx.bAddEOS = (ext && (ext->EndOfSequence == MFX_CODINGOPTION_ON));
1360 
1361         sts = UnlockFrames (m_pGOP, m_pWaitingList,m_pCore);
1362         MFX_CHECK_STS(sts);
1363 
1364         mfxU16 GopRefDist  = m_VideoParamsEx.mfxVideoParams.mfx.GopRefDist;
1365 
1366         mfxI32 maxFramesInWaitingList  = 0;
1367         mfxI32 minFramesInWaitingList = 0;
1368         mfxI32 delayInWaitingList = 0;
1369 
1370 
1371         if (par->mfx.EncodedOrder)
1372         {
1373             maxFramesInWaitingList   = m_VideoParamsEx.mfxVideoParams.AsyncDepth + ((m_VideoParamsEx.bAddEOS)? 1 : 0);
1374             minFramesInWaitingList   = (m_VideoParamsEx.bAddEOS)? 1 : 0;
1375             delayInWaitingList       = minFramesInWaitingList + m_VideoParamsEx.mfxVideoParams.AsyncDepth - 1;
1376         }
1377         else
1378         {
1379             maxFramesInWaitingList = (GopRefDist + 1)*3;
1380             minFramesInWaitingList = ((m_VideoParamsEx.bAddEOS)? 1 : 0);
1381             delayInWaitingList     =  GopRefDist + minFramesInWaitingList;
1382         }
1383 
1384         if (m_pGOP)
1385         {
1386             if (m_pGOP->GetMaxBFrames() < GopRefDist - 1)
1387             {
1388                 return MFX_ERR_INCOMPATIBLE_VIDEO_PARAM;
1389             }
1390             m_pGOP->Reset(m_VideoParamsEx.mfxVideoParams.mfx.GopOptFlag&MFX_GOP_CLOSED, m_VideoParamsEx.mfxVideoParams.mfx.IdrInterval,ext && ext->EndOfSequence !=0,m_VideoParamsEx.mfxVideoParams.mfx.EncodedOrder!=0);
1391         }
1392         else
1393         {
1394             m_pGOP = new MFXGOP;
1395             if (!m_pGOP)
1396             {
1397                 return MFX_ERR_NULL_PTR;
1398             }
1399             sts = m_pGOP->Init(GopRefDist - 1, m_VideoParamsEx.mfxVideoParams.mfx.GopOptFlag&MFX_GOP_CLOSED, m_VideoParamsEx.mfxVideoParams.mfx.IdrInterval,ext && ext->EndOfSequence==MFX_CODINGOPTION_ON,m_VideoParamsEx.mfxVideoParams.mfx.EncodedOrder!=0);
1400             MFX_CHECK_STS(sts);
1401         }
1402 
1403         if (m_pWaitingList)
1404         {
1405             if (m_pWaitingList->GetMaxFrames() < maxFramesInWaitingList)
1406             {
1407                 return MFX_ERR_INCOMPATIBLE_VIDEO_PARAM;
1408             }
1409             m_pWaitingList->Reset(minFramesInWaitingList, delayInWaitingList);
1410         }
1411         else
1412         {
1413             m_pWaitingList = new MFXWaitingList;
1414             if (!m_pWaitingList)
1415             {
1416                 return MFX_ERR_NULL_PTR;
1417             }
1418             sts = m_pWaitingList->Init(maxFramesInWaitingList, minFramesInWaitingList,delayInWaitingList);
1419             MFX_CHECK_STS(sts);
1420         }
1421 
1422         m_VideoParamsEx.bRawFrames = bAllowRawFrames
1423             && (m_pCore->GetHWType() <= MFX_HW_IVB)
1424             && (m_VideoParamsEx.mfxVideoParams.mfx.TargetUsage > 5);
1425 
1426         m_VideoParamsEx.mfxVideoParams.mfx.NumSlice = (mfxU16)((m_VideoParamsEx.mfxVideoParams.mfx.FrameInfo.Height)>>4);
1427 
1428         {
1429             mfxFrameAllocRequest request = {};
1430             sts = QueryIOSurf(m_pCore, par, &request);
1431             MFX_CHECK(sts>=0,sts);
1432             sts = m_InputSurfaces.Reset (par, request.NumFrameMin);
1433             MFX_CHECK(sts != MFX_ERR_INVALID_VIDEO_PARAM, m_bInitialized ? MFX_ERR_INCOMPATIBLE_VIDEO_PARAM: sts);
1434             MFX_CHECK_STS(sts);
1435         }
1436 
1437         if (bUnsupported)
1438             return MFX_ERR_UNSUPPORTED;
1439         if(bInvalid)
1440             return MFX_ERR_INVALID_VIDEO_PARAM;
1441         m_bInitialized = true;
1442 
1443         return bCorrected ? MFX_WRN_INCOMPATIBLE_VIDEO_PARAM : MFX_ERR_NONE;
1444     }
1445 
1446     //virtual mfxStatus Close(void); // same name
Close(void)1447     mfxStatus ControllerBase::Close(void)
1448     {
1449         mfxStatus sts = MFX_ERR_NONE;
1450 
1451         sts = UnlockFrames (m_pGOP, m_pWaitingList,m_pCore);
1452         MFX_CHECK_STS(sts);
1453 
1454         if (m_pGOP)
1455         {
1456             m_pGOP->Close();
1457             delete m_pGOP;
1458             m_pGOP = 0;
1459         }
1460         if (m_pWaitingList)
1461         {
1462             m_pWaitingList->Close();
1463             delete m_pWaitingList;
1464             m_pWaitingList = 0;
1465         }
1466         m_InputSurfaces.Close();
1467 
1468         m_bInitialized = false;
1469 
1470 
1471         return MFX_ERR_NONE;
1472     }
1473 
GetVideoParam(mfxVideoParam * par)1474     mfxStatus ControllerBase::GetVideoParam(mfxVideoParam *par)
1475     {
1476         MFX_CHECK_NULL_PTR1(par);
1477         CHECK_VERSION(par->Version);
1478 
1479         par->mfx = m_VideoParamsEx.mfxVideoParams.mfx;
1480         par->IOPattern = m_VideoParamsEx.mfxVideoParams.IOPattern;
1481         par->mfx.CodecId = MFX_CODEC_MPEG2;
1482         mfxExtCodingOption* ext = GetExtCodingOptions(par->ExtParam, par->NumExtParam);
1483         if (ext)
1484             ext->FramePicture= (mfxU16)((m_VideoParamsEx.bFieldCoding) ? MFX_CODINGOPTION_OFF : MFX_CODINGOPTION_ON);
1485 
1486         return MFX_ERR_NONE;
1487     }
GetEncodeStat(mfxEncodeStat * stat)1488     mfxStatus ControllerBase::GetEncodeStat(mfxEncodeStat *stat)
1489     {
1490         MFX_CHECK_NULL_PTR1(stat)
1491             if(!is_initialized())
1492                 return MFX_ERR_NOT_INITIALIZED;
1493 
1494         stat->NumBit   = (mfxU64)(m_BitstreamLen*8);
1495         stat->NumFrame = m_OutputFrameOrder + 1;
1496 
1497         stat->NumCachedFrame = m_InputFrameOrder - m_OutputFrameOrder;
1498         return MFX_ERR_NONE;
1499     }
ReorderFrame(mfxEncodeInternalParams * pInInternalParams,mfxFrameSurface1 * in,mfxEncodeInternalParams * pOutInternalParams,mfxFrameSurface1 ** out)1500     mfxStatus ControllerBase::ReorderFrame(mfxEncodeInternalParams *pInInternalParams, mfxFrameSurface1 *in,
1501         mfxEncodeInternalParams *pOutInternalParams, mfxFrameSurface1 **out)
1502     {
1503         if (in)
1504         {
1505             if (!m_pWaitingList->AddFrame( in, pInInternalParams))
1506             {
1507                 return MFX_ERR_NOT_ENOUGH_BUFFER;
1508             }
1509         }
1510         // Fill GOP structure using waiting list
1511         for(;;)
1512         {
1513             sFrameEx         CurFrame = {};
1514 
1515             if (!m_pWaitingList->GetFrameEx(&CurFrame, in == NULL))
1516             {
1517                 break;
1518             }
1519             if (!m_pGOP->AddFrame(&CurFrame))
1520             {
1521                 break;
1522             }
1523             m_pWaitingList->MoveOnNextFrame();
1524         }
1525 
1526         if (!in)
1527         {
1528             bool strictGop = 0 != (m_VideoParamsEx.mfxVideoParams.mfx.GopOptFlag & MFX_GOP_STRICT);
1529             m_pGOP->CloseGop(strictGop);
1530         }
1531 
1532         sFrameEx  CurFrame = {};
1533 
1534         // Extract next frame from GOP structure
1535         if (!m_pGOP->GetFrameExForDecoding(&CurFrame,m_pWaitingList->isNextReferenceIntra(), m_pWaitingList->isNextBFrame(),m_pWaitingList->isLastFrame()))
1536         {
1537             return MFX_ERR_MORE_DATA;
1538         }
1539         mfxU16 frameType = CurFrame.m_sEncodeInternalParams.FrameType;
1540 
1541         //Correct InternalFlags
1542         CurFrame.m_sEncodeInternalParams.InternalFlags = (CurFrame.m_bAddHeader)? MFX_IFLAG_ADD_HEADER:0;
1543         if (CurFrame.m_bAddEOS)
1544         {
1545             CurFrame.m_sEncodeInternalParams.InternalFlags |= MFX_IFLAG_ADD_EOS;
1546         }
1547         if (CurFrame.m_bOnlyBwdPrediction && isBPredictedFrame(frameType))
1548         {
1549             CurFrame.m_sEncodeInternalParams.InternalFlags |= MFX_IFLAG_BWD_ONLY;
1550         }
1551         if (CurFrame.m_bOnlyFwdPrediction && isBPredictedFrame(frameType))
1552         {
1553             CurFrame.m_sEncodeInternalParams.InternalFlags |= MFX_IFLAG_FWD_ONLY;
1554         }
1555         // Check frame order parameters
1556         if (isPredictedFrame(frameType))
1557         {
1558             sFrameEx refFrame = {};
1559             if (m_pGOP->GetFrameExReference(&refFrame))
1560             {
1561 
1562                 MFX_CHECK((CurFrame.m_FrameOrder > refFrame.m_FrameOrder) && ((int32_t)CurFrame.m_FrameOrder - (int32_t)refFrame.m_FrameOrder <= m_VideoParamsEx.mfxVideoParams.mfx.GopRefDist) ,MFX_ERR_INCOMPATIBLE_VIDEO_PARAM);
1563             }
1564         }
1565         else if (isBPredictedFrame(frameType))
1566         {
1567             if (CurFrame.m_bOnlyBwdPrediction)
1568             {
1569                 sFrameEx refFrame = {};
1570                 if (m_pGOP->GetFrameExReference(&refFrame,true))
1571                 {
1572                     MFX_CHECK((CurFrame.m_FrameOrder < refFrame.m_FrameOrder) && ((int32_t)refFrame.m_FrameOrder - (int32_t)CurFrame.m_FrameOrder < m_VideoParamsEx.mfxVideoParams.mfx.GopRefDist) ,MFX_ERR_INCOMPATIBLE_VIDEO_PARAM);
1573                 }
1574             }
1575             else if (CurFrame.m_bOnlyFwdPrediction)
1576             {
1577                 sFrameEx refFrame = {};
1578                 if (m_pGOP->GetFrameExReference(&refFrame,false))
1579                 {
1580                     MFX_CHECK((CurFrame.m_FrameOrder > refFrame.m_FrameOrder) && ((int32_t)CurFrame.m_FrameOrder - (int32_t)refFrame.m_FrameOrder < m_VideoParamsEx.mfxVideoParams.mfx.GopRefDist) ,MFX_ERR_INCOMPATIBLE_VIDEO_PARAM);
1581                 }
1582             }
1583             else
1584             {
1585                 sFrameEx refFrameF = {};
1586                 sFrameEx refFrameB = {};
1587                 if (m_pGOP->GetFrameExReference(&refFrameF,false) && m_pGOP->GetFrameExReference(&refFrameB,true))
1588                 {
1589                     MFX_CHECK((CurFrame.m_FrameOrder < refFrameB.m_FrameOrder) && (CurFrame.m_FrameOrder > refFrameF.m_FrameOrder) ,MFX_ERR_INCOMPATIBLE_VIDEO_PARAM);
1590                 }
1591             }
1592         }
1593         *out = CurFrame.m_pFrame;
1594         *pOutInternalParams = CurFrame.m_sEncodeInternalParams;
1595 
1596         m_pGOP->ReleaseCurrentFrame();
1597 
1598         return MFX_ERR_NONE;
1599     }
CheckNextFrame(mfxEncodeInternalParams * pOutInternalParams,mfxFrameSurface1 ** out)1600     mfxStatus ControllerBase::CheckNextFrame(mfxEncodeInternalParams *pOutInternalParams, mfxFrameSurface1 **out)
1601     {
1602 
1603         // Fill GOP structure using waiting list
1604         for(;;)
1605         {
1606             sFrameEx         CurFrame = {};
1607 
1608             if (!m_pWaitingList->GetFrameEx(&CurFrame, false))
1609             {
1610                 break;
1611             }
1612             if (!m_pGOP->AddFrame(&CurFrame))
1613             {
1614                 break;
1615             }
1616             m_pWaitingList->MoveOnNextFrame();
1617         }
1618 
1619         sFrameEx  CurFrame = {};
1620 
1621         // Extract next frame from GOP structure
1622         if (!m_pGOP->GetFrameExForDecoding(&CurFrame,m_pWaitingList->isNextReferenceIntra(), m_pWaitingList->isNextBFrame(),m_pWaitingList->isLastFrame()))
1623         {
1624             return MFX_ERR_MORE_DATA;
1625         }
1626         mfxU16 frameType = CurFrame.m_sEncodeInternalParams.FrameType;
1627 
1628         //Correct InternalFlags
1629         CurFrame.m_sEncodeInternalParams.InternalFlags = (CurFrame.m_bAddHeader)? MFX_IFLAG_ADD_HEADER:0;
1630         if (CurFrame.m_bAddEOS)
1631         {
1632             CurFrame.m_sEncodeInternalParams.InternalFlags |= MFX_IFLAG_ADD_EOS;
1633         }
1634         if (CurFrame.m_bOnlyBwdPrediction && isBPredictedFrame(frameType))
1635         {
1636             CurFrame.m_sEncodeInternalParams.InternalFlags |= MFX_IFLAG_BWD_ONLY;
1637         }
1638         if (CurFrame.m_bOnlyFwdPrediction && isBPredictedFrame(frameType))
1639         {
1640             CurFrame.m_sEncodeInternalParams.InternalFlags |= MFX_IFLAG_FWD_ONLY;
1641         }
1642 
1643         *out = CurFrame.m_pFrame;
1644         *pOutInternalParams = CurFrame.m_sEncodeInternalParams;
1645 
1646         m_pGOP->ReleaseCurrentFrame();
1647 
1648         return MFX_ERR_NONE;
1649     }
1650 
EncodeFrameCheck(mfxEncodeCtrl * ctrl,mfxFrameSurface1 * surface,mfxBitstream * bs,mfxFrameSurface1 ** reordered_surface,mfxEncodeInternalParams * pInternalParams)1651     mfxStatus ControllerBase::EncodeFrameCheck(
1652         mfxEncodeCtrl *ctrl,
1653         mfxFrameSurface1 *surface,
1654         mfxBitstream *bs,
1655         mfxFrameSurface1 **reordered_surface,
1656         mfxEncodeInternalParams *pInternalParams)
1657     {
1658         mfxStatus sts = MFX_ERR_NONE;
1659         bool bWarning = false;
1660 
1661         MFX_CHECK(is_initialized(),MFX_ERR_NOT_INITIALIZED);
1662         CHECK_VERSION(bs->Version);
1663         MFX_CHECK_NULL_PTR2(bs, pInternalParams);
1664         MFX_CHECK(bs->DataOffset <= 32 , MFX_ERR_UNDEFINED_BEHAVIOR);
1665 
1666         mfxU32 startbspos = bs->DataOffset + bs->DataLength;
1667         mfxU32 output_buffer_size = bs->MaxLength > startbspos ? (bs->MaxLength - startbspos) : 0;
1668 
1669         MFX_CHECK(output_buffer_size >= mfxU32(m_VideoParamsEx.mfxVideoParams.mfx.BufferSizeInKB * m_VideoParamsEx.mfxVideoParams.mfx.BRCParamMultiplier * 1000), MFX_ERR_NOT_ENOUGH_BUFFER);
1670         MFX_CHECK_NULL_PTR1(bs->Data);
1671 
1672         if (surface)
1673         {
1674             if ((m_VideoParamsEx.mfxVideoParams.mfx.FrameInfo.PicStruct&0x0f) != MFX_PICSTRUCT_UNKNOWN)
1675             {
1676                 if ((surface->Info.PicStruct&0x0f) != (m_VideoParamsEx.mfxVideoParams.mfx.FrameInfo.PicStruct&0x0f) &&
1677                     (surface->Info.PicStruct&0x0f) != MFX_PICSTRUCT_UNKNOWN &&
1678                     (surface->Info.PicStruct&0x0f) != MFX_PICSTRUCT_PROGRESSIVE)
1679                 {
1680                     bWarning=true;
1681                 }
1682             }
1683             else if ((surface->Info.PicStruct&0x0f) == MFX_PICSTRUCT_UNKNOWN)
1684             {
1685                 return MFX_ERR_UNDEFINED_BEHAVIOR;
1686             }
1687 
1688             MFX_CHECK(surface->Info.Width >= m_VideoParamsEx.mfxVideoParams.mfx.FrameInfo.Width, MFX_ERR_INVALID_VIDEO_PARAM);
1689             MFX_CHECK(surface->Info.Height >= m_VideoParamsEx.mfxVideoParams.mfx.FrameInfo.Height, MFX_ERR_INVALID_VIDEO_PARAM);
1690             MFX_CHECK(surface->Info.FourCC == MFX_FOURCC_NV12, MFX_ERR_UNDEFINED_BEHAVIOR);
1691 
1692             if (surface->Data.Y)
1693             {
1694                 MFX_CHECK(surface->Data.Pitch < 0x8000, MFX_ERR_UNDEFINED_BEHAVIOR);
1695                 CHECK_VERSION(surface->Version);
1696             }
1697             sts = m_pCore->IncreaseReference(&surface->Data);
1698             MFX_CHECK_STS(sts);
1699             m_InputFrameOrder++;
1700 
1701             mfxU16 frameType = (ctrl)? ctrl->FrameType : 0;
1702             if (m_VideoParamsEx.mfxVideoParams.mfx.EncodedOrder)
1703             {
1704                 mfxU16 type = frameType & (MFX_FRAMETYPE_I|MFX_FRAMETYPE_P|MFX_FRAMETYPE_B);
1705                 MFX_CHECK ((type == MFX_FRAMETYPE_I || type == MFX_FRAMETYPE_P || type == MFX_FRAMETYPE_B), MFX_ERR_INCOMPATIBLE_VIDEO_PARAM);
1706             }
1707 
1708             pInternalParams->FrameType    = frameType;
1709             pInternalParams->FrameOrder   = (!m_VideoParamsEx.mfxVideoParams.mfx.EncodedOrder)? m_InputFrameOrder:surface->Data.FrameOrder;
1710             if (ctrl)
1711             {
1712                 pInternalParams->ExtParam    = ctrl->ExtParam;
1713                 pInternalParams->NumExtParam = ctrl->NumExtParam;
1714                 pInternalParams->NumPayload  = ctrl->NumPayload;
1715                 pInternalParams->Payload     = ctrl->Payload;
1716                 pInternalParams->QP          = ctrl->QP;
1717                 pInternalParams->SkipFrame   = ctrl->SkipFrame;
1718             }
1719             else
1720             {
1721                 pInternalParams->ExtParam    = 0;
1722                 pInternalParams->NumExtParam = 0;
1723                 pInternalParams->NumPayload  = 0;
1724                 pInternalParams->Payload     = 0;
1725                 pInternalParams->QP          = 0;
1726                 pInternalParams->SkipFrame   = 0;
1727             }
1728 
1729             *reordered_surface = GetOpaqSurface(surface);
1730 
1731             if (m_InputFrameOrder < m_pWaitingList->GetDelay())
1732             {
1733                 return (mfxStatus)MFX_ERR_MORE_DATA_SUBMIT_TASK;
1734             }
1735             else
1736             {
1737                 m_nEncodeCalls ++;
1738                 return bWarning? MFX_WRN_INCOMPATIBLE_VIDEO_PARAM: MFX_ERR_NONE;
1739             }
1740         }
1741         else
1742         {
1743             m_nEncodeCalls ++;
1744             *reordered_surface = 0;
1745             return (m_nEncodeCalls <= (mfxU32)m_InputFrameOrder+1)?  MFX_ERR_NONE : MFX_ERR_MORE_DATA;
1746         }
1747     }
1748 
CheckFrameType(mfxEncodeInternalParams * pInternalParams)1749     mfxStatus ControllerBase::CheckFrameType(mfxEncodeInternalParams *pInternalParams)
1750     {
1751         mfxU16 type = pInternalParams->FrameType & (MFX_FRAMETYPE_I|MFX_FRAMETYPE_P|MFX_FRAMETYPE_B);
1752         if (!m_VideoParamsEx.mfxVideoParams.mfx.EncodedOrder)
1753         {
1754             if (type != MFX_FRAMETYPE_I)
1755             {
1756                 GetFrameTypeMpeg2 (m_nFrameInGOP,
1757                     m_VideoParamsEx.mfxVideoParams.mfx.GopPicSize,
1758                     m_VideoParamsEx.mfxVideoParams.mfx.GopRefDist,
1759                     m_VideoParamsEx.mfxVideoParams.mfx.GopOptFlag&MFX_GOP_CLOSED,
1760                     &pInternalParams->FrameType);
1761             }
1762             m_nFrameInGOP = (pInternalParams->FrameType & MFX_FRAMETYPE_I) ? 1 : m_nFrameInGOP + 1;
1763         }
1764         else
1765         {
1766             MFX_CHECK((type == MFX_FRAMETYPE_I || type == MFX_FRAMETYPE_P || type == MFX_FRAMETYPE_B), MFX_ERR_UNDEFINED_BEHAVIOR);
1767         }
1768         return MFX_ERR_NONE;
1769     }
1770 
1771 #define RET_UMC_TO_MFX(umc_ret) ConvertStatusUmc2Mfx(umc_ret)
ConvertFrameParamsToUMC(const mfxFrameParamMPEG2 * pFrameParams,UMC::FrameType & frType,uint32_t & picture_structure,uint32_t & repeat_first_field,uint32_t & top_field_first,uint32_t & second_field)1772     static void ConvertFrameParamsToUMC(const mfxFrameParamMPEG2* pFrameParams, UMC::FrameType &frType,
1773         uint32_t &picture_structure,
1774         uint32_t &repeat_first_field,
1775         uint32_t &top_field_first,
1776         uint32_t &second_field)
1777     {
1778         frType             = ((pFrameParams->FrameType &  MFX_FRAMETYPE_I) ? UMC::I_PICTURE : (pFrameParams->FrameType &  MFX_FRAMETYPE_P ? UMC::P_PICTURE : UMC::B_PICTURE));
1779         picture_structure  =  pFrameParams->PicStructure;
1780         repeat_first_field = (pFrameParams->RepeatFirstField) ? 1:0;
1781         top_field_first    = (pFrameParams->TopFieldFirst) ? 1:0;
1782         second_field       = (pFrameParams->SecondFieldFlag) ? 1:0;
1783     }
1784 
QuantIntoScaleTypeAndCode(int32_t quant_value,int32_t & q_scale_type,int32_t & quantiser_scale_code)1785     void MPEG2BRC_HW::QuantIntoScaleTypeAndCode (int32_t quant_value, int32_t &q_scale_type, int32_t &quantiser_scale_code)
1786     {
1787         if(quant_value > 7 && quant_value <= 62)
1788         {
1789             q_scale_type = 0;
1790             quantiser_scale_code = (quant_value + 1) >> 1;
1791         }
1792         else
1793         { // non-linear quantizer
1794             q_scale_type = 1;
1795             if(quant_value <= 8)
1796             {
1797                 quantiser_scale_code = quant_value;
1798             }
1799             else if (quant_value > 62)
1800             {
1801                 quantiser_scale_code = 25+((quant_value-64+4)>>3);
1802             }
1803         }
1804         if(quantiser_scale_code < 1)
1805         {
1806             quantiser_scale_code = 1;
1807         }
1808         if(quantiser_scale_code > 31)
1809         {
1810             quantiser_scale_code = 31;
1811         }
1812     }
ChangeQuant(int32_t quant_value_old,int32_t quant_value_new)1813     int32_t MPEG2BRC_HW::ChangeQuant(int32_t quant_value_old, int32_t quant_value_new)
1814     {
1815         int32_t q_scale_type         = 0;
1816         int32_t quantiser_scale_code = 0;
1817         int32_t quant_value = quant_value_new;
1818 
1819 
1820         if(quant_value_old == quant_value)
1821         {
1822             return quant_value;
1823         }
1824         QuantIntoScaleTypeAndCode (quant_value_new, q_scale_type, quantiser_scale_code);
1825         quant_value = ScaleTypeAndCodeIntoQuant (q_scale_type, quantiser_scale_code);
1826 
1827         if (quant_value == quant_value_old)
1828         {
1829             if (quant_value_new > quant_value_old)
1830             {
1831                 if (quantiser_scale_code == 31)
1832                 {
1833                     return quant_value;
1834                 }
1835                 else
1836                 {
1837                     quantiser_scale_code ++;
1838                 }
1839             }
1840             else
1841             {
1842                 if (quantiser_scale_code == 1)
1843                 {
1844                     return quant_value;
1845                 }
1846                 else
1847                 {
1848                     quantiser_scale_code --;
1849                 }
1850             }
1851             quant_value = ScaleTypeAndCodeIntoQuant (q_scale_type, quantiser_scale_code);
1852         }
1853 
1854         return quant_value;
1855     }
Init(mfxVideoParam * par)1856     mfxStatus MPEG2BRC_HW::Init(mfxVideoParam* par)
1857     {
1858         MFX_AUTO_LTRACE(MFX_TRACE_LEVEL_HOTSPOTS, "MPEG2BRC_HW::Init");
1859         mfxStatus   sts = MFX_ERR_NONE;
1860 
1861         m_bConstantQuant = (par->mfx.RateControlMethod == MFX_RATECONTROL_CQP)? 1:0;
1862         m_bLimitedMode   = 0;
1863 
1864         if (m_bConstantQuant)
1865         {
1866             UMC::Mpeg2_BrcParams brcParams;
1867             UMC::Status ret = UMC::UMC_OK;
1868             brcParams.frameWidth  = par->mfx.FrameInfo.Width;
1869             brcParams.frameHeight = par->mfx.FrameInfo.Height;
1870             brcParams.quant[0] = par->mfx.QPI;
1871             brcParams.quant[1] = par->mfx.QPP;
1872             brcParams.quant[2] = par->mfx.QPB;
1873 
1874 
1875             if (m_pBRC == NULL)
1876             {
1877                 m_pBRC = new UMC::MPEG2BRC_CONST_QUNT;
1878             }
1879             ret = m_pBRC->Init(&brcParams);
1880             MFX_CHECK_UMC_STS (ret);
1881 
1882             ret = m_pBRC->GetParams(&brcParams);
1883             MFX_CHECK_UMC_STS (ret);
1884 
1885             mfxU32 bufferSizeInKB = ((brcParams.maxFrameSize + 999)/1000);
1886             par->mfx.BRCParamMultiplier = (mfxU16)((bufferSizeInKB + 0x10000) / 0x10000);
1887             par->mfx.BufferSizeInKB = (mfxU16)(bufferSizeInKB / par->mfx.BRCParamMultiplier);
1888         }
1889         else
1890         {
1891             UMC::VideoBrcParams brcParams;
1892             UMC::Status ret = UMC::UMC_OK;
1893 
1894             sts = ConvertVideoParam_Brc(par, &brcParams);
1895             MFX_CHECK_STS(sts);
1896             if (brcParams.HRDBufferSizeBytes == 0)
1897                 brcParams.HRDBufferSizeBytes = std::min(65535000, brcParams.targetBitrate / 4); // limit buffer size with 2 seconds
1898             if (brcParams.maxBitrate == 0)
1899                 brcParams.maxBitrate = brcParams.targetBitrate;
1900 
1901             switch (par->mfx.FrameInfo.PicStruct)
1902             {
1903             case MFX_PICSTRUCT_PROGRESSIVE:
1904                 brcParams.info.interlace_type = UMC::PROGRESSIVE;
1905                 break;
1906             case MFX_PICSTRUCT_FIELD_TFF:
1907             case MFX_PICSTRUCT_UNKNOWN:
1908                 brcParams.info.interlace_type = UMC::INTERLEAVED_TOP_FIELD_FIRST;
1909                 break;
1910             case MFX_PICSTRUCT_FIELD_BFF:
1911                 brcParams.info.interlace_type = UMC::INTERLEAVED_BOTTOM_FIELD_FIRST;
1912                 break;
1913             default:
1914                 return MFX_ERR_INVALID_VIDEO_PARAM;
1915             }
1916 
1917             if (m_pBRC == NULL)
1918             {
1919                 m_pBRC = new UMC::MPEG2BRC;
1920                 ret = m_pBRC->Init(&brcParams,m_pCore->GetHWType() < MFX_HW_HSW || m_pCore->GetHWType()==MFX_HW_VLV);
1921                 MFX_CHECK_UMC_STS (ret);
1922             }
1923             else
1924             {
1925                 m_pBRC->Close();
1926                 ret = m_pBRC->Init(&brcParams, m_pCore->GetHWType() < MFX_HW_HSW || m_pCore->GetHWType()==MFX_HW_VLV);
1927                 MFX_CHECK_UMC_STS (ret);
1928             }
1929 
1930             ret = m_pBRC->GetParams(&brcParams);
1931             MFX_CHECK_UMC_STS (ret);
1932 
1933             m_bufferSizeInKB = (mfxU32)(brcParams.HRDBufferSizeBytes / 1000);
1934             m_InputBitsPerFrame = (mfxI32)(brcParams.targetBitrate / brcParams.info.framerate);
1935 
1936             mfxU32 maxVal32 = std::max<mfxU32>({
1937                 mfxU32(brcParams.HRDInitialDelayBytes / 1000),
1938                 mfxU32(brcParams.HRDBufferSizeBytes   / 1000),
1939                 mfxU32(brcParams.targetBitrate        / 1000),
1940                 mfxU32(brcParams.maxBitrate           / 1000)});
1941 
1942             par->mfx.BRCParamMultiplier = (mfxU16)((maxVal32 + 0x10000) / 0x10000);
1943             par->mfx.BufferSizeInKB     = (mfxU16)(m_bufferSizeInKB                      / par->mfx.BRCParamMultiplier);
1944             par->mfx.InitialDelayInKB   = (mfxU16)(brcParams.HRDInitialDelayBytes / 1000 / par->mfx.BRCParamMultiplier);
1945             par->mfx.TargetKbps         = (mfxU16)(brcParams.targetBitrate        / 1000 / par->mfx.BRCParamMultiplier);
1946             par->mfx.MaxKbps            = (mfxU16)(brcParams.maxBitrate           / 1000 / par->mfx.BRCParamMultiplier);
1947 
1948 
1949             mfxU32 MBcount = (par->mfx.FrameInfo.Width/16)*(par->mfx.FrameInfo.Height/16);
1950 
1951             m_MinFrameSizeBits[0] = 16 * 6 * MBcount + 140 + (par->mfx.FrameInfo.Width/16)*32;
1952             m_MinFrameSizeBits[1] = 1*MBcount + 140 + (par->mfx.FrameInfo.Width/16)*32;
1953             m_MinFrameSizeBits[2] = 1*MBcount + 140 + (par->mfx.FrameInfo.Width/16)*32;
1954 
1955             m_MinFieldSizeBits[0] = 12 * 6 * (MBcount/2) + 140 + (par->mfx.FrameInfo.Width/16)*32;
1956             m_MinFieldSizeBits[1] = 1*MBcount/2 + 140 + (par->mfx.FrameInfo.Width/16)*32;
1957             m_MinFieldSizeBits[2] = 1*MBcount/2 + 140 + (par->mfx.FrameInfo.Width/16)*32;
1958 
1959 
1960             mfxU32 GOPLengthBits     = ((mfxU32)(brcParams.maxBitrate/brcParams.info.framerate))*brcParams.GOPPicSize;
1961             mfxI32 numPFrames        = (brcParams.GOPPicSize/brcParams.GOPRefDist > 1) ? brcParams.GOPPicSize/brcParams.GOPRefDist - 1:0;
1962             mfxI32 numBFrames        = (brcParams.GOPPicSize > numPFrames + 1) ? brcParams.GOPPicSize - numPFrames - 1:0;
1963 
1964             mfxU32 minGOPLengthBits  = m_MinFrameSizeBits[0] + numPFrames * m_MinFrameSizeBits[1] + numBFrames *m_MinFrameSizeBits[2];
1965 
1966             m_GopSize       = par->mfx.GopPicSize;
1967             m_FirstGopSize  = (m_GopSize - 1)/par->mfx.GopRefDist * par->mfx.GopRefDist + 1;
1968 
1969 
1970             if (GOPLengthBits < minGOPLengthBits)
1971             {
1972                 return MFX_ERR_INCOMPATIBLE_VIDEO_PARAM;
1973             }
1974 
1975         }
1976         return sts;
1977     }
Close()1978     void MPEG2BRC_HW::Close ()
1979     {
1980         delete m_pBRC;
1981         m_pBRC = 0;
1982 
1983         m_bConstantQuant = 0;
1984         m_MinFrameSizeBits [0] = 0;
1985         m_MinFrameSizeBits [1] = 0;
1986         m_MinFrameSizeBits [2] = 0;
1987 
1988         m_MinFieldSizeBits [0] = 0;
1989         m_MinFieldSizeBits [1] = 0;
1990         m_MinFieldSizeBits [2] = 0;
1991 
1992         m_FirstGopSize = 0;
1993         m_GopSize = 0;
1994         m_bufferSizeInKB = 0;
1995         m_InputBitsPerFrame = 0;
1996         m_bLimitedMode = 0;
1997     }
StartNewFrame(const mfxFrameParamMPEG2 * pFrameParams,mfxI32 recode)1998     mfxStatus MPEG2BRC_HW::StartNewFrame(const mfxFrameParamMPEG2 *pFrameParams, mfxI32 recode)
1999     {
2000         UMC::Status ret = UMC::UMC_OK;
2001         uint32_t        picture_structure  = 0;
2002         uint32_t        repeat_first_field = 0;
2003         uint32_t        top_field_first    = 0;
2004         uint32_t        second_field       = 0;
2005         UMC::FrameType frType   = ((pFrameParams->FrameType &  MFX_FRAMETYPE_I) ?
2006             UMC::I_PICTURE : (pFrameParams->FrameType &  MFX_FRAMETYPE_P ? UMC::P_PICTURE : UMC::B_PICTURE));
2007 
2008         if (UMC::BRC_RECODE_NONE == recode )
2009         {
2010             if (pFrameParams->FrameType &  (MFX_FRAMETYPE_P|MFX_FRAMETYPE_I))
2011             {
2012                 m_bLimitedMode = 0;
2013             }
2014         }
2015         if (UMC::BRC_RECODE_NONE == recode && m_bLimitedMode)
2016         {
2017             recode = UMC::BRC_EXT_FRAMESKIP;
2018         }
2019 
2020         ConvertFrameParamsToUMC(pFrameParams, frType,picture_structure,repeat_first_field, top_field_first,second_field);
2021         ret = m_pBRC->SetPictureFlags(frType, picture_structure, repeat_first_field, top_field_first, second_field);
2022         MFX_CHECK_UMC_STS (ret);
2023         ret = m_pBRC->PreEncFrame(frType,recode);
2024         MFX_CHECK_UMC_STS (ret);
2025 
2026         return MFX_ERR_NONE;
2027     }
2028 
2029 
SetQuantDCPredAndDelay(mfxFrameParamMPEG2 * pFrameParams,mfxU8 * pQuant)2030     mfxStatus MPEG2BRC_HW::SetQuantDCPredAndDelay(mfxFrameParamMPEG2 *pFrameParams, mfxU8 *pQuant)
2031     {
2032         UMC::FrameType  frType   = ((pFrameParams->FrameType &  MFX_FRAMETYPE_I) ?
2033                                     UMC::I_PICTURE : (pFrameParams->FrameType &  MFX_FRAMETYPE_P ? UMC::P_PICTURE : UMC::B_PICTURE));
2034 
2035         int32_t        quant_value             = m_pBRC->GetQP(frType);
2036         int32_t        q_scale_type            = 0;
2037         int32_t        quantiser_scale_code    = 0;
2038         UMC::Status   ret                     = UMC::UMC_OK;
2039         double        hrdBufFullness          = 0;
2040         UMC::VideoBrcParams brcParams;
2041 
2042         QuantIntoScaleTypeAndCode (quant_value, q_scale_type, quantiser_scale_code);
2043 
2044         if (pFrameParams->FrameType &  MFX_FRAMETYPE_I)
2045         {
2046             if(quant_value < 15)
2047                 pFrameParams->IntraVLCformat = 1;
2048             else
2049                 pFrameParams->IntraVLCformat = 0;
2050         }
2051 
2052         pFrameParams->QuantScaleType = q_scale_type;
2053 
2054         ret = m_pBRC->GetHRDBufferFullness(&hrdBufFullness, 0);
2055         MFX_CHECK_UMC_STS (ret);
2056         ret = m_pBRC->GetParams(&brcParams);
2057         MFX_CHECK_UMC_STS (ret);
2058 
2059         pFrameParams->VBVDelay = 0xffff;
2060 
2061         if(quant_value  >= 8)
2062         {
2063             pFrameParams->IntraDCprecision = 0;
2064         }
2065         else if(quant_value  >= 4)
2066         {
2067             pFrameParams->IntraDCprecision = 1;
2068         }
2069         else
2070         {
2071             pFrameParams->IntraDCprecision = 2;
2072         }
2073         *pQuant = (mfxU8)quantiser_scale_code;
2074 
2075         return MFX_ERR_NONE;
2076     }
UpdateBRC(const mfxFrameParamMPEG2 * pParams,mfxBitstream * pBitsream,mfxU32 bitsize,mfxU32 numEncodedFrame,bool bNotEnoughBuffer,mfxI32 & recode)2077     mfxStatus MPEG2BRC_HW::UpdateBRC(const mfxFrameParamMPEG2 *pParams, mfxBitstream* pBitsream, mfxU32 bitsize, mfxU32 numEncodedFrame, bool bNotEnoughBuffer ,mfxI32 &recode)
2078     {
2079         if (m_bConstantQuant)
2080         {
2081             return bNotEnoughBuffer ? MFX_ERR_NOT_ENOUGH_BUFFER: MFX_ERR_NONE;
2082         }
2083 
2084         UMC::BRCStatus  hrdSts      = UMC::BRC_OK;
2085         mfxStatus       sts         = MFX_ERR_NONE;
2086         int32_t          framestoI   = 0;
2087         int32_t          gopSize     = 0;
2088         int32_t          maxSize = 0, minSize = 0;
2089         double          buffullness = 0;
2090         int32_t          buffullnessbyI = 0;
2091 
2092         UMC::VideoBrcParams brcParams;
2093         UMC::FrameType      frType   = ((pParams->FrameType &  MFX_FRAMETYPE_I) ?
2094             UMC::I_PICTURE : (pParams->FrameType &  MFX_FRAMETYPE_P ? UMC::P_PICTURE : UMC::B_PICTURE));
2095 
2096 
2097         if (numEncodedFrame >= m_FirstGopSize)
2098         {
2099             gopSize = m_GopSize;
2100             framestoI = gopSize - ((numEncodedFrame - m_FirstGopSize) % gopSize) - 1;
2101         }
2102         else
2103         {
2104             gopSize = m_FirstGopSize;
2105             framestoI = gopSize - numEncodedFrame - 1;
2106         }
2107         if (bNotEnoughBuffer)
2108         {
2109             bitsize = (m_bufferSizeInKB+1)*1000*8;
2110         }
2111 
2112         hrdSts = m_pBRC->PostPackFrame(frType, bitsize, 0, recode);
2113 
2114         m_pBRC->GetHRDBufferFullness(&buffullness, 0);
2115         m_pBRC->GetMinMaxFrameSize(&minSize, &maxSize);
2116         m_pBRC->GetParams(&brcParams);
2117 
2118         if (hrdSts == UMC::BRC_OK)
2119         {
2120             int32_t inputbitsPerPic = m_InputBitsPerFrame;
2121             int32_t minbitsPerPredPic = 0, minbitsPerIPic = 0;
2122             recode = 0;
2123 
2124             if (pParams->FieldPicFlag)
2125             {
2126                 minbitsPerPredPic   = m_MinFieldSizeBits[1];
2127                 minbitsPerIPic      = m_MinFieldSizeBits[0];
2128                 inputbitsPerPic     >>= 1;
2129                 framestoI           *= 2;
2130                 if (!pParams->SecondFieldFlag)
2131                 {
2132                     framestoI--;
2133                 }
2134             }
2135             else
2136             {
2137                 minbitsPerPredPic   = m_MinFrameSizeBits[1];
2138                 minbitsPerIPic      = m_MinFrameSizeBits[0];
2139             }
2140             buffullnessbyI = (int32_t)buffullness + framestoI * (inputbitsPerPic - minbitsPerPredPic);
2141 
2142             if (buffullnessbyI < minbitsPerIPic ||
2143                 (pParams->FieldPicFlag && !pParams->SecondFieldFlag &&
2144                 bitsize*2 > (mfxU32)(inputbitsPerPic + maxSize) ))
2145             {
2146                 if (!m_bLimitedMode)
2147                 {
2148                     int32_t quant     = m_pBRC->GetQP(frType);
2149                     int32_t new_quant = ChangeQuant(quant, quant+2);
2150 
2151                     recode = UMC::BRC_RECODE_EXT_QP;
2152 
2153                     if (new_quant == quant )
2154                     {
2155                         m_bLimitedMode = true;
2156                         recode = UMC::BRC_RECODE_EXT_PANIC;
2157                     }
2158                     m_pBRC->SetQP(new_quant, frType);
2159                 }
2160                 else
2161                 {
2162                     if (!bNotEnoughBuffer)
2163                     {
2164                         sts = MFX_ERR_NONE;
2165                     }
2166                     else
2167                     {
2168                         sts = MFX_ERR_NOT_ENOUGH_BUFFER;
2169                     }
2170                 }
2171             }
2172         }
2173         else
2174         {
2175             if (!(hrdSts & UMC::BRC_NOT_ENOUGH_BUFFER))
2176             {
2177                 recode = UMC::BRC_RECODE_QP;
2178             }
2179             else
2180             {
2181                 if (hrdSts & UMC::BRC_ERR_SMALL_FRAME)
2182                 {
2183                     maxSize = 0, minSize = 0;
2184                     uint8_t *p = pBitsream->Data + pBitsream->DataOffset + pBitsream->DataLength;
2185                     m_pBRC->GetMinMaxFrameSize(&minSize, &maxSize);
2186                     if (bitsize < (mfxU32)minSize && pBitsream->DataOffset + 1 + pBitsream->DataLength < pBitsream->MaxLength)
2187                     {
2188                         mfxU32 nBytes = ((mfxU32)minSize - bitsize + 7)/8;
2189                         nBytes = (pBitsream->DataOffset  + pBitsream->DataLength + nBytes < pBitsream->MaxLength) ? nBytes : pBitsream->MaxLength - (pBitsream->DataOffset + pBitsream->DataLength);
2190                         memset (p,0,nBytes);
2191                         pBitsream->DataLength += nBytes;
2192                         bitsize += (nBytes*8);
2193                         // p += nBytes;
2194                     }
2195                     m_pBRC->PostPackFrame(frType, bitsize, 0, recode);
2196                     recode = UMC::BRC_RECODE_NONE;
2197 
2198                 }
2199                 else
2200                 {
2201                     if (!m_bLimitedMode)
2202                     {
2203                         m_bLimitedMode = true;
2204                         recode = UMC::BRC_RECODE_EXT_PANIC;
2205                     }
2206                     else
2207                     {
2208                         sts = MFX_ERR_NOT_ENOUGH_BUFFER;
2209                     }
2210                 }
2211             }
2212         }
2213         return sts;
2214 
2215     }
2216 
2217 #define isNONLocked(pSurface) (pSurface->Data.Y == 0)
2218 
GetInternalRefFrame(mfxFrameSurface1 ** ppFrame)2219     mfxStatus FrameStore::GetInternalRefFrame(mfxFrameSurface1** ppFrame)
2220     {
2221         mfxFrameSurface1*   pFrames     = m_pRefFramesStore;
2222         mfxU32              numFrames   = m_nRefFrames;
2223 
2224         for (mfxU32 i = 0; i < numFrames; i++)
2225         {
2226             if (!pFrames[i].Data.Locked)
2227             {
2228                 *ppFrame = &pFrames[i];
2229                 return MFX_ERR_NONE;
2230             }
2231         }
2232         return MFX_ERR_NOT_FOUND;
2233     }
2234 
GetInternalInputFrame(mfxFrameSurface1 ** ppFrame)2235     mfxStatus FrameStore::GetInternalInputFrame(mfxFrameSurface1** ppFrame)
2236     {
2237         mfxFrameSurface1*   pFrames     = m_pInputFramesStore;
2238         mfxU32              numFrames   = m_nInputFrames;
2239 
2240         for (mfxU32 i = 0; i < numFrames; i++)
2241         {
2242             if (!pFrames[i].Data.Locked)
2243             {
2244                 *ppFrame = &pFrames[i];
2245                 return MFX_ERR_NONE;
2246             }
2247         }
2248         return MFX_ERR_NOT_FOUND;
2249     }
2250 
ReleaseFrames()2251     mfxStatus FrameStore::ReleaseFrames ()
2252     {
2253         mfxStatus sts = MFX_ERR_NONE;
2254         if (m_pRefFrame[0])
2255         {
2256             sts = m_pCore->DecreaseReference(&m_pRefFrame[0]->Data);
2257             MFX_CHECK_STS (sts);
2258         }
2259         if (m_pRefFrame[1])
2260         {
2261             sts = m_pCore->DecreaseReference(&m_pRefFrame[1]->Data);
2262             MFX_CHECK_STS (sts);
2263         }
2264         if (m_pRawFrame[0])
2265         {
2266             sts = m_pCore->DecreaseReference(&m_pRawFrame[0]->Data);
2267             MFX_CHECK_STS (sts);
2268         }
2269         if (m_pRawFrame[1])
2270         {
2271             sts = m_pCore->DecreaseReference(&m_pRawFrame[1]->Data);
2272             MFX_CHECK_STS (sts);
2273         }
2274 
2275         m_pRefFrame[0]   = 0;
2276         m_pRefFrame[1]   = 0;
2277 
2278         m_pRawFrame[0]   = 0;
2279         m_pRawFrame[1]   = 0;
2280 
2281         m_nFrame = 0;
2282         m_nRefFrame[0] = 0;
2283         m_nRefFrame[1] = 0;
2284 
2285         m_nLastRefBeforeIntra = -1;
2286         m_nLastRef = -1;
2287 
2288         return sts;
2289 
2290     }
Init(bool bRawFrame,mfxU16 InputFrameType,bool bHW,mfxU32 mTasks,mfxFrameInfo * pFrameInfo,bool bProtected)2291     mfxStatus FrameStore::Init(bool bRawFrame, mfxU16 InputFrameType, bool bHW, mfxU32 mTasks, mfxFrameInfo* pFrameInfo, bool bProtected)
2292     {
2293         MFX_AUTO_LTRACE(MFX_TRACE_LEVEL_HOTSPOTS, "FrameStore::Init");
2294         mfxStatus sts = MFX_ERR_NONE;
2295         mfxU32 numref = 0;
2296         mfxU32 numinput = 0;
2297         mfxU16 type=0;
2298         bool bHWInput = ((InputFrameType & MFX_MEMTYPE_DXVA2_DECODER_TARGET) != 0);
2299 
2300         m_InputType = InputFrameType;
2301         m_bHWFrames = bHW;
2302         m_bRawFrame  = bRawFrame;
2303 
2304         ReleaseFrames();
2305 
2306         if (bHWInput != bHW)
2307         {
2308             numinput += mTasks;
2309             if (m_bRawFrame)
2310             {
2311                 numinput += mTasks*2;
2312             }
2313         }
2314         numref += mTasks*3;  // reconstructed frames
2315 
2316         m_RefRequest.NumFrameSuggested = m_RefRequest.NumFrameMin = (mfxU16)numref;
2317 
2318         m_InputRequest.NumFrameSuggested = m_InputRequest.NumFrameMin = (mfxU16)numinput;
2319 
2320         type = bHW ?
2321             (mfxU16)(MFX_MEMTYPE_INTERNAL_FRAME |MFX_MEMTYPE_DXVA2_DECODER_TARGET|MFX_MEMTYPE_FROM_ENCODE | MFX_MEMTYPE_VIDEO_MEMORY_ENCODER_TARGET):
2322             (mfxU16)(MFX_MEMTYPE_INTERNAL_FRAME |MFX_MEMTYPE_SYSTEM_MEMORY|MFX_MEMTYPE_FROM_ENCODE);
2323 
2324         MFX_CHECK(!bProtected,MFX_ERR_INCOMPATIBLE_VIDEO_PARAM);
2325 
2326 
2327         if (m_RefResponse.NumFrameActual>0)
2328         {
2329             MFX_CHECK(m_RefRequest.Type == type, MFX_ERR_INCOMPATIBLE_VIDEO_PARAM);
2330             MFX_CHECK(m_RefRequest.Info.Width >= pFrameInfo->Width && m_RefRequest.Info.Height >= pFrameInfo->Height, MFX_ERR_INCOMPATIBLE_VIDEO_PARAM);
2331             MFX_CHECK(m_RefResponse.NumFrameActual >= m_RefRequest.NumFrameMin, MFX_ERR_INCOMPATIBLE_VIDEO_PARAM);
2332 
2333             m_nRefFrames = m_RefResponse.NumFrameActual;
2334             for (mfxU32 i = 0; i < m_nRefFrames; i++)
2335             {
2336                 m_pRefFramesStore[i].Data.Locked = 0;
2337             }
2338         }
2339         else if (m_RefRequest.NumFrameSuggested)
2340         {
2341             m_RefRequest.Type = type;
2342             m_RefRequest.Info = *pFrameInfo;
2343 
2344             sts = m_pCore->AllocFrames(&m_RefRequest, &m_RefResponse);
2345             MFX_CHECK_STS(sts);
2346 
2347             if (m_RefResponse.NumFrameActual < m_RefRequest.NumFrameMin)
2348                 return MFX_ERR_MEMORY_ALLOC;
2349 
2350             m_nRefFrames = m_RefResponse.NumFrameActual;
2351 
2352             if (m_pRefFramesStore)
2353                 return MFX_ERR_MEMORY_ALLOC;
2354 
2355             m_pRefFramesStore = new mfxFrameSurface1 [m_nRefFrames];
2356             MFX_CHECK_NULL_PTR1(m_pRefFramesStore);
2357 
2358             memset (m_pRefFramesStore, 0, sizeof(mfxFrameSurface1)*m_nRefFrames);
2359 
2360             for (mfxU32 i=0; i < m_nRefFrames; i++)
2361             {
2362                 m_pRefFramesStore[i].Data.MemId = m_RefResponse.mids[i];
2363                 m_pRefFramesStore[i].Info = m_RefRequest.Info;
2364                 m_pRefFramesStore[i].Data.reserved[0] = 0x01;
2365             }
2366         }
2367 
2368         type = bHW ?
2369             (mfxU16)(MFX_MEMTYPE_INTERNAL_FRAME |MFX_MEMTYPE_DXVA2_DECODER_TARGET|MFX_MEMTYPE_FROM_ENCODE):
2370             (mfxU16)(MFX_MEMTYPE_INTERNAL_FRAME |MFX_MEMTYPE_SYSTEM_MEMORY|MFX_MEMTYPE_FROM_ENCODE);
2371 
2372         if (m_InputResponse.NumFrameActual>0)
2373         {
2374             MFX_CHECK(m_InputRequest.Type == type, MFX_ERR_INCOMPATIBLE_VIDEO_PARAM);
2375             MFX_CHECK(m_InputRequest.Info.Width >= pFrameInfo->Width && m_InputRequest.Info.Height >= pFrameInfo->Height, MFX_ERR_INCOMPATIBLE_VIDEO_PARAM);
2376             MFX_CHECK(m_InputResponse.NumFrameActual >= m_InputRequest.NumFrameMin, MFX_ERR_INCOMPATIBLE_VIDEO_PARAM);
2377 
2378             m_nInputFrames = m_InputResponse.NumFrameActual;
2379             for (mfxU32 i = 0; i < m_nInputFrames; i++)
2380             {
2381                 m_pInputFramesStore[i].Data.Locked = 0;
2382             }
2383         }
2384         else if (m_InputRequest.NumFrameSuggested)
2385         {
2386             m_InputRequest.Type = type;
2387             m_InputRequest.Info = *pFrameInfo;
2388 
2389             sts = m_pCore->AllocFrames(&m_InputRequest, &m_InputResponse);
2390             MFX_CHECK_STS(sts);
2391 
2392             if (m_InputResponse.NumFrameActual < m_InputRequest.NumFrameMin)
2393                 return MFX_ERR_MEMORY_ALLOC;
2394 
2395             m_nInputFrames = m_InputResponse.NumFrameActual;
2396 
2397             if (m_pInputFramesStore)
2398                 return MFX_ERR_MEMORY_ALLOC;
2399 
2400             m_pInputFramesStore = new mfxFrameSurface1 [m_nInputFrames];
2401             MFX_CHECK_NULL_PTR1(m_pInputFramesStore);
2402 
2403             memset (m_pInputFramesStore, 0, sizeof(mfxFrameSurface1)*m_nInputFrames);
2404 
2405             for (mfxU32 i=0; i < m_nInputFrames; i++)
2406             {
2407                 m_pInputFramesStore[i].Data.MemId = m_InputResponse.mids[i];
2408                 m_pInputFramesStore[i].Info = m_InputRequest.Info;
2409                 m_pInputFramesStore[i].Data.reserved[0] = 0x01;
2410             }
2411         }
2412 
2413         return MFX_ERR_NONE;
2414     }
NextFrame(mfxFrameSurface1 * pInputFrame,mfxU32 nFrame,mfxU16 frameType,mfxU32 intFlags,FramesSet * pFrames)2415     mfxStatus FrameStore::NextFrame(mfxFrameSurface1 *pInputFrame, mfxU32 nFrame, mfxU16 frameType, mfxU32 intFlags, FramesSet *pFrames)
2416     {
2417         mfxStatus sts           = MFX_ERR_NONE;
2418         bool      bHWInput      = (m_InputType & MFX_MEMTYPE_DXVA2_DECODER_TARGET)? true: false ;
2419         mfxU16    localFrameType = m_bHWFrames
2420             ? (mfxU16)(MFX_MEMTYPE_INTERNAL_FRAME|MFX_MEMTYPE_DXVA2_DECODER_TARGET|MFX_MEMTYPE_FROM_ENCODE)
2421             : (mfxU16)(MFX_MEMTYPE_INTERNAL_FRAME|MFX_MEMTYPE_SYSTEM_MEMORY|MFX_MEMTYPE_FROM_ENCODE);
2422         bool bReference = !!(frameType & (MFX_FRAMETYPE_I|MFX_FRAMETYPE_P));
2423         bool bIntra = !!(frameType & MFX_FRAMETYPE_I);
2424 
2425         m_nFrame = nFrame;
2426 
2427         if (bIntra)
2428         {
2429             m_nLastRefBeforeIntra = m_nLastRef;
2430         }
2431         if (bReference)
2432         {
2433             m_nLastRef = nFrame;
2434         }
2435         if (bHWInput == m_bHWFrames)
2436         {
2437             pFrames->m_pInputFrame = pInputFrame;
2438         }
2439         else
2440         {
2441             mfxFrameSurface1* pTmpFrame = 0;
2442             sts = GetInternalInputFrame(&pTmpFrame);
2443             MFX_CHECK_STS(sts);
2444             sts = m_pCore->DoFastCopyWrapper(pTmpFrame, localFrameType, pInputFrame, m_InputType);
2445             MFX_CHECK_STS(sts);
2446             pTmpFrame->Data.TimeStamp = pInputFrame->Data.TimeStamp;
2447             pFrames->m_pInputFrame = pTmpFrame;
2448         }
2449         sts = m_pCore->IncreaseReference(&pFrames->m_pInputFrame->Data);
2450         MFX_CHECK_STS(sts);
2451 
2452         // prepare reconstructed
2453         {
2454             mfxFrameSurface1* pTmpFrame = 0;
2455             sts = GetInternalRefFrame(&pTmpFrame);
2456             MFX_CHECK_STS(sts);
2457             pFrames->m_pRecFrame = pTmpFrame;
2458             sts = m_pCore->IncreaseReference(&pFrames->m_pRecFrame->Data);
2459             MFX_CHECK_STS(sts);
2460         }
2461 
2462         if (bReference)
2463         {
2464             m_nRefFrame[0] = m_nRefFrame[1];
2465             m_nRefFrame[1] = nFrame;
2466 
2467             // prepare reference
2468             if (m_pRefFrame[0])
2469             {
2470                 sts = m_pCore->DecreaseReference(&m_pRefFrame[0]->Data);
2471                 MFX_CHECK_STS(sts);
2472             }
2473             m_pRefFrame[0] = m_pRefFrame[1];
2474             m_pRefFrame[1] = pFrames->m_pRecFrame;
2475             sts = m_pCore->IncreaseReference(&m_pRefFrame[1]->Data);
2476             MFX_CHECK_STS(sts);
2477 
2478             if (m_bRawFrame)
2479             {
2480                 if (m_pRawFrame[0])
2481                 {
2482                     sts = m_pCore->DecreaseReference(&m_pRawFrame[0]->Data);
2483                     MFX_CHECK_STS(sts);
2484                 }
2485                 m_pRawFrame[0] = m_pRawFrame[1];
2486                 m_pRawFrame[1] = pFrames->m_pInputFrame;
2487                 sts = m_pCore->IncreaseReference(&m_pRawFrame[1]->Data);
2488                 MFX_CHECK_STS(sts);
2489             }
2490         }
2491         // Set Reference frames
2492 
2493         pFrames->m_pRefFrame[0] = m_pRefFrame[0];
2494         pFrames->m_pRefFrame[1] = m_pRefFrame[1];
2495 
2496         pFrames->m_pRawFrame[0] = m_pRawFrame[0];
2497         pFrames->m_pRawFrame[1] = m_pRawFrame[1];
2498 
2499         pFrames->m_nFrame       = m_nFrame;
2500         pFrames->m_nLastRefBeforeIntra   = m_nLastRefBeforeIntra;
2501         pFrames->m_nLastRef = m_nLastRef;
2502         pFrames->m_nRefFrame[0] = m_nRefFrame [0];
2503         pFrames->m_nRefFrame[1] = m_nRefFrame [1];
2504 
2505         if ((0 != (frameType & MFX_FRAMETYPE_B)) && (0 != (intFlags & MFX_IFLAG_BWD_ONLY)))
2506         {
2507             pFrames->m_pRefFrame[0] = 0;
2508             pFrames->m_nRefFrame[0] = 0;
2509         }
2510         if ((0 != (frameType & MFX_FRAMETYPE_B)) && (0 != (intFlags & MFX_IFLAG_FWD_ONLY)))
2511         {
2512             pFrames->m_pRefFrame[1] = 0;
2513             pFrames->m_nRefFrame[1] = 0;
2514         }
2515 
2516         sts = pFrames->LockRefFrames(m_pCore);
2517         MFX_CHECK_STS(sts);
2518 
2519         return sts;
2520     }
Close()2521     mfxStatus FrameStore::Close()
2522     {
2523         mfxStatus sts = MFX_ERR_NONE;
2524 
2525         sts = ReleaseFrames();
2526         MFX_CHECK_STS(sts);
2527 
2528         if (m_RefResponse.NumFrameActual)
2529         {
2530             sts = m_pCore->FreeFrames(&m_RefResponse);
2531             m_RefResponse.NumFrameActual = 0;
2532         }
2533 
2534         if (m_nRefFrames)
2535         {
2536             delete [] m_pRefFramesStore;
2537             m_nRefFrames = 0;
2538             m_pRefFramesStore = 0;
2539         }
2540 
2541         if (m_InputResponse.NumFrameActual)
2542         {
2543             sts = m_pCore->FreeFrames(&m_InputResponse);
2544             m_InputResponse.NumFrameActual = 0;
2545         }
2546 
2547         if (m_nInputFrames)
2548         {
2549             delete [] m_pInputFramesStore;
2550             m_nInputFrames = 0;
2551             m_pInputFramesStore = 0;
2552         }
2553 
2554         m_InputType = 0;
2555 
2556         memset(&m_RefRequest,  0, sizeof(mfxFrameAllocRequest));
2557         memset(&m_RefResponse, 0, sizeof(mfxFrameAllocResponse));
2558         memset(&m_InputRequest,  0, sizeof(mfxFrameAllocRequest));
2559         memset(&m_InputResponse, 0, sizeof(mfxFrameAllocResponse));
2560 
2561         return sts;
2562     }
2563 
2564 
2565 }
2566 
2567 
2568 
2569 
2570 
2571 #endif // MFX_ENABLE_MPEG2_VIDEO_ENCODE
2572