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*)&param, &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