diff mbox series

[FFmpeg-devel,2/2] lavc/vaapi_hevc: Don't require exact profiles

Message ID e547ab6f-a86d-46e3-abbb-7e6233195992@jkqxz.net
State New
Headers show
Series [FFmpeg-devel,1/2] lavc/h265_profile_level: Expand profile compatibility checking | expand

Checks

Context Check Description
yinshiyou/make_loongarch64 success Make finished
yinshiyou/make_fate_loongarch64 fail Make fate failed
andriy/make_x86 success Make finished
andriy/make_fate_x86 fail Make fate failed

Commit Message

Mark Thompson April 22, 2024, 9:23 p.m. UTC
Rather than turning the constraint flags into a single profile and then
searching for that profile (and failing if it doesn't match any profile
exactly), instead search all supported profiles and use the first one
which supports the given set of constraint flags.
---
This fixes decode of rext 8-bit 4:2:0; it will correctly pick Main 12 or Main 4:2:2 10 or Main 4:4:4 (first one available) to use as the decoding profile after this patch.

 libavcodec/vaapi_decode.c | 45 ++++++++++++-------
 libavcodec/vaapi_hevc.c   | 95 +++++++++++++++++++++------------------
 libavcodec/vaapi_hevc.h   |  4 +-
 3 files changed, 83 insertions(+), 61 deletions(-)

Comments

Xiang, Haihao April 24, 2024, 1:45 p.m. UTC | #1
On Ma, 2024-04-22 at 22:23 +0100, Mark Thompson wrote:
> Rather than turning the constraint flags into a single profile and then
> searching for that profile (and failing if it doesn't match any profile
> exactly), instead search all supported profiles and use the first one
> which supports the given set of constraint flags.
> ---
> This fixes decode of rext 8-bit 4:2:0; it will correctly pick Main 12 or Main
> 4:2:2 10 or Main 4:4:4 (first one available) to use as the decoding profile
> after this patch.

sw decoding and vaapi decoding might have different bits (There is the same
issue if applying Fei's patchset).  

For example:
$ ffmpeg -hwaccel vaapi -f lavfi -i testsrc -vf 'format=nv12,hwupload' -c:v
hevc_vaapi -profile:v rext -vframes 30 -y out.mp4

8bit ouput if using sw decoding:
$ ffmpeg -i out.mp4 -f null - 
[...]
Stream #0:0(und): Video: wrapped_avframe, yuv420p(tv, progressive), 320x240 [SAR
1:1 DAR 4:3], q=2-31, 200 kb/s, 25 fps, 25 tbn (default)

12bit output if using vaapi decoding:
$ ffmpeg -hwaccel vaapi -i out.mp4 -f null -
[...]
 Stream #0:0(und): Video: wrapped_avframe, p012le(tv, progressive), 320x240 [SAR
1:1 DAR 4:3], q=2-31, 200 kb/s, 25 fps, 25 tbn (default)

Thanks
Haihao

> 
>  libavcodec/vaapi_decode.c | 45 ++++++++++++-------
>  libavcodec/vaapi_hevc.c   | 95 +++++++++++++++++++++------------------
>  libavcodec/vaapi_hevc.h   |  4 +-
>  3 files changed, 83 insertions(+), 61 deletions(-)
> 
> diff --git a/libavcodec/vaapi_decode.c b/libavcodec/vaapi_decode.c
> index 21b273cd0f..f1327464f5 100644
> --- a/libavcodec/vaapi_decode.c
> +++ b/libavcodec/vaapi_decode.c
> @@ -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);
> diff --git a/libavcodec/vaapi_hevc.c b/libavcodec/vaapi_hevc.c
> index 77f55ff8b1..28f7c9280e 100644
> --- a/libavcodec/vaapi_hevc.c
> +++ b/libavcodec/vaapi_hevc.c
> @@ -590,63 +590,70 @@ 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_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 },
> +#endif
> +#if VA_CHECK_VERSION(1, 8, 0)
> +        { H265_PROFILE_SCREEN_EXTENDED_MAIN_444,
> +          VAProfileHEVCSccMain444 },
> +#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;
> diff --git a/libavcodec/vaapi_hevc.h b/libavcodec/vaapi_hevc.h
> index 449635d0d7..455c68e6ba 100644
> --- a/libavcodec/vaapi_hevc.h
> +++ b/libavcodec/vaapi_hevc.h
> @@ -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 */
Mark Thompson April 28, 2024, 2:14 p.m. UTC | #2
On 24/04/2024 14:45, Xiang, Haihao wrote:
> On Ma, 2024-04-22 at 22:23 +0100, Mark Thompson wrote:
>> Rather than turning the constraint flags into a single profile and then
>> searching for that profile (and failing if it doesn't match any profile
>> exactly), instead search all supported profiles and use the first one
>> which supports the given set of constraint flags.
>> ---
>> This fixes decode of rext 8-bit 4:2:0; it will correctly pick Main 12 or Main
>> 4:2:2 10 or Main 4:4:4 (first one available) to use as the decoding profile
>> after this patch.
> 
> sw decoding and vaapi decoding might have different bits (There is the same
> issue if applying Fei's patchset).  
> 
> For example:
> $ ffmpeg -hwaccel vaapi -f lavfi -i testsrc -vf 'format=nv12,hwupload' -c:v
> hevc_vaapi -profile:v rext -vframes 30 -y out.mp4
> 
> 8bit ouput if using sw decoding:
> $ ffmpeg -i out.mp4 -f null - 
> [...]
> Stream #0:0(und): Video: wrapped_avframe, yuv420p(tv, progressive), 320x240 [SAR
> 1:1 DAR 4:3], q=2-31, 200 kb/s, 25 fps, 25 tbn (default)
> 
> 12bit output if using vaapi decoding:
> $ ffmpeg -hwaccel vaapi -i out.mp4 -f null -
> [...]
>  Stream #0:0(und): Video: wrapped_avframe, p012le(tv, progressive), 320x240 [SAR
> 1:1 DAR 4:3], q=2-31, 200 kb/s, 25 fps, 25 tbn (default)

