1 /*############################################################################
2 # Copyright (C) Intel Corporation
4 # SPDX-License-Identifier: MIT
5 ############################################################################*/
7 #include "vpl/mfx_dispatcher_vpl.h"
13 // implementation of config context (mfxConfig)
14 // each loader instance can have one or more configs
15 // associated with it - used for filtering implementations
16 // based on what they support (codec types, etc.)
17 ConfigCtxVPL::ConfigCtxVPL()
28 // initially set Type = unset (invalid)
29 // if valid property string and value are passed in,
30 // this will be updated
31 // otherwise loader will ignore this cfg during EnumImplementations
32 for (mfxU32 idx = 0; idx < NUM_TOTAL_FILTER_PROPS; idx++) {
33 m_propVar[idx].Version.Version = MFX_VARIANT_VERSION;
34 m_propVar[idx].Type = MFX_VARIANT_TYPE_UNSET;
35 m_propVar[idx].Data.U64 = 0;
38 m_parentLoader = nullptr;
42 ConfigCtxVPL::~ConfigCtxVPL() {
52 // settable config properties for mfxImplDescription
54 ePropMain_AccelerationMode,
56 ePropMain_ApiVersion_Major,
57 ePropMain_ApiVersion_Minor,
62 ePropMain_VendorImplID,
63 ePropMain_PoolAllocationPolicy,
65 // settable config properties for mfxDeviceDescription
67 ePropDevice_DeviceIDStr,
68 ePropDevice_MediaAdapterType,
70 // settable config properties for mfxDecoderDescription
72 ePropDec_MaxcodecLevel,
74 ePropDec_MemHandleType,
77 ePropDec_ColorFormats,
79 // settable config properties for mfxEncoderDescription
81 ePropEnc_MaxcodecLevel,
82 ePropEnc_BiDirectionalPrediction,
83 ePropEnc_ReportedStats,
85 ePropEnc_MemHandleType,
88 ePropEnc_ColorFormats,
90 // settable config properties for mfxVPPDescription
91 ePropVPP_FilterFourCC,
92 ePropVPP_MaxDelayInFrames,
93 ePropVPP_MemHandleType,
99 // settable config properties for mfxExtendedDeviceId
100 ePropExtDev_VendorID,
101 ePropExtDev_DeviceID,
102 ePropExtDev_PCIDomain,
104 ePropExtDev_PCIDevice,
105 ePropExtDev_PCIFunction,
106 ePropExtDev_DeviceLUID,
107 ePropExtDev_LUIDDeviceNodeMask,
108 ePropExtDev_DRMRenderNodeNum,
109 ePropExtDev_DRMPrimaryNodeNum,
110 ePropExtDev_DeviceName,
112 // special properties not part of description struct
113 ePropSpecial_HandleType,
115 ePropSpecial_NumThread,
116 ePropSpecial_DeviceCopy,
117 ePropSpecial_ExtBuffer,
118 ePropSpecial_DXGIAdapterIndex,
120 // functions which must report as implemented
121 ePropFunc_FunctionName,
123 // number of entries (always last)
127 // leave table formatting alone
130 // order must align exactly with PropIdx list
131 // to avoid mismatches, this should be automated (e.g. pre-processor step)
132 static const PropVariant PropIdxTab[] = {
133 { "ePropMain_Impl", MFX_VARIANT_TYPE_U32 },
134 { "ePropMain_AccelerationMode", MFX_VARIANT_TYPE_U32 },
135 { "ePropMain_ApiVersion", MFX_VARIANT_TYPE_U32 },
136 { "ePropMain_ApiVersion_Major", MFX_VARIANT_TYPE_U16 },
137 { "ePropMain_ApiVersion_Minor", MFX_VARIANT_TYPE_U16 },
138 { "ePropMain_ImplName", MFX_VARIANT_TYPE_PTR },
139 { "ePropMain_License", MFX_VARIANT_TYPE_PTR },
140 { "ePropMain_Keywords", MFX_VARIANT_TYPE_PTR },
141 { "ePropMain_VendorID", MFX_VARIANT_TYPE_U32 },
142 { "ePropMain_VendorImplID", MFX_VARIANT_TYPE_U32 },
143 { "ePropMain_PoolAllocationPolicy", MFX_VARIANT_TYPE_U32 },
145 { "ePropDevice_DeviceID", MFX_VARIANT_TYPE_U16 },
146 { "ePropDevice_DeviceIDStr", MFX_VARIANT_TYPE_PTR },
147 { "ePropDevice_MediaAdapterType", MFX_VARIANT_TYPE_U16 },
149 { "ePropDec_CodecID", MFX_VARIANT_TYPE_U32 },
150 { "ePropDec_MaxcodecLevel", MFX_VARIANT_TYPE_U16 },
151 { "ePropDec_Profile", MFX_VARIANT_TYPE_U32 },
152 { "ePropDec_MemHandleType", MFX_VARIANT_TYPE_U32 },
153 { "ePropDec_Width", MFX_VARIANT_TYPE_PTR },
154 { "ePropDec_Height", MFX_VARIANT_TYPE_PTR },
155 { "ePropDec_ColorFormats", MFX_VARIANT_TYPE_U32 },
157 { "ePropEnc_CodecID", MFX_VARIANT_TYPE_U32 },
158 { "ePropEnc_MaxcodecLevel", MFX_VARIANT_TYPE_U16 },
159 { "ePropEnc_BiDirectionalPrediction", MFX_VARIANT_TYPE_U16 },
160 { "ePropEnc_ReportedStats", MFX_VARIANT_TYPE_U16 },
161 { "ePropEnc_Profile", MFX_VARIANT_TYPE_U32 },
162 { "ePropEnc_MemHandleType", MFX_VARIANT_TYPE_U32 },
163 { "ePropEnc_Width", MFX_VARIANT_TYPE_PTR },
164 { "ePropEnc_Height", MFX_VARIANT_TYPE_PTR },
165 { "ePropEnc_ColorFormats", MFX_VARIANT_TYPE_U32 },
167 { "ePropVPP_FilterFourCC", MFX_VARIANT_TYPE_U32 },
168 { "ePropVPP_MaxDelayInFrames", MFX_VARIANT_TYPE_U16 },
169 { "ePropVPP_MemHandleType", MFX_VARIANT_TYPE_U32 },
170 { "ePropVPP_Width", MFX_VARIANT_TYPE_PTR },
171 { "ePropVPP_Height", MFX_VARIANT_TYPE_PTR },
172 { "ePropVPP_InFormat", MFX_VARIANT_TYPE_U32 },
173 { "ePropVPP_OutFormat", MFX_VARIANT_TYPE_U32 },
175 { "ePropExtDev_VendorID", MFX_VARIANT_TYPE_U16 },
176 { "ePropExtDev_DeviceID", MFX_VARIANT_TYPE_U16 },
177 { "ePropExtDev_PCIDomain", MFX_VARIANT_TYPE_U32 },
178 { "ePropExtDev_PCIBus", MFX_VARIANT_TYPE_U32 },
179 { "ePropExtDev_PCIDevice", MFX_VARIANT_TYPE_U32 },
180 { "ePropExtDev_PCIFunction", MFX_VARIANT_TYPE_U32 },
181 { "ePropExtDev_DeviceLUID", MFX_VARIANT_TYPE_PTR },
182 { "ePropExtDev_LUIDDeviceNodeMask", MFX_VARIANT_TYPE_U32 },
183 { "ePropExtDev_DRMRenderNodeNum", MFX_VARIANT_TYPE_U32 },
184 { "ePropExtDev_DRMPrimaryNodeNum", MFX_VARIANT_TYPE_U32 },
185 { "ePropExtDev_DeviceName", MFX_VARIANT_TYPE_PTR },
187 { "ePropSpecial_HandleType", MFX_VARIANT_TYPE_U32 },
188 { "ePropSpecial_Handle", MFX_VARIANT_TYPE_PTR },
189 { "ePropSpecial_NumThread", MFX_VARIANT_TYPE_U32 },
190 { "ePropSpecial_DeviceCopy", MFX_VARIANT_TYPE_U16 },
191 { "ePropSpecial_ExtBuffer", MFX_VARIANT_TYPE_PTR },
192 { "ePropSpecial_DXGIAdapterIndex", MFX_VARIANT_TYPE_U32 },
194 { "ePropFunc_FunctionName", MFX_VARIANT_TYPE_PTR },
197 // end table formatting
200 // sanity check - property table and indexes must have same number of entries
201 static_assert((sizeof(PropIdxTab) / sizeof(PropVariant)) == eProp_TotalProps,
202 "PropIdx and PropIdxTab are misaligned");
204 static_assert(NUM_TOTAL_FILTER_PROPS == eProp_TotalProps,
205 "NUM_TOTAL_FILTER_PROPS and eProp_TotalProps are misaligned");
207 mfxStatus ConfigCtxVPL::ValidateAndSetProp(mfxI32 idx, mfxVariant value) {
208 if (idx < 0 || idx >= eProp_TotalProps)
209 return MFX_ERR_NOT_FOUND;
211 if (value.Type != PropIdxTab[idx].Type)
212 return MFX_ERR_UNSUPPORTED;
214 m_propVar[idx].Version.Version = MFX_VARIANT_VERSION;
215 m_propVar[idx].Type = value.Type;
217 if (value.Type == MFX_VARIANT_TYPE_PTR) {
218 if (value.Data.Ptr == nullptr) {
219 // unset property to avoid possibly dereferencing null if app ignores error code
220 m_propVar[idx].Type = MFX_VARIANT_TYPE_UNSET;
221 return MFX_ERR_NULL_PTR;
224 // local ptr for copying from array
225 mfxU8 *pU8 = (mfxU8 *)(value.Data.Ptr);
227 mfxExtBuffer *extBuf = nullptr;
229 // save copy of data passed by pointer, into object of the appropriate type
232 m_propRange32U[PROP_RANGE_DEC_W] = *((mfxRange32U *)(value.Data.Ptr));
233 m_propVar[idx].Data.Ptr = &(m_propRange32U[PROP_RANGE_DEC_W]);
235 case ePropDec_Height:
236 m_propRange32U[PROP_RANGE_DEC_H] = *((mfxRange32U *)(value.Data.Ptr));
237 m_propVar[idx].Data.Ptr = &(m_propRange32U[PROP_RANGE_DEC_H]);
240 m_propRange32U[PROP_RANGE_ENC_W] = *((mfxRange32U *)(value.Data.Ptr));
241 m_propVar[idx].Data.Ptr = &(m_propRange32U[PROP_RANGE_ENC_W]);
243 case ePropEnc_Height:
244 m_propRange32U[PROP_RANGE_ENC_H] = *((mfxRange32U *)(value.Data.Ptr));
245 m_propVar[idx].Data.Ptr = &(m_propRange32U[PROP_RANGE_ENC_H]);
248 m_propRange32U[PROP_RANGE_VPP_W] = *((mfxRange32U *)(value.Data.Ptr));
249 m_propVar[idx].Data.Ptr = &(m_propRange32U[PROP_RANGE_VPP_W]);
251 case ePropVPP_Height:
252 m_propRange32U[PROP_RANGE_VPP_H] = *((mfxRange32U *)(value.Data.Ptr));
253 m_propVar[idx].Data.Ptr = &(m_propRange32U[PROP_RANGE_VPP_H]);
255 case ePropSpecial_Handle:
256 m_propVar[idx].Data.Ptr = (mfxHDL)(value.Data.Ptr);
258 case ePropMain_ImplName:
259 m_implName = (char *)(value.Data.Ptr);
260 m_propVar[idx].Data.Ptr = &(m_implName);
262 case ePropMain_License:
263 m_implLicense = (char *)(value.Data.Ptr);
264 m_propVar[idx].Data.Ptr = &(m_implLicense);
266 case ePropMain_Keywords:
267 m_implKeywords = (char *)(value.Data.Ptr);
268 m_propVar[idx].Data.Ptr = &(m_implKeywords);
270 case ePropDevice_DeviceIDStr:
271 m_deviceIdStr = (char *)(value.Data.Ptr);
272 m_propVar[idx].Data.Ptr = &(m_deviceIdStr);
274 case ePropFunc_FunctionName:
275 // no need to save Data.Ptr - parsed in main loop
276 m_implFunctionName = (char *)(value.Data.Ptr);
278 case ePropExtDev_DeviceLUID:
279 for (mfxU32 j = 0; j < 8; j++)
280 m_extDevLUID8U[j] = pU8[j];
281 m_propVar[idx].Data.Ptr = &(m_extDevLUID8U[0]);
283 case ePropExtDev_DeviceName:
284 m_extDevNameStr = (char *)(value.Data.Ptr);
285 m_propVar[idx].Data.Ptr = &(m_extDevNameStr);
287 case ePropSpecial_ExtBuffer:
288 // Don't assume anything about the lifetime of input mfxExtBuffer in Data.Ptr
289 // Instead, we copy the full extBuf into a vector owned by ConfixCtxVPL and will pass this to MFXInitialize()
290 // if app calls MFXSetConfigFilterProperty('ExtBuffer') again with a different extBuf, the old copy will be overwritten
291 SetExtBuf((mfxExtBuffer *)(value.Data.Ptr));
293 if (GetExtBuf(&extBuf))
294 m_propVar[idx].Data.Ptr = extBuf;
301 m_propVar[idx].Data = value.Data;
307 mfxStatus ConfigCtxVPL::SetFilterPropertyDec(std::list<std::string> &propParsedString,
309 std::string nextProp;
311 nextProp = GetNextProp(propParsedString);
313 // no settable top-level members
314 if (nextProp != "decoder")
315 return MFX_ERR_NOT_FOUND;
318 nextProp = GetNextProp(propParsedString);
319 if (nextProp == "CodecID") {
320 return ValidateAndSetProp(ePropDec_CodecID, value);
322 else if (nextProp == "MaxcodecLevel") {
323 return ValidateAndSetProp(ePropDec_MaxcodecLevel, value);
325 else if (nextProp != "decprofile") {
326 return MFX_ERR_NOT_FOUND;
329 // parse 'decprofile'
330 nextProp = GetNextProp(propParsedString);
331 if (nextProp == "Profile") {
332 return ValidateAndSetProp(ePropDec_Profile, value);
334 else if (nextProp != "decmemdesc") {
335 return MFX_ERR_NOT_FOUND;
338 // parse 'decmemdesc'
339 nextProp = GetNextProp(propParsedString);
340 if (nextProp == "MemHandleType") {
341 return ValidateAndSetProp(ePropDec_MemHandleType, value);
343 else if (nextProp == "Width") {
344 return ValidateAndSetProp(ePropDec_Width, value);
346 else if (nextProp == "Height") {
347 return ValidateAndSetProp(ePropDec_Height, value);
349 else if (nextProp == "ColorFormat" || nextProp == "ColorFormats") {
350 return ValidateAndSetProp(ePropDec_ColorFormats, value);
353 // end of mfxDecoderDescription options
354 return MFX_ERR_NOT_FOUND;
357 mfxStatus ConfigCtxVPL::SetFilterPropertyEnc(std::list<std::string> &propParsedString,
359 std::string nextProp;
361 nextProp = GetNextProp(propParsedString);
363 // no settable top-level members
364 if (nextProp != "encoder")
365 return MFX_ERR_NOT_FOUND;
368 nextProp = GetNextProp(propParsedString);
369 if (nextProp == "CodecID") {
370 return ValidateAndSetProp(ePropEnc_CodecID, value);
372 else if (nextProp == "MaxcodecLevel") {
373 return ValidateAndSetProp(ePropEnc_MaxcodecLevel, value);
375 else if (nextProp == "BiDirectionalPrediction") {
376 return ValidateAndSetProp(ePropEnc_BiDirectionalPrediction, value);
378 #ifdef ONEVPL_EXPERIMENTAL
379 else if (nextProp == "ReportedStats") {
380 return ValidateAndSetProp(ePropEnc_ReportedStats, value);
383 else if (nextProp != "encprofile") {
384 return MFX_ERR_NOT_FOUND;
387 // parse 'encprofile'
388 nextProp = GetNextProp(propParsedString);
389 if (nextProp == "Profile") {
390 return ValidateAndSetProp(ePropEnc_Profile, value);
392 else if (nextProp != "encmemdesc") {
393 return MFX_ERR_NOT_FOUND;
396 // parse 'encmemdesc'
397 nextProp = GetNextProp(propParsedString);
398 if (nextProp == "MemHandleType") {
399 return ValidateAndSetProp(ePropEnc_MemHandleType, value);
401 else if (nextProp == "Width") {
402 return ValidateAndSetProp(ePropEnc_Width, value);
404 else if (nextProp == "Height") {
405 return ValidateAndSetProp(ePropEnc_Height, value);
407 else if (nextProp == "ColorFormat" || nextProp == "ColorFormats") {
408 return ValidateAndSetProp(ePropEnc_ColorFormats, value);
411 // end of mfxEncoderDescription options
412 return MFX_ERR_NOT_FOUND;
415 mfxStatus ConfigCtxVPL::SetFilterPropertyVPP(std::list<std::string> &propParsedString,
417 std::string nextProp;
419 nextProp = GetNextProp(propParsedString);
421 // no settable top-level members
422 if (nextProp != "filter")
423 return MFX_ERR_NOT_FOUND;
426 nextProp = GetNextProp(propParsedString);
427 if (nextProp == "FilterFourCC") {
428 return ValidateAndSetProp(ePropVPP_FilterFourCC, value);
430 else if (nextProp == "MaxDelayInFrames") {
431 return ValidateAndSetProp(ePropVPP_MaxDelayInFrames, value);
433 else if (nextProp != "memdesc") {
434 return MFX_ERR_NOT_FOUND;
438 nextProp = GetNextProp(propParsedString);
439 if (nextProp == "MemHandleType") {
440 return ValidateAndSetProp(ePropVPP_MemHandleType, value);
442 else if (nextProp == "Width") {
443 return ValidateAndSetProp(ePropVPP_Width, value);
445 else if (nextProp == "Height") {
446 return ValidateAndSetProp(ePropVPP_Height, value);
448 else if (nextProp != "format") {
449 return MFX_ERR_NOT_FOUND;
453 nextProp = GetNextProp(propParsedString);
454 if (nextProp == "InFormat") {
455 return ValidateAndSetProp(ePropVPP_InFormat, value);
457 else if (nextProp == "OutFormat" || nextProp == "OutFormats") {
458 return ValidateAndSetProp(ePropVPP_OutFormat, value);
461 // end of mfxVPPDescription options
462 return MFX_ERR_NOT_FOUND;
465 // return codes (from spec):
466 // MFX_ERR_NOT_FOUND - name contains unknown parameter name
467 // MFX_ERR_UNSUPPORTED - value data type != parameter with provided name
468 mfxStatus ConfigCtxVPL::SetFilterProperty(const mfxU8 *name, mfxVariant value) {
470 return MFX_ERR_NULL_PTR;
472 std::list<std::string> propParsedString;
474 // parse property string into individual properties,
476 std::stringstream prop((char *)name);
478 propParsedString.clear();
479 while (getline(prop, s, '.')) {
480 propParsedString.push_back(s);
483 // get first property descriptor
484 std::string nextProp = GetNextProp(propParsedString);
486 // check for special-case properties, not part of mfxImplDescription
487 if (nextProp == "mfxHandleType") {
488 return ValidateAndSetProp(ePropSpecial_HandleType, value);
490 else if (nextProp == "mfxHDL") {
491 return ValidateAndSetProp(ePropSpecial_Handle, value);
493 else if (nextProp == "NumThread") {
494 return ValidateAndSetProp(ePropSpecial_NumThread, value);
496 #ifdef ONEVPL_EXPERIMENTAL
497 else if (nextProp == "DeviceCopy") {
498 return ValidateAndSetProp(ePropSpecial_DeviceCopy, value);
501 else if (nextProp == "ExtBuffer") {
502 return ValidateAndSetProp(ePropSpecial_ExtBuffer, value);
504 else if (nextProp == "DXGIAdapterIndex") {
505 #if defined(_WIN32) || defined(_WIN64)
506 // this property is only valid on Windows
507 return ValidateAndSetProp(ePropSpecial_DXGIAdapterIndex, value);
509 return MFX_ERR_NOT_FOUND;
513 // to require that a specific function is implemented, use the property name
514 // "mfxImplementedFunctions.FunctionsName"
515 if (nextProp == "mfxImplementedFunctions") {
516 nextProp = GetNextProp(propParsedString);
517 if (nextProp == "FunctionsName") {
518 return ValidateAndSetProp(ePropFunc_FunctionName, value);
520 return MFX_ERR_NOT_FOUND;
523 #ifdef ONEVPL_EXPERIMENTAL
524 // extended device ID properties must begin with mfxExtendedDeviceId
525 if (nextProp == "mfxExtendedDeviceId") {
526 nextProp = GetNextProp(propParsedString);
527 if (nextProp == "VendorID") {
528 return ValidateAndSetProp(ePropExtDev_VendorID, value);
530 else if (nextProp == "DeviceID") {
531 return ValidateAndSetProp(ePropExtDev_DeviceID, value);
533 else if (nextProp == "PCIDomain") {
534 return ValidateAndSetProp(ePropExtDev_PCIDomain, value);
536 else if (nextProp == "PCIBus") {
537 return ValidateAndSetProp(ePropExtDev_PCIBus, value);
539 else if (nextProp == "PCIDevice") {
540 return ValidateAndSetProp(ePropExtDev_PCIDevice, value);
542 else if (nextProp == "PCIFunction") {
543 return ValidateAndSetProp(ePropExtDev_PCIFunction, value);
545 else if (nextProp == "DeviceLUID") {
546 return ValidateAndSetProp(ePropExtDev_DeviceLUID, value);
548 else if (nextProp == "LUIDDeviceNodeMask") {
549 return ValidateAndSetProp(ePropExtDev_LUIDDeviceNodeMask, value);
551 else if (nextProp == "DRMRenderNodeNum") {
552 return ValidateAndSetProp(ePropExtDev_DRMRenderNodeNum, value);
554 else if (nextProp == "DRMPrimaryNodeNum") {
555 return ValidateAndSetProp(ePropExtDev_DRMPrimaryNodeNum, value);
557 else if (nextProp == "DeviceName") {
558 return ValidateAndSetProp(ePropExtDev_DeviceName, value);
560 return MFX_ERR_NOT_FOUND;
564 // standard properties must begin with "mfxImplDescription"
565 if (nextProp != "mfxImplDescription") {
566 return MFX_ERR_NOT_FOUND;
569 // get next property descriptor
570 nextProp = GetNextProp(propParsedString);
572 // property is a top-level member of mfxImplDescription
573 if (nextProp == "Impl") {
574 return ValidateAndSetProp(ePropMain_Impl, value);
576 else if (nextProp == "AccelerationMode") {
577 return ValidateAndSetProp(ePropMain_AccelerationMode, value);
579 else if (nextProp == "mfxSurfacePoolMode") {
580 return ValidateAndSetProp(ePropMain_PoolAllocationPolicy, value);
582 else if (nextProp == "ApiVersion") {
583 // ApiVersion may be passed as single U32 (Version) or two U16's (Major, Minor)
584 nextProp = GetNextProp(propParsedString);
585 if (nextProp == "Version")
586 return ValidateAndSetProp(ePropMain_ApiVersion, value);
587 else if (nextProp == "Major")
588 return ValidateAndSetProp(ePropMain_ApiVersion_Major, value);
589 else if (nextProp == "Minor")
590 return ValidateAndSetProp(ePropMain_ApiVersion_Minor, value);
592 return MFX_ERR_NOT_FOUND;
594 else if (nextProp == "VendorID") {
595 return ValidateAndSetProp(ePropMain_VendorID, value);
597 else if (nextProp == "ImplName") {
598 return ValidateAndSetProp(ePropMain_ImplName, value);
600 else if (nextProp == "License") {
601 return ValidateAndSetProp(ePropMain_License, value);
603 else if (nextProp == "Keywords") {
604 return ValidateAndSetProp(ePropMain_Keywords, value);
606 else if (nextProp == "VendorImplID") {
607 return ValidateAndSetProp(ePropMain_VendorImplID, value);
610 // property is a member of mfxDeviceDescription
611 if (nextProp == "mfxDeviceDescription") {
612 nextProp = GetNextProp(propParsedString);
613 // old version of table in spec had extra "device", just skip if present
614 if (nextProp == "device")
615 nextProp = GetNextProp(propParsedString);
617 // special case - deviceID may be passed as U16 (default) or string (since API 2.4)
618 // for compatibility, both are supported (value.Type distinguishes between them)
619 if (nextProp == "DeviceID") {
620 if (value.Type == MFX_VARIANT_TYPE_PTR)
621 return ValidateAndSetProp(ePropDevice_DeviceIDStr, value);
623 return ValidateAndSetProp(ePropDevice_DeviceID, value);
626 if (nextProp == "MediaAdapterType") {
627 return ValidateAndSetProp(ePropDevice_MediaAdapterType, value);
630 return MFX_ERR_NOT_FOUND;
633 // property is a member of mfxDecoderDescription
634 if (nextProp == "mfxDecoderDescription") {
635 return SetFilterPropertyDec(propParsedString, value);
638 if (nextProp == "mfxEncoderDescription") {
639 return SetFilterPropertyEnc(propParsedString, value);
642 if (nextProp == "mfxVPPDescription") {
643 return SetFilterPropertyVPP(propParsedString, value);
646 return MFX_ERR_NOT_FOUND;
649 #define CHECK_IDX(idxA, idxB, numB) \
650 if ((idxB) == (numB)) { \
656 mfxStatus ConfigCtxVPL::GetFlatDescriptionsDec(const mfxImplDescription *libImplDesc,
657 std::list<DecConfig> &decConfigList) {
659 mfxU32 profileIdx = 0;
661 mfxU32 outFmtIdx = 0;
663 DecCodec *decCodec = nullptr;
664 DecProfile *decProfile = nullptr;
665 DecMemDesc *decMemDesc = nullptr;
667 while (codecIdx < libImplDesc->Dec.NumCodecs) {
670 decCodec = &(libImplDesc->Dec.Codecs[codecIdx]);
671 dc.CodecID = decCodec->CodecID;
672 dc.MaxcodecLevel = decCodec->MaxcodecLevel;
673 CHECK_IDX(codecIdx, profileIdx, decCodec->NumProfiles);
675 decProfile = &(decCodec->Profiles[profileIdx]);
676 dc.Profile = decProfile->Profile;
677 CHECK_IDX(profileIdx, memIdx, decProfile->NumMemTypes);
679 decMemDesc = &(decProfile->MemDesc[memIdx]);
680 dc.MemHandleType = decMemDesc->MemHandleType;
681 dc.Width = decMemDesc->Width;
682 dc.Height = decMemDesc->Height;
683 CHECK_IDX(memIdx, outFmtIdx, decMemDesc->NumColorFormats);
685 dc.ColorFormat = decMemDesc->ColorFormats[outFmtIdx];
688 // we have a valid, unique description - add to list
689 decConfigList.push_back(dc);
692 if (decConfigList.empty())
693 return MFX_ERR_INVALID_VIDEO_PARAM;
698 mfxStatus ConfigCtxVPL::GetFlatDescriptionsEnc(const mfxImplDescription *libImplDesc,
699 std::list<EncConfig> &encConfigList) {
701 mfxU32 profileIdx = 0;
705 EncCodec *encCodec = nullptr;
706 EncProfile *encProfile = nullptr;
707 EncMemDesc *encMemDesc = nullptr;
709 #ifdef ONEVPL_EXPERIMENTAL
710 // ReportedStats was added with API 2.7 under ONEVPL_EXPERIMENTAL.
711 // When it is promoted to production API, MFX_ENCODERDESCRIPTION_VERSION should be bumped up
712 // and we should check mfxEncoderDescription.Version instead to know whether ReportedStats
713 // is a valid field (taken from reserved[] space).
714 // Until then, best we can do is to check the overall API version for this impl.
715 mfxVersion reqApiVersionReportedStats = {};
716 reqApiVersionReportedStats.Major = 2;
717 reqApiVersionReportedStats.Minor = 7;
720 while (codecIdx < libImplDesc->Enc.NumCodecs) {
723 encCodec = &(libImplDesc->Enc.Codecs[codecIdx]);
724 ec.CodecID = encCodec->CodecID;
725 ec.MaxcodecLevel = encCodec->MaxcodecLevel;
726 ec.BiDirectionalPrediction = encCodec->BiDirectionalPrediction;
728 #ifdef ONEVPL_EXPERIMENTAL
729 // see comment above about checking mfxEncoderDescription version once this is moved out
730 // of experimental API
731 if (libImplDesc->ApiVersion.Version >= reqApiVersionReportedStats.Version)
732 ec.ReportedStats = encCodec->ReportedStats;
735 CHECK_IDX(codecIdx, profileIdx, encCodec->NumProfiles);
737 encProfile = &(encCodec->Profiles[profileIdx]);
738 ec.Profile = encProfile->Profile;
739 CHECK_IDX(profileIdx, memIdx, encProfile->NumMemTypes);
741 encMemDesc = &(encProfile->MemDesc[memIdx]);
742 ec.MemHandleType = encMemDesc->MemHandleType;
743 ec.Width = encMemDesc->Width;
744 ec.Height = encMemDesc->Height;
745 CHECK_IDX(memIdx, inFmtIdx, encMemDesc->NumColorFormats);
747 ec.ColorFormat = encMemDesc->ColorFormats[inFmtIdx];
750 // we have a valid, unique description - add to list
751 encConfigList.push_back(ec);
754 if (encConfigList.empty())
755 return MFX_ERR_INVALID_VIDEO_PARAM;
760 mfxStatus ConfigCtxVPL::GetFlatDescriptionsVPP(const mfxImplDescription *libImplDesc,
761 std::list<VPPConfig> &vppConfigList) {
762 mfxU32 filterIdx = 0;
765 mfxU32 outFmtIdx = 0;
767 VPPFilter *vppFilter = nullptr;
768 VPPMemDesc *vppMemDesc = nullptr;
769 VPPFormat *vppFormat = nullptr;
771 while (filterIdx < libImplDesc->VPP.NumFilters) {
774 vppFilter = &(libImplDesc->VPP.Filters[filterIdx]);
775 vc.FilterFourCC = vppFilter->FilterFourCC;
776 vc.MaxDelayInFrames = vppFilter->MaxDelayInFrames;
777 CHECK_IDX(filterIdx, memIdx, vppFilter->NumMemTypes);
779 vppMemDesc = &(vppFilter->MemDesc[memIdx]);
780 vc.MemHandleType = vppMemDesc->MemHandleType;
781 vc.Width = vppMemDesc->Width;
782 vc.Height = vppMemDesc->Height;
783 CHECK_IDX(memIdx, inFmtIdx, vppMemDesc->NumInFormats);
785 vppFormat = &(vppMemDesc->Formats[inFmtIdx]);
786 vc.InFormat = vppFormat->InFormat;
787 CHECK_IDX(inFmtIdx, outFmtIdx, vppFormat->NumOutFormat);
789 vc.OutFormat = vppFormat->OutFormats[outFmtIdx];
792 // we have a valid, unique description - add to list
793 vppConfigList.push_back(vc);
796 if (vppConfigList.empty())
797 return MFX_ERR_INVALID_VIDEO_PARAM;
802 #define CHECK_PROP(idx, type, val) \
803 if ((cfgPropsAll[(idx)].Type != MFX_VARIANT_TYPE_UNSET) && \
804 (cfgPropsAll[(idx)].Data.type != val)) \
805 isCompatible = false;
807 mfxStatus ConfigCtxVPL::CheckPropsGeneral(const mfxVariant cfgPropsAll[],
808 const mfxImplDescription *libImplDesc) {
809 bool isCompatible = true;
811 // check if this implementation includes
812 // all of the required top-level properties
813 CHECK_PROP(ePropMain_Impl, U32, libImplDesc->Impl);
814 CHECK_PROP(ePropMain_VendorID, U32, libImplDesc->VendorID);
815 CHECK_PROP(ePropMain_VendorImplID, U32, libImplDesc->VendorImplID);
817 // check API version in calling function since major and minor may be passed
818 // in separate cfg objects
820 if (libImplDesc->AccelerationModeDescription.NumAccelerationModes > 0) {
821 if (cfgPropsAll[ePropMain_AccelerationMode].Type != MFX_VARIANT_TYPE_UNSET) {
822 // check all supported modes if list is filled out
823 mfxU16 numModes = libImplDesc->AccelerationModeDescription.NumAccelerationModes;
824 mfxAccelerationMode modeRequested =
825 (mfxAccelerationMode)(cfgPropsAll[ePropMain_AccelerationMode].Data.U32);
826 auto *modeTab = libImplDesc->AccelerationModeDescription.Mode;
828 auto *m = std::find(modeTab, modeTab + numModes, modeRequested);
829 if (m == modeTab + numModes)
830 isCompatible = false;
834 // check default mode
835 CHECK_PROP(ePropMain_AccelerationMode, U32, libImplDesc->AccelerationMode);
838 if (cfgPropsAll[ePropMain_PoolAllocationPolicy].Type != MFX_VARIANT_TYPE_UNSET) {
839 // mfxPoolAllocationPolicy added with struct version 1.2
840 mfxU16 numPolicies = 0;
841 if (libImplDesc->Version.Version >= MFX_STRUCT_VERSION(1, 2))
842 numPolicies = libImplDesc->PoolPolicies.NumPoolPolicies;
844 // check all supported policies if list is filled out
845 // if structure is not present (old version) numPolicies will be 0, so skipped
846 if (isCompatible == true && numPolicies > 0) {
847 mfxPoolAllocationPolicy policyRequested =
848 (mfxPoolAllocationPolicy)(cfgPropsAll[ePropMain_PoolAllocationPolicy].Data.U32);
849 auto *policyTab = libImplDesc->PoolPolicies.Policy;
851 auto *m = std::find(policyTab, policyTab + numPolicies, policyRequested);
852 if (m == policyTab + numPolicies)
853 isCompatible = false;
856 isCompatible = false;
860 // check string: ImplName (string match)
861 if (cfgPropsAll[ePropMain_ImplName].Type != MFX_VARIANT_TYPE_UNSET) {
862 std::string filtName = *(std::string *)(cfgPropsAll[ePropMain_ImplName].Data.Ptr);
863 std::string implName = libImplDesc->ImplName;
864 if (filtName != implName)
865 isCompatible = false;
868 // check string: License (tokenized)
869 if (cfgPropsAll[ePropMain_License].Type != MFX_VARIANT_TYPE_UNSET) {
870 std::string license = *(std::string *)(cfgPropsAll[ePropMain_License].Data.Ptr);
871 if (CheckPropString(libImplDesc->License, license) != MFX_ERR_NONE)
872 isCompatible = false;
875 // check string: Keywords (tokenized)
876 if (cfgPropsAll[ePropMain_Keywords].Type != MFX_VARIANT_TYPE_UNSET) {
877 std::string keywords = *(std::string *)(cfgPropsAll[ePropMain_Keywords].Data.Ptr);
878 if (CheckPropString(libImplDesc->Keywords, keywords) != MFX_ERR_NONE)
879 isCompatible = false;
882 // check DeviceID - stored as char*, but passed in for filtering as U16
883 // convert both to unsigned ints and compare
884 if (cfgPropsAll[ePropDevice_DeviceID].Type != MFX_VARIANT_TYPE_UNSET) {
885 unsigned int implDeviceID = 0;
887 implDeviceID = std::stoi(libImplDesc->Dev.DeviceID, 0, 16);
890 return MFX_ERR_UNSUPPORTED;
893 unsigned int filtDeviceID = (unsigned int)(cfgPropsAll[ePropDevice_DeviceID].Data.U16);
894 if (implDeviceID != filtDeviceID)
895 isCompatible = false;
898 if (cfgPropsAll[ePropDevice_DeviceIDStr].Type != MFX_VARIANT_TYPE_UNSET) {
899 // since API 2.4 - pass DeviceID as string (do string match)
900 std::string filtDeviceID = *(std::string *)(cfgPropsAll[ePropDevice_DeviceIDStr].Data.Ptr);
901 std::string implDeviceID = libImplDesc->Dev.DeviceID;
902 if (filtDeviceID != implDeviceID)
903 isCompatible = false;
906 // mfxDeviceDescription.MediaAdapterType introduced in API 2.5, structure version 1.1
907 // do not check this for MSDK libs (allow it to pass)
908 if (libImplDesc->ApiVersion.Major >= 2) {
909 if (cfgPropsAll[ePropDevice_MediaAdapterType].Type != MFX_VARIANT_TYPE_UNSET) {
910 if (libImplDesc->Dev.Version.Version < MFX_STRUCT_VERSION(1, 1))
911 isCompatible = false;
913 CHECK_PROP(ePropDevice_MediaAdapterType, U16, libImplDesc->Dev.MediaAdapterType);
917 if (isCompatible == true)
920 return MFX_ERR_UNSUPPORTED;
923 mfxStatus ConfigCtxVPL::CheckPropsDec(const mfxVariant cfgPropsAll[],
924 std::list<DecConfig> decConfigList) {
925 auto it = decConfigList.begin();
926 while (it != decConfigList.end()) {
927 DecConfig dc = (DecConfig)(*it);
928 bool isCompatible = true;
930 // check if this decode description includes
931 // all of the required decoder properties
932 CHECK_PROP(ePropDec_CodecID, U32, dc.CodecID);
933 CHECK_PROP(ePropDec_MaxcodecLevel, U16, dc.MaxcodecLevel);
934 CHECK_PROP(ePropDec_Profile, U32, dc.Profile);
935 CHECK_PROP(ePropDec_MemHandleType, U32, dc.MemHandleType);
936 CHECK_PROP(ePropDec_ColorFormats, U32, dc.ColorFormat);
938 // special handling for properties passed via pointer
939 if (cfgPropsAll[ePropDec_Width].Type != MFX_VARIANT_TYPE_UNSET) {
940 mfxRange32U width = {};
941 if (cfgPropsAll[ePropDec_Width].Data.Ptr)
942 width = *((mfxRange32U *)(cfgPropsAll[ePropDec_Width].Data.Ptr));
944 if ((width.Max > dc.Width.Max) || (width.Min < dc.Width.Min) ||
945 (width.Step < dc.Width.Step))
946 isCompatible = false;
949 if (cfgPropsAll[ePropDec_Height].Type != MFX_VARIANT_TYPE_UNSET) {
950 mfxRange32U height = {};
951 if (cfgPropsAll[ePropDec_Height].Data.Ptr)
952 height = *((mfxRange32U *)(cfgPropsAll[ePropDec_Height].Data.Ptr));
954 if ((height.Max > dc.Height.Max) || (height.Min < dc.Height.Min) ||
955 (height.Step < dc.Height.Step))
956 isCompatible = false;
959 if (isCompatible == true)
965 return MFX_ERR_UNSUPPORTED;
968 mfxStatus ConfigCtxVPL::CheckPropsEnc(const mfxVariant cfgPropsAll[],
969 std::list<EncConfig> encConfigList) {
970 auto it = encConfigList.begin();
971 while (it != encConfigList.end()) {
972 EncConfig ec = (EncConfig)(*it);
973 bool isCompatible = true;
975 // check if this encode description includes
976 // all of the required encoder properties
977 CHECK_PROP(ePropEnc_CodecID, U32, ec.CodecID);
978 CHECK_PROP(ePropEnc_MaxcodecLevel, U16, ec.MaxcodecLevel);
979 CHECK_PROP(ePropEnc_BiDirectionalPrediction, U16, ec.BiDirectionalPrediction);
980 CHECK_PROP(ePropEnc_Profile, U32, ec.Profile);
981 CHECK_PROP(ePropEnc_MemHandleType, U32, ec.MemHandleType);
982 CHECK_PROP(ePropEnc_ColorFormats, U32, ec.ColorFormat);
984 // special handling for properties passed via pointer
985 if (cfgPropsAll[ePropEnc_Width].Type != MFX_VARIANT_TYPE_UNSET) {
986 mfxRange32U width = {};
987 if (cfgPropsAll[ePropEnc_Width].Data.Ptr)
988 width = *((mfxRange32U *)(cfgPropsAll[ePropEnc_Width].Data.Ptr));
990 if ((width.Max > ec.Width.Max) || (width.Min < ec.Width.Min) ||
991 (width.Step < ec.Width.Step))
992 isCompatible = false;
995 if (cfgPropsAll[ePropEnc_Height].Type != MFX_VARIANT_TYPE_UNSET) {
996 mfxRange32U height = {};
997 if (cfgPropsAll[ePropEnc_Height].Data.Ptr)
998 height = *((mfxRange32U *)(cfgPropsAll[ePropEnc_Height].Data.Ptr));
1000 if ((height.Max > ec.Height.Max) || (height.Min < ec.Height.Min) ||
1001 (height.Step < ec.Height.Step))
1002 isCompatible = false;
1005 if (cfgPropsAll[ePropEnc_ReportedStats].Type != MFX_VARIANT_TYPE_UNSET) {
1006 mfxU16 requestedStats = cfgPropsAll[ePropEnc_ReportedStats].Data.U16;
1008 // ReportedStats is a logical OR of one or more flags: MFX_ENCODESTATS_LEVEL_xxx
1009 if ((requestedStats & ec.ReportedStats) != requestedStats)
1010 isCompatible = false;
1013 if (isCompatible == true)
1014 return MFX_ERR_NONE;
1019 return MFX_ERR_UNSUPPORTED;
1022 mfxStatus ConfigCtxVPL::CheckPropsVPP(const mfxVariant cfgPropsAll[],
1023 std::list<VPPConfig> vppConfigList) {
1024 auto it = vppConfigList.begin();
1025 while (it != vppConfigList.end()) {
1026 VPPConfig vc = (VPPConfig)(*it);
1027 bool isCompatible = true;
1029 // check if this filter description includes
1030 // all of the required VPP properties
1031 CHECK_PROP(ePropVPP_FilterFourCC, U32, vc.FilterFourCC);
1032 CHECK_PROP(ePropVPP_MaxDelayInFrames, U16, vc.MaxDelayInFrames);
1033 CHECK_PROP(ePropVPP_MemHandleType, U32, vc.MemHandleType);
1034 CHECK_PROP(ePropVPP_InFormat, U32, vc.InFormat);
1035 CHECK_PROP(ePropVPP_OutFormat, U32, vc.OutFormat);
1037 // special handling for properties passed via pointer
1038 if (cfgPropsAll[ePropVPP_Width].Type != MFX_VARIANT_TYPE_UNSET) {
1039 mfxRange32U width = {};
1040 if (cfgPropsAll[ePropVPP_Width].Data.Ptr)
1041 width = *((mfxRange32U *)(cfgPropsAll[ePropVPP_Width].Data.Ptr));
1043 if ((width.Max > vc.Width.Max) || (width.Min < vc.Width.Min) ||
1044 (width.Step < vc.Width.Step))
1045 isCompatible = false;
1048 if (cfgPropsAll[ePropVPP_Height].Type != MFX_VARIANT_TYPE_UNSET) {
1049 mfxRange32U height = {};
1050 if (cfgPropsAll[ePropVPP_Height].Data.Ptr)
1051 height = *((mfxRange32U *)(cfgPropsAll[ePropVPP_Height].Data.Ptr));
1053 if ((height.Max > vc.Height.Max) || (height.Min < vc.Height.Min) ||
1054 (height.Step < vc.Height.Step))
1055 isCompatible = false;
1058 if (isCompatible == true)
1059 return MFX_ERR_NONE;
1064 return MFX_ERR_UNSUPPORTED;
1067 #ifdef ONEVPL_EXPERIMENTAL
1068 mfxStatus ConfigCtxVPL::CheckPropsExtDevID(const mfxVariant cfgPropsAll[],
1069 const mfxExtendedDeviceId *libImplExtDevID) {
1070 bool isCompatible = true;
1072 // check if this implementation includes
1073 // all of the required extended device ID properties
1074 CHECK_PROP(ePropExtDev_VendorID, U16, libImplExtDevID->VendorID);
1075 CHECK_PROP(ePropExtDev_DeviceID, U16, libImplExtDevID->DeviceID);
1077 CHECK_PROP(ePropExtDev_PCIDomain, U32, libImplExtDevID->PCIDomain);
1078 CHECK_PROP(ePropExtDev_PCIBus, U32, libImplExtDevID->PCIBus);
1079 CHECK_PROP(ePropExtDev_PCIDevice, U32, libImplExtDevID->PCIDevice);
1080 CHECK_PROP(ePropExtDev_PCIFunction, U32, libImplExtDevID->PCIFunction);
1082 // check DeviceLUID, require LUIDValid == true
1083 if (cfgPropsAll[ePropExtDev_DeviceLUID].Type != MFX_VARIANT_TYPE_UNSET) {
1084 // LUID filter is passed as ptr to 8-byte array, which was saved in local copy
1085 mfxU8 *pU8 = (mfxU8 *)(cfgPropsAll[ePropExtDev_DeviceLUID].Data.Ptr);
1086 if (libImplExtDevID->LUIDValid) {
1087 for (mfxU32 j = 0; j < 8; j++) {
1088 if (pU8[j] != libImplExtDevID->DeviceLUID[j])
1089 isCompatible = false;
1093 isCompatible = false;
1097 // check LUIDDeviceNodeMask, require LUIDValid == true
1098 if (cfgPropsAll[ePropExtDev_LUIDDeviceNodeMask].Type != MFX_VARIANT_TYPE_UNSET) {
1099 if (libImplExtDevID->LUIDValid) {
1100 CHECK_PROP(ePropExtDev_LUIDDeviceNodeMask, U32, libImplExtDevID->LUIDDeviceNodeMask);
1103 isCompatible = false;
1107 // check DRMRenderNodeNum
1108 if (cfgPropsAll[ePropExtDev_DRMRenderNodeNum].Type != MFX_VARIANT_TYPE_UNSET) {
1109 if (libImplExtDevID->DRMRenderNodeNum != 0) {
1110 CHECK_PROP(ePropExtDev_DRMRenderNodeNum, U32, libImplExtDevID->DRMRenderNodeNum);
1113 isCompatible = false;
1117 // check DRMPrimaryNodeNum
1118 if (cfgPropsAll[ePropExtDev_DRMPrimaryNodeNum].Type != MFX_VARIANT_TYPE_UNSET) {
1119 if (libImplExtDevID->DRMRenderNodeNum != 0x7FFFFFFF) {
1120 CHECK_PROP(ePropExtDev_DRMPrimaryNodeNum, U32, libImplExtDevID->DRMPrimaryNodeNum);
1123 isCompatible = false;
1127 // check string: DeviceName (string match)
1128 if (cfgPropsAll[ePropExtDev_DeviceName].Type != MFX_VARIANT_TYPE_UNSET) {
1129 std::string filtName = *(std::string *)(cfgPropsAll[ePropExtDev_DeviceName].Data.Ptr);
1130 std::string implName = libImplExtDevID->DeviceName;
1131 if (filtName != implName)
1132 isCompatible = false;
1135 if (isCompatible == true)
1136 return MFX_ERR_NONE;
1138 return MFX_ERR_UNSUPPORTED;
1142 // implString = string from implDesc - one or more comma-separated tokens
1143 // filtString = string user is looking for - one or more comma-separated tokens
1144 // we parse filtString into tokens, then check if all of them are present in implString
1145 mfxStatus ConfigCtxVPL::CheckPropString(const mfxChar *implString, const std::string filtString) {
1146 std::list<std::string> tokenString;
1149 // parse implString string into tokens, separated by ','
1150 std::stringstream implSS((char *)implString);
1151 while (getline(implSS, s, ',')) {
1152 tokenString.push_back(s);
1155 // parse filtString string into tokens, separated by ','
1156 // check that each token is present in implString, otherwise return error
1157 std::stringstream filtSS(filtString);
1158 while (getline(filtSS, s, ',')) {
1159 if (std::find(tokenString.begin(), tokenString.end(), s) == tokenString.end())
1160 return MFX_ERR_UNSUPPORTED;
1163 return MFX_ERR_NONE;
1166 mfxStatus ConfigCtxVPL::ValidateConfig(const mfxImplDescription *libImplDesc,
1167 const mfxImplementedFunctions *libImplFuncs,
1168 #ifdef ONEVPL_EXPERIMENTAL
1169 const mfxExtendedDeviceId *libImplExtDevID,
1171 std::list<ConfigCtxVPL *> configCtxList,
1173 SpecialConfig *specialConfig) {
1175 bool decRequested = false;
1176 bool encRequested = false;
1177 bool vppRequested = false;
1178 bool extDevRequested = false;
1180 bool bImplValid = true;
1183 return MFX_ERR_NULL_PTR;
1185 std::list<DecConfig> decConfigList;
1186 std::list<EncConfig> encConfigList;
1187 std::list<VPPConfig> vppConfigList;
1189 // generate "flat" descriptions of each combination
1190 // (e.g. multiple profiles from the same codec)
1191 GetFlatDescriptionsDec(libImplDesc, decConfigList);
1192 GetFlatDescriptionsEnc(libImplDesc, encConfigList);
1193 GetFlatDescriptionsVPP(libImplDesc, vppConfigList);
1195 // list of functions required to be implemented
1196 std::list<std::string> implFunctionList;
1197 implFunctionList.clear();
1199 // check requested API version
1200 mfxVersion reqVersion = {};
1201 bool bVerSetMajor = false;
1202 bool bVerSetMinor = false;
1204 // clear list of extension buffers
1205 specialConfig->bIsSet_ExtBuffer = false;
1206 specialConfig->ExtBuffers.clear();
1208 // iterate through all filters and populate cfgPropsAll
1209 auto it = configCtxList.begin();
1211 while (it != configCtxList.end()) {
1212 ConfigCtxVPL *config = (*it);
1215 // initially all properties are unset
1216 mfxVariant cfgPropsAll[eProp_TotalProps] = {};
1217 for (idx = 0; idx < eProp_TotalProps; idx++) {
1218 cfgPropsAll[idx].Type = MFX_VARIANT_TYPE_UNSET;
1221 for (idx = 0; idx < eProp_TotalProps; idx++) {
1222 // ignore unset properties
1223 if (config->m_propVar[idx].Type == MFX_VARIANT_TYPE_UNSET)
1226 // if property is required function, add to list which will be checked below
1227 if (idx == ePropFunc_FunctionName) {
1228 implFunctionList.push_back(config->m_implFunctionName);
1232 cfgPropsAll[idx].Type = config->m_propVar[idx].Type;
1233 cfgPropsAll[idx].Data = config->m_propVar[idx].Data;
1235 if (idx >= ePropDec_CodecID && idx <= ePropDec_ColorFormats)
1236 decRequested = true;
1237 else if (idx >= ePropEnc_CodecID && idx <= ePropEnc_ColorFormats)
1238 encRequested = true;
1239 else if (idx >= ePropVPP_FilterFourCC && idx <= ePropVPP_OutFormat)
1240 vppRequested = true;
1241 else if (idx >= ePropExtDev_VendorID && idx <= ePropExtDev_DeviceName)
1242 extDevRequested = true;
1245 // if already marked invalid, no need to check props again
1246 // however we still need to iterate over all of the config objects
1247 // to get any non-filtering properties (returned in SpecialConfig)
1248 if (bImplValid == true) {
1249 if (CheckPropsGeneral(cfgPropsAll, libImplDesc))
1252 #ifdef ONEVPL_EXPERIMENTAL
1253 if (extDevRequested) {
1254 // fail if extDevID is not available (null) or if prop is not supported
1255 if (!libImplExtDevID || CheckPropsExtDevID(cfgPropsAll, libImplExtDevID))
1259 if (extDevRequested)
1263 // MSDK RT compatibility mode (1.x) does not provide Dec/Enc/VPP caps
1264 // ignore these filters if set (do not use them to _exclude_ the library)
1265 if (libType != LibTypeMSDK) {
1266 if (decRequested && CheckPropsDec(cfgPropsAll, decConfigList))
1269 if (encRequested && CheckPropsEnc(cfgPropsAll, encConfigList))
1272 if (vppRequested && CheckPropsVPP(cfgPropsAll, vppConfigList))
1277 // update any special (including non-filtering) properties, for use by caller
1278 // if multiple cfg objects set the same non-filtering property, the last (most recent) one is used
1279 if (cfgPropsAll[ePropSpecial_HandleType].Type != MFX_VARIANT_TYPE_UNSET) {
1280 specialConfig->deviceHandleType =
1281 (mfxHandleType)cfgPropsAll[ePropSpecial_HandleType].Data.U32;
1282 specialConfig->bIsSet_deviceHandleType = true;
1285 if (cfgPropsAll[ePropSpecial_Handle].Type != MFX_VARIANT_TYPE_UNSET) {
1286 specialConfig->deviceHandle = (mfxHDL)cfgPropsAll[ePropSpecial_Handle].Data.Ptr;
1287 specialConfig->bIsSet_deviceHandle = true;
1290 if (cfgPropsAll[ePropSpecial_NumThread].Type != MFX_VARIANT_TYPE_UNSET) {
1291 specialConfig->NumThread = cfgPropsAll[ePropSpecial_NumThread].Data.U32;
1292 specialConfig->bIsSet_NumThread = true;
1295 if (cfgPropsAll[ePropSpecial_DeviceCopy].Type != MFX_VARIANT_TYPE_UNSET) {
1296 specialConfig->DeviceCopy = cfgPropsAll[ePropSpecial_DeviceCopy].Data.U16;
1297 specialConfig->bIsSet_DeviceCopy = true;
1300 if (cfgPropsAll[ePropSpecial_DXGIAdapterIndex].Type != MFX_VARIANT_TYPE_UNSET) {
1301 specialConfig->dxgiAdapterIdx =
1302 (mfxU32)cfgPropsAll[ePropSpecial_DXGIAdapterIndex].Data.U32;
1303 specialConfig->bIsSet_dxgiAdapterIdx = true;
1306 if (cfgPropsAll[ePropMain_AccelerationMode].Type != MFX_VARIANT_TYPE_UNSET) {
1307 specialConfig->accelerationMode =
1308 (mfxAccelerationMode)cfgPropsAll[ePropMain_AccelerationMode].Data.U32;
1309 specialConfig->bIsSet_accelerationMode = true;
1312 if (cfgPropsAll[ePropSpecial_ExtBuffer].Type != MFX_VARIANT_TYPE_UNSET) {
1313 specialConfig->ExtBuffers.push_back(
1314 (mfxExtBuffer *)cfgPropsAll[ePropSpecial_ExtBuffer].Data.Ptr);
1315 specialConfig->bIsSet_ExtBuffer = true;
1318 // special handling for API version which may be passed either as single U32 (Version)
1319 // or two U16 (Major, Minor) which could come in separate cfg objects
1320 if (cfgPropsAll[ePropMain_ApiVersion].Type != MFX_VARIANT_TYPE_UNSET) {
1321 reqVersion.Version = (mfxU32)cfgPropsAll[ePropMain_ApiVersion].Data.U32;
1322 bVerSetMajor = true;
1323 bVerSetMinor = true;
1326 if (cfgPropsAll[ePropMain_ApiVersion_Major].Type != MFX_VARIANT_TYPE_UNSET) {
1327 reqVersion.Major = (mfxU32)cfgPropsAll[ePropMain_ApiVersion_Major].Data.U16;
1328 bVerSetMajor = true;
1331 if (cfgPropsAll[ePropMain_ApiVersion_Minor].Type != MFX_VARIANT_TYPE_UNSET) {
1332 reqVersion.Minor = (mfxU32)cfgPropsAll[ePropMain_ApiVersion_Minor].Data.U16;
1333 bVerSetMinor = true;
1338 if (bVerSetMajor && bVerSetMinor) {
1339 // require both Major and Minor to be set if filtering this way
1340 if (libImplDesc->ApiVersion.Version < reqVersion.Version)
1343 specialConfig->ApiVersion.Version = reqVersion.Version;
1344 specialConfig->bIsSet_ApiVersion = true;
1347 if (bImplValid == false)
1348 return MFX_ERR_UNSUPPORTED;
1350 // check whether required functions are implemented
1351 if (!implFunctionList.empty()) {
1352 if (!libImplFuncs) {
1353 // library did not provide list of implemented functions
1354 return MFX_ERR_UNSUPPORTED;
1357 auto fn = implFunctionList.begin();
1358 while (fn != implFunctionList.end()) {
1359 std::string fnName = (*fn++);
1362 // search for fnName in list of implemented functions
1363 for (fnIdx = 0; fnIdx < libImplFuncs->NumFunctions; fnIdx++) {
1364 if (fnName == libImplFuncs->FunctionsName[fnIdx])
1368 if (fnIdx == libImplFuncs->NumFunctions)
1369 return MFX_ERR_UNSUPPORTED;
1373 return MFX_ERR_NONE;
1376 bool ConfigCtxVPL::CheckLowLatencyConfig(std::list<ConfigCtxVPL *> configCtxList,
1377 SpecialConfig *specialConfig) {
1379 bool bLowLatency = true;
1381 // initially all properties are unset
1382 mfxVariant cfgPropsAll[eProp_TotalProps] = {};
1383 for (idx = 0; idx < eProp_TotalProps; idx++)
1384 cfgPropsAll[idx].Type = MFX_VARIANT_TYPE_UNSET;
1386 // iterate through all filters and populate cfgPropsAll
1387 // for purposes of low-latency enabling, we check the last (most recent) value of each filter
1388 // property, in the case that multiple mfxConfig objects were created
1389 // preferred usage is just to create one mfxConfig and set all of the required props in it
1390 // Exception: there can be more than one ExtBuffer attached via multiple mfxConfig objects (API >= 2.7)
1392 // clear list of extension buffers
1393 specialConfig->bIsSet_ExtBuffer = false;
1394 specialConfig->ExtBuffers.clear();
1396 auto it = configCtxList.begin();
1397 while (it != configCtxList.end()) {
1398 ConfigCtxVPL *config = (*it);
1401 for (idx = 0; idx < eProp_TotalProps; idx++) {
1402 // ignore unset properties
1403 if (config->m_propVar[idx].Type == MFX_VARIANT_TYPE_UNSET)
1406 cfgPropsAll[idx].Type = config->m_propVar[idx].Type;
1407 cfgPropsAll[idx].Data = config->m_propVar[idx].Data;
1409 if (idx == ePropSpecial_ExtBuffer) {
1410 specialConfig->ExtBuffers.push_back(
1411 (mfxExtBuffer *)cfgPropsAll[ePropSpecial_ExtBuffer].Data.Ptr);
1412 specialConfig->bIsSet_ExtBuffer = true;
1417 for (mfxU32 idx = 0; idx < eProp_TotalProps; idx++) {
1419 case ePropMain_Impl:
1420 if (cfgPropsAll[idx].Type == MFX_VARIANT_TYPE_U32) {
1421 if (cfgPropsAll[idx].Data.U32 == MFX_IMPL_TYPE_HARDWARE)
1424 bLowLatency = false;
1427 case ePropMain_ImplName:
1428 if (cfgPropsAll[idx].Type == MFX_VARIANT_TYPE_PTR && cfgPropsAll[idx].Data.Ptr) {
1429 std::string s = *(std::string *)(cfgPropsAll[idx].Data.Ptr);
1433 bLowLatency = false;
1436 case ePropMain_VendorID:
1437 if (cfgPropsAll[idx].Type == MFX_VARIANT_TYPE_U32) {
1438 if (cfgPropsAll[idx].Data.U32 == 0x8086)
1441 bLowLatency = false;
1444 // application must set AccelerationMode for lowlatency - will be passed to RT in MFXInitialize()
1445 case ePropMain_AccelerationMode:
1446 if (cfgPropsAll[idx].Type == MFX_VARIANT_TYPE_U32) {
1447 specialConfig->accelerationMode =
1448 (mfxAccelerationMode)cfgPropsAll[ePropMain_AccelerationMode].Data.U32;
1449 specialConfig->bIsSet_accelerationMode = true;
1452 bLowLatency = false;
1455 // application may set ApiVersion with lowlatency, but not required
1456 case ePropMain_ApiVersion:
1457 if (cfgPropsAll[ePropMain_ApiVersion].Type != MFX_VARIANT_TYPE_UNSET) {
1458 specialConfig->ApiVersion.Version =
1459 (mfxU32)cfgPropsAll[ePropMain_ApiVersion].Data.U32;
1460 specialConfig->bIsSet_ApiVersion = true;
1464 // following are non-filtering properties - they may be set here or not (don't affect low latency)
1465 case ePropSpecial_HandleType:
1466 if (cfgPropsAll[ePropSpecial_HandleType].Type != MFX_VARIANT_TYPE_UNSET) {
1467 specialConfig->deviceHandleType =
1468 (mfxHandleType)cfgPropsAll[ePropSpecial_HandleType].Data.U32;
1469 specialConfig->bIsSet_deviceHandleType = true;
1473 case ePropSpecial_Handle:
1474 if (cfgPropsAll[ePropSpecial_Handle].Type != MFX_VARIANT_TYPE_UNSET) {
1475 specialConfig->deviceHandle = (mfxHDL)cfgPropsAll[ePropSpecial_Handle].Data.Ptr;
1476 specialConfig->bIsSet_deviceHandle = true;
1480 case ePropSpecial_NumThread:
1481 if (cfgPropsAll[ePropSpecial_NumThread].Type != MFX_VARIANT_TYPE_UNSET) {
1482 specialConfig->NumThread = cfgPropsAll[ePropSpecial_NumThread].Data.U32;
1483 specialConfig->bIsSet_NumThread = true;
1487 case ePropSpecial_DeviceCopy:
1488 if (cfgPropsAll[ePropSpecial_DeviceCopy].Type != MFX_VARIANT_TYPE_UNSET) {
1489 specialConfig->DeviceCopy = cfgPropsAll[ePropSpecial_DeviceCopy].Data.U16;
1490 specialConfig->bIsSet_DeviceCopy = true;
1494 case ePropSpecial_ExtBuffer:
1495 // extBufs were already pushed into the overall list, above
1498 // will be passed to RT in MFXInitialize(), if unset will be 0
1499 case ePropSpecial_DXGIAdapterIndex:
1500 if (cfgPropsAll[idx].Type == MFX_VARIANT_TYPE_U32) {
1501 specialConfig->dxgiAdapterIdx =
1502 (mfxU32)cfgPropsAll[ePropSpecial_DXGIAdapterIndex].Data.U32;
1503 specialConfig->bIsSet_dxgiAdapterIdx = true;
1509 if (cfgPropsAll[idx].Type != MFX_VARIANT_TYPE_UNSET)
1510 bLowLatency = false;
1518 bool ConfigCtxVPL::ParseDeviceIDx86(mfxChar *cDeviceID, mfxU32 &deviceID, mfxU32 &adapterIdx) {
1519 std::string strDevID(cDeviceID);
1520 std::regex reDevIDAll("[0-9a-fA-F]+/[0-9]+");
1521 std::regex reDevIDMin("[0-9a-fA-F]+");
1523 deviceID = DEVICE_ID_UNKNOWN;
1524 adapterIdx = ADAPTER_IDX_UNKNOWN;
1526 bool bHasAdapterIdx = false;
1527 if (std::regex_match(strDevID, reDevIDAll)) {
1528 // check for DeviceID in format "devID/adapterIdx"
1529 // devID = hex value
1530 // adapterIdx = decimal integer
1531 bHasAdapterIdx = true;
1533 else if (std::regex_match(strDevID, reDevIDMin)) {
1534 // check for DeviceID in format "devID"
1536 bHasAdapterIdx = false;
1543 // get deviceID (value before the slash, if present)
1545 deviceID = std::stoi(strDevID, 0, 16);
1551 if (bHasAdapterIdx) {
1552 // get adapter index (value after the slash)
1553 size_t idx = strDevID.rfind('/');
1554 if (idx == std::string::npos)
1558 adapterIdx = std::stoi(strDevID.substr(idx + 1));