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