1 // Copyright (c) 2018-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 <math.h>
22 #include "mfx_common.h"
23
24 #if defined (MFX_ENABLE_VPP)
25 #include "mfx_enc_common.h"
26 #include "mfx_vpp_utils.h"
27
28 #include "mfx_vpp_hw.h"
29
30 const mfxU32 g_TABLE_DO_NOT_USE [] =
31 {
32 MFX_EXTBUFF_VPP_DENOISE,
33 #ifdef MFX_ENABLE_MCTF
34 MFX_EXTBUFF_VPP_MCTF,
35 #endif
36 MFX_EXTBUFF_VPP_SCENE_ANALYSIS,
37 MFX_EXTBUFF_VPP_PROCAMP,
38 MFX_EXTBUFF_VPP_DETAIL,
39 MFX_EXTBUFF_VPP_IMAGE_STABILIZATION,
40 MFX_EXTBUFF_VPP_COMPOSITE,
41 MFX_EXTBUFF_VPP_ROTATION,
42 MFX_EXTBUFF_VPP_SCALING,
43 #if (MFX_VERSION >= 1025)
44 MFX_EXTBUFF_VPP_COLOR_CONVERSION,
45 #endif
46 MFX_EXTBUFF_VPP_VIDEO_SIGNAL_INFO,
47 MFX_EXTBUFF_VPP_FIELD_PROCESSING,
48 MFX_EXTBUFF_VPP_MIRRORING
49 };
50
51
52 const mfxU32 g_TABLE_DO_USE [] =
53 {
54 MFX_EXTBUFF_VPP_DENOISE,
55 #ifdef MFX_ENABLE_MCTF
56 MFX_EXTBUFF_VPP_MCTF,
57 #endif
58 MFX_EXTBUFF_VPP_SCENE_ANALYSIS,
59 MFX_EXTBUFF_VPP_PROCAMP,
60 MFX_EXTBUFF_VPP_DETAIL,
61 MFX_EXTBUFF_VPP_FRAME_RATE_CONVERSION,
62 MFX_EXTBUFF_VPP_IMAGE_STABILIZATION,
63 MFX_EXTBUFF_VPP_COMPOSITE,
64 MFX_EXTBUFF_VPP_ROTATION,
65 MFX_EXTBUFF_VPP_SCALING,
66 #if (MFX_VERSION >= 1025)
67 MFX_EXTBUFF_VPP_COLOR_CONVERSION,
68 #endif
69 MFX_EXTBUFF_VPP_DEINTERLACING,
70 MFX_EXTBUFF_VPP_VIDEO_SIGNAL_INFO,
71 MFX_EXTBUFF_VPP_FIELD_PROCESSING,
72 MFX_EXTBUFF_VPP_MIRRORING
73 };
74
75
76 // should be synch with GetConfigSize()
77 const mfxU32 g_TABLE_CONFIG [] =
78 {
79 MFX_EXTBUFF_VPP_DENOISE,
80 #ifdef MFX_ENABLE_MCTF
81 MFX_EXTBUFF_VPP_MCTF,
82 #endif
83 MFX_EXTBUFF_VPP_SCENE_ANALYSIS,
84 MFX_EXTBUFF_VPP_PROCAMP,
85 MFX_EXTBUFF_VPP_DETAIL,
86 MFX_EXTBUFF_VPP_FRAME_RATE_CONVERSION,
87 MFX_EXTBUFF_VPP_IMAGE_STABILIZATION,
88 MFX_EXTBUFF_VPP_COMPOSITE,
89 MFX_EXTBUFF_VPP_ROTATION,
90 MFX_EXTBUFF_VPP_DEINTERLACING,
91 MFX_EXTBUFF_VPP_VIDEO_SIGNAL_INFO,
92 MFX_EXTBUFF_VPP_FIELD_PROCESSING,
93 MFX_EXTBUFF_VPP_SCALING,
94 #if (MFX_VERSION >= 1025)
95 MFX_EXTBUFF_VPP_COLOR_CONVERSION,
96 #endif
97 MFX_EXTBUFF_VPP_MIRRORING
98 };
99
100
101 const mfxU32 g_TABLE_EXT_PARAM [] =
102 {
103 MFX_EXTBUFF_OPAQUE_SURFACE_ALLOCATION,
104 MFX_EXTBUFF_MVC_SEQ_DESC,
105
106 MFX_EXTBUFF_VPP_DONOTUSE,
107 MFX_EXTBUFF_VPP_DOUSE,
108
109 // should be the same as g_TABLE_CONFIG
110 MFX_EXTBUFF_VPP_DENOISE,
111 #ifdef MFX_ENABLE_MCTF
112 MFX_EXTBUFF_VPP_MCTF,
113 #endif
114 MFX_EXTBUFF_VPP_SCENE_ANALYSIS,
115 MFX_EXTBUFF_VPP_PROCAMP,
116 MFX_EXTBUFF_VPP_DETAIL,
117 MFX_EXTBUFF_VPP_ROTATION,
118 MFX_EXTBUFF_VPP_FRAME_RATE_CONVERSION,
119 MFX_EXTBUFF_VPP_IMAGE_STABILIZATION,
120 MFX_EXTBUFF_VPP_COMPOSITE,
121 MFX_EXTBUFF_VPP_DEINTERLACING,
122 MFX_EXTBUFF_VPP_VIDEO_SIGNAL_INFO,
123 MFX_EXTBUFF_VPP_FIELD_PROCESSING,
124 MFX_EXTBUFF_VPP_SCALING,
125 #if (MFX_VERSION >= 1025)
126 MFX_EXTBUFF_VPP_COLOR_CONVERSION,
127 #endif
128 MFX_EXTBUFF_VPP_MIRRORING
129 };
130
GetPicStructMode(mfxU16 inPicStruct,mfxU16 outPicStruct)131 PicStructMode GetPicStructMode(mfxU16 inPicStruct, mfxU16 outPicStruct)
132 {
133 if( (inPicStruct & (MFX_PICSTRUCT_FIELD_BFF | MFX_PICSTRUCT_FIELD_TFF)) &&
134 MFX_PICSTRUCT_PROGRESSIVE == outPicStruct)
135 {
136 return DYNAMIC_DI_PICSTRUCT_MODE;
137 }
138 else if( MFX_PICSTRUCT_UNKNOWN == inPicStruct && MFX_PICSTRUCT_PROGRESSIVE == outPicStruct)
139 {
140 return DYNAMIC_DI_PICSTRUCT_MODE;
141 }
142 else
143 {
144 return PASS_THROUGH_PICSTRUCT_MODE;
145 }
146
147 } // PicStructMode GetPicStructMode(mfxU16 inPicStruct, mfxU16 outPicStruct)
148
149
150 // in according with spec requirements VPP controls input picstruct
CheckInputPicStruct(mfxU16 inPicStruct)151 mfxStatus CheckInputPicStruct( mfxU16 inPicStruct )
152 {
153 /*if( MFX_PICSTRUCT_UNKNOWN == inPicStruct )
154 {
155 return MFX_ERR_INCOMPATIBLE_VIDEO_PARAM;
156 }*/
157
158 const mfxU16 case1 = MFX_PICSTRUCT_PROGRESSIVE;
159 const mfxU16 case2 = MFX_PICSTRUCT_PROGRESSIVE | MFX_PICSTRUCT_FRAME_DOUBLING;
160 const mfxU16 case3 = MFX_PICSTRUCT_PROGRESSIVE | MFX_PICSTRUCT_FRAME_TRIPLING;
161 const mfxU16 case4 = MFX_PICSTRUCT_PROGRESSIVE | MFX_PICSTRUCT_FIELD_BFF;
162 const mfxU16 case5 = MFX_PICSTRUCT_PROGRESSIVE | MFX_PICSTRUCT_FIELD_TFF;
163 const mfxU16 case6 = MFX_PICSTRUCT_PROGRESSIVE | MFX_PICSTRUCT_FIELD_BFF | MFX_PICSTRUCT_FIELD_REPEATED;
164 const mfxU16 case7 = MFX_PICSTRUCT_PROGRESSIVE | MFX_PICSTRUCT_FIELD_TFF | MFX_PICSTRUCT_FIELD_REPEATED;
165 const mfxU16 case8 = MFX_PICSTRUCT_FIELD_BFF;
166 const mfxU16 case9 = MFX_PICSTRUCT_FIELD_TFF;
167 const mfxU16 case10 = MFX_PICSTRUCT_FIELD_SINGLE;
168 const mfxU16 case11 = MFX_PICSTRUCT_FIELD_TOP;
169 const mfxU16 case12 = MFX_PICSTRUCT_FIELD_TOP | MFX_PICSTRUCT_FIELD_PAIRED_NEXT;
170 const mfxU16 case13 = MFX_PICSTRUCT_FIELD_TOP | MFX_PICSTRUCT_FIELD_PAIRED_PREV;
171 const mfxU16 case14 = MFX_PICSTRUCT_FIELD_BOTTOM;
172 const mfxU16 case15 = MFX_PICSTRUCT_FIELD_BOTTOM | MFX_PICSTRUCT_FIELD_PAIRED_NEXT;
173 const mfxU16 case16 = MFX_PICSTRUCT_FIELD_BOTTOM | MFX_PICSTRUCT_FIELD_PAIRED_PREV;
174
175 mfxStatus sts = MFX_ERR_NONE;
176
177 switch( inPicStruct )
178 {
179 case case1:
180 case case2:
181 case case3:
182 case case4:
183 case case5:
184 case case6:
185 case case7:
186 case case8:
187 case case9:
188 case case10:
189 case case11:
190 case case12:
191 case case13:
192 case case14:
193 case case15:
194 case case16:
195 {
196 sts = MFX_ERR_NONE;
197 break;
198 }
199
200 default:
201 {
202 sts = MFX_ERR_UNDEFINED_BEHAVIOR;
203 break;
204 }
205 }
206
207 return sts;
208
209 } // mfxStatus CheckInputPicStruct( mfxU16 inPicStruct )
210
211
212 // rules for this algorithm see in spec
UpdatePicStruct(mfxU16 inPicStruct,mfxU16 outPicStruct,bool bDynamicDeinterlace,mfxStatus & sts,mfxU32 outputFrameCounter)213 mfxU16 UpdatePicStruct( mfxU16 inPicStruct, mfxU16 outPicStruct, bool bDynamicDeinterlace, mfxStatus& sts, mfxU32 outputFrameCounter )
214 {
215 mfxU16 resultPicStruct;
216
217 // XXX->UNKOWN
218 if( MFX_PICSTRUCT_UNKNOWN == outPicStruct )
219 {
220 if( (inPicStruct & MFX_PICSTRUCT_PROGRESSIVE) || !bDynamicDeinterlace )
221 {
222 resultPicStruct = inPicStruct;
223 }
224 else // DynamicDeinterlace
225 {
226 resultPicStruct = MFX_PICSTRUCT_PROGRESSIVE;
227 }
228
229 sts = MFX_ERR_NONE;
230 return resultPicStruct;
231 }
232
233 // PROGRESSIVE->PROGRESSIVE
234 mfxU16 inPicStructCore = (mfxU16)(inPicStruct & MFX_PICSTRUCT_PROGRESSIVE);
235 mfxU16 outPicStructCore = (mfxU16)(outPicStruct & MFX_PICSTRUCT_PROGRESSIVE);
236 if( inPicStructCore && outPicStructCore )
237 {
238 mfxU16 decorateFlags = ( MFX_PICSTRUCT_FRAME_DOUBLING |
239 MFX_PICSTRUCT_FRAME_TRIPLING |
240 MFX_PICSTRUCT_FIELD_REPEATED |
241 MFX_PICSTRUCT_FIELD_TFF |
242 MFX_PICSTRUCT_FIELD_BFF );
243
244 resultPicStruct = outPicStruct | ( inPicStruct & decorateFlags );
245
246 sts = MFX_ERR_NONE;
247 return resultPicStruct;
248 }
249 // PROGRESSIVE->INTERLACE
250 else if( (inPicStruct & MFX_PICSTRUCT_PROGRESSIVE) && (outPicStruct & (MFX_PICSTRUCT_FIELD_TFF | MFX_PICSTRUCT_FIELD_BFF)) )
251 {
252 resultPicStruct = outPicStruct;
253
254 sts = MFX_WRN_INCOMPATIBLE_VIDEO_PARAM;
255 return resultPicStruct;
256 }
257 // INTERLACE->PROGRESSIVE
258 else if( (inPicStruct & (MFX_PICSTRUCT_FIELD_TFF | MFX_PICSTRUCT_FIELD_BFF)) && (outPicStruct & MFX_PICSTRUCT_PROGRESSIVE) )
259 {
260 resultPicStruct = outPicStruct;
261
262 sts = (bDynamicDeinterlace) ? MFX_ERR_NONE : MFX_WRN_INCOMPATIBLE_VIDEO_PARAM;
263 return resultPicStruct;
264 }
265
266 // INTERLACE->FIELDS
267 if( (inPicStruct & (MFX_PICSTRUCT_FIELD_TFF | MFX_PICSTRUCT_FIELD_BFF)) && (outPicStruct & MFX_PICSTRUCT_FIELD_SINGLE) )
268 {
269 if (inPicStruct & MFX_PICSTRUCT_FIELD_TFF)
270 {
271 resultPicStruct = (mfxU16)((outputFrameCounter & 1) ? MFX_PICSTRUCT_FIELD_BOTTOM : MFX_PICSTRUCT_FIELD_TOP);
272 }
273 else if(inPicStruct & MFX_PICSTRUCT_FIELD_BFF)
274 {
275 resultPicStruct = (mfxU16)((outputFrameCounter & 1) ? MFX_PICSTRUCT_FIELD_TOP : MFX_PICSTRUCT_FIELD_BOTTOM);
276 }
277 else // return error on progressive input
278 {
279 sts = MFX_ERR_INVALID_VIDEO_PARAM;
280 resultPicStruct = outPicStruct;
281 return resultPicStruct;
282 }
283
284 sts = MFX_ERR_NONE;
285 return resultPicStruct;
286 }
287
288 // FIELDS->INTERLACE
289 if( (inPicStruct & MFX_PICSTRUCT_FIELD_SINGLE) && (outPicStruct & (MFX_PICSTRUCT_FIELD_TFF | MFX_PICSTRUCT_FIELD_BFF)) )
290 {
291 resultPicStruct = outPicStruct;
292 sts = MFX_ERR_NONE;
293 return resultPicStruct;
294 }
295
296 // INTERLACE->INTERLACE
297 inPicStructCore = inPicStruct & (MFX_PICSTRUCT_FIELD_TFF | MFX_PICSTRUCT_FIELD_BFF);
298 outPicStructCore = outPicStruct & (MFX_PICSTRUCT_FIELD_TFF | MFX_PICSTRUCT_FIELD_BFF);
299 if( inPicStructCore == outPicStructCore ) // the same type (tff->tff or bff->bff)
300 {
301 mfxU16 decorateFlags = ( MFX_PICSTRUCT_FRAME_DOUBLING |
302 MFX_PICSTRUCT_FRAME_TRIPLING |
303 MFX_PICSTRUCT_FIELD_REPEATED );
304
305 resultPicStruct = outPicStruct | ( inPicStruct & decorateFlags );
306
307 //sts = MFX_ERR_NONE;
308 sts = ( !bDynamicDeinterlace ) ? MFX_ERR_NONE : MFX_WRN_INCOMPATIBLE_VIDEO_PARAM;
309 return resultPicStruct;
310 }
311 else if( inPicStructCore && outPicStructCore ) // different type (tff->bff or bff->tff)
312 {
313 resultPicStruct = outPicStruct;
314
315 sts = MFX_WRN_INCOMPATIBLE_VIDEO_PARAM;
316 return resultPicStruct;
317 }
318
319 // default
320 resultPicStruct = outPicStruct;
321
322 sts = MFX_ERR_INCOMPATIBLE_VIDEO_PARAM;
323 return resultPicStruct;
324
325 } // void UpdatePicStruct( mfxU16 inPicStruct, mfxU16& outPicStruct, PicStructMode mode )
326
327 // this function requires 0!= FrameRate
IsFrameRatesCorrespondITC(mfxU32 inFrameRateExtN,mfxU32 inFrameRateExtD,mfxU32 outFrameRateExtN,mfxU32 outFrameRateExtD)328 bool IsFrameRatesCorrespondITC(mfxU32 inFrameRateExtN, mfxU32 inFrameRateExtD,
329 mfxU32 outFrameRateExtN, mfxU32 outFrameRateExtD)
330 {
331 //under investigation. now we decided ITC is enabled 29.97(+/-)0.1 -> 23.976(+/-)0.1
332 const mfxF64 EPS = 0.1;
333 const mfxF64 IN_FRAME_RATE_ETALON = 30.0 * 1000.0 / 1001.0;
334 const mfxF64 OUT_FRAME_RATE_ETALON = 24.0 * 1000.0 / 1001.0;
335
336 mfxF64 inFrameRate = CalculateUMCFramerate(inFrameRateExtN, inFrameRateExtD);
337 mfxF64 outFrameRate = CalculateUMCFramerate(outFrameRateExtN, outFrameRateExtD);
338
339 if( fabs(IN_FRAME_RATE_ETALON - inFrameRate) < EPS && fabs(OUT_FRAME_RATE_ETALON - outFrameRate) < EPS )
340 {
341 return true;
342 }
343
344 return false;
345
346 } // bool IsFrameRatesCorrespondITC(...)
347
348 // this function requires 0!= FrameRate
IsFrameRatesCorrespondDI(mfxU32 inFrameRateExtN,mfxU32 inFrameRateExtD,mfxU32 outFrameRateExtN,mfxU32 outFrameRateExtD,mfxU32 * mode)349 bool IsFrameRatesCorrespondDI(mfxU32 inFrameRateExtN, mfxU32 inFrameRateExtD,
350 mfxU32 outFrameRateExtN, mfxU32 outFrameRateExtD,
351 mfxU32* mode)
352 {
353 const mfxU32 RATIO_FOR_SINGLE_FIELD_PROCESSED = 1;
354 const mfxU32 RATIO_FOR_BOTH_FIELDS_PROCESSED = 2;
355
356 // convert to internal mfx frame rates range
357 mfxF64 inFrameRate = CalculateUMCFramerate(inFrameRateExtN, inFrameRateExtD);
358 mfxF64 outFrameRate = CalculateUMCFramerate(outFrameRateExtN, outFrameRateExtD);
359
360 CalculateMFXFramerate(inFrameRate, &inFrameRateExtN, &inFrameRateExtD);
361 CalculateMFXFramerate(outFrameRate, &outFrameRateExtN, &outFrameRateExtD);
362
363 if( inFrameRateExtD != outFrameRateExtD )
364 {
365 return false;
366 }
367
368 mfxU32 residue = outFrameRateExtN % inFrameRateExtN;
369 mfxU32 ratio = outFrameRateExtN / inFrameRateExtN;
370
371 if( (inFrameRateExtD == outFrameRateExtD) && (0 == residue) &&
372 ( (RATIO_FOR_SINGLE_FIELD_PROCESSED == ratio) || ( RATIO_FOR_BOTH_FIELDS_PROCESSED == ratio) ) )
373 {
374 if( NULL != mode )
375 {
376 *mode = ratio-1;
377 }
378
379 return true;
380 }
381
382 return false;
383
384 } // bool IsFrameRatesCorrespondDI(...)
385
IsFrameRatesCorrespondWeaving(mfxU32 inFrameRateExtN,mfxU32 inFrameRateExtD,mfxU32 outFrameRateExtN,mfxU32 outFrameRateExtD)386 bool IsFrameRatesCorrespondWeaving(mfxU32 inFrameRateExtN, mfxU32 inFrameRateExtD,
387 mfxU32 outFrameRateExtN, mfxU32 outFrameRateExtD)
388 {
389 const mfxU32 RATIO_FOR_SINGLE_FIELD_PROCESSED = 1;
390 const mfxU32 RATIO_FOR_BOTH_FIELDS_PROCESSED = 2;
391
392 // convert to internal mfx frame rates range
393 mfxF64 inFrameRate = CalculateUMCFramerate(inFrameRateExtN, inFrameRateExtD);
394 mfxF64 outFrameRate = CalculateUMCFramerate(outFrameRateExtN, outFrameRateExtD);
395
396 CalculateMFXFramerate(inFrameRate, &inFrameRateExtN, &inFrameRateExtD);
397 CalculateMFXFramerate(outFrameRate, &outFrameRateExtN, &outFrameRateExtD);
398
399 if( inFrameRateExtD != outFrameRateExtD )
400 {
401 return false;
402 }
403
404 mfxU32 residue = inFrameRateExtN % outFrameRateExtN;
405 mfxU32 ratio = inFrameRateExtN / outFrameRateExtN;
406
407 if( (inFrameRateExtD == outFrameRateExtD) && (0 == residue) &&
408 ( (RATIO_FOR_SINGLE_FIELD_PROCESSED == ratio) || ( RATIO_FOR_BOTH_FIELDS_PROCESSED == ratio) ) )
409 {
410 return true;
411 }
412
413 return false;
414
415 } // bool IsFrameRatesCorrespondModeWeaving(...)
416
IsFrameRatesCorrespondMode30i60p(mfxU32 inFrameRateExtN,mfxU32 inFrameRateExtD,mfxU32 outFrameRateExtN,mfxU32 outFrameRateExtD)417 bool IsFrameRatesCorrespondMode30i60p(mfxU32 inFrameRateExtN, mfxU32 inFrameRateExtD,
418 mfxU32 outFrameRateExtN, mfxU32 outFrameRateExtD)
419 {
420 mfxU32 modeAdvDI;
421 bool bResult = IsFrameRatesCorrespondDI(inFrameRateExtN, inFrameRateExtD,
422 outFrameRateExtN, outFrameRateExtD, &modeAdvDI);
423
424 if( bResult && modeAdvDI )
425 {
426 return true;
427 }
428
429 return false;
430
431 } // bool IsFrameRatesCorrespondMode60i60p(...)
432
IsFrameRatesCorrespondDIorITC(mfxU32 inFrameRateExtN,mfxU32 inFrameRateExtD,mfxU32 outFrameRateExtN,mfxU32 outFrameRateExtD)433 bool IsFrameRatesCorrespondDIorITC(mfxU32 inFrameRateExtN, mfxU32 inFrameRateExtD,
434 mfxU32 outFrameRateExtN, mfxU32 outFrameRateExtD)
435 {
436 bool isITCRespond = IsFrameRatesCorrespondITC(inFrameRateExtN, inFrameRateExtD,
437 outFrameRateExtN, outFrameRateExtD);
438
439 bool isDIRespond = IsFrameRatesCorrespondDI(inFrameRateExtN, inFrameRateExtD,
440 outFrameRateExtN, outFrameRateExtD, NULL);
441
442 if( isITCRespond || isDIRespond )
443 {
444 return true;
445 }
446
447 return false;
448
449 } // bool IsFrameRatesCorrespondDIorITC(...)
450
GetFilterParam(mfxVideoParam * par,mfxU32 filterName,mfxExtBuffer ** ppHint)451 mfxStatus GetFilterParam(mfxVideoParam* par, mfxU32 filterName, mfxExtBuffer** ppHint)
452 {
453 MFX_CHECK_NULL_PTR1( par );
454 MFX_CHECK_NULL_PTR1( ppHint );
455
456 *ppHint = NULL;
457
458 if( par->ExtParam && par->NumExtParam > 0 )
459 {
460 mfxU32 paramIndex;
461
462 for( paramIndex = 0; paramIndex < par->NumExtParam; paramIndex++ )
463 {
464 if( filterName == par->ExtParam[paramIndex]->BufferId )
465 {
466 *ppHint = par->ExtParam[paramIndex];
467 break;
468 }
469 }
470 }
471
472 return MFX_ERR_NONE;
473
474 } // mfxStatus GetFilterParam(mfxVideoParam* par, mfxU32 filterName, mfxExtBuffer** ppHint)
475
IsRoiDifferent(mfxFrameSurface1 * input,mfxFrameSurface1 * output)476 bool IsRoiDifferent(mfxFrameSurface1 *input, mfxFrameSurface1 *output)
477 {
478 if ((input->Info.Width == output->Info.Width && input->Info.Height == output->Info.Height) &&
479 (input->Info.CropW == output->Info.CropW && input->Info.CropH == output->Info.CropH) &&
480 (input->Info.CropX == output->Info.CropX && input->Info.CropY == output->Info.CropY) &&
481 (input->Info.PicStruct == output->Info.PicStruct)
482 )
483 {
484 return false;
485 }
486
487 return true;
488
489 } // bool IsRoiDifferent(mfxFrameSurface1 *input, mfxFrameSurface1 *output)
490
ShowPipeline(std::vector<mfxU32> pipelineList)491 void ShowPipeline( std::vector<mfxU32> pipelineList )
492 {
493 #if !defined(_DEBUG) && \
494 !defined(_WIN32) && !defined(_WIN64) || \
495 !defined(LINUX) && !defined(LINUX32) && !defined(LINUX64)
496
497 (void)pipelineList;
498 #endif
499
500 #ifdef _DEBUG
501
502 #if defined(LINUX) || defined(LINUX32) || defined(LINUX64)
503 mfxU32 filterIndx;
504 fprintf(stderr, "VPP PIPELINE: \n");
505
506 for( filterIndx = 0; filterIndx < pipelineList.size(); filterIndx++ )
507 {
508 switch( pipelineList[filterIndx] )
509 {
510 case (mfxU32)MFX_EXTBUFF_VPP_DENOISE:
511 {
512 fprintf(stderr, "DENOISE \n");
513 break;
514 }
515
516 case (mfxU32)MFX_EXTBUFF_VPP_RSHIFT_IN:
517 {
518 fprintf(stderr, "MFX_EXTBUFF_VPP_RSHIFT_IN \n");
519 break;
520 }
521
522 case (mfxU32)MFX_EXTBUFF_VPP_RSHIFT_OUT:
523 {
524 fprintf(stderr, "MFX_EXTBUFF_VPP_RSHIFT_OUT \n");
525 break;
526 }
527
528 case (mfxU32)MFX_EXTBUFF_VPP_LSHIFT_IN:
529 {
530 fprintf(stderr, "MFX_EXTBUFF_VPP_LSHIFT_IN \n");
531 break;
532 }
533
534 case (mfxU32)MFX_EXTBUFF_VPP_LSHIFT_OUT:
535 {
536 fprintf(stderr, "MFX_EXTBUFF_VPP_LSHIFT_OUT \n");
537 break;
538 }
539
540 case (mfxU32)MFX_EXTBUFF_VPP_RESIZE:
541 {
542 fprintf(stderr, "RESIZE \n");
543 break;
544 }
545
546 case (mfxU32)MFX_EXTBUFF_VPP_FRAME_RATE_CONVERSION:
547 {
548 fprintf(stderr, "FRC \n");
549 break;
550 }
551
552 case (mfxU32)MFX_EXTBUFF_VPP_DI_30i60p:
553 {
554 fprintf(stderr, "ADV DI 30i60p \n");
555 break;
556 }
557
558 case (mfxU32)MFX_EXTBUFF_VPP_DI_WEAVE:
559 {
560 fprintf(stderr, "WEAVE DI\n");
561 break;
562 }
563
564 case (mfxU32)MFX_EXTBUFF_VPP_ITC:
565 {
566 fprintf(stderr, "ITC \n");
567
568 break;
569 }
570
571 case (mfxU32)MFX_EXTBUFF_VPP_DI:
572 {
573 fprintf(stderr, "DI \n");
574 break;
575 }
576
577 case (mfxU32)MFX_EXTBUFF_VPP_DEINTERLACING:
578 {
579 fprintf(stderr, "DI EXT BUF\n");
580 break;
581 }
582
583 case (mfxU32)MFX_EXTBUFF_VPP_CSC:
584 {
585 fprintf(stderr, "CSC_NV12 \n");
586 break;
587 }
588
589 case (mfxU32)MFX_EXTBUFF_VPP_CSC_OUT_RGB4:
590 {
591 fprintf(stderr,"%s \n", "CSC_RGB4");
592 break;
593 }
594
595 case (mfxU32)MFX_EXTBUFF_VPP_CSC_OUT_A2RGB10:
596 {
597 fprintf(stderr, "CSC_A2RGB10 \n");
598 break;
599 }
600
601 case (mfxU32)MFX_EXTBUFF_VPP_SCENE_ANALYSIS:
602 {
603 fprintf(stderr, "SA \n");
604 break;
605 }
606
607 case (mfxU32)MFX_EXTBUFF_VPP_PROCAMP:
608 {
609 fprintf(stderr, "PROCAMP \n");
610 break;
611 }
612
613 case (mfxU32)MFX_EXTBUFF_VPP_DETAIL:
614 {
615 fprintf(stderr, "DETAIL \n");
616 break;
617 }
618
619
620
621 case (mfxU32)MFX_EXTBUFF_VPP_COMPOSITE:
622 {
623 fprintf(stderr, "COMPOSITE \n");
624 break;
625 }
626
627 case (mfxU32)MFX_EXTBUFF_VPP_FIELD_PROCESSING:
628 {
629 fprintf(stderr, "VPP_FIELD_PROCESSING \n");
630 break;
631 }
632 case (mfxU32)MFX_EXTBUFF_VPP_ROTATION:
633 {
634 fprintf(stderr, "VPP_ROTATION\n");
635 break;
636 }
637 case (mfxU32)MFX_EXTBUFF_VPP_SCALING:
638 {
639 fprintf(stderr,"MFX_EXTBUFF_VPP_SCALING\n");
640 break;
641 }
642 #if (MFX_VERSION >= 1025)
643 case (mfxU32)MFX_EXTBUFF_VPP_COLOR_CONVERSION:
644 {
645 fprintf(stderr,"MFX_EXTBUFF_VPP_COLOR_CONVERSION\n");
646 break;
647 }
648 #endif
649 case (mfxU32)MFX_EXTBUFF_VPP_VIDEO_SIGNAL_INFO:
650 {
651 fprintf(stderr,"MFX_EXTBUFF_VPP_VIDEO_SIGNAL_INFO\n");
652 break;
653 }
654
655 case (mfxU32)MFX_EXTBUFF_VPP_MIRRORING:
656 {
657 fprintf(stderr,"MFX_EXTBUFF_VPP_MIRRORING\n");
658 break;
659 }
660 case (mfxU32)MFX_EXTBUFF_VPP_FIELD_WEAVING:
661 {
662 fprintf(stderr, "VPP_FIELD_WEAVING\n");
663 break;
664 }
665 case (mfxU32)MFX_EXTBUFF_VPP_FIELD_SPLITTING:
666 {
667 fprintf(stderr, "VPP_FIELD_SPLITTING\n");
668 break;
669 }
670 #ifdef MFX_ENABLE_MCTF
671 case (mfxU32)MFX_EXTBUFF_VPP_MCTF:
672 {
673 fprintf(stderr, "VPP_MCTF\n");
674 break;
675 }
676 #endif
677 default:
678 {
679 fprintf(stderr, "UNKNOWN Filter ID!!! \n");
680 break;
681 }
682
683 }// CASE
684 } //end of filter search
685
686 //fprintf(stderr,"\n");
687 #endif // #if defined(LINUX) || defined(LINUX32) || defined(LINUX64)
688
689 #endif //#ifdef _DEBUG
690 return;
691
692 } // void ShowPipeline( std::vector<mfxU32> pipelineList )
693
694
695 /* ********************************************************************************************** */
696 /* Pipeline Building Stage */
697 /* ********************************************************************************************** */
698 /* VPP best quality is |CSC| + |DN| + |DI| + |IS| + |RS| + |Detail| + |ProcAmp| + |FRC| + |SA| */
699 /* SW_VPP reorder |FRC| to meet best speed */
700 /* ********************************************************************************************** */
701
ReorderPipelineListForQuality(std::vector<mfxU32> & pipelineList)702 void ReorderPipelineListForQuality( std::vector<mfxU32> & pipelineList )
703 {
704 //mfxU32 newList[MAX_NUM_VPP_FILTERS] = {0};
705 std::vector<mfxU32> newList;
706 newList.resize( pipelineList.size() );
707 mfxU32 index = 0;
708
709 // [-1] Shift is very first, since shifted content is not supported by VPP
710 if( IsFilterFound( &pipelineList[0], (mfxU32)pipelineList.size(), MFX_EXTBUFF_VPP_RSHIFT_IN ) )
711 {
712 newList[index] = MFX_EXTBUFF_VPP_RSHIFT_IN;
713 index++;
714 }
715
716 // [0] canonical order
717 if( IsFilterFound( &pipelineList[0], (mfxU32)pipelineList.size(), MFX_EXTBUFF_VPP_CSC ) )
718 {
719 newList[index] = MFX_EXTBUFF_VPP_CSC;
720 index++;
721 }
722 // Resize for Best Speed
723 /*if( IsFilterFound( pList, len, MFX_EXTBUFF_VPP_RESIZE ) )
724 {
725 newList[index] = MFX_EXTBUFF_VPP_RESIZE;
726 index++;
727 }*/
728 if( IsFilterFound( &pipelineList[0], (mfxU32)pipelineList.size(), MFX_EXTBUFF_VPP_DENOISE ) )
729 {
730 newList[index] = MFX_EXTBUFF_VPP_DENOISE;
731 index++;
732 }
733 // DI, advDI, ITC has the same priority
734 if( IsFilterFound( &pipelineList[0], (mfxU32)pipelineList.size(), MFX_EXTBUFF_VPP_DI ) )
735 {
736 newList[index] = MFX_EXTBUFF_VPP_DI;
737 index++;
738 }
739 if( IsFilterFound( &pipelineList[0], (mfxU32)pipelineList.size(), MFX_EXTBUFF_VPP_DI_WEAVE ) )
740 {
741 newList[index] = MFX_EXTBUFF_VPP_DI_WEAVE;
742 index++;
743 }
744 if( IsFilterFound( &pipelineList[0], (mfxU32)pipelineList.size(), MFX_EXTBUFF_VPP_DI_30i60p ) )
745 {
746 newList[index] = MFX_EXTBUFF_VPP_DI_30i60p;
747 index++;
748 }
749 if( IsFilterFound( &pipelineList[0], (mfxU32)pipelineList.size(), MFX_EXTBUFF_VPP_ITC ) )
750 {
751 newList[index] = MFX_EXTBUFF_VPP_ITC;
752 index++;
753 }
754 if( IsFilterFound( &pipelineList[0], (mfxU32)pipelineList.size(), MFX_EXTBUFF_VPP_DEINTERLACING ) &&
755 ! IsFilterFound( &pipelineList[0], (mfxU32)pipelineList.size(), MFX_EXTBUFF_VPP_DI_30i60p ) &&
756 ! IsFilterFound( &pipelineList[0], (mfxU32)pipelineList.size(), MFX_EXTBUFF_VPP_DI_WEAVE ) &&
757 ! IsFilterFound( &pipelineList[0], (mfxU32)pipelineList.size(), MFX_EXTBUFF_VPP_DI ))
758 {
759 newList[index] = MFX_EXTBUFF_VPP_DEINTERLACING;
760 index++;
761 }
762 if( IsFilterFound( &pipelineList[0], (mfxU32)pipelineList.size(), MFX_EXTBUFF_VPP_VIDEO_SIGNAL_INFO ) )
763 {
764 newList[index] = MFX_EXTBUFF_VPP_VIDEO_SIGNAL_INFO;
765 index++;
766 }
767
768 /* [IStab] FILTER */
769
770 // Resize for Best Quality
771 if( IsFilterFound( &pipelineList[0], (mfxU32)pipelineList.size(), MFX_EXTBUFF_VPP_RESIZE ) )
772 {
773 newList[index] = MFX_EXTBUFF_VPP_RESIZE;
774 index++;
775 }
776
777 if( IsFilterFound( &pipelineList[0], (mfxU32)pipelineList.size(), MFX_EXTBUFF_VPP_DETAIL ) )
778 {
779 newList[index] = MFX_EXTBUFF_VPP_DETAIL;
780 index++;
781 }
782
783 if( IsFilterFound( &pipelineList[0], (mfxU32)pipelineList.size(), MFX_EXTBUFF_VPP_PROCAMP ) )
784 {
785 newList[index] = MFX_EXTBUFF_VPP_PROCAMP;
786 index++;
787 }
788
789
790 if( IsFilterFound( &pipelineList[0], (mfxU32)pipelineList.size(), MFX_EXTBUFF_VPP_FRAME_RATE_CONVERSION ) )
791 {
792 newList[index] = MFX_EXTBUFF_VPP_FRAME_RATE_CONVERSION;
793 index++;
794 }
795
796 if( IsFilterFound( &pipelineList[0], (mfxU32)pipelineList.size(), MFX_EXTBUFF_VPP_SCENE_ANALYSIS ) )
797 {
798 newList[index] = MFX_EXTBUFF_VPP_SCENE_ANALYSIS;
799 index++;
800 }
801
802 if( IsFilterFound( &pipelineList[0], (mfxU32)pipelineList.size(), MFX_EXTBUFF_VPP_CSC_OUT_RGB4 ) )
803 {
804 newList[index] = MFX_EXTBUFF_VPP_CSC_OUT_RGB4;
805 index++;
806 }
807
808 if( IsFilterFound( &pipelineList[0], (mfxU32)pipelineList.size(), MFX_EXTBUFF_VPP_CSC_OUT_A2RGB10 ) )
809 {
810 newList[index] = MFX_EXTBUFF_VPP_CSC_OUT_A2RGB10;
811 index++;
812 }
813
814 if( IsFilterFound( &pipelineList[0], (mfxU32)pipelineList.size(), MFX_EXTBUFF_VPP_COMPOSITE ) )
815 {
816 newList[index] = MFX_EXTBUFF_VPP_COMPOSITE;
817 index++;
818 }
819
820 if( IsFilterFound( &pipelineList[0], (mfxU32)pipelineList.size(), MFX_EXTBUFF_VPP_FIELD_PROCESSING ) )
821 {
822 newList[index] = MFX_EXTBUFF_VPP_FIELD_PROCESSING;
823 index++;
824 }
825
826 if( IsFilterFound( &pipelineList[0], (mfxU32)pipelineList.size(), MFX_EXTBUFF_VPP_FIELD_WEAVING ) )
827 {
828 newList[index] = MFX_EXTBUFF_VPP_FIELD_WEAVING;
829 index++;
830 }
831
832 if( IsFilterFound( &pipelineList[0], (mfxU32)pipelineList.size(), MFX_EXTBUFF_VPP_FIELD_SPLITTING ) )
833 {
834 newList[index] = MFX_EXTBUFF_VPP_FIELD_SPLITTING;
835 index++;
836 }
837
838 if( IsFilterFound( &pipelineList[0], (mfxU32)pipelineList.size(), MFX_EXTBUFF_VPP_LSHIFT_OUT ) )
839 {
840 newList[index] = MFX_EXTBUFF_VPP_LSHIFT_OUT;
841 index++;
842 }
843
844 if( IsFilterFound( &pipelineList[0], (mfxU32)pipelineList.size(), MFX_EXTBUFF_VPP_ROTATION ) )
845 {
846 newList[index] = MFX_EXTBUFF_VPP_ROTATION;
847 index++;
848 }
849
850 if( IsFilterFound( &pipelineList[0], (mfxU32)pipelineList.size(), MFX_EXTBUFF_VPP_SCALING ) )
851 {
852 newList[index] = MFX_EXTBUFF_VPP_SCALING;
853 index++;
854 }
855
856 #if (MFX_VERSION >= 1025)
857 if (IsFilterFound(&pipelineList[0], (mfxU32)pipelineList.size(), MFX_EXTBUFF_VPP_COLOR_CONVERSION))
858 {
859 newList[index] = MFX_EXTBUFF_VPP_COLOR_CONVERSION;
860 index++;
861 }
862 #endif
863
864 if( IsFilterFound( &pipelineList[0], (mfxU32)pipelineList.size(), MFX_EXTBUFF_VPP_MIRRORING ) )
865 {
866 newList[index] = MFX_EXTBUFF_VPP_MIRRORING;
867 index++;
868 }
869 #ifdef MFX_ENABLE_MCTF
870 // add to the end
871 if (IsFilterFound(&pipelineList[0], (mfxU32)pipelineList.size(), MFX_EXTBUFF_VPP_MCTF))
872 {
873 newList[index] = MFX_EXTBUFF_VPP_MCTF;
874 index++;
875 }
876 #endif
877 // [1] update
878 pipelineList.resize(index);
879 for( index = 0; index < (mfxU32)pipelineList.size(); index++ )
880 {
881 pipelineList[index] = newList[index];
882 }
883
884 } // void ReorderPipelineListForQuality(std::vector<mfxU32> & pipelineList)
885
886
ReorderPipelineListForSpeed(mfxVideoParam * videoParam,std::vector<mfxU32> & pipelineList)887 void ReorderPipelineListForSpeed(
888 mfxVideoParam* videoParam,
889 std::vector<mfxU32> & pipelineList)
890 {
891
892 // optimization in case of FRC
893 if( IsFilterFound( &pipelineList[0], (mfxU32)pipelineList.size(), MFX_EXTBUFF_VPP_FRAME_RATE_CONVERSION ) )
894 {
895 mfxFrameInfo* in = &(videoParam->vpp.In);
896 mfxFrameInfo* out = &(videoParam->vpp.Out);
897
898 mfxF64 inFrameRate = CalculateUMCFramerate(in->FrameRateExtN, in->FrameRateExtD);
899 mfxF64 outFrameRate = CalculateUMCFramerate(out->FrameRateExtN, out->FrameRateExtD);
900
901 mfxU32 filterIndex = 0;
902 mfxU32 filterIndexFRC = GetFilterIndex(&pipelineList[0], (mfxU32)pipelineList.size(), MFX_EXTBUFF_VPP_FRAME_RATE_CONVERSION);
903
904 if( inFrameRate > outFrameRate )
905 {
906 // FRC_DOWN must be first filter in pipeline
907 for( filterIndex = filterIndexFRC; filterIndex > 0; filterIndex-- )
908 {
909 std::swap(pipelineList[filterIndex], pipelineList[filterIndex-1]);
910 }
911 //exclude CSC
912 if( IsFilterFound( &pipelineList[0], (mfxU32)pipelineList.size(), MFX_EXTBUFF_VPP_CSC ) )
913 {
914 std::swap(pipelineList[1], pipelineList[0]);
915 }
916 }
917 }
918
919 } // void ReorderPipelineListForSpeed(mfxVideoParam* videoParam, std::vector<mfxU32> & pipelineList)
920
921
GetPipelineList(mfxVideoParam * videoParam,std::vector<mfxU32> & pipelineList,bool bExtended)922 mfxStatus GetPipelineList(
923 mfxVideoParam* videoParam,
924 //mfxU32* pList,
925 std::vector<mfxU32> & pipelineList,
926 //mfxU32* pLen,
927 bool bExtended)
928 {
929 mfxInfoVPP* par = NULL;
930 mfxFrameInfo* srcFrameInfo = NULL;
931 mfxFrameInfo* dstFrameInfo = NULL;
932 mfxStatus sts = MFX_ERR_NONE;
933
934 MFX_CHECK_NULL_PTR1( videoParam );
935
936 //MFX_CHECK_NULL_PTR2( pList, pLen );
937
938 par = &(videoParam->vpp);
939 srcFrameInfo = &(par->In);
940 dstFrameInfo = &(par->Out);
941 /* ************************************************************************** */
942 /* [1] the filter chain first based on input and output mismatch formats only */
943 /* ************************************************************************** */
944 if( (MFX_FOURCC_RGB4 != par->In.FourCC) || (MFX_FOURCC_RGB4 != par->Out.FourCC) )
945 {
946 switch (par->In.FourCC)
947 {
948 case MFX_FOURCC_P210:
949 switch (par->Out.FourCC)
950 {
951 case MFX_FOURCC_A2RGB10:
952 pipelineList.push_back(MFX_EXTBUFF_VPP_CSC_OUT_A2RGB10);
953 break;
954 case MFX_FOURCC_NV12:
955 case MFX_FOURCC_NV16:
956 case MFX_FOURCC_P010:
957 pipelineList.push_back(MFX_EXTBUFF_VPP_CSC);
958 break;
959 }
960 break;
961 case MFX_FOURCC_P010:
962 switch (par->Out.FourCC)
963 {
964 case MFX_FOURCC_A2RGB10:
965 pipelineList.push_back(MFX_EXTBUFF_VPP_CSC_OUT_A2RGB10);
966 break;
967 case MFX_FOURCC_NV12:
968 case MFX_FOURCC_P210:
969 pipelineList.push_back(MFX_EXTBUFF_VPP_CSC);
970 break;
971 }
972 break;
973
974 case MFX_FOURCC_NV12:
975 switch (par->Out.FourCC)
976 {
977 case MFX_FOURCC_NV16:
978 case MFX_FOURCC_P010:
979 pipelineList.push_back(MFX_EXTBUFF_VPP_CSC);
980 break;
981 case MFX_FOURCC_RGB4:
982 pipelineList.push_back(MFX_EXTBUFF_VPP_CSC_OUT_RGB4);
983 break;
984 }
985 break;
986 default:
987 switch (par->Out.FourCC)
988 {
989 case MFX_FOURCC_RGB4:
990 pipelineList.push_back(MFX_EXTBUFF_VPP_CSC_OUT_RGB4);
991 break;
992 }
993 break;
994 }
995
996 if( MFX_FOURCC_NV12 != par->In.FourCC && MFX_FOURCC_P010 != par->In.FourCC && MFX_FOURCC_P210 != par->In.FourCC)
997 {
998 /* [Color Space Conversion] FILTER */
999 pipelineList.push_back(MFX_EXTBUFF_VPP_CSC);
1000 }
1001
1002 }
1003 else if (!bExtended)
1004 {
1005 /* ********************************************************************** */
1006 /* RGB32->RGB32 (resize only) */
1007 /* ********************************************************************** */
1008 pipelineList.push_back(MFX_EXTBUFF_VPP_RESIZE);
1009
1010 return MFX_ERR_NONE;
1011 }
1012
1013 /* VPP natively supports P010 and P210 formats w/o shift. If input is shifted,
1014 * need get it back to normal position.
1015 */
1016 if ( ( MFX_FOURCC_P010 == srcFrameInfo->FourCC || MFX_FOURCC_P210 == srcFrameInfo->FourCC)
1017 && srcFrameInfo->Shift )
1018 {
1019 pipelineList.push_back(MFX_EXTBUFF_VPP_RSHIFT_IN);
1020 }
1021
1022 /*
1023 * VPP produces P010 and P210 formats w/o shift. If output is requested to be shifted, need to do so
1024 */
1025 if ( ( MFX_FOURCC_P010 == dstFrameInfo->FourCC || MFX_FOURCC_P210 == dstFrameInfo->FourCC)
1026 && dstFrameInfo->Shift )
1027 {
1028 pipelineList.push_back(MFX_EXTBUFF_VPP_LSHIFT_OUT);
1029 }
1030
1031 { //resize or cropping
1032 pipelineList.push_back(MFX_EXTBUFF_VPP_RESIZE);
1033 }
1034
1035 /* [Deinterlace] FILTER */
1036 if( 0 != videoParam->NumExtParam && NULL == videoParam->ExtParam )
1037 {
1038 return MFX_ERR_NULL_PTR;
1039 }
1040 PicStructMode picStructMode = GetPicStructMode(par->In.PicStruct, par->Out.PicStruct);
1041
1042 mfxI32 deinterlacingMode = 0;
1043 for (mfxU32 i = 0; i < videoParam->NumExtParam; i++)
1044 {
1045 // look for user defined deinterlacing mode
1046 if (videoParam->ExtParam[i] && videoParam->ExtParam[i]->BufferId == MFX_EXTBUFF_VPP_DEINTERLACING)
1047 {
1048 mfxExtVPPDeinterlacing* extDI = (mfxExtVPPDeinterlacing*) videoParam->ExtParam[i];
1049 /* MSDK ignored all any DI modes values except two defined:
1050 * MFX_DEINTERLACING_ADVANCED && MFX_DEINTERLACING_BOB
1051 * If DI mode in Ext Buffer is not related BOB or ADVANCED Ext buffer ignored
1052 * */
1053 if (extDI->Mode == MFX_DEINTERLACING_ADVANCED ||
1054 #if defined (MFX_ENABLE_SCENE_CHANGE_DETECTION_VPP)
1055 extDI->Mode == MFX_DEINTERLACING_ADVANCED_SCD ||
1056 #endif
1057 extDI->Mode == MFX_DEINTERLACING_BOB ||
1058 extDI->Mode == MFX_DEINTERLACING_ADVANCED_NOREF ||
1059 extDI->Mode == MFX_DEINTERLACING_FIELD_WEAVING)
1060 {
1061 /* DI Ext buffer present
1062 * and DI type is correct
1063 * */
1064 deinterlacingMode = extDI->Mode;
1065 }
1066 break;
1067 }
1068 // check scaling parameters
1069 else if (videoParam->ExtParam[i] && videoParam->ExtParam[i]->BufferId == MFX_EXTBUFF_VPP_SCALING)
1070 {
1071 sts = CheckScalingParam(videoParam->ExtParam[i]);
1072 break;
1073 }
1074 }
1075 MFX_CHECK_STS(sts);
1076
1077 /* DI configuration cases:
1078 * Default "-spic 0 -dpic 1" (TFF to progressive ) -> MFX_EXTBUFF_VPP_DI
1079 * Default "-spic 0 -dpic 1 -sf 30 -df 60" -> MFX_EXTBUFF_VPP_DI_30i60p
1080 * !!! in both cases above, DI mode, ADVANCED(ADI) or BOB will be selected later, by driver's caps analysis.
1081 * If ADI reported in driver's Caps MSDK should select ADI mode
1082 * */
1083
1084 if ((DYNAMIC_DI_PICSTRUCT_MODE == picStructMode ) || /* configuration via "-spic 0 -spic 1" */
1085 (0 != deinterlacingMode) ) /* configuration via Ext Buf */
1086 {
1087 if( IsFrameRatesCorrespondMode30i60p(par->In.FrameRateExtN,
1088 par->In.FrameRateExtD,
1089 par->Out.FrameRateExtN,
1090 par->Out.FrameRateExtD) )
1091 {
1092 pipelineList.push_back(MFX_EXTBUFF_VPP_DI_30i60p);
1093 }
1094 else if( IsFrameRatesCorrespondITC(par->In.FrameRateExtN,
1095 par->In.FrameRateExtD,
1096 par->Out.FrameRateExtN,
1097 par->Out.FrameRateExtD) )
1098 {
1099 pipelineList.push_back(MFX_EXTBUFF_VPP_ITC);
1100 }
1101 else if (0 != deinterlacingMode)
1102 {
1103 /* Put DI filter in pipeline only if filter configured via Ext buffer */
1104 pipelineList.push_back(MFX_EXTBUFF_VPP_DEINTERLACING);
1105 }
1106 else if (DYNAMIC_DI_PICSTRUCT_MODE == picStructMode)
1107 {
1108 /* Put DI filter in pipeline only if filter configured via default way "-spic 0 -dpic 1" */
1109 pipelineList.push_back(MFX_EXTBUFF_VPP_DI);
1110 }
1111
1112 }
1113
1114 /* Weaving DI part. Can be enabled thru ext buffer only, there is no dinamic enabling based on
1115 * input/output pic type
1116 */
1117 if (MFX_DEINTERLACING_FIELD_WEAVING == deinterlacingMode && IsFrameRatesCorrespondWeaving(par->In.FrameRateExtN,
1118 par->In.FrameRateExtD,
1119 par->Out.FrameRateExtN,
1120 par->Out.FrameRateExtD))
1121 {
1122 pipelineList.push_back(MFX_EXTBUFF_VPP_DI_WEAVE);
1123 }
1124
1125 /* Field weaving/splitting cases:
1126 */
1127 if ((par->In.PicStruct & MFX_PICSTRUCT_FIELD_SINGLE) && !(par->Out.PicStruct & MFX_PICSTRUCT_FIELD_SINGLE))
1128 {
1129 pipelineList.push_back(MFX_EXTBUFF_VPP_FIELD_WEAVING);
1130 }
1131 else if (!(par->In.PicStruct & MFX_PICSTRUCT_FIELD_SINGLE) && (par->Out.PicStruct & MFX_PICSTRUCT_FIELD_SINGLE))
1132 {
1133 pipelineList.push_back(MFX_EXTBUFF_VPP_FIELD_SPLITTING);
1134 }
1135 #ifdef MFX_ENABLE_MCTF
1136 for (mfxU32 i = 0; i < videoParam->NumExtParam; i++)
1137 {
1138 if (videoParam->ExtParam[i] && videoParam->ExtParam[i]->BufferId == MFX_EXTBUFF_VPP_MCTF)
1139 {
1140 pipelineList.push_back(MFX_EXTBUFF_VPP_MCTF);
1141 break;
1142 }
1143 }
1144 #endif
1145
1146 /* ********************************************************************** */
1147 /* 2. optional filters, enabled by default, disabled by DO_NOT_USE */
1148 /* ********************************************************************** */
1149
1150 // DO_NOT_USE structure is ignored by VPP since MSDK 3.0
1151
1152 /* *************************************************************************** */
1153 /* 3. optional filters, disabled by default, enabled by DO_USE */
1154 /* *************************************************************************** */
1155 mfxU32* pExtList = NULL;
1156 mfxU32 extCount = 0;
1157
1158 GetDoUseFilterList( videoParam, &pExtList, &extCount );
1159
1160 /* [Core Frame Rate Conversion] FILTER */
1161 /* must be used AFTER [Deinterlace] FILTER !!! due to SW performance specific */
1162 if( !IsFilterFound( &pipelineList[0], (mfxU32)pipelineList.size(), MFX_EXTBUFF_VPP_DI_30i60p ) &&
1163 !IsFilterFound( &pipelineList[0], (mfxU32)pipelineList.size(), MFX_EXTBUFF_VPP_DI_WEAVE ) &&
1164 !IsFilterFound( &pipelineList[0], (mfxU32)pipelineList.size(), MFX_EXTBUFF_VPP_ITC ) )
1165 {
1166 if( IsFilterFound( pExtList, extCount, MFX_EXTBUFF_VPP_FRAME_RATE_CONVERSION ) ||
1167 ( par->In.FrameRateExtN * par->Out.FrameRateExtD != par->Out.FrameRateExtN * par->In.FrameRateExtD ) )
1168 {
1169 pipelineList.push_back(MFX_EXTBUFF_VPP_FRAME_RATE_CONVERSION);
1170 }
1171 }
1172
1173 mfxU32 searchCount = sizeof(g_TABLE_DO_USE) / sizeof(*g_TABLE_DO_USE);
1174 mfxU32 fCount = extCount;
1175 mfxU32 fIdx = 0;
1176 for(fIdx = 0; fIdx < fCount; fIdx++)
1177 {
1178 if( IsFilterFound( &g_TABLE_DO_USE[0], searchCount, pExtList[fIdx] ) && !IsFilterFound(&pipelineList[0], (mfxU32)pipelineList.size(), pExtList[fIdx]) )
1179 {
1180 pipelineList.push_back( pExtList[fIdx] );
1181 }
1182 }
1183
1184
1185 /* *************************************************************************** */
1186 /* 4. optional filters, disabled by default, enabled by EXT_BUFFER */
1187 /* *************************************************************************** */
1188 mfxU32 configCount = std::max<mfxU32>(sizeof(g_TABLE_CONFIG) / sizeof(*g_TABLE_CONFIG), videoParam->NumExtParam);
1189 std::vector<mfxU32> configList(configCount);
1190
1191 GetConfigurableFilterList( videoParam, &configList[0], &configCount );
1192
1193 /* [FrameRateConversion] FILTER */
1194 if( IsFilterFound( &configList[0], configCount, MFX_EXTBUFF_VPP_FRAME_RATE_CONVERSION ) && !IsFilterFound(&pipelineList[0], (mfxU32)pipelineList.size(), MFX_EXTBUFF_VPP_FRAME_RATE_CONVERSION) )
1195 {
1196 if( !IsFilterFound( &pipelineList[0], (mfxU32)pipelineList.size(), MFX_EXTBUFF_VPP_DI_30i60p ) && !IsFilterFound( &pipelineList[0], (mfxU32)pipelineList.size(), MFX_EXTBUFF_VPP_ITC ) )
1197 {
1198 pipelineList.push_back( MFX_EXTBUFF_VPP_FRAME_RATE_CONVERSION );
1199 }
1200 }
1201
1202 /* ROTATION FILTER */
1203 if( IsFilterFound( &configList[0], configCount, MFX_EXTBUFF_VPP_ROTATION ) && !IsFilterFound(&pipelineList[0], (mfxU32)pipelineList.size(), MFX_EXTBUFF_VPP_ROTATION) )
1204 {
1205 if( !IsFilterFound( &pipelineList[0], (mfxU32)pipelineList.size(), MFX_EXTBUFF_VPP_ROTATION ) )
1206 {
1207 pipelineList.push_back( MFX_EXTBUFF_VPP_ROTATION );
1208 }
1209 }
1210
1211 if( IsFilterFound( &configList[0], configCount, MFX_EXTBUFF_VPP_SCALING ) && !IsFilterFound(&pipelineList[0], (mfxU32)pipelineList.size(), MFX_EXTBUFF_VPP_SCALING) )
1212 {
1213 if( !IsFilterFound( &pipelineList[0], (mfxU32)pipelineList.size(), MFX_EXTBUFF_VPP_SCALING ) )
1214 {
1215 pipelineList.push_back( MFX_EXTBUFF_VPP_SCALING );
1216 }
1217 }
1218
1219 #if (MFX_VERSION >= 1025)
1220 if (IsFilterFound(&configList[0], configCount, MFX_EXTBUFF_VPP_COLOR_CONVERSION) && !IsFilterFound(&pipelineList[0], (mfxU32)pipelineList.size(), MFX_EXTBUFF_VPP_COLOR_CONVERSION))
1221 {
1222 if (!IsFilterFound(&pipelineList[0], (mfxU32)pipelineList.size(), MFX_EXTBUFF_VPP_COLOR_CONVERSION))
1223 {
1224 pipelineList.push_back(MFX_EXTBUFF_VPP_COLOR_CONVERSION);
1225 }
1226 }
1227 #endif
1228
1229 if( IsFilterFound( &configList[0], configCount, MFX_EXTBUFF_VPP_MIRRORING ) && !IsFilterFound(&pipelineList[0], (mfxU32)pipelineList.size(), MFX_EXTBUFF_VPP_MIRRORING) )
1230 {
1231 if( !IsFilterFound( &pipelineList[0], (mfxU32)pipelineList.size(), MFX_EXTBUFF_VPP_MIRRORING ) )
1232 {
1233 pipelineList.push_back( MFX_EXTBUFF_VPP_MIRRORING );
1234 }
1235 }
1236
1237 if( IsFilterFound( &configList[0], configCount, MFX_EXTBUFF_VPP_VIDEO_SIGNAL_INFO ) && !IsFilterFound(&pipelineList[0], (mfxU32)pipelineList.size(), MFX_EXTBUFF_VPP_VIDEO_SIGNAL_INFO) )
1238 {
1239 if( !IsFilterFound( &pipelineList[0], (mfxU32)pipelineList.size(), MFX_EXTBUFF_VPP_VIDEO_SIGNAL_INFO ) )
1240 {
1241 pipelineList.push_back( MFX_EXTBUFF_VPP_VIDEO_SIGNAL_INFO );
1242 }
1243 }
1244
1245 searchCount = sizeof(g_TABLE_CONFIG) / sizeof(*g_TABLE_CONFIG);
1246 fCount = configCount;
1247 for(fIdx = 0; fIdx < fCount; fIdx++)
1248 {
1249 if( IsFilterFound( g_TABLE_CONFIG, searchCount, configList[fIdx] ) &&
1250 !IsFilterFound(&pipelineList[0], (mfxU32)pipelineList.size(), configList[fIdx]) )
1251 {
1252 /* Add filter to the list.
1253 * Don't care about duplicates, they will be eliminated by Reorder... calls below
1254 */
1255 pipelineList.push_back(configList[fIdx]);
1256 } /* if( IsFilterFound( g_TABLE_CONFIG */
1257 } /*for(fIdx = 0; fIdx < fCount; fIdx++)*/
1258
1259 /* *************************************************************************** */
1260 /* 5. reordering for speed/quality */
1261 /* *************************************************************************** */
1262 if( pipelineList.size() > 1 )
1263 {
1264 ReorderPipelineListForQuality(pipelineList);
1265 ReorderPipelineListForSpeed(videoParam, pipelineList);
1266 }
1267
1268 if( pipelineList.size() > 0 )
1269 {
1270 ShowPipeline(pipelineList);
1271 }
1272 return ( ( pipelineList.size() > 0 ) ? MFX_ERR_NONE : MFX_ERR_INVALID_VIDEO_PARAM );
1273
1274 } // mfxStatus GetPipelineList(mfxVideoParam* videoParam, std::vector<mfxU32> pipelineList)
1275
1276
IsFilterFound(const mfxU32 * pList,mfxU32 len,mfxU32 filterName)1277 bool IsFilterFound( const mfxU32* pList, mfxU32 len, mfxU32 filterName )
1278 {
1279 mfxU32 i;
1280
1281 if( 0 == len )
1282 {
1283 return false;
1284 }
1285
1286 for( i = 0; i < len; i++ )
1287 {
1288 if( filterName == pList[i] )
1289 {
1290 return true;
1291 }
1292 }
1293
1294 return false;
1295
1296 } // bool IsFilterFound( mfxU32* pList, mfxU32 len, mfxU32 filterName )
1297
1298 // function requires filterName belong pList. all check must be done before
GetFilterIndex(mfxU32 * pList,mfxU32 len,mfxU32 filterName)1299 mfxU32 GetFilterIndex( mfxU32* pList, mfxU32 len, mfxU32 filterName )
1300 {
1301 mfxU32 filterIndex;
1302
1303 for( filterIndex = 0; filterIndex < len; filterIndex++ )
1304 {
1305 if( filterName == pList[filterIndex] )
1306 {
1307 return filterIndex;
1308 }
1309 }
1310
1311 return 0;
1312
1313 } // mfxU32 GetFilterIndex( mfxU32* pList, mfxU32 len, mfxU32 filterName )
1314
1315
1316 /* check each field of FrameInfo excluding PicStruct */
CheckFrameInfo(mfxFrameInfo * info,mfxU32 request,eMFXHWType platform)1317 mfxStatus CheckFrameInfo(mfxFrameInfo* info, mfxU32 request, eMFXHWType platform)
1318 {
1319 (void)platform;
1320 mfxStatus mfxSts = MFX_ERR_NONE;
1321
1322 /* FourCC */
1323 switch (info->FourCC)
1324 {
1325 case MFX_FOURCC_NV12:
1326 case MFX_FOURCC_YV12:
1327 #if defined (MFX_ENABLE_FOURCC_RGB565)
1328 case MFX_FOURCC_RGB565:
1329 #endif // MFX_ENABLE_FOURCC_RGB565
1330 case MFX_FOURCC_RGB4:
1331 case MFX_FOURCC_P010:
1332 case MFX_FOURCC_P210:
1333 case MFX_FOURCC_NV16:
1334 case MFX_FOURCC_YUY2:
1335 case MFX_FOURCC_AYUV:
1336 // A2RGB10 supported as input in case of passthru copy
1337 case MFX_FOURCC_A2RGB10:
1338 #if defined(MFX_VA_LINUX)
1339 // UYVY is supported on Linux only
1340 case MFX_FOURCC_UYVY:
1341 #endif
1342 break;
1343 #if (MFX_VERSION >= 1027)
1344 case MFX_FOURCC_Y210:
1345 case MFX_FOURCC_Y410:
1346 MFX_CHECK(platform >= MFX_HW_ICL, MFX_ERR_INVALID_VIDEO_PARAM);
1347 break;
1348 #endif
1349 #if (MFX_VERSION >= 1031)
1350 case MFX_FOURCC_P016:
1351 case MFX_FOURCC_Y216:
1352 case MFX_FOURCC_Y416:
1353 if (platform < MFX_HW_TGL_LP)
1354 return MFX_ERR_INVALID_VIDEO_PARAM;
1355 break;
1356 #endif
1357 case MFX_FOURCC_IMC3:
1358 case MFX_FOURCC_YUV400:
1359 case MFX_FOURCC_YUV411:
1360 case MFX_FOURCC_YUV422H:
1361 case MFX_FOURCC_YUV422V:
1362 case MFX_FOURCC_YUV444:
1363 if (VPP_OUT == request)
1364 return MFX_ERR_INVALID_VIDEO_PARAM;
1365 break;
1366 #ifdef MFX_ENABLE_RGBP
1367 case MFX_FOURCC_RGBP:
1368 #endif
1369 if (VPP_IN == request)
1370 return MFX_ERR_INVALID_VIDEO_PARAM;
1371
1372 break;
1373 default:
1374 return MFX_ERR_INVALID_VIDEO_PARAM;
1375 }
1376
1377 /* Picture Size */
1378 if( 0 == info->Width || 0 == info->Height )
1379 {
1380 return MFX_ERR_INVALID_VIDEO_PARAM;
1381 }
1382
1383 if ( (info->Width & 15 ) != 0 )
1384 {
1385 return MFX_ERR_INVALID_VIDEO_PARAM;
1386 }
1387
1388
1389 /* Frame Rate */
1390 if (0 == info->FrameRateExtN || 0 == info->FrameRateExtD)
1391 {
1392 return MFX_ERR_INVALID_VIDEO_PARAM;
1393 }
1394
1395 /* checking Height based on PicStruct filed */
1396 if (MFX_PICSTRUCT_PROGRESSIVE & info->PicStruct ||
1397 MFX_PICSTRUCT_FIELD_SINGLE & info->PicStruct)
1398 {
1399 if ((info->Height & 15) !=0)
1400 {
1401 return MFX_ERR_INVALID_VIDEO_PARAM;
1402 }
1403 }
1404 else if( MFX_PICSTRUCT_FIELD_BFF & info->PicStruct ||
1405 MFX_PICSTRUCT_FIELD_TFF & info->PicStruct ||
1406 (MFX_PICSTRUCT_UNKNOWN == info->PicStruct))
1407 {
1408 if ((info->Height & 15) != 0 )
1409 {
1410 return MFX_ERR_INVALID_VIDEO_PARAM;
1411 }
1412 }
1413 else//error protection
1414 {
1415 return MFX_ERR_INVALID_VIDEO_PARAM;
1416 }
1417
1418 return mfxSts;
1419
1420 } // mfxStatus CheckFrameInfo(mfxFrameInfo* info, mfxU32 request)
1421
CompareFrameInfo(mfxFrameInfo * info1,mfxFrameInfo * info2)1422 mfxStatus CompareFrameInfo(mfxFrameInfo* info1, mfxFrameInfo* info2)
1423 {
1424 MFX_CHECK_NULL_PTR2( info1, info2 );
1425
1426 if( info1->FourCC != info2->FourCC )
1427 return MFX_ERR_INCOMPATIBLE_VIDEO_PARAM;
1428
1429 if( info1->Width < info2->Width )
1430 return MFX_ERR_INCOMPATIBLE_VIDEO_PARAM;
1431
1432 if( info1->Height < info2->Height )
1433 return MFX_ERR_INCOMPATIBLE_VIDEO_PARAM;
1434
1435 return MFX_ERR_NONE;
1436
1437 } // mfxStatus CompareFrameInfo(mfxFrameInfo* info1, mfxFrameInfo* info2)
1438
CheckCropParam(mfxFrameInfo * info)1439 mfxStatus CheckCropParam( mfxFrameInfo* info )
1440 {
1441 // in according with spec CropW/H are mandatory for VPP
1442 if( 0 == info->CropH || 0 == info->CropW )
1443 {
1444 return MFX_ERR_INVALID_VIDEO_PARAM;
1445 }
1446
1447 if (info->CropX > info->Width)
1448 {
1449 return MFX_ERR_INVALID_VIDEO_PARAM;
1450 }
1451
1452 if (info->CropY > info->Height)
1453 {
1454 return MFX_ERR_INVALID_VIDEO_PARAM;
1455 }
1456
1457 if (info->CropW > info->Width)
1458 {
1459 return MFX_ERR_INVALID_VIDEO_PARAM;
1460 }
1461
1462 if (info->CropH > info->Height)
1463 {
1464 return MFX_ERR_INVALID_VIDEO_PARAM;
1465 }
1466
1467 if (info->CropX + info->CropW > info->Width)
1468 {
1469 return MFX_ERR_INVALID_VIDEO_PARAM;
1470 }
1471
1472 if (info->CropY + info->CropH > info->Height)
1473 {
1474 return MFX_ERR_INVALID_VIDEO_PARAM;
1475 }
1476
1477 return MFX_ERR_NONE;
1478
1479 } // mfxStatus CheckCropParam( mfxFrameInfo* info )
1480
vppMax_16u(const mfxU16 * pSrc,int len)1481 mfxU16 vppMax_16u(const mfxU16* pSrc, int len)
1482 {
1483 mfxU16 maxElement = 0;
1484
1485 for (int indx = 0 ; indx < len; indx++)
1486 {
1487 if ( pSrc[indx] > maxElement )
1488 {
1489 maxElement = pSrc[indx];
1490 }
1491 }
1492 return maxElement;
1493
1494 } // mfxU16 vppMax_16u(const mfxU16* pSrc, int len)
1495
1496 /* ********************************************* */
1497 /* utility for parsering of VPP optional filters */
1498 /* ********************************************* */
1499
GetDoNotUseFilterList(mfxVideoParam * par,mfxU32 ** ppList,mfxU32 * pLen)1500 void GetDoNotUseFilterList( mfxVideoParam* par, mfxU32** ppList, mfxU32* pLen )
1501 {
1502 mfxU32 i = 0;
1503 mfxExtVPPDoNotUse* pVPPHint = NULL;
1504
1505 /* robustness */
1506 *ppList = NULL;
1507 *pLen = 0;
1508
1509 for( i = 0; i < par->NumExtParam; i++ )
1510 {
1511 if( MFX_EXTBUFF_VPP_DONOTUSE == par->ExtParam[i]->BufferId )
1512 {
1513 pVPPHint = (mfxExtVPPDoNotUse*)(par->ExtParam[i]);
1514 *ppList = pVPPHint->AlgList;
1515 *pLen = pVPPHint->NumAlg;
1516
1517 return;
1518 }
1519 }
1520
1521 return;
1522
1523 } // void GetDoNotUseFilterList( mfxVideoParam* par, mfxU32** ppList, mfxU32* pLen )
1524
1525
GetDoUseFilterList(mfxVideoParam * par,mfxU32 ** ppList,mfxU32 * pLen)1526 void GetDoUseFilterList( mfxVideoParam* par, mfxU32** ppList, mfxU32* pLen )
1527 {
1528 mfxU32 i = 0;
1529 mfxExtVPPDoUse* pVPPHint = NULL;
1530
1531 /* robustness */
1532 *ppList = NULL;
1533 *pLen = 0;
1534
1535 for( i = 0; i < par->NumExtParam; i++ )
1536 {
1537 if( MFX_EXTBUFF_VPP_DOUSE == par->ExtParam[i]->BufferId )
1538 {
1539 pVPPHint = (mfxExtVPPDoUse*)(par->ExtParam[i]);
1540 *ppList = pVPPHint->AlgList;
1541 *pLen = pVPPHint->NumAlg;
1542
1543 return;
1544 }
1545 }
1546
1547 return;
1548
1549 } // void GetDoUseFilterList( mfxVideoParam* par, mfxU32* pList, mfxU32* pLen )
1550
1551
CheckFilterList(mfxU32 * pList,mfxU32 count,bool bDoUseTable)1552 bool CheckFilterList(mfxU32* pList, mfxU32 count, bool bDoUseTable)
1553 {
1554 bool bResOK = true;
1555 // strong check
1556 if( (NULL == pList && count > 0) || (NULL != pList && count == 0) )
1557 {
1558 bResOK = false;
1559 return bResOK;
1560 }
1561
1562 mfxU32 searchCount = sizeof(g_TABLE_DO_USE) / sizeof( *g_TABLE_DO_USE );
1563 mfxU32* pSearchTab = (mfxU32*)&g_TABLE_DO_USE[0];
1564 if( !bDoUseTable )
1565 {
1566 searchCount = sizeof(g_TABLE_DO_NOT_USE) / sizeof( *g_TABLE_DO_NOT_USE );
1567 pSearchTab = (mfxU32*)&g_TABLE_DO_NOT_USE[0];
1568 }
1569
1570 mfxU32 fIdx = 0;
1571 for( fIdx = 0; fIdx < count; fIdx++ )
1572 {
1573 mfxU32 curId = pList[fIdx];
1574
1575 if( !IsFilterFound(pSearchTab, searchCount, curId) )
1576 {
1577 bResOK = false; //invalid ID
1578 }
1579 else if( fIdx == count - 1 )
1580 {
1581 continue;
1582 }
1583 else if( IsFilterFound(pList + 1 + fIdx, count - 1 - fIdx, curId) )
1584 {
1585 bResOK = false; //duplicate ID
1586 }
1587 }
1588
1589 return bResOK;
1590
1591 } // bool CheckFilterList(mfxU32* pList, mfxU32 count, bool bDoUseTable)
1592
1593
GetExtParamList(mfxVideoParam * par,mfxU32 * pList,mfxU32 * pLen)1594 bool GetExtParamList(
1595 mfxVideoParam* par,
1596 mfxU32* pList,
1597 mfxU32* pLen)
1598 {
1599 mfxU32 fIdx = 0;
1600
1601 /* robustness */
1602 *pLen = 0;
1603
1604 mfxU32 searchCount = sizeof(g_TABLE_EXT_PARAM) / sizeof( *g_TABLE_EXT_PARAM );
1605 mfxU32 fCount = par->NumExtParam;
1606 bool bResOK = true;
1607
1608 for( fIdx = 0; fIdx < fCount; fIdx++ )
1609 {
1610 mfxU32 curId = par->ExtParam[fIdx]->BufferId;
1611 if( IsFilterFound(g_TABLE_EXT_PARAM, searchCount, curId) )
1612 {
1613 if( !IsFilterFound(pList, *pLen, curId) )
1614 {
1615 pList[ (*pLen)++ ] = curId;
1616 }
1617 else
1618 {
1619 bResOK = false; // duplicate ID
1620 }
1621 }
1622 else
1623 {
1624 bResOK = false; //invalid ID
1625 }
1626 }
1627
1628 return bResOK;
1629
1630 } // void GetExtParamList( mfxVideoParam* par, mfxU32* pList, mfxU32* pLen )
1631
1632
GetConfigurableFilterList(mfxVideoParam * par,mfxU32 * pList,mfxU32 * pLen)1633 void GetConfigurableFilterList( mfxVideoParam* par, mfxU32* pList, mfxU32* pLen )
1634 {
1635 mfxU32 fIdx = 0;
1636
1637 /* robustness */
1638 *pLen = 0;
1639
1640 mfxU32 fCount = par->NumExtParam;
1641 mfxU32 searchCount = sizeof(g_TABLE_CONFIG) / sizeof( *g_TABLE_CONFIG );
1642
1643 for( fIdx = 0; fIdx < fCount; fIdx++ )
1644 {
1645 mfxU32 curId = par->ExtParam[fIdx]->BufferId;
1646 if( IsFilterFound(g_TABLE_CONFIG, searchCount, curId) && !IsFilterFound(pList, *pLen, curId) )
1647 {
1648 pList[ (*pLen)++ ] = curId;
1649 }
1650 }
1651
1652 return;
1653
1654 } // void GetConfigurableFilterList( mfxVideoParam* par, mfxU32* pList, mfxU32* pLen )
1655
1656
1657 // check is buffer or filter are configurable
IsConfigurable(mfxU32 filterId)1658 bool IsConfigurable( mfxU32 filterId )
1659 {
1660 mfxU32 searchCount = sizeof(g_TABLE_CONFIG) / sizeof( *g_TABLE_CONFIG );
1661
1662 return IsFilterFound(g_TABLE_CONFIG, searchCount, filterId) ? true : false;
1663
1664 } // void GetConfigurableFilterList( mfxU32 filterId )
1665
1666
GetConfigSize(mfxU32 filterId)1667 size_t GetConfigSize( mfxU32 filterId )
1668 {
1669 switch( filterId )
1670 {
1671 case MFX_EXTBUFF_VPP_DENOISE:
1672 {
1673 return sizeof(mfxExtVPPDenoise);
1674 }
1675 case MFX_EXTBUFF_VPP_PROCAMP:
1676 {
1677 return sizeof(mfxExtVPPProcAmp);
1678 }
1679 case MFX_EXTBUFF_VPP_DETAIL:
1680 {
1681 return sizeof(mfxExtVPPDetail);
1682 }
1683 case MFX_EXTBUFF_VPP_FRAME_RATE_CONVERSION:
1684 {
1685 return sizeof(mfxExtVPPFrameRateConversion);
1686 }
1687 case MFX_EXTBUFF_VPP_DEINTERLACING:
1688 {
1689 return sizeof(mfxExtVPPDeinterlacing);
1690 }
1691 /*case MFX_EXTBUFF_VPP_COMPOSITE:
1692 {
1693 return sizeof(mfxExtVPPDeinterlacing);
1694 }???*/
1695
1696 default:
1697 return 0;
1698 }
1699
1700 } // size_t GetConfigSize( mfxU32 filterId )
1701
1702
CheckTransferMatrix(mfxU16)1703 mfxStatus CheckTransferMatrix( mfxU16 /*transferMatrix*/ )
1704 {
1705 return MFX_ERR_NONE;
1706
1707 } // mfxStatus CheckTransferMatrix( mfxU16 transferMatrix )
1708
1709
GetGamutMode(mfxU16 srcTransferMatrix,mfxU16 dstTransferMatrix)1710 mfxGamutMode GetGamutMode( mfxU16 srcTransferMatrix, mfxU16 dstTransferMatrix )
1711 {
1712 mfxStatus mfxSts;
1713
1714 mfxSts = CheckTransferMatrix( srcTransferMatrix );
1715 if( MFX_ERR_NONE != mfxSts )
1716 {
1717 return GAMUT_INVALID_MODE;
1718 }
1719
1720 mfxSts = CheckTransferMatrix( dstTransferMatrix );
1721 if( MFX_ERR_NONE != mfxSts )
1722 {
1723 return GAMUT_INVALID_MODE;
1724 }
1725
1726 mfxGamutMode mode = GAMUT_COMPRESS_BASE_MODE;
1727
1728 if( srcTransferMatrix == dstTransferMatrix )
1729 {
1730 mode = GAMUT_PASSIVE_MODE;
1731 }
1732 return mode;
1733
1734 } // mfxGamutMode GetGamutMode( mfxU16 srcTransferMatrix, mfxU16 dstTransferMatrix )
1735
1736
CheckOpaqMode(mfxVideoParam * par,bool bOpaqMode[2])1737 mfxStatus CheckOpaqMode( mfxVideoParam* par, bool bOpaqMode[2] )
1738 {
1739 if ( (par->IOPattern & MFX_IOPATTERN_IN_OPAQUE_MEMORY) || (par->IOPattern & MFX_IOPATTERN_OUT_OPAQUE_MEMORY) )
1740 {
1741 mfxExtOpaqueSurfaceAlloc *pOpaqAlloc = 0;
1742
1743 pOpaqAlloc = (mfxExtOpaqueSurfaceAlloc *)GetExtendedBuffer(par->ExtParam, par->NumExtParam, MFX_EXTBUFF_OPAQUE_SURFACE_ALLOCATION);
1744
1745 if (!pOpaqAlloc)
1746 {
1747 return MFX_ERR_INVALID_VIDEO_PARAM;
1748 }
1749 else
1750 {
1751 if( par->IOPattern & MFX_IOPATTERN_IN_OPAQUE_MEMORY )
1752 {
1753 if (!(pOpaqAlloc->In.Type & (MFX_MEMTYPE_DXVA2_DECODER_TARGET|MFX_MEMTYPE_DXVA2_PROCESSOR_TARGET)) && !(pOpaqAlloc->In.Type & MFX_MEMTYPE_SYSTEM_MEMORY))
1754 {
1755 return MFX_ERR_INVALID_VIDEO_PARAM;
1756 }
1757
1758 if ((pOpaqAlloc->In.Type & MFX_MEMTYPE_SYSTEM_MEMORY) && (pOpaqAlloc->In.Type & (MFX_MEMTYPE_DXVA2_DECODER_TARGET|MFX_MEMTYPE_DXVA2_PROCESSOR_TARGET)))
1759 {
1760 return MFX_ERR_INVALID_VIDEO_PARAM;
1761 }
1762
1763 bOpaqMode[VPP_IN] = true;
1764 }
1765
1766 if( par->IOPattern & MFX_IOPATTERN_OUT_OPAQUE_MEMORY )
1767 {
1768 if (!(pOpaqAlloc->Out.Type & (MFX_MEMTYPE_DXVA2_DECODER_TARGET|MFX_MEMTYPE_DXVA2_PROCESSOR_TARGET)) && !(pOpaqAlloc->Out.Type & MFX_MEMTYPE_SYSTEM_MEMORY))
1769 {
1770 return MFX_ERR_INVALID_VIDEO_PARAM;
1771 }
1772
1773 if ((pOpaqAlloc->Out.Type & MFX_MEMTYPE_SYSTEM_MEMORY) && (pOpaqAlloc->Out.Type & (MFX_MEMTYPE_DXVA2_DECODER_TARGET|MFX_MEMTYPE_DXVA2_PROCESSOR_TARGET)))
1774 {
1775 return MFX_ERR_INVALID_VIDEO_PARAM;
1776 }
1777
1778 bOpaqMode[VPP_OUT] = true;
1779 }
1780 }
1781 }
1782
1783 return MFX_ERR_NONE;
1784
1785 } // mfxStatus CheckOpaqMode( mfxVideoParam* par, bool bOpaqMode[2] )
1786
1787
GetOpaqRequest(mfxVideoParam * par,bool bOpaqMode[2],mfxFrameAllocRequest requestOpaq[2])1788 mfxStatus GetOpaqRequest( mfxVideoParam* par, bool bOpaqMode[2], mfxFrameAllocRequest requestOpaq[2] )
1789 {
1790 if( bOpaqMode[VPP_IN] || bOpaqMode[VPP_OUT] )
1791 {
1792 mfxExtOpaqueSurfaceAlloc *pOpaqAlloc = (mfxExtOpaqueSurfaceAlloc *)GetExtendedBufferInternal(par->ExtParam, par->NumExtParam, MFX_EXTBUFF_OPAQUE_SURFACE_ALLOCATION);
1793
1794 if( bOpaqMode[VPP_IN] )
1795 {
1796 requestOpaq[VPP_IN].Info = par->vpp.In;
1797 requestOpaq[VPP_IN].NumFrameMin = requestOpaq[VPP_IN].NumFrameSuggested = (mfxU16)pOpaqAlloc->In.NumSurface;
1798 requestOpaq[VPP_IN].Type = (mfxU16)pOpaqAlloc->In.Type;
1799 }
1800
1801 if( bOpaqMode[VPP_OUT] )
1802 {
1803 requestOpaq[VPP_OUT].Info = par->vpp.Out;
1804 requestOpaq[VPP_OUT].NumFrameMin = requestOpaq[VPP_OUT].NumFrameSuggested = (mfxU16)pOpaqAlloc->Out.NumSurface;
1805 requestOpaq[VPP_OUT].Type = (mfxU16)pOpaqAlloc->Out.Type;
1806 }
1807 }
1808
1809 return MFX_ERR_NONE;
1810
1811 } // mfxStatus GetOpaqRequest( mfxVideoParam* par, bool bOpaqMode[2], mfxFrameAllocRequest requestOpaq[2] )
1812
1813
CheckIOPattern_AndSetIOMemTypes(mfxU16 IOPattern,mfxU16 * pInMemType,mfxU16 * pOutMemType,bool bSWLib)1814 mfxStatus CheckIOPattern_AndSetIOMemTypes(mfxU16 IOPattern, mfxU16* pInMemType, mfxU16* pOutMemType, bool bSWLib)
1815 {
1816 if ((IOPattern & MFX_IOPATTERN_IN_VIDEO_MEMORY) &&
1817 (IOPattern & MFX_IOPATTERN_IN_SYSTEM_MEMORY))
1818 {
1819 return MFX_ERR_INVALID_VIDEO_PARAM;
1820 }
1821
1822 if ((IOPattern & MFX_IOPATTERN_OUT_VIDEO_MEMORY) &&
1823 (IOPattern & MFX_IOPATTERN_OUT_SYSTEM_MEMORY))
1824 {
1825 return MFX_ERR_INVALID_VIDEO_PARAM;
1826 }
1827
1828
1829 mfxU16 nativeMemType = (bSWLib) ? (mfxU16)MFX_MEMTYPE_SYSTEM_MEMORY : (mfxU16)MFX_MEMTYPE_DXVA2_PROCESSOR_TARGET;
1830
1831 if( IOPattern & MFX_IOPATTERN_IN_SYSTEM_MEMORY )
1832 {
1833 *pInMemType = MFX_MEMTYPE_FROM_VPPIN|MFX_MEMTYPE_EXTERNAL_FRAME|MFX_MEMTYPE_SYSTEM_MEMORY;
1834 }
1835 else if (IOPattern & MFX_IOPATTERN_IN_VIDEO_MEMORY)
1836 {
1837 *pInMemType = MFX_MEMTYPE_FROM_VPPIN|MFX_MEMTYPE_EXTERNAL_FRAME|MFX_MEMTYPE_DXVA2_PROCESSOR_TARGET;
1838 }
1839 else if (IOPattern & MFX_IOPATTERN_IN_OPAQUE_MEMORY)
1840 {
1841 *pInMemType = MFX_MEMTYPE_FROM_VPPIN|MFX_MEMTYPE_OPAQUE_FRAME|nativeMemType;
1842 }
1843 else
1844 {
1845 return MFX_ERR_INVALID_VIDEO_PARAM;
1846 }
1847
1848 if( IOPattern & MFX_IOPATTERN_OUT_SYSTEM_MEMORY )
1849 {
1850 *pOutMemType = MFX_MEMTYPE_FROM_VPPOUT|MFX_MEMTYPE_EXTERNAL_FRAME|MFX_MEMTYPE_SYSTEM_MEMORY;
1851 }
1852 else if (IOPattern & MFX_IOPATTERN_OUT_VIDEO_MEMORY)
1853 {
1854 *pOutMemType = MFX_MEMTYPE_FROM_VPPOUT|MFX_MEMTYPE_EXTERNAL_FRAME|MFX_MEMTYPE_DXVA2_PROCESSOR_TARGET;
1855 }
1856 else if(IOPattern & MFX_IOPATTERN_OUT_OPAQUE_MEMORY)
1857 {
1858 *pOutMemType = MFX_MEMTYPE_FROM_VPPOUT|MFX_MEMTYPE_OPAQUE_FRAME|nativeMemType;
1859 }
1860 else
1861 {
1862 return MFX_ERR_INVALID_VIDEO_PARAM;
1863 }
1864
1865 return MFX_ERR_NONE;
1866
1867 } // mfxStatus CheckIOPattern_AndSetIOMemTypes(mfxU16 IOPattern,mfxU16* pInMemType, mfxU16* pOutMemType, bool bSWLib)
1868
1869
EstimatePicStruct(mfxU32 * pVariance,mfxU16 width,mfxU16 height)1870 mfxU16 EstimatePicStruct(
1871 mfxU32* pVariance,
1872 mfxU16 width,
1873 mfxU16 height)
1874 {
1875 mfxU16 resPicStruct = MFX_PICSTRUCT_UNKNOWN;
1876
1877 mfxU32 varMin = pVariance[0]* 16 / (width * height);
1878 mfxU32 varMax = pVariance[1]* 16 / (width * height);
1879
1880 //mfxU32 v0 = pVariance[0]* 16 / (width * height);
1881 //mfxU32 v1 = pVariance[1]* 16 / (width * height);
1882 mfxU32 v2 = pVariance[2]* 16 / (width * height);
1883 mfxU32 v3 = pVariance[3]* 16 / (width * height);
1884 mfxU32 v4 = pVariance[4]* 16 / (width * height);
1885
1886 if(varMin > varMax)
1887 {
1888 std::swap(varMin, varMax);
1889 }
1890
1891 if(varMax == 0)
1892 {
1893 resPicStruct = MFX_PICSTRUCT_UNKNOWN;
1894 }
1895 else
1896 {
1897 mfxF64 varRatio = (mfxF64)(varMin) / (mfxF64)(varMax);
1898 mfxF64 result = 100.0 * (1.0 - varRatio);
1899 mfxU32 absDiff= (mfxU32)abs((int)varMax - (int)varMin);
1900
1901 bool bProgressive = false;
1902 if( absDiff < 2 && v2 < 50) // strong progressive;
1903 {
1904 bProgressive = true;
1905 }
1906 else if( result <= 1.0 && v2 < 50) // middle
1907 {
1908 bProgressive = true;
1909 }
1910 else if(result <= 1.0 && v2 < 110) // weak
1911 {
1912 bProgressive = true;
1913 }
1914
1915 if( !bProgressive )
1916 {
1917 //printf("\n picstruct = INTERLACE ("); fflush(stderr);
1918 if( v3 < v4)
1919 {
1920 //printf("TFF) \n"); fflush(stderr);
1921 resPicStruct = MFX_PICSTRUCT_FIELD_TFF;
1922 }
1923 else
1924 {
1925 //printf("BFF) \n"); fflush(stderr);
1926 resPicStruct = MFX_PICSTRUCT_FIELD_BFF;
1927 }
1928 }
1929 else
1930 {
1931 /*printf("\n picstruct = PROGRESSIVE (%f %i %i) \n",
1932 result,
1933 varMin,
1934 varMax); fflush(stderr);*/
1935 resPicStruct = MFX_PICSTRUCT_PROGRESSIVE;
1936 }
1937 }
1938
1939 return resPicStruct;
1940
1941 } // mfxU16 EstimatePicStruct( mfxU32* pVariance )
1942
MapDNFactor(mfxU16 denoiseFactor)1943 mfxU16 MapDNFactor( mfxU16 denoiseFactor )
1944 {
1945 #if defined(LINUX32) || defined(LINUX64)
1946 // On Linux detail and de-noise factors mapped to the real libva values
1947 // at execution time.
1948 mfxU16 gfxFactor = denoiseFactor;
1949 #else
1950 mfxU16 gfxFactor = (mfxU16)floor(64.0 / 100.0 * denoiseFactor + 0.5);
1951 #endif
1952
1953 return gfxFactor;
1954
1955 } // mfxU16 MapDNFactor( mfxU16 denoiseFactor )
1956
CheckScalingParam(mfxExtBuffer * pScalingExtBuffer)1957 mfxStatus CheckScalingParam(mfxExtBuffer* pScalingExtBuffer)
1958 {
1959 mfxStatus sts = MFX_ERR_NONE;
1960
1961 mfxExtVPPScaling* pScalingParams = (mfxExtVPPScaling*)pScalingExtBuffer;
1962 if (pScalingParams)
1963 {
1964 #if (MFX_VERSION >= 1033)
1965 // Scaling parameter combination includes the below 2 cases
1966 // (MFX_SCALING_MODE_DEFAULT / MFX_SCALING_MODE_QUALITY) + (MFX_INTERPOLATION_DEFAULT / MFX_INTERPOLATION_ADVANCED)
1967 // MFX_SCALING_MODE_LOWPOWER + (MFX_INTERPOLATION_DEFAULT / MFX_INTERPOLATION_NEAREST_NEIGHBOR / MFX_INTERPOLATION_BILINEAR / MFX_INTERPOLATION_ADVANCED)
1968 switch (pScalingParams->ScalingMode)
1969 {
1970 case MFX_SCALING_MODE_DEFAULT:
1971 sts = ((pScalingParams->InterpolationMethod == MFX_INTERPOLATION_DEFAULT) || (pScalingParams->InterpolationMethod == MFX_INTERPOLATION_ADVANCED)) ? MFX_ERR_NONE : MFX_ERR_INVALID_VIDEO_PARAM;
1972 break;
1973 case MFX_SCALING_MODE_QUALITY:
1974 sts = ((pScalingParams->InterpolationMethod == MFX_INTERPOLATION_DEFAULT) || (pScalingParams->InterpolationMethod == MFX_INTERPOLATION_ADVANCED)) ? MFX_ERR_NONE : MFX_ERR_INVALID_VIDEO_PARAM;
1975 break;
1976 case MFX_SCALING_MODE_LOWPOWER:
1977 sts = (pScalingParams->InterpolationMethod <= MFX_INTERPOLATION_ADVANCED) ? MFX_ERR_NONE : MFX_ERR_INVALID_VIDEO_PARAM;
1978 break;
1979 default:
1980 sts = MFX_ERR_INVALID_VIDEO_PARAM;
1981 break;
1982 }
1983 #endif
1984 }
1985
1986 return sts;
1987 }
1988
CheckExtParam(VideoCORE * core,mfxExtBuffer ** ppExtParam,mfxU16 count)1989 mfxStatus CheckExtParam(VideoCORE * core, mfxExtBuffer** ppExtParam, mfxU16 count)
1990 {
1991 if( (NULL == ppExtParam && count > 0) )
1992 {
1993 return MFX_ERR_INVALID_VIDEO_PARAM;
1994 }
1995
1996 bool bError = false;
1997
1998 // [1] ExtParam
1999 mfxVideoParam tmpParam;
2000 tmpParam.ExtParam = ppExtParam;
2001 tmpParam.NumExtParam= count;
2002
2003 mfxU32 extParamCount = sizeof(g_TABLE_EXT_PARAM) / sizeof(*g_TABLE_EXT_PARAM);
2004 std::vector<mfxU32> extParamList(extParamCount);
2005 if( !GetExtParamList( &tmpParam, &extParamList[0], &extParamCount ) )
2006 {
2007 bError = true;
2008 }
2009
2010
2011 // [2] configurable
2012 mfxU32 configCount = sizeof(g_TABLE_CONFIG) / sizeof(*g_TABLE_CONFIG);
2013 std::vector<mfxU32> configList(configCount);
2014
2015 GetConfigurableFilterList( &tmpParam, &configList[0], &configCount );
2016
2017 //-----------------------------------------------------
2018 mfxStatus sts = MFX_ERR_NONE, sts_wrn = MFX_ERR_NONE;
2019 mfxU32 fIdx = 0;
2020 for(fIdx = 0; fIdx < configCount; fIdx++)
2021 {
2022 mfxU32 curId = configList[fIdx];
2023
2024 mfxExtBuffer* pHint = NULL;
2025 GetFilterParam( &tmpParam, curId, &pHint);
2026
2027 //3 status's could be returned only: MFX_ERR_NONE, MFX_WRN_INCOMPATIBLE_VIDEO_PARAM, MFX_ERR_UNSUPPORTED
2028 // AL update: now 4 status, added MFX_WRN_FILTER_SKIPPED
2029 sts = ExtendedQuery(core, curId, pHint);
2030
2031 if( MFX_WRN_INCOMPATIBLE_VIDEO_PARAM == sts || MFX_WRN_FILTER_SKIPPED == sts )
2032 {
2033 sts_wrn = sts;
2034 sts = MFX_ERR_NONE;
2035 }
2036 else if( MFX_ERR_UNSUPPORTED == sts )
2037 {
2038 bError = true;
2039 sts = MFX_ERR_NONE;
2040 }
2041 MFX_CHECK_STS(sts); // for double check only
2042 }
2043 //-----------------------------------------------------
2044
2045 // [3] Do NOT USE
2046 mfxU32* pDnuList = NULL;
2047 mfxU32 dnuCount = 0;
2048 GetDoNotUseFilterList( &tmpParam, &pDnuList, &dnuCount );
2049
2050 if( !CheckFilterList(pDnuList, dnuCount, false) )
2051 {
2052 bError = true;
2053 }
2054
2055 for( mfxU32 extParIdx = 0; extParIdx < count; extParIdx++ )
2056 {
2057 // configured via extended parameters filter should not be disabled
2058 if ( IsFilterFound( pDnuList, dnuCount, ppExtParam[extParIdx]->BufferId ) )
2059 {
2060 sts = MFX_ERR_INVALID_VIDEO_PARAM;
2061 }
2062 MFX_CHECK_STS(sts);
2063 }
2064
2065 // [4] Do USE
2066 mfxU32* pDO_USE_List = NULL;
2067 mfxU32 douseCount = 0;
2068 GetDoUseFilterList( &tmpParam, &pDO_USE_List, &douseCount );
2069
2070 if( !CheckFilterList(pDO_USE_List, douseCount, true) )
2071 {
2072 bError = true;
2073 }
2074
2075 // [5] cmp DO_USE vs DO_NOT_USE
2076 for( fIdx = 0; fIdx < dnuCount; fIdx++ )
2077 {
2078 if( IsFilterFound(pDO_USE_List, douseCount, pDnuList[fIdx]) )
2079 {
2080 bError = true;
2081 }
2082 }
2083
2084
2085 if( bError )
2086 {
2087 return MFX_ERR_INVALID_VIDEO_PARAM;
2088 }
2089 else if( MFX_ERR_NONE != sts_wrn )
2090 {
2091 return sts_wrn;
2092 }
2093 else
2094 {
2095 return MFX_ERR_NONE;
2096 }
2097
2098 } // mfxStatus CheckExtParam(mfxExtBuffer** ppExtParam, mfxU32 count)
2099
2100
SignalPlatformCapabilities(const mfxVideoParam & param,const std::vector<mfxU32> & supportedList)2101 void SignalPlatformCapabilities(
2102 const mfxVideoParam & param,
2103 const std::vector<mfxU32> & supportedList)
2104 {
2105 // fill output DOUSE list
2106 //if(bCorrectionEnable)
2107 {
2108 mfxU32* pDO_USE_List = NULL;
2109 mfxU32 douseCount = 0;
2110 GetDoUseFilterList( (mfxVideoParam*)¶m, &pDO_USE_List, &douseCount );
2111 if(douseCount > 0)
2112 {
2113 size_t fCount = std::min<size_t>(supportedList.size(), douseCount);
2114 size_t fIdx = 0;
2115 for(fIdx = 0; fIdx < fCount; fIdx++)
2116 {
2117 pDO_USE_List[fIdx] = supportedList[fIdx];
2118 }
2119
2120 for(; fIdx< douseCount; fIdx++)
2121 {
2122 pDO_USE_List[fIdx] = 0;// EMPTY
2123 }
2124 }
2125 }
2126
2127 // ExtBuffer Correction (will be fixed late)
2128
2129 } // mfxStatus SignalPlatformCapabilities(...)
2130
2131
ExtractDoUseList(mfxU32 * pSrcList,mfxU32 len,std::vector<mfxU32> & dstList)2132 void ExtractDoUseList(mfxU32* pSrcList, mfxU32 len, std::vector<mfxU32> & dstList)
2133 {
2134 dstList.resize(0);
2135
2136 mfxU32 searchCount = sizeof(g_TABLE_DO_USE) / sizeof( *g_TABLE_DO_USE );
2137
2138 for(mfxU32 searchIdx = 0; searchIdx < searchCount; searchIdx++)
2139 {
2140 if( IsFilterFound(pSrcList, len, g_TABLE_DO_USE[searchIdx]) )
2141 {
2142 dstList.push_back(g_TABLE_DO_USE[searchIdx]);
2143 }
2144 }
2145
2146 } // void ExtractDoUseList(mfxU32* pSrcList, mfxU32 len, std::vector<mfxU32> & dstList)
2147
2148
CheckDoUseCompatibility(mfxU32 filterName)2149 bool CheckDoUseCompatibility( mfxU32 filterName )
2150 {
2151 bool bResult = false;
2152
2153 mfxU32 douseCount = sizeof(g_TABLE_DO_USE) / sizeof( *g_TABLE_DO_USE );
2154
2155 bResult = IsFilterFound(g_TABLE_DO_USE, douseCount, filterName);
2156
2157 return bResult;
2158
2159 } // bool CheckDoUseCompatibility( mfxU32 filterName )
2160
2161
GetCrossList(const std::vector<mfxU32> & pipelineList,const std::vector<mfxU32> & capsList,std::vector<mfxU32> & doUseList,std::vector<mfxU32> & dontUseList)2162 mfxStatus GetCrossList(
2163 const std::vector<mfxU32> & pipelineList,
2164 const std::vector<mfxU32> & capsList,
2165 std::vector<mfxU32> & doUseList,
2166 std::vector<mfxU32> & dontUseList )
2167 {
2168 mfxStatus sts = MFX_ERR_NONE;
2169 mfxU32 fIdx;
2170
2171 for(fIdx = 0; fIdx < pipelineList.size(); fIdx++)
2172 {
2173 if( !IsFilterFound(&capsList[0], (mfxU32)capsList.size(), pipelineList[fIdx]) )
2174 {
2175 if( CheckDoUseCompatibility( pipelineList[fIdx] ) )
2176 {
2177 dontUseList.push_back( pipelineList[fIdx] );
2178 sts = MFX_WRN_FILTER_SKIPPED;
2179 }
2180 }
2181 else
2182 {
2183 doUseList.push_back( pipelineList[fIdx] );
2184 }
2185 }
2186
2187 return sts;
2188
2189 } // mfxStatus GetCrossList(...)
2190
2191
IsFrcInterpolationEnable(const mfxVideoParam & param,const MfxHwVideoProcessing::mfxVppCaps & caps)2192 bool IsFrcInterpolationEnable(const mfxVideoParam & param, const MfxHwVideoProcessing::mfxVppCaps & caps)
2193 {
2194 mfxF64 inFrameRate = CalculateUMCFramerate(param.vpp.In.FrameRateExtN, param.vpp.In.FrameRateExtD);
2195 mfxF64 outFrameRate = CalculateUMCFramerate(param.vpp.Out.FrameRateExtN, param.vpp.Out.FrameRateExtD);
2196 mfxF64 mfxRatio = inFrameRate == 0 ? 0 : outFrameRate / inFrameRate;
2197
2198 mfxU32 frcCount = (mfxU32)caps.frcCaps.customRateData.size();
2199 mfxF64 FRC_EPS = 0.01;
2200
2201 for(mfxU32 frcIdx = 0; frcIdx < frcCount; frcIdx++)
2202 {
2203 MfxHwVideoProcessing::CustomRateData* rateData = (MfxHwVideoProcessing::CustomRateData*)&(caps.frcCaps.customRateData[frcIdx]);
2204 // it is outFrameRate / inputFrameRate.
2205 mfxF64 gfxRatio = CalculateUMCFramerate(rateData->customRate.FrameRateExtN, rateData->customRate.FrameRateExtD);
2206
2207 if( fabs(gfxRatio - mfxRatio) < FRC_EPS )
2208 {
2209 return true;
2210 }
2211 }
2212
2213 return false;
2214
2215 } // bool IsFrcInterpolationEnable(const mfxVideoParam & param, const MfxHwVideoProcessing::mfxVppCaps & caps)
2216
2217
ConvertCaps2ListDoUse(MfxHwVideoProcessing::mfxVppCaps & caps,std::vector<mfxU32> & list)2218 void ConvertCaps2ListDoUse(MfxHwVideoProcessing::mfxVppCaps& caps, std::vector<mfxU32>& list)
2219 {
2220 if(caps.uProcampFilter)
2221 {
2222 list.push_back(MFX_EXTBUFF_VPP_PROCAMP);
2223 }
2224 #ifdef MFX_ENABLE_MCTF
2225 if (caps.uMCTF)
2226 {
2227 list.push_back(MFX_EXTBUFF_VPP_MCTF);
2228 }
2229 #endif
2230 if(caps.uDenoiseFilter)
2231 {
2232 list.push_back(MFX_EXTBUFF_VPP_DENOISE);
2233 }
2234
2235 if(caps.uDetailFilter)
2236 {
2237 list.push_back(MFX_EXTBUFF_VPP_DETAIL);
2238 }
2239
2240 if(caps.uFrameRateConversion)
2241 {
2242 list.push_back(MFX_EXTBUFF_VPP_FRAME_RATE_CONVERSION);
2243 }
2244
2245 if(caps.uDeinterlacing)
2246 {
2247 list.push_back(MFX_EXTBUFF_VPP_DEINTERLACING);
2248 }
2249
2250 if(caps.uVideoSignalInfo)
2251 {
2252 list.push_back(MFX_EXTBUFF_VPP_VIDEO_SIGNAL_INFO);
2253 }
2254
2255 if(caps.uIStabFilter)
2256 {
2257 list.push_back(MFX_EXTBUFF_VPP_IMAGE_STABILIZATION);
2258 }
2259
2260 if(caps.uVariance)
2261 {
2262 list.push_back(MFX_EXTBUFF_VPP_PICSTRUCT_DETECTION);
2263 }
2264
2265 if(caps.uRotation)
2266 {
2267 list.push_back(MFX_EXTBUFF_VPP_ROTATION);
2268 }
2269
2270 if(caps.uMirroring)
2271 {
2272 list.push_back(MFX_EXTBUFF_VPP_MIRRORING);
2273 }
2274
2275 if(caps.uScaling)
2276 {
2277 list.push_back(MFX_EXTBUFF_VPP_SCALING);
2278 }
2279
2280 #if (MFX_VERSION >= 1025)
2281 if (caps.uChromaSiting)
2282 {
2283 list.push_back(MFX_EXTBUFF_VPP_COLOR_CONVERSION);
2284 }
2285 #endif
2286
2287 /* FIELD Copy is always present*/
2288 list.push_back(MFX_EXTBUFF_VPP_FIELD_PROCESSING);
2289 /* Field weaving is always present*/
2290 list.push_back(MFX_EXTBUFF_VPP_FIELD_WEAVING);
2291 /* Field splitting is always present*/
2292 list.push_back(MFX_EXTBUFF_VPP_FIELD_SPLITTING);
2293 /* Composition is always present*/
2294 list.push_back(MFX_EXTBUFF_VPP_COMPOSITE);
2295
2296 } // void ConvertCaps2ListDoUse(MfxHwVideoProcessing::mfxVppCaps& caps, std::vector<mfxU32> list)
2297
2298
2299 #endif // MFX_ENABLE_VPP
2300 /* EOF */
2301