summaryrefslogtreecommitdiffstats
path: root/libhb/qsv_common.c
diff options
context:
space:
mode:
Diffstat (limited to 'libhb/qsv_common.c')
-rw-r--r--libhb/qsv_common.c172
1 files changed, 172 insertions, 0 deletions
diff --git a/libhb/qsv_common.c b/libhb/qsv_common.c
index 8a808b80c..ac15d7856 100644
--- a/libhb/qsv_common.c
+++ b/libhb/qsv_common.c
@@ -32,6 +32,41 @@ static hb_qsv_info_t qsv_hardware_info_avc = { .available = 0, .codec_id = MFX_
static hb_qsv_info_t qsv_software_info_hevc = { .available = 0, .codec_id = MFX_CODEC_HEVC, .implementation = MFX_IMPL_SOFTWARE, };
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, };
+// QSV-supported profile and level lists (not all exposed to the user)
+static hb_triplet_t hb_qsv_h264_profiles[] =
+{
+ { "Baseline", "baseline", MFX_PROFILE_AVC_BASELINE, },
+ { "Main", "main", MFX_PROFILE_AVC_MAIN, },
+ { "Extended", "extended", MFX_PROFILE_AVC_EXTENDED, },
+ { "High", "high", MFX_PROFILE_AVC_HIGH, },
+ { "High 4:2:2", "high422", MFX_PROFILE_AVC_HIGH_422, },
+ { "Constrained Baseline", "baseline|set1", MFX_PROFILE_AVC_CONSTRAINED_BASELINE, },
+ { "Constrained High", "high|set4|set5", MFX_PROFILE_AVC_CONSTRAINED_HIGH, },
+ { "Progressive High", "high|set4", MFX_PROFILE_AVC_PROGRESSIVE_HIGH, },
+ { NULL, },
+};
+static hb_triplet_t hb_qsv_h264_levels[] =
+{
+ { "1.0", "1.0", MFX_LEVEL_AVC_1, },
+ { "1b", "1b", MFX_LEVEL_AVC_1b, },
+ { "1.1", "1.1", MFX_LEVEL_AVC_11, },
+ { "1.2", "1.2", MFX_LEVEL_AVC_12, },
+ { "1.3", "1.3", MFX_LEVEL_AVC_13, },
+ { "2.0", "2.0", MFX_LEVEL_AVC_2, },
+ { "2.1", "2.1", MFX_LEVEL_AVC_21, },
+ { "2.2", "2.2", MFX_LEVEL_AVC_22, },
+ { "3.0", "3.0", MFX_LEVEL_AVC_3, },
+ { "3.1", "3.1", MFX_LEVEL_AVC_31, },
+ { "3.2", "3.2", MFX_LEVEL_AVC_32, },
+ { "4.0", "4.0", MFX_LEVEL_AVC_4, },
+ { "4.1", "4.1", MFX_LEVEL_AVC_41, },
+ { "4.2", "4.2", MFX_LEVEL_AVC_42, },
+ { "5.0", "5.0", MFX_LEVEL_AVC_5, },
+ { "5.1", "5.1", MFX_LEVEL_AVC_51, },
+ { "5.2", "5.2", MFX_LEVEL_AVC_52, },
+ { NULL, },
+};
+
// check available Intel Media SDK version against a minimum
#define HB_CHECK_MFX_VERSION(MFX_VERSION, MAJOR, MINOR) \
(MFX_VERSION.Major == MAJOR && MFX_VERSION.Minor >= MINOR)
@@ -1227,6 +1262,65 @@ int hb_qsv_param_parse(hb_qsv_param_t *param, hb_qsv_info_t *info,
return error ? HB_QSV_PARAM_BAD_VALUE : HB_QSV_PARAM_OK;
}
+int hb_qsv_profile_parse(hb_qsv_param_t *param, hb_qsv_info_t *info, const char *profile_key)
+{
+ hb_triplet_t *profile = NULL;
+ if (profile_key != NULL && *profile_key && strcasecmp(profile_key, "auto"))
+ {
+ switch (param->videoParam->mfx.CodecId)
+ {
+ case MFX_CODEC_AVC:
+ profile = hb_triplet4key(hb_qsv_h264_profiles, profile_key);
+ break;
+ default:
+ break;
+ }
+ if (profile == NULL)
+ {
+ return -1;
+ }
+ param->videoParam->mfx.CodecProfile = profile->value;
+ }
+ return 0;
+}
+
+int hb_qsv_level_parse(hb_qsv_param_t *param, hb_qsv_info_t *info, const char *level_key)
+{
+ hb_triplet_t *level = NULL;
+ if (level_key != NULL && *level_key && strcasecmp(level_key, "auto"))
+ {
+ switch (param->videoParam->mfx.CodecId)
+ {
+ case MFX_CODEC_AVC:
+ level = hb_triplet4key(hb_qsv_h264_levels, level_key);
+ break;
+ default:
+ break;
+ }
+ if (level == NULL)
+ {
+ return -1;
+ }
+ if (param->videoParam->mfx.CodecId == MFX_CODEC_AVC)
+ {
+ if (info->capabilities & HB_QSV_CAP_MSDK_API_1_6)
+ {
+ param->videoParam->mfx.CodecLevel = FFMIN(MFX_LEVEL_AVC_52, level->value);
+ }
+ else
+ {
+ // Media SDK API < 1.6, MFX_LEVEL_AVC_52 unsupported
+ param->videoParam->mfx.CodecLevel = FFMIN(MFX_LEVEL_AVC_51, level->value);
+ }
+ }
+ else
+ {
+ param->videoParam->mfx.CodecLevel = level->value;
+ }
+ }
+ return 0;
+}
+
const char* const* hb_qsv_preset_get_names()
{
if (qsv_hardware_generation(hb_get_cpu_platform()) >= QSV_G3)
@@ -1543,6 +1637,84 @@ int hb_qsv_param_default(hb_qsv_param_t *param, mfxVideoParam *videoParam,
return 0;
}
+hb_triplet_t* hb_triplet4value(hb_triplet_t *triplets, const int value)
+{
+ for (int i = 0; triplets[i].name != NULL; i++)
+ {
+ if (triplets[i].value == value)
+ {
+ return &triplets[i];
+ }
+ }
+ return NULL;
+}
+
+hb_triplet_t* hb_triplet4name(hb_triplet_t *triplets, const char *name)
+{
+ for (int i = 0; triplets[i].name != NULL; i++)
+ {
+ if (!strcasecmp(triplets[i].name, name))
+ {
+ return &triplets[i];
+ }
+ }
+ return NULL;
+}
+
+hb_triplet_t* hb_triplet4key(hb_triplet_t *triplets, const char *key)
+{
+ for (int i = 0; triplets[i].name != NULL; i++)
+ {
+ if (!strcasecmp(triplets[i].key, key))
+ {
+ return &triplets[i];
+ }
+ }
+ return NULL;
+}
+
+const char* hb_qsv_codec_name(uint32_t codec_id)
+{
+ switch (codec_id)
+ {
+ case MFX_CODEC_AVC:
+ return "H.264/AVC";
+
+ default:
+ return NULL;
+ }
+}
+
+const char* hb_qsv_profile_name(uint32_t codec_id, uint16_t profile_id)
+{
+ hb_triplet_t *profile = NULL;
+ switch (codec_id)
+ {
+ case MFX_CODEC_AVC:
+ profile = hb_triplet4value(hb_qsv_h264_profiles, profile_id);
+ break;
+
+ default:
+ break;
+ }
+ return profile != NULL ? profile->name : NULL;
+}
+
+const char* hb_qsv_level_name(uint32_t codec_id, uint16_t level_id)
+{
+ hb_triplet_t *level = NULL;
+ switch (codec_id)
+ {
+ case MFX_CODEC_AVC:
+ level = hb_triplet4value(hb_qsv_h264_levels, level_id);
+ break;
+
+ default:
+ break;
+ }
+ return level != NULL ? level->name : NULL;
+}
+
const char* hb_qsv_frametype_name(uint16_t qsv_frametype)
{
if (qsv_frametype & MFX_FRAMETYPE_IDR)