1 // Copyright (c) 2017 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 "umc_defs.h"
22 
23 #include <cmath>
24 #include <algorithm>
25 #include <limits.h>
26 #include "mfx_enc_common.h"
27 #include "mfx_utils.h"
28 
29 //----MFX data -> UMC data--------------------------------------------
CalculateMAXBFrames(mfxU8 GopRefDist)30 uint8_t CalculateMAXBFrames (mfxU8 GopRefDist)
31 {
32     if(GopRefDist)
33         return (GopRefDist - 1);
34     else
35         return 0;
36 }
37 
CalculateUMCGOPLength(mfxU16 GOPSize,mfxU8 targetUsage)38 uint16_t CalculateUMCGOPLength (mfxU16 GOPSize, mfxU8 targetUsage)
39 {
40     if(GOPSize)
41         return (GOPSize);
42     else
43         switch (targetUsage)
44         {
45         case MFX_TARGETUSAGE_BEST_QUALITY:
46             return 200;
47         case 2:
48             return 200;
49         case 3:
50              return 200;
51         case 4:
52             return 20;
53         case 5:
54             return 10;
55         case 6:
56             return 4;
57         case MFX_TARGETUSAGE_BEST_SPEED:
58             return 1;
59         }
60     return 1;
61 }
SetUFParameters(mfxU8 TargetUsages,bool & mixed,uint32_t & twoRef)62 bool SetUFParameters(mfxU8 TargetUsages, bool& mixed,uint32_t& twoRef )
63 {
64     switch (TargetUsages)
65     {
66     case MFX_TARGETUSAGE_BEST_QUALITY:
67         mixed=0;twoRef=2;
68         break;
69     case 2:
70         mixed=0;twoRef=2;
71         break;
72     case 3:
73         mixed=0;twoRef=2;
74         break;
75     case 4:
76         mixed=0;twoRef=1;
77         break;
78     case 5:
79         mixed=0;twoRef=1;
80         break;
81     case 6:
82         mixed=0;twoRef=1;
83         break;
84     case MFX_TARGETUSAGE_BEST_SPEED:
85         mixed=0;twoRef=1;
86         break;
87     default:
88         return false;
89     }
90     return true;
91 }
SetPROParameters(mfxU8 TargetUsages,uint8_t & MESpeed,bool & UseFB,bool & FastFB,bool & bIntensityCompensation,bool & bChangeInterpolationType,bool & bChangeVLCTables,bool & bTrellisQuantization,bool & bUsePadding,bool & bVSTransform,bool & deblocking,mfxU8 & smoothing,bool & fastUVMC)92 bool SetPROParameters (mfxU8 TargetUsages,uint8_t &MESpeed, bool &UseFB, bool &FastFB, bool &bIntensityCompensation,
93                        bool &bChangeInterpolationType, bool &bChangeVLCTables,bool &bTrellisQuantization, bool &bUsePadding,
94                        bool &bVSTransform, bool &deblocking, mfxU8 &smoothing, bool &fastUVMC)
95 {
96     switch (TargetUsages)
97     {
98     case MFX_TARGETUSAGE_BEST_QUALITY:
99         MESpeed=25; UseFB=1; FastFB=0; bIntensityCompensation=0;
100         bChangeInterpolationType=1;bTrellisQuantization = 1;
101         bUsePadding  = 1; bChangeVLCTables =1;
102         bVSTransform = 1; deblocking = 1;  smoothing = 0; fastUVMC = 0;
103         break;
104     case 2:
105         MESpeed=25; UseFB=1; FastFB=0; bIntensityCompensation=0;
106         bChangeInterpolationType=1;bTrellisQuantization = 1;
107         bUsePadding  = 1; bChangeVLCTables =1;
108         bVSTransform = 0; deblocking = 1;  smoothing = 0; fastUVMC = 0;
109         break;
110     case 3:
111         MESpeed=25; UseFB=1; FastFB=0; bIntensityCompensation=0;
112         bChangeInterpolationType=0;bTrellisQuantization = 0;
113         bUsePadding  = 1; bChangeVLCTables =0;
114         bVSTransform = 0; deblocking = 1;  smoothing = 0; fastUVMC = 0;
115         break;
116     case 4:
117         MESpeed=25; UseFB=1; FastFB=0; bIntensityCompensation=0;
118         bChangeInterpolationType=0;bTrellisQuantization = 0;
119         bUsePadding  = 1; bChangeVLCTables =0;
120         bVSTransform = 0; deblocking = 1;  smoothing = 0; fastUVMC = 0;
121         break;
122     case 5:
123         MESpeed=25; UseFB=0; FastFB=0; bIntensityCompensation=0;
124         bChangeInterpolationType=0;bTrellisQuantization = 0;
125         bUsePadding  = 1; bChangeVLCTables =0;
126         bVSTransform = 0; deblocking = 1;  smoothing = 0; fastUVMC = 0;
127         break;
128     case 6:
129         MESpeed=25; UseFB=0; FastFB=0; bIntensityCompensation=0;
130         bChangeInterpolationType=0;bTrellisQuantization = 0;
131         bUsePadding  = 0; bChangeVLCTables =0;
132         bVSTransform = 0; deblocking = 1;  smoothing = 0; fastUVMC = 1;
133         break;
134     case MFX_TARGETUSAGE_BEST_SPEED:
135         MESpeed=25; UseFB=0; FastFB=0; bIntensityCompensation=0;
136         bChangeInterpolationType=0;bTrellisQuantization = 0;
137         bUsePadding  = 0; bChangeVLCTables =0;
138         bVSTransform = 0; deblocking = 0;  smoothing = 0; fastUVMC = 1;
139         break;
140     default:
141         return false;
142     }
143     return true;
144 }
145 
146 
CalculateUMCBitrate(mfxU16 TargetKbps)147 uint32_t CalculateUMCBitrate(mfxU16    TargetKbps)
148 {
149     return TargetKbps*1000;
150 }
151 
CalculateUMCFramerate(mfxU32 FrameRateExtN,mfxU32 FrameRateExtD)152 double CalculateUMCFramerate( mfxU32 FrameRateExtN, mfxU32 FrameRateExtD)
153 {
154     if (FrameRateExtN && FrameRateExtD)
155         return (double)FrameRateExtN / FrameRateExtD;
156     else
157         return 0;
158 }
159 
CalculateMFXFramerate(double framerate,mfxU32 * FrameRateExtN,mfxU32 * FrameRateExtD)160 void CalculateMFXFramerate(double framerate, mfxU32* FrameRateExtN, mfxU32* FrameRateExtD)
161 {
162   mfxU32 fr;
163   if (!FrameRateExtN || !FrameRateExtD)
164     return;
165 
166   fr = (mfxU32)(framerate + .5);
167   if (fabs(fr - framerate) < 0.0001) {
168     *FrameRateExtN = fr;
169     *FrameRateExtD = 1;
170     return;
171   }
172 
173   fr = (mfxU32)(framerate * 1.001 + .5);
174   if (fabs(fr * 1000 - framerate * 1001) < 10) {
175     *FrameRateExtN = fr * 1000;
176     *FrameRateExtD = 1001;
177     return;
178   }
179   // can do more
180 
181   *FrameRateExtN = (mfxU32)(framerate * 10000 + .5);
182   *FrameRateExtD = 10000;
183   return;
184 }
185 
186 
GetFrameType(mfxU16 FrameOrder,mfxInfoMFX * info)187 UMC::FrameType GetFrameType (mfxU16 FrameOrder, mfxInfoMFX* info)
188 {
189   mfxU16 GOPSize = info->GopPicSize;
190   mfxU16 IPDist = info->GopRefDist;
191   mfxU16 pos = (GOPSize)? FrameOrder %(GOPSize):FrameOrder;
192 
193 
194   if (pos == 0 || IPDist == 0)
195   {
196       return UMC::I_PICTURE;
197   }
198   else
199   {
200       pos = pos % (IPDist);
201       return (pos != 0) ? UMC::B_PICTURE : UMC::P_PICTURE;
202   }
203 }
204 
205 
206 //----UMC data -> MFX data--------------------------------------------
207 
CalculateMFXGOPLength(uint16_t GOPSize)208 mfxU16 CalculateMFXGOPLength (uint16_t GOPSize)
209 {
210     if(!GOPSize)
211         return GOPSize;
212     else
213         return 15;
214 }
215 
CalculateGopRefDist(mfxU8 BNum)216 mfxU8 CalculateGopRefDist(mfxU8 BNum)
217 {
218     return (BNum + 1);
219 }
220 
TranslateMfxFRCodeMPEG2(mfxFrameInfo * info,mfxU32 * codeN,mfxU32 * codeD)221 mfxU32 TranslateMfxFRCodeMPEG2(mfxFrameInfo *info, mfxU32 *codeN, mfxU32* codeD)
222 {
223   mfxU32 n = info->FrameRateExtN, d = info->FrameRateExtD, code = 0;
224   mfxU32 flag1001 = 0;
225 
226   if (!n || !d) return 0;
227   if(d%1001 == 0 && n%1000 == 0) {
228     n /= 1000;
229     d /= 1001;
230     flag1001 = 1;
231   }
232   switch(n) {
233     case 48: case 72: case 96:
234     case 24 : code = 2 - flag1001; n /= 24; break;
235     case 90:
236     case 30 : code = 5 - flag1001; n /= 30; break;
237     case 120: case 180: case 240:
238     case 60 : code = 8 - flag1001; n /= 60; break;
239     case 75:
240     case 25 : code = 3; n /= 25; break;
241     case 100: case 150: case 200:
242     case 50 : code = 6; n /= 50; break;
243     default: code = 0;
244   }
245   if( code != 0 && d <= 0x20 &&
246     ((code !=3 && code != 6) || !flag1001) ) {
247       *codeN = n-1;
248       *codeD = d-1;
249       return code;
250   }
251   // can do more
252   return 0;
253 }
254 
GetExtBuffer(mfxExtBuffer ** ebuffers,mfxU32 nbuffers,mfxU32 BufferId)255 mfxExtBuffer* GetExtBuffer(mfxExtBuffer** ebuffers, mfxU32 nbuffers, mfxU32 BufferId)
256 {
257     if (!ebuffers) return 0;
258     for(mfxU32 i=0; i<nbuffers; i++) {
259         if (!ebuffers[i]) continue;
260         if (ebuffers[i]->BufferId == BufferId) {
261             return ebuffers[i];
262         }
263     }
264     return 0;
265 }
266 
GetExtCodingOptions(mfxExtBuffer ** ebuffers,mfxU32 nbuffers)267 mfxExtCodingOption* GetExtCodingOptions(mfxExtBuffer** ebuffers, mfxU32 nbuffers)
268 {
269     return (mfxExtCodingOption*)GetExtBuffer(ebuffers, nbuffers, MFX_EXTBUFF_CODING_OPTION);
270 }
271 
GetExtVideoSignalInfo(mfxExtBuffer ** ebuffers,mfxU32 nbuffers)272 mfxExtVideoSignalInfo* GetExtVideoSignalInfo(mfxExtBuffer** ebuffers, mfxU32 nbuffers)
273 {
274     return (mfxExtVideoSignalInfo *)GetExtBuffer(ebuffers, nbuffers, MFX_EXTBUFF_VIDEO_SIGNAL_INFO);
275 }
276 
277 //----------work with marker-----------------------------
SetFrameLockMarker(mfxFrameData * pFrame,mfxU8 LockMarker)278 mfxStatus SetFrameLockMarker(mfxFrameData* pFrame, mfxU8 LockMarker)
279 {
280     MFX_CHECK_NULL_PTR1(pFrame);
281 
282     pFrame->Locked = LockMarker;
283 
284     return MFX_ERR_NONE;
285 }
286 
GetFrameLockMarker(mfxFrameData * pFrame)287 mfxU8 GetFrameLockMarker(mfxFrameData* pFrame)
288 {
289     return (mfxU8)pFrame->Locked;
290 }
291 
292 const Rational RATETAB[8]=
293 {
294     {24000, 1001},
295     {   24,    1},
296     {   25,    1},
297     {30000, 1001},
298     {   30,    1},
299     {   50,    1},
300     {60000, 1001},
301     {   60,    1},
302 };
303 
304 static const Rational SORTED_RATIO[] =
305 {
306     {1,32},{1,31},{1,30},{1,29},{1,28},{1,27},{1,26},{1,25},{1,24},{1,23},{1,22},{1,21},{1,20},{1,19},{1,18},{1,17},
307     {1,16},{2,31},{1,15},{2,29},{1,14},{2,27},{1,13},{2,25},{1,12},{2,23},{1,11},{3,32},{2,21},{3,31},{1,10},{3,29},
308     {2,19},{3,28},{1, 9},{3,26},{2,17},{3,25},{1, 8},{4,31},{3,23},{2,15},{3,22},{4,29},{1, 7},{4,27},{3,20},{2,13},
309     {3,19},{4,25},{1, 6},{4,23},{3,17},{2,11},{3,16},{4,21},{1, 5},{4,19},{3,14},{2, 9},{3,13},{4,17},{1, 4},{4,15},
310     {3,11},{2, 7},{3,10},{4,13},{1, 3},{4,11},{3, 8},{2, 5},{3, 7},{4, 9},{1, 2},{4, 7},{3, 5},{2, 3},{3, 4},{4, 5},
311     {1,1},{4,3},{3,2},{2,1},{3,1},{4,1}
312 };
313 
314 class FR_Compare
315 {
316 public:
317 
operator ()(Rational rfirst,Rational rsecond)318     bool operator () (Rational rfirst, Rational rsecond)
319     {
320         mfxF64 first = (mfxF64) rfirst.n/rfirst.d;
321         mfxF64 second = (mfxF64) rsecond.n/rsecond.d;
322         return ( first < second );
323     }
324 };
325 
326 
ConvertFrameRateMPEG2(mfxU32 FrameRateExtD,mfxU32 FrameRateExtN,mfxI32 & frame_rate_code,mfxI32 & frame_rate_extension_n,mfxI32 & frame_rate_extension_d)327 void ConvertFrameRateMPEG2(mfxU32 FrameRateExtD, mfxU32 FrameRateExtN, mfxI32 &frame_rate_code, mfxI32 &frame_rate_extension_n, mfxI32 &frame_rate_extension_d)
328 {
329     Rational convertedFR;
330     Rational bestFR = {INT_MAX, 1};
331     mfxF64 minDifference = MFX_MAXABS_64F;
332 
333     for (mfxU32 i = 0; i < sizeof(RATETAB) / sizeof(RATETAB[0]); i++)
334     {
335         if (FrameRateExtN * RATETAB[i].d == FrameRateExtD * RATETAB[i].n )
336         {
337             frame_rate_code = i + 1;
338             frame_rate_extension_n = 0;
339             frame_rate_extension_d = 0;
340 
341             return;
342         }
343     }
344 
345     for (mfxU32 i = 0; i < sizeof(RATETAB) / sizeof(RATETAB[0]); i++)
346     {
347         convertedFR.n = (mfxI64) FrameRateExtN * RATETAB[i].d;
348         convertedFR.d = (mfxI64) FrameRateExtD * RATETAB[i].n;
349 
350         const Rational* it_lower = std::lower_bound(
351             SORTED_RATIO,
352             SORTED_RATIO + sizeof(SORTED_RATIO) / sizeof(SORTED_RATIO[0]),
353             convertedFR,
354             FR_Compare());
355 
356         if (it_lower == SORTED_RATIO + sizeof(SORTED_RATIO) / sizeof(SORTED_RATIO[0]))  // exceed max FR
357         {
358             it_lower--;
359         }
360         else if (it_lower != SORTED_RATIO) // min FR not reached
361         {
362             if ( std::abs( (mfxF64) (it_lower - 1)->n / (it_lower - 1)->d - (mfxF64) convertedFR.n / convertedFR.d) <
363                 std::abs((mfxF64)it_lower->n / it_lower->d - (mfxF64)convertedFR.n / convertedFR.d))
364             {
365                 it_lower--;
366             }
367         }
368 
369         if (minDifference > std::abs((mfxF64)convertedFR.n / convertedFR.d - (mfxF64)it_lower->n / it_lower->d))
370         {
371             minDifference = std::abs((mfxF64)convertedFR.n / convertedFR.d - (mfxF64)it_lower->n / it_lower->d);
372             frame_rate_code = i + 1;
373             bestFR = *it_lower;
374         }
375     }
376 
377     for (mfxU32 i = 0; i < sizeof(RATETAB) / sizeof(RATETAB[0]); i++)
378     {// check that exist equal RATETAB with FR = 1:1
379         if (RATETAB[i].d * RATETAB[frame_rate_code - 1].n * bestFR.n == RATETAB[i].n * RATETAB[frame_rate_code - 1].d * bestFR.d)
380         {
381             frame_rate_code = i + 1;
382             frame_rate_extension_n = 0;
383             frame_rate_extension_d = 0;
384             return;
385         }
386     }
387 
388     frame_rate_extension_n = (mfxI32) bestFR.n - 1;
389     frame_rate_extension_d = (mfxI32) bestFR.d - 1;
390     return;
391 }
392 
CheckFrameRateMPEG2(mfxU32 & FrameRateExtD,mfxU32 & FrameRateExtN)393 mfxStatus CheckFrameRateMPEG2(mfxU32 &FrameRateExtD, mfxU32 &FrameRateExtN)
394 {
395     mfxI32 frame_rate_code        = 0;
396     mfxI32 frame_rate_extension_n = 0;
397     mfxI32 frame_rate_extension_d = 0;
398     mfxF64 input_ratio = (mfxF64) FrameRateExtN / FrameRateExtD;
399     mfxF64 difference_ratio = 0;
400 
401     ConvertFrameRateMPEG2(FrameRateExtD, FrameRateExtN, frame_rate_code, frame_rate_extension_n, frame_rate_extension_d);
402     difference_ratio =  fabs(input_ratio - (mfxF64)(frame_rate_extension_n + 1) / (frame_rate_extension_d + 1) * RATETAB[frame_rate_code - 1].n / RATETAB[frame_rate_code - 1].d);
403 
404     if (difference_ratio < input_ratio / 50000)
405     { //difference less than 0.05%
406        return MFX_ERR_NONE;
407     }
408     else
409     {
410        FrameRateExtD = (mfxU32) ((frame_rate_extension_d + 1) * RATETAB[frame_rate_code - 1].d);
411        FrameRateExtN = (mfxU32) ((frame_rate_extension_n + 1) * RATETAB[frame_rate_code - 1].n);
412 
413        if (difference_ratio < input_ratio / 1000)
414            return MFX_WRN_INCOMPATIBLE_VIDEO_PARAM;
415        else //difference more than 0.1%
416            return MFX_ERR_INVALID_VIDEO_PARAM;
417     }
418 }
CheckAspectRatioMPEG2(mfxU16 & aspectRatioW,mfxU16 & aspectRatioH,mfxU32 frame_width,mfxU32 frame_heigth,mfxU16 cropW,mfxU16 cropH)419 mfxStatus CheckAspectRatioMPEG2 (mfxU16 &aspectRatioW, mfxU16 &aspectRatioH, mfxU32 frame_width, mfxU32 frame_heigth, mfxU16 cropW, mfxU16 cropH)
420 {
421     mfxU32 width = (cropW != 0) ? cropW : frame_width;
422     mfxU32 height =(cropH != 0) ? cropH : frame_heigth;
423 
424     if ((aspectRatioW == 0 && aspectRatioH == 0) || (aspectRatioW == 1 && aspectRatioH == 1))
425         return MFX_ERR_NONE;
426     if (aspectRatioW == 0 || aspectRatioH == 0)
427         return MFX_ERR_INVALID_VIDEO_PARAM;
428     if (width != 0 && height != 0)
429     {
430         mfxU64 k   = ((mfxU64)aspectRatioW * width * 100000) / (aspectRatioH * height);
431 
432         if ((aspectRatioW * width * 3 == aspectRatioH * height * 4) ||
433             (aspectRatioW * width * 9 == aspectRatioH * height * 16) ||
434             (aspectRatioW * width * 100 == aspectRatioH * height * 221) )
435         {
436             return MFX_ERR_NONE;
437         }
438 
439         if (k > (400000/3 - 133) && k < (400000/3 + 133))
440         {
441             return MFX_ERR_NONE;
442         }
443         else if ( k > ( 1600000/9 - 177) && k < (1600000/9 + 177) )
444         {
445             return MFX_ERR_NONE;
446         }
447         else if (k > (22100000/100 - 221) && k < (22100000/100 + 221))
448         {
449              return MFX_ERR_NONE;
450         }
451         else
452             return MFX_ERR_INCOMPATIBLE_VIDEO_PARAM;
453     }
454     else
455     {
456         if (width == 0 && height == 0)
457             return MFX_ERR_NONE;
458         else
459             return MFX_ERR_INVALID_VIDEO_PARAM;
460     }
461 }
GetAspectRatioCode(mfxU32 dispAspectRatioW,mfxU32 dispAspectRatioH)462 mfxU8 GetAspectRatioCode (mfxU32 dispAspectRatioW, mfxU32 dispAspectRatioH)
463 {
464     if (dispAspectRatioH == 0)
465     {
466         return 1;
467     }
468     mfxU64 k  = ((mfxU64)dispAspectRatioW*1000)/(dispAspectRatioH);
469 
470      if  (k <= (4000/3  + 1)  && k >= (4000/3 - 1))
471      {
472          return 2;
473      }
474      if (k <= (16000/9  + 1)  && k >= (16000/9 - 1))
475      {
476          return 3;
477      }
478      if (k <= (221000/100  + 1)  && k >= (221000/100 - 1))
479      {
480          return 4;
481      }
482      return 1;
483 }
484 
CorrectProfileLevelMpeg2(mfxU16 & profile,mfxU16 & level,mfxU32 w,mfxU32 h,mfxF64 frame_rate,mfxU32 bitrate,mfxU32 GopRefDist)485 bool CorrectProfileLevelMpeg2(mfxU16 &profile, mfxU16 & level, mfxU32 w, mfxU32 h, mfxF64 frame_rate, mfxU32 bitrate, mfxU32 GopRefDist)
486 {
487     mfxU16 oldLevel   = level;
488     mfxU16 oldProfile = profile;
489 
490     if (MFX_LEVEL_MPEG2_HIGH !=  level && MFX_LEVEL_MPEG2_HIGH1440 !=  level && MFX_LEVEL_MPEG2_MAIN !=  level &&  MFX_LEVEL_MPEG2_LOW !=  level)
491         level = MFX_LEVEL_MPEG2_MAIN;
492 
493     if (MFX_PROFILE_MPEG2_SIMPLE != profile
494         && MFX_PROFILE_MPEG2_MAIN != profile
495 #if !defined(MFX_VA_LINUX)
496         && MFX_PROFILE_MPEG2_HIGH != profile
497 #endif
498         )
499     {
500         profile = MFX_PROFILE_MPEG2_MAIN;
501     }
502 
503     if (MFX_PROFILE_MPEG2_HIGH == profile)
504     {
505         if (w > 1440 || h > 1152 || frame_rate*w*h > 62668800.0 || bitrate > 80000000)
506         {
507             level = MFX_LEVEL_MPEG2_HIGH;
508         }
509         else if ((w > 720 || h > 576 || frame_rate > 30 || frame_rate*w*h > 14745600.0 || bitrate > 20000000) && (level != MFX_LEVEL_MPEG2_HIGH))
510         {
511             level = MFX_LEVEL_MPEG2_HIGH1440;
512         }
513     }
514     else
515     {
516         if (w > 1440 || h > 1152 || frame_rate*w*h > 47001600.0 || bitrate > 60000000)
517         {
518             level = MFX_LEVEL_MPEG2_HIGH;
519         }
520         else if ((w > 720 || h > 576 || frame_rate > 30 || frame_rate*w*h > 10368000.0 || bitrate > 15000000) && (level != MFX_LEVEL_MPEG2_HIGH))
521         {
522             level = MFX_LEVEL_MPEG2_HIGH1440;
523         }
524         else if ((w > 352 || h > 288 || frame_rate*w*h > 3041280.0 || bitrate > 4000000) && (level != MFX_LEVEL_MPEG2_HIGH && level != MFX_LEVEL_MPEG2_HIGH1440))
525         {
526             level = MFX_LEVEL_MPEG2_MAIN;
527         }
528     }
529 
530     if (MFX_PROFILE_MPEG2_SIMPLE == profile && ((MFX_LEVEL_MPEG2_MAIN != level && MFX_LEVEL_MPEG2_LOW != level) || (GopRefDist >1)))
531     {
532         profile = MFX_PROFILE_MPEG2_MAIN;
533     }
534 
535     if (MFX_PROFILE_MPEG2_HIGH == profile && MFX_LEVEL_MPEG2_LOW == level )
536     {
537         profile = MFX_PROFILE_MPEG2_MAIN;
538     }
539     return (((oldLevel!=0) && (oldLevel!=level)) || ((oldProfile!=0) && (oldProfile!=profile)));
540 
541 }
Reset(mfxVideoParam * par,mfxU16 NumFrameMin)542 mfxStatus InputSurfaces::Reset(mfxVideoParam *par, mfxU16 NumFrameMin)
543 {
544     mfxStatus sts = MFX_ERR_NONE;
545 
546     mfxU32 ioPattern = par->IOPattern & (MFX_IOPATTERN_IN_VIDEO_MEMORY|MFX_IOPATTERN_IN_SYSTEM_MEMORY|MFX_IOPATTERN_IN_OPAQUE_MEMORY);
547     if (ioPattern & (ioPattern - 1))
548         return MFX_ERR_INVALID_VIDEO_PARAM;
549 
550     MFX_INTERNAL_CPY(&m_Info,&par->mfx.FrameInfo,sizeof(mfxFrameInfo));
551 
552     bool bOpaq = (par->IOPattern & MFX_IOPATTERN_IN_OPAQUE_MEMORY)!=0;
553 
554     MFX_CHECK(bOpaq == m_bOpaq || !m_bInitialized, MFX_ERR_INCOMPATIBLE_VIDEO_PARAM);
555 
556     if (bOpaq)
557     {
558         MFX_CHECK (m_pCore->IsCompatibleForOpaq(), MFX_ERR_UNDEFINED_BEHAVIOR);
559 
560         mfxExtOpaqueSurfaceAlloc * pOpaqAlloc = (mfxExtOpaqueSurfaceAlloc *)GetExtendedBuffer(par->ExtParam, par->NumExtParam, MFX_EXTBUFF_OPAQUE_SURFACE_ALLOCATION);
561         MFX_CHECK (pOpaqAlloc, MFX_ERR_INVALID_VIDEO_PARAM);
562 
563         switch (pOpaqAlloc->In.Type & (MFX_MEMTYPE_DXVA2_DECODER_TARGET|MFX_MEMTYPE_SYSTEM_MEMORY|MFX_MEMTYPE_DXVA2_PROCESSOR_TARGET))
564         {
565         case MFX_MEMTYPE_SYSTEM_MEMORY:
566             m_bSysMemFrames = true;
567             break;
568         case MFX_MEMTYPE_DXVA2_DECODER_TARGET:
569         case MFX_MEMTYPE_DXVA2_PROCESSOR_TARGET:
570             m_bSysMemFrames = false;
571             break;
572         default:
573             return MFX_ERR_INCOMPATIBLE_VIDEO_PARAM;
574         }
575 
576        if (pOpaqAlloc->In.NumSurface < NumFrameMin)
577             return m_bInitialized ? MFX_ERR_INCOMPATIBLE_VIDEO_PARAM : MFX_ERR_INVALID_VIDEO_PARAM;
578         if (pOpaqAlloc->In.NumSurface > m_request.NumFrameMin && m_bInitialized)
579             return MFX_ERR_INCOMPATIBLE_VIDEO_PARAM;
580 
581         if (!m_bInitialized)
582         {
583             m_request.Info = par->mfx.FrameInfo;
584             m_request.NumFrameMin = m_request.NumFrameSuggested = (mfxU16)pOpaqAlloc->In.NumSurface;
585             m_request.Type = (mfxU16)pOpaqAlloc->In.Type;
586 
587             sts = m_pCore->AllocFrames(&m_request,
588                 &m_response,
589                 pOpaqAlloc->In.Surfaces,
590                 pOpaqAlloc->In.NumSurface);
591 
592             if (MFX_ERR_UNSUPPORTED == sts && (pOpaqAlloc->In.Type & MFX_MEMTYPE_FROM_ENCODE) == 0)  sts = MFX_ERR_NONE;
593             MFX_CHECK_STS(sts);
594         }
595         m_bOpaq = true;
596     }
597     else
598     {
599         bool bSysMemFrames = (par->IOPattern & MFX_IOPATTERN_IN_SYSTEM_MEMORY) != 0;
600         MFX_CHECK(bSysMemFrames == m_bSysMemFrames || !m_bInitialized, MFX_ERR_INCOMPATIBLE_VIDEO_PARAM);
601         m_bSysMemFrames = bSysMemFrames;
602     }
603     m_bInitialized = true;
604     return sts;
605 }
Close()606 mfxStatus InputSurfaces::Close()
607 {
608     if (m_response.NumFrameActual != 0)
609     {
610         m_pCore->FreeFrames (&m_response);
611     }
612     m_bOpaq = false;
613     m_bSysMemFrames = false;
614     m_bInitialized = false;
615 
616     memset(&m_request,  0, sizeof(mfxFrameAllocRequest));
617     memset(&m_response, 0, sizeof (mfxFrameAllocResponse));
618 
619     return MFX_ERR_NONE;
620 }
621 
CheckExtVideoSignalInfo(mfxExtVideoSignalInfo * videoSignalInfo)622 mfxStatus CheckExtVideoSignalInfo(mfxExtVideoSignalInfo * videoSignalInfo)
623 {
624     mfxStatus sts = MFX_ERR_NONE;
625 
626     if (videoSignalInfo->VideoFormat > 7)
627     {
628         videoSignalInfo->VideoFormat = 5; // unspecified video format
629         sts = MFX_WRN_INCOMPATIBLE_VIDEO_PARAM;
630     }
631 
632     if (videoSignalInfo->ColourDescriptionPresent > 1)
633     {
634         videoSignalInfo->ColourDescriptionPresent = 0;
635         sts = MFX_WRN_INCOMPATIBLE_VIDEO_PARAM;
636     }
637 
638     if (videoSignalInfo->ColourDescriptionPresent)
639     {
640         if (videoSignalInfo->ColourPrimaries > 255)
641         {
642             videoSignalInfo->ColourPrimaries = 2; // unspecified image characteristics
643             sts = MFX_WRN_INCOMPATIBLE_VIDEO_PARAM;
644         }
645 
646         if (videoSignalInfo->TransferCharacteristics > 255)
647         {
648             videoSignalInfo->TransferCharacteristics = 2; // unspecified image characteristics
649             sts = MFX_WRN_INCOMPATIBLE_VIDEO_PARAM;
650         }
651 
652         if (videoSignalInfo->MatrixCoefficients > 255)
653         {
654             videoSignalInfo->MatrixCoefficients = 2; // unspecified image characteristics
655             sts = MFX_WRN_INCOMPATIBLE_VIDEO_PARAM;
656         }
657     }
658 
659     return sts;
660 }
661