WinGui: Fix another instance of the Caliburn vs Json.net sillyness where objects...
[HandBrake.git] / libhb / qsv_common.c
blobe383b806e8998cd40ec2a07bf66c13556298474c
1 /* qsv_common.c
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
8 */
10 #ifdef USE_QSV
12 #include <stdio.h>
13 #include <string.h>
15 #include "hb.h"
16 #include "ports.h"
17 #include "common.h"
18 #include "hb_dict.h"
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;
25 // API versions
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, },
46 { NULL, },
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, },
67 { NULL, },
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.
79 enum
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)
89 switch (cpu_platform)
91 case HB_CPU_PLATFORM_INTEL_BNL:
92 return QSV_G0;
93 case HB_CPU_PLATFORM_INTEL_SNB:
94 return QSV_G1;
95 case HB_CPU_PLATFORM_INTEL_IVB:
96 case HB_CPU_PLATFORM_INTEL_SLM:
97 case HB_CPU_PLATFORM_INTEL_CHT:
98 return QSV_G2;
99 case HB_CPU_PLATFORM_INTEL_HSW:
100 return QSV_G3;
101 case HB_CPU_PLATFORM_INTEL_BDW:
102 default:
103 return QSV_G4;
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)
122 switch (encoder)
124 case HB_VCODEC_QSV_H264:
125 return hb_qsv_info_avc != NULL && hb_qsv_info_avc->available;
126 default:
127 return 0;
131 int hb_qsv_audio_encoder_is_enabled(int encoder)
133 switch (encoder)
135 default:
136 return 0;
140 static void init_video_param(mfxVideoParam *videoParam)
142 if (videoParam == NULL)
144 return;
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)
174 return;
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)
192 return;
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)
207 return;
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);
229 * Mode 1:
230 * - in is NULL
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
235 * Mode 2:
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
241 mfxStatus status;
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 */
270 return 0;
272 else
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)
290 info->available = 1;
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)
298 fprintf(stderr,
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 */
310 return 0;
313 if (info->implementation & MFX_IMPL_AUDIO)
315 /* We don't have any audio capability checks yet */
316 return 0;
318 else
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;
330 else
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)
427 fprintf(stderr,
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)
459 fprintf(stderr,
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)
486 #if 0
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");
498 #endif
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;
576 else
578 fprintf(stderr,
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);
588 return 0;
591 int hb_qsv_info_init()
593 static int init_done = 0;
594 if (init_done)
595 return 0;
596 init_done = 1;
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.
605 mfxSession session;
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");
623 MFXClose(session);
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");
644 MFXClose(session);
647 // success
648 return 0;
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");
665 else
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");
677 else
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): ");
770 else
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): ");
790 else
792 hb_deep_log(2, " - H.265 encoder: no");
797 hb_qsv_info_t* hb_qsv_info_get(int encoder)
799 switch (encoder)
801 case HB_VCODEC_QSV_H264:
802 return hb_qsv_info_avc;
803 default:
804 return NULL;
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");
814 goto fail;
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)
826 goto fail;
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)
834 goto fail;
836 hb_list_add(mfxPluginList, (void*)&MFX_PLUGINID_HEVCE_SW);
841 return mfxPluginList;
843 fail:
844 hb_list_close(&mfxPluginList);
845 return NULL;
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);
863 hb_list_close(_l);
866 const char* hb_qsv_decode_get_codec_name(enum AVCodecID codec_id)
868 switch (codec_id)
870 case AV_CODEC_ID_H264:
871 return "h264_qsv";
873 default:
874 return NULL;
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);
894 return 0;
897 int hb_qsv_codingoption_xlat(int val)
899 switch (HB_QSV_CLIP3(-1, 2, val))
901 case 0:
902 return MFX_CODINGOPTION_OFF;
903 case 1:
904 case 2: // MFX_CODINGOPTION_ADAPTIVE, reserved
905 return MFX_CODINGOPTION_ON;
906 case -1:
907 default:
908 return MFX_CODINGOPTION_UNKNOWN;
912 int hb_qsv_trellisvalue_xlat(int val)
914 switch (HB_QSV_CLIP3(0, 3, val))
916 case 0:
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;
924 default:
925 return MFX_TRELLIS_UNKNOWN;
929 const char* hb_qsv_codingoption_get_name(int val)
931 switch (val)
933 case MFX_CODINGOPTION_ON:
934 return "on";
935 case MFX_CODINGOPTION_OFF:
936 return "off";
937 case MFX_CODINGOPTION_ADAPTIVE:
938 return "adaptive";
939 case MFX_CODINGOPTION_UNKNOWN:
940 return "unknown (auto)";
941 default:
942 return NULL;
946 int hb_qsv_atoindex(const char* const *arr, const char *str, int *err)
948 int i;
949 for (i = 0; arr[i] != NULL; i++)
951 if (!strcasecmp(arr[i], str))
953 break;
956 *err = (arr[i] == NULL);
957 return i;
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"))
967 return 1;
969 if (!strcasecmp(str, "0") ||
970 !strcasecmp(str, "no") ||
971 !strcasecmp(str, "false"))
973 return 0;
975 *err = 1;
976 return 0;
979 // adapted from libx264
980 int hb_qsv_atoi(const char *str, int *err)
982 char *end;
983 int v = strtol(str, &end, 0);
984 if (end == str || end[0] != '\0')
986 *err = 1;
988 return v;
991 // adapted from libx264
992 float hb_qsv_atof(const char *str, int *err)
994 char *end;
995 float v = strtod(str, &end);
996 if (end == str || end[0] != '\0')
998 *err = 1;
1000 return v;
1003 int hb_qsv_param_parse(hb_qsv_param_t *param, hb_qsv_info_t *info,
1004 const char *key, const char *value)
1006 float fvalue;
1007 int ivalue, error = 0;
1008 if (param == NULL || info == NULL)
1010 return HB_QSV_PARAM_ERROR;
1012 if (value == NULL || value[0] == '\0')
1014 value = "true";
1016 else if (value[0] == '=')
1018 value++;
1020 if (key == NULL || key[0] == '\0')
1022 return HB_QSV_PARAM_BAD_NAME;
1024 else if (!strncasecmp(key, "no-", 3))
1026 key += 3;
1027 value = hb_qsv_atobool(value, &error) ? "false" : "true";
1028 if (error)
1030 return HB_QSV_PARAM_BAD_VALUE;
1033 if (!strcasecmp(key, "target-usage") ||
1034 !strcasecmp(key, "tu"))
1036 ivalue = hb_qsv_atoi(value, &error);
1037 if (!error)
1039 param->videoParam->mfx.TargetUsage = HB_QSV_CLIP3(MFX_TARGETUSAGE_1,
1040 MFX_TARGETUSAGE_7,
1041 ivalue);
1044 else if (!strcasecmp(key, "num-ref-frame") ||
1045 !strcasecmp(key, "ref"))
1047 ivalue = hb_qsv_atoi(value, &error);
1048 if (!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);
1056 if (!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);
1065 if (!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);
1075 if (!error)
1077 param->gop.b_pyramid = HB_QSV_CLIP3(-1, 1, ivalue);
1080 else
1082 return HB_QSV_PARAM_UNSUPPORTED;
1085 else if (!strcasecmp(key, "scenecut"))
1087 ivalue = hb_qsv_atobool(value, &error);
1088 if (!error)
1090 if (!ivalue)
1092 param->videoParam->mfx.GopOptFlag |= MFX_GOP_STRICT;
1094 else
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);
1106 if (!error)
1108 param->codingOption2.AdaptiveI = hb_qsv_codingoption_xlat(ivalue);
1111 else
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);
1122 if (!error)
1124 param->codingOption2.AdaptiveB = hb_qsv_codingoption_xlat(ivalue);
1127 else
1129 return HB_QSV_PARAM_UNSUPPORTED;
1132 else if (!strcasecmp(key, "force-cqp"))
1134 ivalue = hb_qsv_atobool(value, &error);
1135 if (!error)
1137 param->rc.icq = !ivalue;
1140 else if (!strcasecmp(key, "cqp-offset-i"))
1142 ivalue = hb_qsv_atoi(value, &error);
1143 if (!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);
1151 if (!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);
1159 if (!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);
1167 if (!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);
1175 if (!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);
1183 if (!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)
1194 case MFX_CODEC_AVC:
1195 ivalue = hb_qsv_atobool(value, &error);
1196 break;
1197 default:
1198 return HB_QSV_PARAM_UNSUPPORTED;
1201 else
1203 return HB_QSV_PARAM_UNSUPPORTED;
1205 if (!error)
1207 if (!strcasecmp(key, "cabac"))
1209 ivalue = !ivalue;
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)
1220 case MFX_CODEC_AVC:
1221 ivalue = hb_qsv_atoindex(hb_h264_vidformat_names, value, &error);
1222 break;
1223 default:
1224 return HB_QSV_PARAM_UNSUPPORTED;
1227 else
1229 return HB_QSV_PARAM_UNSUPPORTED;
1231 if (!error)
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)
1242 case MFX_CODEC_AVC:
1243 ivalue = hb_qsv_atoindex(hb_h264_fullrange_names, value, &error);
1244 break;
1245 default:
1246 return HB_QSV_PARAM_UNSUPPORTED;
1249 else
1251 return HB_QSV_PARAM_UNSUPPORTED;
1253 if (!error)
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)
1264 case MFX_CODEC_AVC:
1265 ivalue = hb_qsv_atoindex(hb_h264_colorprim_names, value, &error);
1266 break;
1267 default:
1268 return HB_QSV_PARAM_UNSUPPORTED;
1271 else
1273 return HB_QSV_PARAM_UNSUPPORTED;
1275 if (!error)
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)
1287 case MFX_CODEC_AVC:
1288 ivalue = hb_qsv_atoindex(hb_h264_transfer_names, value, &error);
1289 break;
1290 default:
1291 return HB_QSV_PARAM_UNSUPPORTED;
1294 else
1296 return HB_QSV_PARAM_UNSUPPORTED;
1298 if (!error)
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)
1310 case MFX_CODEC_AVC:
1311 ivalue = hb_qsv_atoindex(hb_h264_colmatrix_names, value, &error);
1312 break;
1313 default:
1314 return HB_QSV_PARAM_UNSUPPORTED;
1317 else
1319 return HB_QSV_PARAM_UNSUPPORTED;
1321 if (!error)
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)
1332 case MFX_CODEC_AVC:
1333 ivalue = hb_qsv_atobool(value, &error);
1334 break;
1335 default:
1336 return HB_QSV_PARAM_UNSUPPORTED;
1338 if (!error)
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)
1349 case MFX_CODEC_AVC:
1350 ivalue = hb_qsv_atobool(value, &error);
1351 break;
1352 default:
1353 return HB_QSV_PARAM_UNSUPPORTED;
1355 if (!error)
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);
1367 if (!error)
1369 param->codingOption2.MBBRC = hb_qsv_codingoption_xlat(ivalue);
1372 else
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);
1382 if (!error)
1384 param->codingOption2.ExtBRC = hb_qsv_codingoption_xlat(ivalue);
1387 else
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);
1398 if (!error)
1400 param->rc.lookahead = ivalue;
1403 else
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);
1414 if (!error)
1416 param->codingOption2.LookAheadDepth = HB_QSV_CLIP3(10, 100,
1417 ivalue);
1420 else
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);
1431 if (!error)
1433 param->codingOption2.LookAheadDS = HB_QSV_CLIP3(MFX_LOOKAHEAD_DS_UNKNOWN,
1434 MFX_LOOKAHEAD_DS_4x,
1435 ivalue);
1438 else
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);
1448 if (!error)
1450 param->codingOption2.Trellis = hb_qsv_trellisvalue_xlat(ivalue);
1453 else
1455 return HB_QSV_PARAM_UNSUPPORTED;
1458 else
1461 * TODO:
1462 * - slice count (num-slice/slices, num-mb-per-slice/slice-max-mbs)
1463 * - open-gop
1464 * - fake-interlaced (mfxExtCodingOption.FramePicture???)
1465 * - intra-refresh
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)
1479 case MFX_CODEC_AVC:
1480 profile = hb_triplet4key(hb_qsv_h264_profiles, profile_key);
1481 break;
1482 default:
1483 break;
1485 if (profile == NULL)
1487 return -1;
1489 param->videoParam->mfx.CodecProfile = profile->value;
1491 return 0;
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)
1501 case MFX_CODEC_AVC:
1502 level = hb_triplet4key(hb_qsv_h264_levels, level_key);
1503 break;
1504 default:
1505 break;
1507 if (level == NULL)
1509 return -1;
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);
1517 else
1519 // Media SDK API < 1.6, MFX_LEVEL_AVC_52 unsupported
1520 param->videoParam->mfx.CodecLevel = FFMIN(MFX_LEVEL_AVC_51, level->value);
1523 else
1525 param->videoParam->mfx.CodecLevel = level->value;
1528 return 0;
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;
1537 else
1539 return hb_qsv_preset_names1;
1543 const char* const* hb_qsv_profile_get_names(int encoder)
1545 switch (encoder)
1547 case HB_VCODEC_QSV_H264:
1548 return hb_h264_profile_names;
1549 default:
1550 return NULL;
1554 const char* const* hb_qsv_level_get_names(int encoder)
1556 switch (encoder)
1558 case HB_VCODEC_QSV_H264:
1559 return hb_h264_level_names;
1560 default:
1561 return NULL;
1565 const char* hb_qsv_video_quality_get_name(uint32_t codec)
1567 uint64_t caps;
1568 switch (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";
1574 default:
1575 return "QP";
1579 void hb_qsv_video_quality_get_limits(uint32_t codec, float *low, float *high,
1580 float *granularity, int *direction)
1582 uint64_t caps;
1583 switch (codec)
1585 case HB_VCODEC_QSV_H264:
1586 caps = hb_qsv_info_avc != NULL ? hb_qsv_info_avc->capabilities : 0;
1587 *direction = 1;
1588 *granularity = 1.;
1589 *low = (caps & HB_QSV_CAP_RATECONTROL_ICQ) ? 1. : 0.;
1590 *high = 51.;
1591 break;
1593 default:
1594 *direction = 1;
1595 *granularity = 1.;
1596 *low = 0.;
1597 *high = 51.;
1598 break;
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);
1609 if (ret)
1611 return ret;
1614 else
1616 hb_error("hb_qsv_param_default_preset: invalid pointer(s)");
1617 return -1;
1619 if (preset != NULL && preset[0] != '\0')
1621 if (!strcasecmp(preset, "quality"))
1624 * HSW TargetUsage: 2
1625 * NumRefFrame: 0
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)
1629 * LookAhead: 1 (on)
1630 * LookAheadDepth: 40
1633 * SNB
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
1643 * NumRefFrame: 1
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;
1656 else
1659 * SNB
1660 * IVB TargetUsage: 2
1661 * NumRefFrame: 0
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;
1697 else
1700 * SNB
1701 * IVB TargetUsage: 4
1702 * NumRefFrame: 0
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;
1712 else
1714 hb_error("hb_qsv_param_default_preset: invalid preset '%s'", preset);
1715 return -1;
1718 return 0;
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(&param->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(&param->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(&param->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*)&param->videoSignalInfo;
1836 if (info->capabilities & HB_QSV_CAP_OPTION1)
1838 param->videoParam->ExtParam[param->videoParam->NumExtParam++] = (mfxExtBuffer*)&param->codingOption;
1840 if (info->capabilities & HB_QSV_CAP_OPTION2)
1842 param->videoParam->ExtParam[param->videoParam->NumExtParam++] = (mfxExtBuffer*)&param->codingOption2;
1845 else
1847 hb_error("hb_qsv_param_default: invalid pointer(s)");
1848 return -1;
1850 return 0;
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];
1862 return NULL;
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];
1874 return NULL;
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];
1886 return NULL;
1889 const char* hb_qsv_codec_name(uint32_t codec_id)
1891 switch (codec_id)
1893 case MFX_CODEC_AVC:
1894 return "H.264/AVC";
1896 default:
1897 return NULL;
1901 const char* hb_qsv_profile_name(uint32_t codec_id, uint16_t profile_id)
1903 hb_triplet_t *profile = NULL;
1904 switch (codec_id)
1906 case MFX_CODEC_AVC:
1907 profile = hb_triplet4value(hb_qsv_h264_profiles, profile_id);
1908 break;
1910 default:
1911 break;
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;
1919 switch (codec_id)
1921 case MFX_CODEC_AVC:
1922 level = hb_triplet4value(hb_qsv_h264_levels, level_id);
1923 break;
1925 default:
1926 break;
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";
1949 else
1951 return "unknown";
1955 uint8_t hb_qsv_frametype_xlat(uint16_t qsv_frametype, uint16_t *out_flags)
1957 uint16_t flags = 0;
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)
1984 *out_flags = flags;
1986 return frametype;
1989 int hb_qsv_impl_set_preferred(const char *name)
1991 if (name == NULL)
1993 return -1;
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;
2005 return 0;
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;
2017 return 0;
2019 return -1;
2022 const char* hb_qsv_impl_get_name(int impl)
2024 switch (MFX_IMPL_BASETYPE(impl))
2026 case MFX_IMPL_SOFTWARE:
2027 return "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)";
2040 case MFX_IMPL_AUTO:
2041 return "automatic";
2042 case MFX_IMPL_AUTO_ANY:
2043 return "automatic (any)";
2045 default:
2046 return NULL;
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
2060 #endif // USE_QSV