3 * Copyright (c) 2003-2015 HandBrake Team
4 * This file is part of the HandBrake source code.
5 * Homepage: <http://handbrake.fr/>.
6 * It may be used under the terms of the GNU General Public License v2.
7 * For full terms see the file COPYING file or visit http://www.gnu.org/licenses/gpl-2.0.html
19 #include "qsv_common.h"
20 #include "h264_common.h"
22 // QSV info for each codec
23 static hb_qsv_info_t
*hb_qsv_info_avc
= NULL
;
24 static hb_qsv_info_t
*hb_qsv_info_hevc
= NULL
;
26 static mfxVersion qsv_software_version
= { .Version
= 0, };
27 static mfxVersion qsv_hardware_version
= { .Version
= 0, };
28 // AVC implementations
29 static hb_qsv_info_t qsv_software_info_avc
= { .available
= 0, .codec_id
= MFX_CODEC_AVC
, .implementation
= MFX_IMPL_SOFTWARE
, };
30 static hb_qsv_info_t qsv_hardware_info_avc
= { .available
= 0, .codec_id
= MFX_CODEC_AVC
, .implementation
= MFX_IMPL_HARDWARE_ANY
|MFX_IMPL_VIA_ANY
, };
31 // HEVC implementations
32 static hb_qsv_info_t qsv_software_info_hevc
= { .available
= 0, .codec_id
= MFX_CODEC_HEVC
, .implementation
= MFX_IMPL_SOFTWARE
, };
33 static hb_qsv_info_t qsv_hardware_info_hevc
= { .available
= 0, .codec_id
= MFX_CODEC_HEVC
, .implementation
= MFX_IMPL_HARDWARE_ANY
|MFX_IMPL_VIA_ANY
, };
35 // QSV-supported profile and level lists (not all exposed to the user)
36 static hb_triplet_t hb_qsv_h264_profiles
[] =
38 { "Baseline", "baseline", MFX_PROFILE_AVC_BASELINE
, },
39 { "Main", "main", MFX_PROFILE_AVC_MAIN
, },
40 { "Extended", "extended", MFX_PROFILE_AVC_EXTENDED
, },
41 { "High", "high", MFX_PROFILE_AVC_HIGH
, },
42 { "High 4:2:2", "high422", MFX_PROFILE_AVC_HIGH_422
, },
43 { "Constrained Baseline", "baseline|set1", MFX_PROFILE_AVC_CONSTRAINED_BASELINE
, },
44 { "Constrained High", "high|set4|set5", MFX_PROFILE_AVC_CONSTRAINED_HIGH
, },
45 { "Progressive High", "high|set4", MFX_PROFILE_AVC_PROGRESSIVE_HIGH
, },
48 static hb_triplet_t hb_qsv_h264_levels
[] =
50 { "1.0", "1.0", MFX_LEVEL_AVC_1
, },
51 { "1b", "1b", MFX_LEVEL_AVC_1b
, },
52 { "1.1", "1.1", MFX_LEVEL_AVC_11
, },
53 { "1.2", "1.2", MFX_LEVEL_AVC_12
, },
54 { "1.3", "1.3", MFX_LEVEL_AVC_13
, },
55 { "2.0", "2.0", MFX_LEVEL_AVC_2
, },
56 { "2.1", "2.1", MFX_LEVEL_AVC_21
, },
57 { "2.2", "2.2", MFX_LEVEL_AVC_22
, },
58 { "3.0", "3.0", MFX_LEVEL_AVC_3
, },
59 { "3.1", "3.1", MFX_LEVEL_AVC_31
, },
60 { "3.2", "3.2", MFX_LEVEL_AVC_32
, },
61 { "4.0", "4.0", MFX_LEVEL_AVC_4
, },
62 { "4.1", "4.1", MFX_LEVEL_AVC_41
, },
63 { "4.2", "4.2", MFX_LEVEL_AVC_42
, },
64 { "5.0", "5.0", MFX_LEVEL_AVC_5
, },
65 { "5.1", "5.1", MFX_LEVEL_AVC_51
, },
66 { "5.2", "5.2", MFX_LEVEL_AVC_52
, },
70 // check available Intel Media SDK version against a minimum
71 #define HB_CHECK_MFX_VERSION(MFX_VERSION, MAJOR, MINOR) \
72 (MFX_VERSION.Major == MAJOR && MFX_VERSION.Minor >= MINOR)
75 * Determine the "generation" of QSV hardware based on the CPU microarchitecture.
76 * Anything unknown is assumed to be more recent than the latest known generation.
77 * This avoids having to order the hb_cpu_platform enum depending on QSV hardware.
81 QSV_G0
, // third party hardware
82 QSV_G1
, // Sandy Bridge or equivalent
83 QSV_G2
, // Ivy Bridge or equivalent
84 QSV_G3
, // Haswell or equivalent
85 QSV_G4
, // Broadwell or equivalent
87 static int qsv_hardware_generation(int cpu_platform
)
91 case HB_CPU_PLATFORM_INTEL_BNL
:
93 case HB_CPU_PLATFORM_INTEL_SNB
:
95 case HB_CPU_PLATFORM_INTEL_IVB
:
96 case HB_CPU_PLATFORM_INTEL_SLM
:
97 case HB_CPU_PLATFORM_INTEL_CHT
:
99 case HB_CPU_PLATFORM_INTEL_HSW
:
101 case HB_CPU_PLATFORM_INTEL_BDW
:
108 * Determine whether a given mfxIMPL is hardware-accelerated.
110 static int qsv_implementation_is_hardware(mfxIMPL implementation
)
112 return MFX_IMPL_BASETYPE(implementation
) != MFX_IMPL_SOFTWARE
;
115 int hb_qsv_available()
117 return hb_qsv_video_encoder_is_enabled(HB_VCODEC_QSV_H264
);
120 int hb_qsv_video_encoder_is_enabled(int encoder
)
124 case HB_VCODEC_QSV_H264
:
125 return hb_qsv_info_avc
!= NULL
&& hb_qsv_info_avc
->available
;
131 int hb_qsv_audio_encoder_is_enabled(int encoder
)
140 static void init_video_param(mfxVideoParam
*videoParam
)
142 if (videoParam
== NULL
)
147 memset(videoParam
, 0, sizeof(mfxVideoParam
));
148 videoParam
->mfx
.CodecId
= MFX_CODEC_AVC
;
149 videoParam
->mfx
.CodecLevel
= MFX_LEVEL_UNKNOWN
;
150 videoParam
->mfx
.CodecProfile
= MFX_PROFILE_UNKNOWN
;
151 videoParam
->mfx
.RateControlMethod
= MFX_RATECONTROL_VBR
;
152 videoParam
->mfx
.TargetUsage
= MFX_TARGETUSAGE_BALANCED
;
153 videoParam
->mfx
.TargetKbps
= 5000;
154 videoParam
->mfx
.GopOptFlag
= MFX_GOP_CLOSED
;
155 videoParam
->mfx
.FrameInfo
.FourCC
= MFX_FOURCC_NV12
;
156 videoParam
->mfx
.FrameInfo
.ChromaFormat
= MFX_CHROMAFORMAT_YUV420
;
157 videoParam
->mfx
.FrameInfo
.PicStruct
= MFX_PICSTRUCT_PROGRESSIVE
;
158 videoParam
->mfx
.FrameInfo
.FrameRateExtN
= 25;
159 videoParam
->mfx
.FrameInfo
.FrameRateExtD
= 1;
160 videoParam
->mfx
.FrameInfo
.Width
= 1920;
161 videoParam
->mfx
.FrameInfo
.CropW
= 1920;
162 videoParam
->mfx
.FrameInfo
.AspectRatioW
= 1;
163 videoParam
->mfx
.FrameInfo
.Height
= 1088;
164 videoParam
->mfx
.FrameInfo
.CropH
= 1080;
165 videoParam
->mfx
.FrameInfo
.AspectRatioH
= 1;
166 videoParam
->AsyncDepth
= AV_QSV_ASYNC_DEPTH_DEFAULT
;
167 videoParam
->IOPattern
= MFX_IOPATTERN_IN_SYSTEM_MEMORY
;
170 static void init_ext_video_signal_info(mfxExtVideoSignalInfo
*extVideoSignalInfo
)
172 if (extVideoSignalInfo
== NULL
)
177 memset(extVideoSignalInfo
, 0, sizeof(mfxExtVideoSignalInfo
));
178 extVideoSignalInfo
->Header
.BufferId
= MFX_EXTBUFF_VIDEO_SIGNAL_INFO
;
179 extVideoSignalInfo
->Header
.BufferSz
= sizeof(mfxExtVideoSignalInfo
);
180 extVideoSignalInfo
->VideoFormat
= 5; // undefined
181 extVideoSignalInfo
->VideoFullRange
= 0; // TV range
182 extVideoSignalInfo
->ColourDescriptionPresent
= 0; // don't write to bitstream
183 extVideoSignalInfo
->ColourPrimaries
= 2; // undefined
184 extVideoSignalInfo
->TransferCharacteristics
= 2; // undefined
185 extVideoSignalInfo
->MatrixCoefficients
= 2; // undefined
188 static void init_ext_coding_option(mfxExtCodingOption
*extCodingOption
)
190 if (extCodingOption
== NULL
)
195 memset(extCodingOption
, 0, sizeof(mfxExtCodingOption
));
196 extCodingOption
->Header
.BufferId
= MFX_EXTBUFF_CODING_OPTION
;
197 extCodingOption
->Header
.BufferSz
= sizeof(mfxExtCodingOption
);
198 extCodingOption
->AUDelimiter
= MFX_CODINGOPTION_OFF
;
199 extCodingOption
->PicTimingSEI
= MFX_CODINGOPTION_OFF
;
200 extCodingOption
->CAVLC
= MFX_CODINGOPTION_OFF
;
203 static void init_ext_coding_option2(mfxExtCodingOption2
*extCodingOption2
)
205 if (extCodingOption2
== NULL
)
210 memset(extCodingOption2
, 0, sizeof(mfxExtCodingOption2
));
211 extCodingOption2
->Header
.BufferId
= MFX_EXTBUFF_CODING_OPTION2
;
212 extCodingOption2
->Header
.BufferSz
= sizeof(mfxExtCodingOption2
);
213 extCodingOption2
->MBBRC
= MFX_CODINGOPTION_ON
;
214 extCodingOption2
->ExtBRC
= MFX_CODINGOPTION_ON
;
215 extCodingOption2
->Trellis
= MFX_TRELLIS_I
|MFX_TRELLIS_P
|MFX_TRELLIS_B
;
216 extCodingOption2
->RepeatPPS
= MFX_CODINGOPTION_ON
;
217 extCodingOption2
->BRefType
= MFX_B_REF_PYRAMID
;
218 extCodingOption2
->AdaptiveI
= MFX_CODINGOPTION_ON
;
219 extCodingOption2
->AdaptiveB
= MFX_CODINGOPTION_ON
;
220 extCodingOption2
->LookAheadDS
= MFX_LOOKAHEAD_DS_4x
;
221 extCodingOption2
->NumMbPerSlice
= 2040; // 1920x1088/4
224 static int query_capabilities(mfxSession session
, mfxVersion version
, hb_qsv_info_t
*info
)
227 * MFXVideoENCODE_Query(mfxSession, mfxVideoParam *in, mfxVideoParam *out);
231 * - out has the parameters we want to query set to 1
232 * - out->mfx.CodecId field has to be set (mandatory)
233 * - MFXVideoENCODE_Query should zero out all unsupported parameters
236 * - the paramaters we want to query are set for in
237 * - in ->mfx.CodecId field has to be set (mandatory)
238 * - out->mfx.CodecId field has to be set (mandatory)
239 * - MFXVideoENCODE_Query should sanitize all unsupported parameters
242 hb_list_t
*mfxPluginList
;
243 mfxExtBuffer
*videoExtParam
[1];
244 mfxVideoParam videoParam
, inputParam
;
245 mfxExtCodingOption extCodingOption
;
246 mfxExtCodingOption2 extCodingOption2
;
247 mfxExtVideoSignalInfo extVideoSignalInfo
;
249 /* Reset capabilities before querying */
250 info
->capabilities
= 0;
252 /* Load required MFX plug-ins */
253 if ((mfxPluginList
= hb_qsv_load_plugins(info
, session
, version
)) == NULL
)
255 return 0; // the required plugin(s) couldn't be loaded
259 * First of all, check availability of an encoder for
260 * this combination of a codec ID and implementation.
262 * Note: can error out rather than sanitizing
263 * unsupported codec IDs, so don't log errors.
265 if (HB_CHECK_MFX_VERSION(version
, HB_QSV_MINVERSION_MAJOR
, HB_QSV_MINVERSION_MINOR
))
267 if (info
->implementation
& MFX_IMPL_AUDIO
)
269 /* Not yet supported */
274 init_video_param(&inputParam
);
275 inputParam
.mfx
.CodecId
= info
->codec_id
;
277 memset(&videoParam
, 0, sizeof(mfxVideoParam
));
278 videoParam
.mfx
.CodecId
= inputParam
.mfx
.CodecId
;
280 if (MFXVideoENCODE_Query(session
, &inputParam
, &videoParam
) >= MFX_ERR_NONE
&&
281 videoParam
.mfx
.CodecId
== info
->codec_id
)
284 * MFXVideoENCODE_Query might tell you that an HEVC encoder is
285 * available on Haswell hardware, but it'll fail to initialize.
286 * So check encoder availability with MFXVideoENCODE_Init too.
288 if ((status
= MFXVideoENCODE_Init(session
, &videoParam
)) >= MFX_ERR_NONE
)
292 else if (info
->codec_id
== MFX_CODEC_AVC
)
295 * This should not fail for AVC encoders, so we want to know
296 * about it - however, it may fail for other encoders (ignore)
299 "hb_qsv_info_init: MFXVideoENCODE_Init failed"
300 " (0x%"PRIX32
", 0x%"PRIX32
", %d)\n",
301 info
->codec_id
, info
->implementation
, status
);
303 MFXVideoENCODE_Close(session
);
307 if (!info
->available
)
309 /* Don't check capabilities for unavailable encoders */
313 if (info
->implementation
& MFX_IMPL_AUDIO
)
315 /* We don't have any audio capability checks yet */
320 /* Implementation-specific features that can't be queried */
321 if (info
->codec_id
== MFX_CODEC_AVC
|| info
->codec_id
== MFX_CODEC_HEVC
)
323 if (qsv_implementation_is_hardware(info
->implementation
))
325 if (qsv_hardware_generation(hb_get_cpu_platform()) >= QSV_G3
)
327 info
->capabilities
|= HB_QSV_CAP_B_REF_PYRAMID
;
332 if (HB_CHECK_MFX_VERSION(version
, 1, 6))
334 info
->capabilities
|= HB_QSV_CAP_B_REF_PYRAMID
;
339 /* API-specific features that can't be queried */
340 if (HB_CHECK_MFX_VERSION(version
, 1, 6))
342 // API >= 1.6 (mfxBitstream::DecodeTimeStamp, mfxExtCodingOption2)
343 info
->capabilities
|= HB_QSV_CAP_MSDK_API_1_6
;
347 * Check availability of optional rate control methods.
349 * Mode 2 tends to error out, but mode 1 gives false negatives, which
350 * is worse. So use mode 2 and assume an error means it's unsupported.
352 * Also assume that LA and ICQ combined imply LA_ICQ is
353 * supported, so we don't need to check the latter too.
355 if (HB_CHECK_MFX_VERSION(version
, 1, 7))
357 init_video_param(&inputParam
);
358 inputParam
.mfx
.CodecId
= info
->codec_id
;
359 inputParam
.mfx
.RateControlMethod
= MFX_RATECONTROL_LA
;
361 memset(&videoParam
, 0, sizeof(mfxVideoParam
));
362 videoParam
.mfx
.CodecId
= inputParam
.mfx
.CodecId
;
364 if (MFXVideoENCODE_Query(session
, &inputParam
, &videoParam
) >= MFX_ERR_NONE
&&
365 videoParam
.mfx
.RateControlMethod
== MFX_RATECONTROL_LA
)
367 info
->capabilities
|= HB_QSV_CAP_RATECONTROL_LA
;
369 // also check for LA + interlaced support
370 init_video_param(&inputParam
);
371 inputParam
.mfx
.CodecId
= info
->codec_id
;
372 inputParam
.mfx
.RateControlMethod
= MFX_RATECONTROL_LA
;
373 inputParam
.mfx
.FrameInfo
.PicStruct
= MFX_PICSTRUCT_FIELD_TFF
;
375 memset(&videoParam
, 0, sizeof(mfxVideoParam
));
376 videoParam
.mfx
.CodecId
= inputParam
.mfx
.CodecId
;
378 if (MFXVideoENCODE_Query(session
, &inputParam
, &videoParam
) >= MFX_ERR_NONE
&&
379 videoParam
.mfx
.FrameInfo
.PicStruct
== MFX_PICSTRUCT_FIELD_TFF
&&
380 videoParam
.mfx
.RateControlMethod
== MFX_RATECONTROL_LA
)
382 info
->capabilities
|= HB_QSV_CAP_RATECONTROL_LAi
;
386 if (HB_CHECK_MFX_VERSION(version
, 1, 8))
388 init_video_param(&inputParam
);
389 inputParam
.mfx
.CodecId
= info
->codec_id
;
390 inputParam
.mfx
.RateControlMethod
= MFX_RATECONTROL_ICQ
;
392 memset(&videoParam
, 0, sizeof(mfxVideoParam
));
393 videoParam
.mfx
.CodecId
= inputParam
.mfx
.CodecId
;
395 if (MFXVideoENCODE_Query(session
, &inputParam
, &videoParam
) >= MFX_ERR_NONE
&&
396 videoParam
.mfx
.RateControlMethod
== MFX_RATECONTROL_ICQ
)
398 info
->capabilities
|= HB_QSV_CAP_RATECONTROL_ICQ
;
403 * Determine whether mfxExtVideoSignalInfo is supported.
405 if (HB_CHECK_MFX_VERSION(version
, 1, 3))
407 init_video_param(&videoParam
);
408 videoParam
.mfx
.CodecId
= info
->codec_id
;
410 init_ext_video_signal_info(&extVideoSignalInfo
);
411 videoParam
.ExtParam
= videoExtParam
;
412 videoParam
.ExtParam
[0] = (mfxExtBuffer
*)&extVideoSignalInfo
;
413 videoParam
.NumExtParam
= 1;
415 status
= MFXVideoENCODE_Query(session
, NULL
, &videoParam
);
416 if (status
>= MFX_ERR_NONE
)
418 /* Encoder can be configured via mfxExtVideoSignalInfo */
419 info
->capabilities
|= HB_QSV_CAP_VUI_VSINFO
;
421 else if (info
->codec_id
== MFX_CODEC_AVC
)
424 * This should not fail for AVC encoders, so we want to know
425 * about it - however, it may fail for other encoders (ignore)
428 "hb_qsv_info_init: mfxExtVideoSignalInfo check"
429 " failed (0x%"PRIX32
", 0x%"PRIX32
", %d)\n",
430 info
->codec_id
, info
->implementation
, status
);
435 * Determine whether mfxExtCodingOption is supported.
437 if (HB_CHECK_MFX_VERSION(version
, 1, 0))
439 init_video_param(&videoParam
);
440 videoParam
.mfx
.CodecId
= info
->codec_id
;
442 init_ext_coding_option(&extCodingOption
);
443 videoParam
.ExtParam
= videoExtParam
;
444 videoParam
.ExtParam
[0] = (mfxExtBuffer
*)&extCodingOption
;
445 videoParam
.NumExtParam
= 1;
447 status
= MFXVideoENCODE_Query(session
, NULL
, &videoParam
);
448 if (status
>= MFX_ERR_NONE
)
450 /* Encoder can be configured via mfxExtCodingOption */
451 info
->capabilities
|= HB_QSV_CAP_OPTION1
;
453 else if (info
->codec_id
== MFX_CODEC_AVC
)
456 * This should not fail for AVC encoders, so we want to know
457 * about it - however, it may fail for other encoders (ignore)
460 "hb_qsv_info_init: mfxExtCodingOption check"
461 " failed (0x%"PRIX32
", 0x%"PRIX32
", %d)\n",
462 info
->codec_id
, info
->implementation
, status
);
467 * Determine whether mfxExtCodingOption2 and its fields are supported.
469 * Mode 2 suffers from false negatives with some drivers, whereas mode 1
470 * suffers from false positives instead. The latter is probably easier
471 * and/or safer to sanitize for us, so use mode 1.
473 if (HB_CHECK_MFX_VERSION(version
, 1, 6) && info
->codec_id
== MFX_CODEC_AVC
)
475 init_video_param(&videoParam
);
476 videoParam
.mfx
.CodecId
= info
->codec_id
;
478 init_ext_coding_option2(&extCodingOption2
);
479 videoParam
.ExtParam
= videoExtParam
;
480 videoParam
.ExtParam
[0] = (mfxExtBuffer
*)&extCodingOption2
;
481 videoParam
.NumExtParam
= 1;
483 status
= MFXVideoENCODE_Query(session
, NULL
, &videoParam
);
484 if (status
>= MFX_ERR_NONE
)
487 // testing code that could come in handy
488 fprintf(stderr
, "-------------------\n");
489 fprintf(stderr
, "MBBRC: 0x%02X\n", extCodingOption2
.MBBRC
);
490 fprintf(stderr
, "ExtBRC: 0x%02X\n", extCodingOption2
.ExtBRC
);
491 fprintf(stderr
, "Trellis: 0x%02X\n", extCodingOption2
.Trellis
);
492 fprintf(stderr
, "RepeatPPS: 0x%02X\n", extCodingOption2
.RepeatPPS
);
493 fprintf(stderr
, "BRefType: %4"PRIu16
"\n", extCodingOption2
.BRefType
);
494 fprintf(stderr
, "AdaptiveI: 0x%02X\n", extCodingOption2
.AdaptiveI
);
495 fprintf(stderr
, "AdaptiveB: 0x%02X\n", extCodingOption2
.AdaptiveB
);
496 fprintf(stderr
, "LookAheadDS: %4"PRIu16
"\n", extCodingOption2
.LookAheadDS
);
497 fprintf(stderr
, "-------------------\n");
500 /* Encoder can be configured via mfxExtCodingOption2 */
501 info
->capabilities
|= HB_QSV_CAP_OPTION2
;
504 * Sanitize API 1.6 fields:
506 * - MBBRC requires G3 hardware (Haswell or equivalent)
507 * - ExtBRC requires G2 hardware (Ivy Bridge or equivalent)
509 if (qsv_implementation_is_hardware(info
->implementation
) &&
510 qsv_hardware_generation(hb_get_cpu_platform()) >= QSV_G3
)
512 if (extCodingOption2
.MBBRC
)
514 info
->capabilities
|= HB_QSV_CAP_OPTION2_MBBRC
;
517 if (qsv_implementation_is_hardware(info
->implementation
) &&
518 qsv_hardware_generation(hb_get_cpu_platform()) >= QSV_G2
)
520 if (extCodingOption2
.ExtBRC
)
522 info
->capabilities
|= HB_QSV_CAP_OPTION2_EXTBRC
;
527 * Sanitize API 1.7 fields:
529 * - Trellis requires G3 hardware (Haswell or equivalent)
531 if (HB_CHECK_MFX_VERSION(version
, 1, 7))
533 if (qsv_implementation_is_hardware(info
->implementation
) &&
534 qsv_hardware_generation(hb_get_cpu_platform()) >= QSV_G3
)
536 if (extCodingOption2
.Trellis
)
538 info
->capabilities
|= HB_QSV_CAP_OPTION2_TRELLIS
;
544 * Sanitize API 1.8 fields:
546 * - BRefType requires B-pyramid support
547 * - LookAheadDS requires lookahead support
548 * - AdaptiveI, AdaptiveB, NumMbPerSlice unknown (trust Query)
550 if (HB_CHECK_MFX_VERSION(version
, 1, 8))
552 if (info
->capabilities
& HB_QSV_CAP_B_REF_PYRAMID
)
554 if (extCodingOption2
.BRefType
)
556 info
->capabilities
|= HB_QSV_CAP_OPTION2_BREFTYPE
;
559 if (info
->capabilities
& HB_QSV_CAP_RATECONTROL_LA
)
561 if (extCodingOption2
.LookAheadDS
)
563 info
->capabilities
|= HB_QSV_CAP_OPTION2_LA_DOWNS
;
566 if (extCodingOption2
.AdaptiveI
&& extCodingOption2
.AdaptiveB
)
568 info
->capabilities
|= HB_QSV_CAP_OPTION2_IB_ADAPT
;
570 if (extCodingOption2
.NumMbPerSlice
)
572 info
->capabilities
|= HB_QSV_CAP_OPTION2_NMPSLICE
;
579 "hb_qsv_info_init: mfxExtCodingOption2 check failed (0x%"PRIX32
", 0x%"PRIX32
", %d)\n",
580 info
->codec_id
, info
->implementation
, status
);
585 /* Unload MFX plug-ins */
586 hb_qsv_unload_plugins(&mfxPluginList
, session
, version
);
591 int hb_qsv_info_init()
593 static int init_done
= 0;
599 * First, check for any MSDK version to determine whether one or
600 * more implementations are present; then check if we can use them.
602 * I've had issues using a NULL version with some combinations of
603 * hardware and driver, so use a low version number (1.0) instead.
606 mfxVersion version
= { .Major
= 1, .Minor
= 0, };
608 // check for software fallback
609 if (MFXInit(MFX_IMPL_SOFTWARE
, &version
, &session
) == MFX_ERR_NONE
)
611 // Media SDK software found, but check that our minimum is supported
612 MFXQueryVersion(session
, &qsv_software_version
);
613 if (HB_CHECK_MFX_VERSION(qsv_software_version
,
614 HB_QSV_MINVERSION_MAJOR
,
615 HB_QSV_MINVERSION_MINOR
))
617 query_capabilities(session
, qsv_software_version
, &qsv_software_info_avc
);
618 query_capabilities(session
, qsv_software_version
, &qsv_software_info_hevc
);
619 // now that we know which hardware encoders are
620 // available, we can set the preferred implementation
621 hb_qsv_impl_set_preferred("software");
626 // check for actual hardware support
627 if (MFXInit(MFX_IMPL_HARDWARE_ANY
, &version
, &session
) == MFX_ERR_NONE
)
629 // Media SDK hardware found, but check that our minimum is supported
631 // Note: this-party hardware (QSV_G0) is unsupported for the time being
632 MFXQueryVersion(session
, &qsv_hardware_version
);
633 if (qsv_hardware_generation(hb_get_cpu_platform()) >= QSV_G1
&&
634 HB_CHECK_MFX_VERSION(qsv_hardware_version
,
635 HB_QSV_MINVERSION_MAJOR
,
636 HB_QSV_MINVERSION_MINOR
))
638 query_capabilities(session
, qsv_hardware_version
, &qsv_hardware_info_avc
);
639 query_capabilities(session
, qsv_hardware_version
, &qsv_hardware_info_hevc
);
640 // now that we know which hardware encoders are
641 // available, we can set the preferred implementation
642 hb_qsv_impl_set_preferred("hardware");
651 static void log_capabilities(int log_level
, uint64_t caps
, const char *prefix
)
654 * Note: keep the string short, as it may be logged by default.
656 char buffer
[128] = "";
658 /* B-Pyramid, with or without direct control (BRefType) */
659 if (caps
& HB_QSV_CAP_B_REF_PYRAMID
)
661 if (caps
& HB_QSV_CAP_OPTION2_BREFTYPE
)
663 strcat(buffer
, " breftype");
667 strcat(buffer
, " bpyramid");
670 /* Rate control: ICQ, lookahead (options: interlaced, downsampling) */
671 if (caps
& HB_QSV_CAP_RATECONTROL_LA
)
673 if (caps
& HB_QSV_CAP_RATECONTROL_ICQ
)
675 strcat(buffer
, " icq+la");
679 strcat(buffer
, " la");
681 if (caps
& HB_QSV_CAP_RATECONTROL_LAi
)
683 strcat(buffer
, "+i");
685 if (caps
& HB_QSV_CAP_OPTION2_LA_DOWNS
)
687 strcat(buffer
, "+downs");
690 else if (caps
& HB_QSV_CAP_RATECONTROL_ICQ
)
692 strcat(buffer
, " icq");
694 if (caps
& HB_QSV_CAP_VUI_VSINFO
)
696 strcat(buffer
, " vsinfo");
698 if (caps
& HB_QSV_CAP_OPTION1
)
700 strcat(buffer
, " opt1");
702 if (caps
& HB_QSV_CAP_OPTION2
)
705 strcat(buffer
, " opt2");
707 if (caps
& HB_QSV_CAP_OPTION2_MBBRC
)
709 strcat(buffer
, "+mbbrc");
711 if (caps
& HB_QSV_CAP_OPTION2_EXTBRC
)
713 strcat(buffer
, "+extbrc");
715 if (caps
& HB_QSV_CAP_OPTION2_TRELLIS
)
717 strcat(buffer
, "+trellis");
719 if (caps
& HB_QSV_CAP_OPTION2_IB_ADAPT
)
721 strcat(buffer
, "+ib_adapt");
723 if (caps
& HB_QSV_CAP_OPTION2_NMPSLICE
)
725 strcat(buffer
, "+nmpslice");
729 hb_deep_log(log_level
, "%s%s", prefix
,
730 strnlen(buffer
, 1) ? buffer
: " standard feature set");
733 void hb_qsv_info_print()
735 // is QSV available and usable?
736 hb_log("Intel Quick Sync Video support: %s",
737 hb_qsv_available() ? "yes": "no");
739 // also print the details
740 if (qsv_hardware_version
.Version
)
742 hb_log(" - Intel Media SDK hardware: API %"PRIu16
".%"PRIu16
" (minimum: %"PRIu16
".%"PRIu16
")",
743 qsv_hardware_version
.Major
, qsv_hardware_version
.Minor
,
744 HB_QSV_MINVERSION_MAJOR
, HB_QSV_MINVERSION_MINOR
);
746 if (qsv_software_version
.Version
)
748 hb_log(" - Intel Media SDK software: API %"PRIu16
".%"PRIu16
" (minimum: %"PRIu16
".%"PRIu16
")",
749 qsv_software_version
.Major
, qsv_software_version
.Minor
,
750 HB_QSV_MINVERSION_MAJOR
, HB_QSV_MINVERSION_MINOR
);
752 if (hb_qsv_available())
754 if (hb_qsv_info_avc
!= NULL
&& hb_qsv_info_avc
->available
)
756 hb_log(" - H.264 encoder: yes");
757 hb_log(" - preferred implementation: %s",
758 hb_qsv_impl_get_name(hb_qsv_info_avc
->implementation
));
759 if (qsv_hardware_info_avc
.available
)
761 log_capabilities(1, qsv_hardware_info_avc
.capabilities
,
762 " - capabilities (hardware): ");
764 if (qsv_software_info_avc
.available
)
766 log_capabilities(1, qsv_software_info_avc
.capabilities
,
767 " - capabilities (software): ");
772 hb_log(" - H.264 encoder: no");
774 if (hb_qsv_info_hevc
!= NULL
&& hb_qsv_info_hevc
->available
)
776 hb_deep_log(2, " - H.265 encoder: yes (unsupported)");
777 hb_deep_log(2, " - preferred implementation: %s",
778 hb_qsv_impl_get_name(hb_qsv_info_hevc
->implementation
));
779 if (qsv_hardware_info_hevc
.available
)
781 log_capabilities(2, qsv_hardware_info_hevc
.capabilities
,
782 " - capabilities (hardware): ");
784 if (qsv_software_info_hevc
.available
)
786 log_capabilities(2, qsv_software_info_hevc
.capabilities
,
787 " - capabilities (software): ");
792 hb_deep_log(2, " - H.265 encoder: no");
797 hb_qsv_info_t
* hb_qsv_info_get(int encoder
)
801 case HB_VCODEC_QSV_H264
:
802 return hb_qsv_info_avc
;
808 hb_list_t
* hb_qsv_load_plugins(hb_qsv_info_t
*info
, mfxSession session
, mfxVersion version
)
810 hb_list_t
*mfxPluginList
= hb_list_init();
811 if (mfxPluginList
== NULL
)
813 hb_log("hb_qsv_load_plugins: hb_list_init() failed");
817 if (HB_CHECK_MFX_VERSION(version
, 1, 8))
819 if (info
->codec_id
== MFX_CODEC_HEVC
)
821 if (HB_CHECK_MFX_VERSION(version
, 1, 15) &&
822 qsv_implementation_is_hardware(info
->implementation
))
824 if (MFXVideoUSER_Load(session
, &MFX_PLUGINID_HEVCE_HW
, 0) < MFX_ERR_NONE
)
828 hb_list_add(mfxPluginList
, (void*)&MFX_PLUGINID_HEVCE_HW
);
830 else if (HB_CHECK_MFX_VERSION(version
, 1, 15))
832 if (MFXVideoUSER_Load(session
, &MFX_PLUGINID_HEVCE_SW
, 0) < MFX_ERR_NONE
)
836 hb_list_add(mfxPluginList
, (void*)&MFX_PLUGINID_HEVCE_SW
);
841 return mfxPluginList
;
844 hb_list_close(&mfxPluginList
);
848 void hb_qsv_unload_plugins(hb_list_t
**_l
, mfxSession session
, mfxVersion version
)
850 mfxPluginUID
*pluginUID
;
851 hb_list_t
*mfxPluginList
= *_l
;
853 if (mfxPluginList
!= NULL
&& HB_CHECK_MFX_VERSION(version
, 1, 8))
855 for (int i
= 0; i
< hb_list_count(mfxPluginList
); i
++)
857 if ((pluginUID
= hb_list_item(mfxPluginList
, i
)) != NULL
)
859 MFXVideoUSER_UnLoad(session
, pluginUID
);
866 const char* hb_qsv_decode_get_codec_name(enum AVCodecID codec_id
)
870 case AV_CODEC_ID_H264
:
878 int hb_qsv_decode_is_enabled(hb_job_t
*job
)
880 return ((job
!= NULL
&& job
->qsv
.decode
) &&
881 (job
->vcodec
& HB_VCODEC_QSV_MASK
) &&
882 (job
->title
->video_decode_support
& HB_DECODE_SUPPORT_QSV
));
885 int hb_qsv_copyframe_is_slow(int encoder
)
887 hb_qsv_info_t
*info
= hb_qsv_info_get(encoder
);
888 if (info
!= NULL
&& qsv_implementation_is_hardware(info
->implementation
))
890 // we should really check the driver version, but since it's not
891 // available, checking the API version is the best we can do :-(
892 return !HB_CHECK_MFX_VERSION(qsv_hardware_version
, 1, 7);
897 int hb_qsv_codingoption_xlat(int val
)
899 switch (HB_QSV_CLIP3(-1, 2, val
))
902 return MFX_CODINGOPTION_OFF
;
904 case 2: // MFX_CODINGOPTION_ADAPTIVE, reserved
905 return MFX_CODINGOPTION_ON
;
908 return MFX_CODINGOPTION_UNKNOWN
;
912 int hb_qsv_trellisvalue_xlat(int val
)
914 switch (HB_QSV_CLIP3(0, 3, val
))
917 return MFX_TRELLIS_OFF
;
918 case 1: // I-frames only
919 return MFX_TRELLIS_I
;
920 case 2: // I- and P-frames
921 return MFX_TRELLIS_I
|MFX_TRELLIS_P
;
922 case 3: // all frames
923 return MFX_TRELLIS_I
|MFX_TRELLIS_P
|MFX_TRELLIS_B
;
925 return MFX_TRELLIS_UNKNOWN
;
929 const char* hb_qsv_codingoption_get_name(int val
)
933 case MFX_CODINGOPTION_ON
:
935 case MFX_CODINGOPTION_OFF
:
937 case MFX_CODINGOPTION_ADAPTIVE
:
939 case MFX_CODINGOPTION_UNKNOWN
:
940 return "unknown (auto)";
946 int hb_qsv_atoindex(const char* const *arr
, const char *str
, int *err
)
949 for (i
= 0; arr
[i
] != NULL
; i
++)
951 if (!strcasecmp(arr
[i
], str
))
956 *err
= (arr
[i
] == NULL
);
960 // adapted from libx264
961 int hb_qsv_atobool(const char *str
, int *err
)
963 if (!strcasecmp(str
, "1") ||
964 !strcasecmp(str
, "yes") ||
965 !strcasecmp(str
, "true"))
969 if (!strcasecmp(str
, "0") ||
970 !strcasecmp(str
, "no") ||
971 !strcasecmp(str
, "false"))
979 // adapted from libx264
980 int hb_qsv_atoi(const char *str
, int *err
)
983 int v
= strtol(str
, &end
, 0);
984 if (end
== str
|| end
[0] != '\0')
991 // adapted from libx264
992 float hb_qsv_atof(const char *str
, int *err
)
995 float v
= strtod(str
, &end
);
996 if (end
== str
|| end
[0] != '\0')
1003 int hb_qsv_param_parse(hb_qsv_param_t
*param
, hb_qsv_info_t
*info
,
1004 const char *key
, const char *value
)
1007 int ivalue
, error
= 0;
1008 if (param
== NULL
|| info
== NULL
)
1010 return HB_QSV_PARAM_ERROR
;
1012 if (value
== NULL
|| value
[0] == '\0')
1016 else if (value
[0] == '=')
1020 if (key
== NULL
|| key
[0] == '\0')
1022 return HB_QSV_PARAM_BAD_NAME
;
1024 else if (!strncasecmp(key
, "no-", 3))
1027 value
= hb_qsv_atobool(value
, &error
) ? "false" : "true";
1030 return HB_QSV_PARAM_BAD_VALUE
;
1033 if (!strcasecmp(key
, "target-usage") ||
1034 !strcasecmp(key
, "tu"))
1036 ivalue
= hb_qsv_atoi(value
, &error
);
1039 param
->videoParam
->mfx
.TargetUsage
= HB_QSV_CLIP3(MFX_TARGETUSAGE_1
,
1044 else if (!strcasecmp(key
, "num-ref-frame") ||
1045 !strcasecmp(key
, "ref"))
1047 ivalue
= hb_qsv_atoi(value
, &error
);
1050 param
->videoParam
->mfx
.NumRefFrame
= HB_QSV_CLIP3(0, 16, ivalue
);
1053 else if (!strcasecmp(key
, "gop-ref-dist"))
1055 ivalue
= hb_qsv_atoi(value
, &error
);
1058 param
->gop
.gop_ref_dist
= HB_QSV_CLIP3(-1, 32, ivalue
);
1061 else if (!strcasecmp(key
, "gop-pic-size") ||
1062 !strcasecmp(key
, "keyint"))
1064 ivalue
= hb_qsv_atoi(value
, &error
);
1067 param
->gop
.gop_pic_size
= HB_QSV_CLIP3(-1, UINT16_MAX
, ivalue
);
1070 else if (!strcasecmp(key
, "b-pyramid"))
1072 if (info
->capabilities
& HB_QSV_CAP_B_REF_PYRAMID
)
1074 ivalue
= hb_qsv_atoi(value
, &error
);
1077 param
->gop
.b_pyramid
= HB_QSV_CLIP3(-1, 1, ivalue
);
1082 return HB_QSV_PARAM_UNSUPPORTED
;
1085 else if (!strcasecmp(key
, "scenecut"))
1087 ivalue
= hb_qsv_atobool(value
, &error
);
1092 param
->videoParam
->mfx
.GopOptFlag
|= MFX_GOP_STRICT
;
1096 param
->videoParam
->mfx
.GopOptFlag
&= ~MFX_GOP_STRICT
;
1100 else if (!strcasecmp(key
, "adaptive-i") ||
1101 !strcasecmp(key
, "i-adapt"))
1103 if (info
->capabilities
& HB_QSV_CAP_OPTION2_IB_ADAPT
)
1105 ivalue
= hb_qsv_atobool(value
, &error
);
1108 param
->codingOption2
.AdaptiveI
= hb_qsv_codingoption_xlat(ivalue
);
1113 return HB_QSV_PARAM_UNSUPPORTED
;
1116 else if (!strcasecmp(key
, "adaptive-b") ||
1117 !strcasecmp(key
, "b-adapt"))
1119 if (info
->capabilities
& HB_QSV_CAP_OPTION2_IB_ADAPT
)
1121 ivalue
= hb_qsv_atobool(value
, &error
);
1124 param
->codingOption2
.AdaptiveB
= hb_qsv_codingoption_xlat(ivalue
);
1129 return HB_QSV_PARAM_UNSUPPORTED
;
1132 else if (!strcasecmp(key
, "force-cqp"))
1134 ivalue
= hb_qsv_atobool(value
, &error
);
1137 param
->rc
.icq
= !ivalue
;
1140 else if (!strcasecmp(key
, "cqp-offset-i"))
1142 ivalue
= hb_qsv_atoi(value
, &error
);
1145 param
->rc
.cqp_offsets
[0] = HB_QSV_CLIP3(INT16_MIN
, INT16_MAX
, ivalue
);
1148 else if (!strcasecmp(key
, "cqp-offset-p"))
1150 ivalue
= hb_qsv_atoi(value
, &error
);
1153 param
->rc
.cqp_offsets
[1] = HB_QSV_CLIP3(INT16_MIN
, INT16_MAX
, ivalue
);
1156 else if (!strcasecmp(key
, "cqp-offset-b"))
1158 ivalue
= hb_qsv_atoi(value
, &error
);
1161 param
->rc
.cqp_offsets
[2] = HB_QSV_CLIP3(INT16_MIN
, INT16_MAX
, ivalue
);
1164 else if (!strcasecmp(key
, "vbv-init"))
1166 fvalue
= hb_qsv_atof(value
, &error
);
1169 param
->rc
.vbv_buffer_init
= HB_QSV_CLIP3(0, UINT16_MAX
, fvalue
);
1172 else if (!strcasecmp(key
, "vbv-bufsize"))
1174 ivalue
= hb_qsv_atoi(value
, &error
);
1177 param
->rc
.vbv_buffer_size
= HB_QSV_CLIP3(0, UINT16_MAX
, ivalue
);
1180 else if (!strcasecmp(key
, "vbv-maxrate"))
1182 ivalue
= hb_qsv_atoi(value
, &error
);
1185 param
->rc
.vbv_max_bitrate
= HB_QSV_CLIP3(0, UINT16_MAX
, ivalue
);
1188 else if (!strcasecmp(key
, "cavlc") || !strcasecmp(key
, "cabac"))
1190 if (info
->capabilities
& HB_QSV_CAP_OPTION1
)
1192 switch (info
->codec_id
)
1195 ivalue
= hb_qsv_atobool(value
, &error
);
1198 return HB_QSV_PARAM_UNSUPPORTED
;
1203 return HB_QSV_PARAM_UNSUPPORTED
;
1207 if (!strcasecmp(key
, "cabac"))
1211 param
->codingOption
.CAVLC
= hb_qsv_codingoption_xlat(ivalue
);
1214 else if (!strcasecmp(key
, "videoformat"))
1216 if (info
->capabilities
& HB_QSV_CAP_VUI_VSINFO
)
1218 switch (info
->codec_id
)
1221 ivalue
= hb_qsv_atoindex(hb_h264_vidformat_names
, value
, &error
);
1224 return HB_QSV_PARAM_UNSUPPORTED
;
1229 return HB_QSV_PARAM_UNSUPPORTED
;
1233 param
->videoSignalInfo
.VideoFormat
= ivalue
;
1236 else if (!strcasecmp(key
, "fullrange"))
1238 if (info
->capabilities
& HB_QSV_CAP_VUI_VSINFO
)
1240 switch (info
->codec_id
)
1243 ivalue
= hb_qsv_atoindex(hb_h264_fullrange_names
, value
, &error
);
1246 return HB_QSV_PARAM_UNSUPPORTED
;
1251 return HB_QSV_PARAM_UNSUPPORTED
;
1255 param
->videoSignalInfo
.VideoFullRange
= ivalue
;
1258 else if (!strcasecmp(key
, "colorprim"))
1260 if (info
->capabilities
& HB_QSV_CAP_VUI_VSINFO
)
1262 switch (info
->codec_id
)
1265 ivalue
= hb_qsv_atoindex(hb_h264_colorprim_names
, value
, &error
);
1268 return HB_QSV_PARAM_UNSUPPORTED
;
1273 return HB_QSV_PARAM_UNSUPPORTED
;
1277 param
->videoSignalInfo
.ColourDescriptionPresent
= 1;
1278 param
->videoSignalInfo
.ColourPrimaries
= ivalue
;
1281 else if (!strcasecmp(key
, "transfer"))
1283 if (info
->capabilities
& HB_QSV_CAP_VUI_VSINFO
)
1285 switch (info
->codec_id
)
1288 ivalue
= hb_qsv_atoindex(hb_h264_transfer_names
, value
, &error
);
1291 return HB_QSV_PARAM_UNSUPPORTED
;
1296 return HB_QSV_PARAM_UNSUPPORTED
;
1300 param
->videoSignalInfo
.ColourDescriptionPresent
= 1;
1301 param
->videoSignalInfo
.TransferCharacteristics
= ivalue
;
1304 else if (!strcasecmp(key
, "colormatrix"))
1306 if (info
->capabilities
& HB_QSV_CAP_VUI_VSINFO
)
1308 switch (info
->codec_id
)
1311 ivalue
= hb_qsv_atoindex(hb_h264_colmatrix_names
, value
, &error
);
1314 return HB_QSV_PARAM_UNSUPPORTED
;
1319 return HB_QSV_PARAM_UNSUPPORTED
;
1323 param
->videoSignalInfo
.ColourDescriptionPresent
= 1;
1324 param
->videoSignalInfo
.MatrixCoefficients
= ivalue
;
1327 else if (!strcasecmp(key
, "tff") ||
1328 !strcasecmp(key
, "interlaced"))
1330 switch (info
->codec_id
)
1333 ivalue
= hb_qsv_atobool(value
, &error
);
1336 return HB_QSV_PARAM_UNSUPPORTED
;
1340 param
->videoParam
->mfx
.FrameInfo
.PicStruct
= (ivalue
?
1341 MFX_PICSTRUCT_FIELD_TFF
:
1342 MFX_PICSTRUCT_PROGRESSIVE
);
1345 else if (!strcasecmp(key
, "bff"))
1347 switch (info
->codec_id
)
1350 ivalue
= hb_qsv_atobool(value
, &error
);
1353 return HB_QSV_PARAM_UNSUPPORTED
;
1357 param
->videoParam
->mfx
.FrameInfo
.PicStruct
= (ivalue
?
1358 MFX_PICSTRUCT_FIELD_BFF
:
1359 MFX_PICSTRUCT_PROGRESSIVE
);
1362 else if (!strcasecmp(key
, "mbbrc"))
1364 if (info
->capabilities
& HB_QSV_CAP_OPTION2_MBBRC
)
1366 ivalue
= hb_qsv_atobool(value
, &error
);
1369 param
->codingOption2
.MBBRC
= hb_qsv_codingoption_xlat(ivalue
);
1374 return HB_QSV_PARAM_UNSUPPORTED
;
1377 else if (!strcasecmp(key
, "extbrc"))
1379 if (info
->capabilities
& HB_QSV_CAP_OPTION2_EXTBRC
)
1381 ivalue
= hb_qsv_atobool(value
, &error
);
1384 param
->codingOption2
.ExtBRC
= hb_qsv_codingoption_xlat(ivalue
);
1389 return HB_QSV_PARAM_UNSUPPORTED
;
1392 else if (!strcasecmp(key
, "lookahead") ||
1393 !strcasecmp(key
, "la"))
1395 if (info
->capabilities
& HB_QSV_CAP_RATECONTROL_LA
)
1397 ivalue
= hb_qsv_atobool(value
, &error
);
1400 param
->rc
.lookahead
= ivalue
;
1405 return HB_QSV_PARAM_UNSUPPORTED
;
1408 else if (!strcasecmp(key
, "lookahead-depth") ||
1409 !strcasecmp(key
, "la-depth"))
1411 if (info
->capabilities
& HB_QSV_CAP_RATECONTROL_LA
)
1413 ivalue
= hb_qsv_atoi(value
, &error
);
1416 param
->codingOption2
.LookAheadDepth
= HB_QSV_CLIP3(10, 100,
1422 return HB_QSV_PARAM_UNSUPPORTED
;
1425 else if (!strcasecmp(key
, "lookahead-ds") ||
1426 !strcasecmp(key
, "la-ds"))
1428 if (info
->capabilities
& HB_QSV_CAP_OPTION2_LA_DOWNS
)
1430 ivalue
= hb_qsv_atoi(value
, &error
);
1433 param
->codingOption2
.LookAheadDS
= HB_QSV_CLIP3(MFX_LOOKAHEAD_DS_UNKNOWN
,
1434 MFX_LOOKAHEAD_DS_4x
,
1440 return HB_QSV_PARAM_UNSUPPORTED
;
1443 else if (!strcasecmp(key
, "trellis"))
1445 if (info
->capabilities
& HB_QSV_CAP_OPTION2_TRELLIS
)
1447 ivalue
= hb_qsv_atoi(value
, &error
);
1450 param
->codingOption2
.Trellis
= hb_qsv_trellisvalue_xlat(ivalue
);
1455 return HB_QSV_PARAM_UNSUPPORTED
;
1462 * - slice count (num-slice/slices, num-mb-per-slice/slice-max-mbs)
1464 * - fake-interlaced (mfxExtCodingOption.FramePicture???)
1467 return HB_QSV_PARAM_BAD_NAME
;
1469 return error
? HB_QSV_PARAM_BAD_VALUE
: HB_QSV_PARAM_OK
;
1472 int hb_qsv_profile_parse(hb_qsv_param_t
*param
, hb_qsv_info_t
*info
, const char *profile_key
)
1474 hb_triplet_t
*profile
= NULL
;
1475 if (profile_key
!= NULL
&& *profile_key
&& strcasecmp(profile_key
, "auto"))
1477 switch (param
->videoParam
->mfx
.CodecId
)
1480 profile
= hb_triplet4key(hb_qsv_h264_profiles
, profile_key
);
1485 if (profile
== NULL
)
1489 param
->videoParam
->mfx
.CodecProfile
= profile
->value
;
1494 int hb_qsv_level_parse(hb_qsv_param_t
*param
, hb_qsv_info_t
*info
, const char *level_key
)
1496 hb_triplet_t
*level
= NULL
;
1497 if (level_key
!= NULL
&& *level_key
&& strcasecmp(level_key
, "auto"))
1499 switch (param
->videoParam
->mfx
.CodecId
)
1502 level
= hb_triplet4key(hb_qsv_h264_levels
, level_key
);
1511 if (param
->videoParam
->mfx
.CodecId
== MFX_CODEC_AVC
)
1513 if (info
->capabilities
& HB_QSV_CAP_MSDK_API_1_6
)
1515 param
->videoParam
->mfx
.CodecLevel
= FFMIN(MFX_LEVEL_AVC_52
, level
->value
);
1519 // Media SDK API < 1.6, MFX_LEVEL_AVC_52 unsupported
1520 param
->videoParam
->mfx
.CodecLevel
= FFMIN(MFX_LEVEL_AVC_51
, level
->value
);
1525 param
->videoParam
->mfx
.CodecLevel
= level
->value
;
1531 const char* const* hb_qsv_preset_get_names()
1533 if (qsv_hardware_generation(hb_get_cpu_platform()) >= QSV_G3
)
1535 return hb_qsv_preset_names2
;
1539 return hb_qsv_preset_names1
;
1543 const char* const* hb_qsv_profile_get_names(int encoder
)
1547 case HB_VCODEC_QSV_H264
:
1548 return hb_h264_profile_names
;
1554 const char* const* hb_qsv_level_get_names(int encoder
)
1558 case HB_VCODEC_QSV_H264
:
1559 return hb_h264_level_names
;
1565 const char* hb_qsv_video_quality_get_name(uint32_t codec
)
1570 case HB_VCODEC_QSV_H264
:
1571 caps
= hb_qsv_info_avc
!= NULL
? hb_qsv_info_avc
->capabilities
: 0;
1572 return (caps
& HB_QSV_CAP_RATECONTROL_ICQ
) ? "ICQ" : "QP";
1579 void hb_qsv_video_quality_get_limits(uint32_t codec
, float *low
, float *high
,
1580 float *granularity
, int *direction
)
1585 case HB_VCODEC_QSV_H264
:
1586 caps
= hb_qsv_info_avc
!= NULL
? hb_qsv_info_avc
->capabilities
: 0;
1589 *low
= (caps
& HB_QSV_CAP_RATECONTROL_ICQ
) ? 1. : 0.;
1602 int hb_qsv_param_default_preset(hb_qsv_param_t
*param
,
1603 mfxVideoParam
*videoParam
,
1604 hb_qsv_info_t
*info
, const char *preset
)
1606 if (param
!= NULL
&& videoParam
!= NULL
&& info
!= NULL
)
1608 int ret
= hb_qsv_param_default(param
, videoParam
, info
);
1616 hb_error("hb_qsv_param_default_preset: invalid pointer(s)");
1619 if (preset
!= NULL
&& preset
[0] != '\0')
1621 if (!strcasecmp(preset
, "quality"))
1624 * HSW TargetUsage: 2
1626 * GopRefDist: 4 (CQP), 3 (VBR) -> -1 (set by encoder)
1627 * GopPicSize: 32 (CQP), 1 second (VBR) -> -1 (set by encoder)
1628 * BPyramid: 1 (CQP), 0 (VBR) -> -1 (set by encoder)
1630 * LookAheadDepth: 40
1634 * IVB Preset Not Available
1636 * Note: this preset is the libhb default (like x264's "medium").
1639 else if (!strcasecmp(preset
, "balanced"))
1642 * HSW TargetUsage: 4
1644 * GopRefDist: 4 (CQP), 3 (VBR) -> -1 (set by encoder)
1645 * GopPicSize: 32 (CQP), 1 second (VBR) -> -1 (set by encoder)
1646 * BPyramid: 1 (CQP), 0 (VBR) -> -1 (set by encoder)
1647 * LookAhead: 0 (off)
1648 * LookAheadDepth: Not Applicable
1650 if (qsv_hardware_generation(hb_get_cpu_platform()) >= QSV_G3
)
1652 param
->rc
.lookahead
= 0;
1653 param
->videoParam
->mfx
.NumRefFrame
= 1;
1654 param
->videoParam
->mfx
.TargetUsage
= MFX_TARGETUSAGE_4
;
1660 * IVB TargetUsage: 2
1662 * GopRefDist: 4 (CQP), 3 (VBR) -> -1 (set by encoder)
1663 * GopPicSize: 32 (CQP), 1 second (VBR) -> -1 (set by encoder)
1664 * BPyramid: Not Applicable
1665 * LookAhead: Not Applicable
1666 * LookAheadDepth: Not Applicable
1668 * Note: this preset is not the libhb default,
1669 * but the settings are the same so do nothing.
1673 else if (!strcasecmp(preset
, "speed"))
1675 if (qsv_hardware_generation(hb_get_cpu_platform()) >= QSV_G3
)
1678 * HSW TargetUsage: 6
1679 * NumRefFrame: 0 (CQP), 1 (VBR) -> see note
1680 * GopRefDist: 4 (CQP), 3 (VBR) -> -1 (set by encoder)
1681 * GopPicSize: 32 (CQP), 1 second (VBR) -> -1 (set by encoder)
1682 * BPyramid: 1 (CQP), 0 (VBR) -> -1 (set by encoder)
1683 * LookAhead: 0 (off)
1684 * LookAheadDepth: Not Applicable
1686 * Note: NumRefFrame depends on the RC method, which we don't
1687 * know here. Rather than have an additional variable and
1688 * having the encoder set it, we set it to 1 and let the
1689 * B-pyramid code sanitize it. Since BPyramid is 1 w/CQP,
1690 * the result (3) is the same as what MSDK would pick for
1691 * NumRefFrame 0 GopRefDist 4 GopPicSize 32.
1693 param
->rc
.lookahead
= 0;
1694 param
->videoParam
->mfx
.NumRefFrame
= 1;
1695 param
->videoParam
->mfx
.TargetUsage
= MFX_TARGETUSAGE_6
;
1701 * IVB TargetUsage: 4
1703 * GopRefDist: 4 (CQP), 3 (VBR) -> -1 (set by encoder)
1704 * GopPicSize: 32 (CQP), 1 second (VBR) -> -1 (set by encoder)
1705 * BPyramid: Not Applicable
1706 * LookAhead: Not Applicable
1707 * LookAheadDepth: Not Applicable
1709 param
->videoParam
->mfx
.TargetUsage
= MFX_TARGETUSAGE_4
;
1714 hb_error("hb_qsv_param_default_preset: invalid preset '%s'", preset
);
1721 int hb_qsv_param_default(hb_qsv_param_t
*param
, mfxVideoParam
*videoParam
,
1722 hb_qsv_info_t
*info
)
1724 if (param
!= NULL
&& videoParam
!= NULL
&& info
!= NULL
)
1726 // introduced in API 1.0
1727 memset(¶m
->codingOption
, 0, sizeof(mfxExtCodingOption
));
1728 param
->codingOption
.Header
.BufferId
= MFX_EXTBUFF_CODING_OPTION
;
1729 param
->codingOption
.Header
.BufferSz
= sizeof(mfxExtCodingOption
);
1730 param
->codingOption
.MECostType
= 0; // reserved, must be 0
1731 param
->codingOption
.MESearchType
= 0; // reserved, must be 0
1732 param
->codingOption
.MVSearchWindow
.x
= 0; // reserved, must be 0
1733 param
->codingOption
.MVSearchWindow
.y
= 0; // reserved, must be 0
1734 param
->codingOption
.RefPicListReordering
= 0; // reserved, must be 0
1735 param
->codingOption
.IntraPredBlockSize
= 0; // reserved, must be 0
1736 param
->codingOption
.InterPredBlockSize
= 0; // reserved, must be 0
1737 param
->codingOption
.MVPrecision
= 0; // reserved, must be 0
1738 param
->codingOption
.EndOfSequence
= MFX_CODINGOPTION_UNKNOWN
;
1739 param
->codingOption
.RateDistortionOpt
= MFX_CODINGOPTION_UNKNOWN
;
1740 param
->codingOption
.ResetRefList
= MFX_CODINGOPTION_UNKNOWN
;
1741 param
->codingOption
.MaxDecFrameBuffering
= 0; // unspecified
1742 param
->codingOption
.AUDelimiter
= MFX_CODINGOPTION_OFF
;
1743 param
->codingOption
.SingleSeiNalUnit
= MFX_CODINGOPTION_UNKNOWN
;
1744 param
->codingOption
.PicTimingSEI
= MFX_CODINGOPTION_OFF
;
1745 param
->codingOption
.VuiNalHrdParameters
= MFX_CODINGOPTION_UNKNOWN
;
1746 param
->codingOption
.FramePicture
= MFX_CODINGOPTION_UNKNOWN
;
1747 param
->codingOption
.CAVLC
= MFX_CODINGOPTION_OFF
;
1748 // introduced in API 1.3
1749 param
->codingOption
.RefPicMarkRep
= MFX_CODINGOPTION_UNKNOWN
;
1750 param
->codingOption
.FieldOutput
= MFX_CODINGOPTION_UNKNOWN
;
1751 param
->codingOption
.NalHrdConformance
= MFX_CODINGOPTION_UNKNOWN
;
1752 param
->codingOption
.SingleSeiNalUnit
= MFX_CODINGOPTION_UNKNOWN
;
1753 param
->codingOption
.VuiVclHrdParameters
= MFX_CODINGOPTION_UNKNOWN
;
1754 // introduced in API 1.4
1755 param
->codingOption
.ViewOutput
= MFX_CODINGOPTION_UNKNOWN
;
1756 // introduced in API 1.6
1757 param
->codingOption
.RecoveryPointSEI
= MFX_CODINGOPTION_UNKNOWN
;
1759 // introduced in API 1.3
1760 memset(¶m
->videoSignalInfo
, 0, sizeof(mfxExtVideoSignalInfo
));
1761 param
->videoSignalInfo
.Header
.BufferId
= MFX_EXTBUFF_VIDEO_SIGNAL_INFO
;
1762 param
->videoSignalInfo
.Header
.BufferSz
= sizeof(mfxExtVideoSignalInfo
);
1763 param
->videoSignalInfo
.VideoFormat
= 5; // undefined
1764 param
->videoSignalInfo
.VideoFullRange
= 0; // TV range
1765 param
->videoSignalInfo
.ColourDescriptionPresent
= 0; // don't write to bitstream
1766 param
->videoSignalInfo
.ColourPrimaries
= 2; // undefined
1767 param
->videoSignalInfo
.TransferCharacteristics
= 2; // undefined
1768 param
->videoSignalInfo
.MatrixCoefficients
= 2; // undefined
1770 // introduced in API 1.6
1771 memset(¶m
->codingOption2
, 0, sizeof(mfxExtCodingOption2
));
1772 param
->codingOption2
.Header
.BufferId
= MFX_EXTBUFF_CODING_OPTION2
;
1773 param
->codingOption2
.Header
.BufferSz
= sizeof(mfxExtCodingOption2
);
1774 param
->codingOption2
.IntRefType
= 0;
1775 param
->codingOption2
.IntRefCycleSize
= 2;
1776 param
->codingOption2
.IntRefQPDelta
= 0;
1777 param
->codingOption2
.MaxFrameSize
= 0;
1778 param
->codingOption2
.BitrateLimit
= MFX_CODINGOPTION_ON
;
1779 param
->codingOption2
.MBBRC
= MFX_CODINGOPTION_ON
;
1780 param
->codingOption2
.ExtBRC
= MFX_CODINGOPTION_OFF
;
1781 // introduced in API 1.7
1782 param
->codingOption2
.LookAheadDepth
= 40;
1783 param
->codingOption2
.Trellis
= MFX_TRELLIS_OFF
;
1784 // introduced in API 1.8
1785 param
->codingOption2
.RepeatPPS
= MFX_CODINGOPTION_ON
;
1786 param
->codingOption2
.BRefType
= MFX_B_REF_UNKNOWN
; // controlled via gop.b_pyramid
1787 param
->codingOption2
.AdaptiveI
= MFX_CODINGOPTION_OFF
;
1788 param
->codingOption2
.AdaptiveB
= MFX_CODINGOPTION_OFF
;
1789 param
->codingOption2
.LookAheadDS
= MFX_LOOKAHEAD_DS_OFF
;
1790 param
->codingOption2
.NumMbPerSlice
= 0;
1792 // GOP & rate control
1793 param
->gop
.b_pyramid
= -1; // set automatically
1794 param
->gop
.gop_pic_size
= -1; // set automatically
1795 param
->gop
.gop_ref_dist
= -1; // set automatically
1796 param
->gop
.int_ref_cycle_size
= -1; // set automatically
1797 param
->rc
.icq
= 1; // enabled by default (if supported)
1798 param
->rc
.lookahead
= 1; // enabled by default (if supported)
1799 param
->rc
.cqp_offsets
[0] = 0;
1800 param
->rc
.cqp_offsets
[1] = 2;
1801 param
->rc
.cqp_offsets
[2] = 4;
1802 param
->rc
.vbv_max_bitrate
= 0; // set automatically
1803 param
->rc
.vbv_buffer_size
= 0; // set automatically
1804 param
->rc
.vbv_buffer_init
= .0; // set automatically
1806 // introduced in API 1.0
1807 memset(videoParam
, 0, sizeof(mfxVideoParam
));
1808 param
->videoParam
= videoParam
;
1809 param
->videoParam
->Protected
= 0; // reserved, must be 0
1810 param
->videoParam
->NumExtParam
= 0;
1811 param
->videoParam
->IOPattern
= MFX_IOPATTERN_IN_SYSTEM_MEMORY
;
1812 param
->videoParam
->mfx
.TargetUsage
= MFX_TARGETUSAGE_2
;
1813 param
->videoParam
->mfx
.GopOptFlag
= MFX_GOP_CLOSED
;
1814 param
->videoParam
->mfx
.NumThread
= 0; // deprecated, must be 0
1815 param
->videoParam
->mfx
.EncodedOrder
= 0; // input is in display order
1816 param
->videoParam
->mfx
.IdrInterval
= 0; // all I-frames are IDR
1817 param
->videoParam
->mfx
.NumSlice
= 0; // use Media SDK default
1818 param
->videoParam
->mfx
.NumRefFrame
= 0; // use Media SDK default
1819 param
->videoParam
->mfx
.GopPicSize
= 0; // use Media SDK default
1820 param
->videoParam
->mfx
.GopRefDist
= 0; // use Media SDK default
1821 // introduced in API 1.1
1822 param
->videoParam
->AsyncDepth
= AV_QSV_ASYNC_DEPTH_DEFAULT
;
1823 // introduced in API 1.3
1824 param
->videoParam
->mfx
.BRCParamMultiplier
= 0; // no multiplier
1826 // FrameInfo: set by video encoder, except PicStruct
1827 param
->videoParam
->mfx
.FrameInfo
.PicStruct
= MFX_PICSTRUCT_PROGRESSIVE
;
1829 // attach supported mfxExtBuffer structures to the mfxVideoParam
1830 param
->videoParam
->NumExtParam
= 0;
1831 param
->videoParam
->ExtParam
= param
->ExtParamArray
;
1832 if (info
->capabilities
& HB_QSV_CAP_VUI_VSINFO
)
1834 param
->videoParam
->ExtParam
[param
->videoParam
->NumExtParam
++] = (mfxExtBuffer
*)¶m
->videoSignalInfo
;
1836 if (info
->capabilities
& HB_QSV_CAP_OPTION1
)
1838 param
->videoParam
->ExtParam
[param
->videoParam
->NumExtParam
++] = (mfxExtBuffer
*)¶m
->codingOption
;
1840 if (info
->capabilities
& HB_QSV_CAP_OPTION2
)
1842 param
->videoParam
->ExtParam
[param
->videoParam
->NumExtParam
++] = (mfxExtBuffer
*)¶m
->codingOption2
;
1847 hb_error("hb_qsv_param_default: invalid pointer(s)");
1853 hb_triplet_t
* hb_triplet4value(hb_triplet_t
*triplets
, const int value
)
1855 for (int i
= 0; triplets
[i
].name
!= NULL
; i
++)
1857 if (triplets
[i
].value
== value
)
1859 return &triplets
[i
];
1865 hb_triplet_t
* hb_triplet4name(hb_triplet_t
*triplets
, const char *name
)
1867 for (int i
= 0; triplets
[i
].name
!= NULL
; i
++)
1869 if (!strcasecmp(triplets
[i
].name
, name
))
1871 return &triplets
[i
];
1877 hb_triplet_t
* hb_triplet4key(hb_triplet_t
*triplets
, const char *key
)
1879 for (int i
= 0; triplets
[i
].name
!= NULL
; i
++)
1881 if (!strcasecmp(triplets
[i
].key
, key
))
1883 return &triplets
[i
];
1889 const char* hb_qsv_codec_name(uint32_t codec_id
)
1901 const char* hb_qsv_profile_name(uint32_t codec_id
, uint16_t profile_id
)
1903 hb_triplet_t
*profile
= NULL
;
1907 profile
= hb_triplet4value(hb_qsv_h264_profiles
, profile_id
);
1913 return profile
!= NULL
? profile
->name
: NULL
;
1916 const char* hb_qsv_level_name(uint32_t codec_id
, uint16_t level_id
)
1918 hb_triplet_t
*level
= NULL
;
1922 level
= hb_triplet4value(hb_qsv_h264_levels
, level_id
);
1928 return level
!= NULL
? level
->name
: NULL
;
1931 const char* hb_qsv_frametype_name(uint16_t qsv_frametype
)
1933 if (qsv_frametype
& MFX_FRAMETYPE_IDR
)
1935 return qsv_frametype
& MFX_FRAMETYPE_REF
? "IDR (ref)" : "IDR";
1937 else if (qsv_frametype
& MFX_FRAMETYPE_I
)
1939 return qsv_frametype
& MFX_FRAMETYPE_REF
? "I (ref)" : "I";
1941 else if (qsv_frametype
& MFX_FRAMETYPE_P
)
1943 return qsv_frametype
& MFX_FRAMETYPE_REF
? "P (ref)" : "P";
1945 else if (qsv_frametype
& MFX_FRAMETYPE_B
)
1947 return qsv_frametype
& MFX_FRAMETYPE_REF
? "B (ref)" : "B";
1955 uint8_t hb_qsv_frametype_xlat(uint16_t qsv_frametype
, uint16_t *out_flags
)
1958 uint8_t frametype
= 0;
1960 if (qsv_frametype
& MFX_FRAMETYPE_IDR
)
1962 frametype
= HB_FRAME_IDR
;
1964 else if (qsv_frametype
& MFX_FRAMETYPE_I
)
1966 frametype
= HB_FRAME_I
;
1968 else if (qsv_frametype
& MFX_FRAMETYPE_P
)
1970 frametype
= HB_FRAME_P
;
1972 else if (qsv_frametype
& MFX_FRAMETYPE_B
)
1974 frametype
= HB_FRAME_B
;
1977 if (qsv_frametype
& MFX_FRAMETYPE_REF
)
1979 flags
|= HB_FRAME_REF
;
1982 if (out_flags
!= NULL
)
1989 int hb_qsv_impl_set_preferred(const char *name
)
1995 if (!strcasecmp(name
, "software"))
1997 if (qsv_software_info_avc
.available
)
1999 hb_qsv_info_avc
= &qsv_software_info_avc
;
2001 if (qsv_software_info_hevc
.available
)
2003 hb_qsv_info_hevc
= &qsv_software_info_hevc
;
2007 if (!strcasecmp(name
, "hardware"))
2009 if (qsv_hardware_info_avc
.available
)
2011 hb_qsv_info_avc
= &qsv_hardware_info_avc
;
2013 if (qsv_hardware_info_hevc
.available
)
2015 hb_qsv_info_hevc
= &qsv_hardware_info_hevc
;
2022 const char* hb_qsv_impl_get_name(int impl
)
2024 switch (MFX_IMPL_BASETYPE(impl
))
2026 case MFX_IMPL_SOFTWARE
:
2029 case MFX_IMPL_HARDWARE
:
2030 return "hardware (1)";
2031 case MFX_IMPL_HARDWARE2
:
2032 return "hardware (2)";
2033 case MFX_IMPL_HARDWARE3
:
2034 return "hardware (3)";
2035 case MFX_IMPL_HARDWARE4
:
2036 return "hardware (4)";
2037 case MFX_IMPL_HARDWARE_ANY
:
2038 return "hardware (any)";
2042 case MFX_IMPL_AUTO_ANY
:
2043 return "automatic (any)";
2050 void hb_qsv_force_workarounds()
2052 #define FORCE_WORKAROUNDS ~(HB_QSV_CAP_OPTION2_BREFTYPE)
2053 qsv_software_info_avc
.capabilities
&= FORCE_WORKAROUNDS
;
2054 qsv_hardware_info_avc
.capabilities
&= FORCE_WORKAROUNDS
;
2055 qsv_software_info_hevc
.capabilities
&= FORCE_WORKAROUNDS
;
2056 qsv_hardware_info_hevc
.capabilities
&= FORCE_WORKAROUNDS
;
2057 #undef FORCE_WORKAROUNDS