@@ -387,7 +387,9 @@ static const struct {
enum AVCodecID codec_id;
int codec_profile;
VAProfile va_profile;
- VAProfile (*profile_parser)(AVCodecContext *avctx);
+ VAProfile (*match_profile)(AVCodecContext *avctx,
+ const VAProfile *profile_list,
+ int profile_count);
} vaapi_profile_map[] = {
#define MAP(c, p, v, ...) { AV_CODEC_ID_ ## c, AV_PROFILE_ ## p, VAProfile ## v, __VA_ARGS__ }
MAP(MPEG2VIDEO, MPEG2_SIMPLE, MPEG2Simple ),
@@ -414,9 +416,9 @@ static const struct {
#endif
#if VA_CHECK_VERSION(1, 2, 0) && CONFIG_HEVC_VAAPI_HWACCEL
MAP(HEVC, HEVC_REXT, None,
- ff_vaapi_parse_hevc_rext_scc_profile ),
+ ff_vaapi_hevc_match_rext_scc_profile ),
MAP(HEVC, HEVC_SCC, None,
- ff_vaapi_parse_hevc_rext_scc_profile ),
+ ff_vaapi_hevc_match_rext_scc_profile ),
#endif
MAP(MJPEG, MJPEG_HUFFMAN_BASELINE_DCT,
JPEGBaseline),
@@ -499,22 +501,33 @@ static int vaapi_decode_make_config(AVCodecContext *avctx,
vaapi_profile_map[i].codec_profile == AV_PROFILE_UNKNOWN)
profile_match = 1;
- va_profile = vaapi_profile_map[i].profile_parser ?
- vaapi_profile_map[i].profile_parser(avctx) :
- vaapi_profile_map[i].va_profile;
codec_profile = vaapi_profile_map[i].codec_profile;
-
- for (j = 0; j < profile_count; j++) {
- if (va_profile == profile_list[j]) {
- exact_match = profile_match;
+ if (vaapi_profile_map[i].match_profile) {
+ va_profile =
+ vaapi_profile_map[i].match_profile(avctx, profile_list,
+ profile_count);
+ if (va_profile != VAProfileNone) {
+ matched_va_profile = va_profile;
+ matched_ff_profile = codec_profile;
+ exact_match = 1;
break;
}
- }
- if (j < profile_count) {
- matched_va_profile = va_profile;
- matched_ff_profile = codec_profile;
- if (exact_match)
- break;
+ } else {
+ va_profile = vaapi_profile_map[i].va_profile;
+
+ for (j = 0; j < profile_count; j++) {
+ if (va_profile == profile_list[j]) {
+ exact_match = profile_match;
+ break;
+ }
+ }
+
+ if (j < profile_count) {
+ matched_va_profile = va_profile;
+ matched_ff_profile = codec_profile;
+ if (exact_match)
+ break;
+ }
}
}
av_freep(&profile_list);
@@ -590,63 +590,74 @@ static int ptl_convert(const PTLCommon *general_ptl, H265RawProfileTierLevel *h2
}
/*
- * Find exact va_profile for HEVC Range Extension and Screen Content Coding Extension
+ * Find compatible va_profile for HEVC Range Extension and Screen
+ * Content Coding Extension profiles.
*/
-VAProfile ff_vaapi_parse_hevc_rext_scc_profile(AVCodecContext *avctx)
+VAProfile ff_vaapi_hevc_match_rext_scc_profile(AVCodecContext *avctx,
+ const VAProfile *profile_list,
+ int profile_count)
{
const HEVCContext *h = avctx->priv_data;
const HEVCSPS *sps = h->ps.sps;
const PTL *ptl = &sps->ptl;
const PTLCommon *general_ptl = &ptl->general_ptl;
- const H265ProfileDescriptor *profile;
H265RawProfileTierLevel h265_raw_ptl = {0};
+ static const struct {
+ int profile;
+ VAProfile va_profile;
+ } map[] = {
+#if VA_CHECK_VERSION(1, 2, 0)
+ { H265_PROFILE_MAIN_12,
+ VAProfileHEVCMain12 },
+ { H265_PROFILE_MAIN_422_10,
+ VAProfileHEVCMain422_10 },
+ { H265_PROFILE_MAIN_422_12,
+ VAProfileHEVCMain422_12 },
+ { H265_PROFILE_MAIN_444,
+ VAProfileHEVCMain444 },
+ { H265_PROFILE_MAIN_444_10,
+ VAProfileHEVCMain444_10 },
+ { H265_PROFILE_MAIN_444_12,
+ VAProfileHEVCMain444_12 },
+ { H265_PROFILE_SCREEN_EXTENDED_MAIN,
+ VAProfileHEVCSccMain },
+ { H265_PROFILE_SCREEN_EXTENDED_MAIN_10,
+ VAProfileHEVCSccMain10 },
+ { H265_PROFILE_SCREEN_EXTENDED_MAIN_444,
+ VAProfileHEVCSccMain444 },
+#endif
+#if VA_CHECK_VERSION(1, 8, 0)
+ { H265_PROFILE_SCREEN_EXTENDED_MAIN_444_10,
+ VAProfileHEVCSccMain444_10 },
+#endif
+ };
+
/* convert PTLCommon to H265RawProfileTierLevel */
ptl_convert(general_ptl, &h265_raw_ptl);
- profile = ff_h265_find_profile(&h265_raw_ptl);
- if (!profile) {
- av_log(avctx, AV_LOG_WARNING, "HEVC profile is not found.\n");
- goto end;
- } else {
- av_log(avctx, AV_LOG_VERBOSE, "HEVC profile %s is found.\n", profile->name);
+ for (int i = 0; i < FF_ARRAY_ELEMS(map); i++) {
+ int available = 0;
+ for (int j = 0; j < profile_count; j++) {
+ if (profile_list[j] == map[i].va_profile) {
+ available = 1;
+ break;
+ }
+ }
+ if (!available)
+ continue;
+
+ if (ff_h265_profile_compatible(&h265_raw_ptl,
+ map[i].profile)) {
+ const H265ProfileDescriptor *profile_desc =
+ ff_h265_get_profile(map[i].profile);
+ av_log(avctx, AV_LOG_VERBOSE,
+ "Decoding with HEVC profile %s.\n",
+ profile_desc->name);
+ return map[i].va_profile;
+ }
}
-#if VA_CHECK_VERSION(1, 2, 0)
- if (!strcmp(profile->name, "Main 12") ||
- !strcmp(profile->name, "Main 12 Intra"))
- return VAProfileHEVCMain12;
- else if (!strcmp(profile->name, "Main 4:2:2 10") ||
- !strcmp(profile->name, "Main 4:2:2 10 Intra"))
- return VAProfileHEVCMain422_10;
- else if (!strcmp(profile->name, "Main 4:2:2 12") ||
- !strcmp(profile->name, "Main 4:2:2 12 Intra"))
- return VAProfileHEVCMain422_12;
- else if (!strcmp(profile->name, "Main 4:4:4") ||
- !strcmp(profile->name, "Main 4:4:4 Intra"))
- return VAProfileHEVCMain444;
- else if (!strcmp(profile->name, "Main 4:4:4 10") ||
- !strcmp(profile->name, "Main 4:4:4 10 Intra"))
- return VAProfileHEVCMain444_10;
- else if (!strcmp(profile->name, "Main 4:4:4 12") ||
- !strcmp(profile->name, "Main 4:4:4 12 Intra"))
- return VAProfileHEVCMain444_12;
- else if (!strcmp(profile->name, "Screen-Extended Main"))
- return VAProfileHEVCSccMain;
- else if (!strcmp(profile->name, "Screen-Extended Main 10"))
- return VAProfileHEVCSccMain10;
- else if (!strcmp(profile->name, "Screen-Extended Main 4:4:4"))
- return VAProfileHEVCSccMain444;
-#if VA_CHECK_VERSION(1, 8, 0)
- else if (!strcmp(profile->name, "Screen-Extended Main 4:4:4 10"))
- return VAProfileHEVCSccMain444_10;
-#endif
-#else
- av_log(avctx, AV_LOG_WARNING, "HEVC profile %s is "
- "not supported with this VA version.\n", profile->name);
-#endif
-
-end:
if (avctx->hwaccel_flags & AV_HWACCEL_FLAG_ALLOW_PROFILE_MISMATCH) {
// Default to selecting Main profile if profile mismatch is allowed
return VAProfileHEVCMain;
@@ -22,6 +22,8 @@
#include <va/va.h>
#include "avcodec.h"
-VAProfile ff_vaapi_parse_hevc_rext_scc_profile(AVCodecContext *avctx);
+VAProfile ff_vaapi_hevc_match_rext_scc_profile(AVCodecContext *avctx,
+ const VAProfile *profile_list,
+ int profile_count);
#endif /* AVCODEC_VAAPI_HEVC_H */