That comes from what the driver reports support for, though?

E.g. with the Intel iHD driver, I have

        {
            "profile": 23,
            "name": "HEVCMain12",
...
                    "surface_formats": [
                        {
                            "rt_format": "YUV420",
                            "max_width": 16384,
                            "max_height": 16384,
                            "memory_types": [
                                "VA",
                                "DRM_PRIME_2",
                            ],
                            "pixel_formats": [
                                "P012",
                                "P016",
                            ],
                        },

So to decode a 4:2:0 8-bit input it is asking for a P012 or P016 surface.

If the driver reported that a Main 12 profile 4:2:0 8-bit input could be decoded to an NV12 surface then it would be picked by the logic in vaapi_decode_find_best_format(), since it would be a better match than the higher-depth formats.

Thanks,

- Mark
Xiang, Haihao April 30, 2024, 6 a.m. UTC | #3
On So, 2024-04-28 at 15:14 +0100, Mark Thompson wrote:
> On 24/04/2024 14:45, Xiang, Haihao wrote:
> > On Ma, 2024-04-22 at 22:23 +0100, Mark Thompson wrote:
> > > Rather than turning the constraint flags into a single profile and then
> > > searching for that profile (and failing if it doesn't match any profile
> > > exactly), instead search all supported profiles and use the first one
> > > which supports the given set of constraint flags.
> > > ---
> > > This fixes decode of rext 8-bit 4:2:0; it will correctly pick Main 12 or
> > > Main
> > > 4:2:2 10 or Main 4:4:4 (first one available) to use as the decoding
> > > profile
> > > after this patch.
> > 
> > sw decoding and vaapi decoding might have different bits (There is the same
> > issue if applying Fei's patchset).  
> > 
> > For example:
> > $ ffmpeg -hwaccel vaapi -f lavfi -i testsrc -vf 'format=nv12,hwupload' -c:v
> > hevc_vaapi -profile:v rext -vframes 30 -y out.mp4
> > 
> > 8bit ouput if using sw decoding:
> > $ ffmpeg -i out.mp4 -f null - 
> > [...]
> > Stream #0:0(und): Video: wrapped_avframe, yuv420p(tv, progressive), 320x240
> > [SAR
> > 1:1 DAR 4:3], q=2-31, 200 kb/s, 25 fps, 25 tbn (default)
> > 
> > 12bit output if using vaapi decoding:
> > $ ffmpeg -hwaccel vaapi -i out.mp4 -f null -
> > [...]
> >  Stream #0:0(und): Video: wrapped_avframe, p012le(tv, progressive), 320x240
> > [SAR
> > 1:1 DAR 4:3], q=2-31, 200 kb/s, 25 fps, 25 tbn (default)
> 
> That comes from what the driver reports support for, though?
> 
> E.g. with the Intel iHD driver, I have
> 
>         {
>             "profile": 23,
>             "name": "HEVCMain12",
> ...
>                     "surface_formats": [
>                         {
>                             "rt_format": "YUV420",
>                             "max_width": 16384,
>                             "max_height": 16384,
>                             "memory_types": [
>                                 "VA",
>                                 "DRM_PRIME_2",
>                             ],
>                             "pixel_formats": [
>                                 "P012",
>                                 "P016",
>                             ],
>                         },
> 
> So to decode a 4:2:0 8-bit input it is asking for a P012 or P016 surface.
> 
> If the driver reported that a Main 12 profile 4:2:0 8-bit input could be
> decoded to an NV12 surface then it would be picked by the logic in
> vaapi_decode_find_best_format(), since it would be a better match than the
> higher-depth formats.

You are right, the iHD driver doesn't report the support for HEVCMain12 8bit. 

Thanks
Haihao
diff mbox series

Patch

diff --git a/libavcodec/vaapi_decode.c b/libavcodec/vaapi_decode.c
index 21b273cd0f..f1327464f5 100644
--- a/libavcodec/vaapi_decode.c
+++ b/libavcodec/vaapi_decode.c
@@ -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);
diff --git a/libavcodec/vaapi_hevc.c b/libavcodec/vaapi_hevc.c
index 77f55ff8b1..28f7c9280e 100644
--- a/libavcodec/vaapi_hevc.c
+++ b/libavcodec/vaapi_hevc.c
@@ -590,63 +590,70 @@  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_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 },
+#endif
+#if VA_CHECK_VERSION(1, 8, 0)
+        { H265_PROFILE_SCREEN_EXTENDED_MAIN_444,
+          VAProfileHEVCSccMain444 },
+#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;
diff --git a/libavcodec/vaapi_hevc.h b/libavcodec/vaapi_hevc.h
index 449635d0d7..455c68e6ba 100644
--- a/libavcodec/vaapi_hevc.h
+++ b/libavcodec/vaapi_hevc.h
@@ -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 */