On 09/04/2019 03:33, Linjie Fu wrote:
> Use the profile constraint flags to determine the exact va_profile for
> HEVC_REXT.
> 
> Directly cast PTLCommon to H265RawProfileTierLevel,

Please don't.  The two structures aren't really connected, they shouldn't be 
assumed to be compatible.

>                                                     and use 
> ff_h265_get_profile
> to get the exact profile.
> 
> Add h265_profile_level.o to build objects for vaapi_decode to fix the compile
> dependency issue.
> 
> Signed-off-by: Linjie Fu <linjie...@intel.com>
> ---
> [v2]: use constraint flags to determine the exact profile, expose the
> codec-specific stuff at the beginning.
> [v3]: move the VA version check to fix the compile issue.
> [v4]: fix the build issue.
> 
>  libavcodec/Makefile       |  2 +-
>  libavcodec/vaapi_decode.c | 73 +++++++++++++++++++++++++++++++--------
>  2 files changed, 59 insertions(+), 16 deletions(-)
> 
> diff --git a/libavcodec/Makefile b/libavcodec/Makefile
> index 15c43a8a6a..c0df0ad90a 100644
> --- a/libavcodec/Makefile
> +++ b/libavcodec/Makefile
> @@ -857,7 +857,7 @@ OBJS-$(CONFIG_ADPCM_YAMAHA_ENCODER)       += adpcmenc.o 
> adpcm_data.o
>  OBJS-$(CONFIG_D3D11VA)                    += dxva2.o
>  OBJS-$(CONFIG_DXVA2)                      += dxva2.o
>  OBJS-$(CONFIG_NVDEC)                      += nvdec.o
> -OBJS-$(CONFIG_VAAPI)                      += vaapi_decode.o
> +OBJS-$(CONFIG_VAAPI)                      += vaapi_decode.o 
> h265_profile_level.o
>  OBJS-$(CONFIG_VIDEOTOOLBOX)               += videotoolbox.o
>  OBJS-$(CONFIG_VDPAU)                      += vdpau.o
>  
> diff --git a/libavcodec/vaapi_decode.c b/libavcodec/vaapi_decode.c
> index 69512e1d45..47db6c874a 100644
> --- a/libavcodec/vaapi_decode.c
> +++ b/libavcodec/vaapi_decode.c
> @@ -24,6 +24,8 @@
>  #include "decode.h"
>  #include "internal.h"
>  #include "vaapi_decode.h"
> +#include "hevcdec.h"
> +#include "h265_profile_level.h"
>  
>  
>  int ff_vaapi_decode_make_param_buffer(AVCodecContext *avctx,
> @@ -401,6 +403,33 @@ static const struct {
>  #undef MAP
>  };
>  
> +/*
> + * Find exact va_profile for HEVC Range Extension
> + */
> +static VAProfile vaapi_decode_find_exact_profile(AVCodecContext *avctx)
> +{
> +    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;
> +
> +    /* PTLCommon should match the member sequence in 
> H265RawProfileTierLevel*/
> +    profile = ff_h265_get_profile((H265RawProfileTierLevel *)general_ptl);

This can return NULL.

> +
> +#if VA_CHECK_VERSION(1, 2, 0)
> +    if (!strcmp(profile->name, "Main 4:2:2 10"))
> +        return VAProfileHEVCMain422_10;
> +    else if (!strcmp(profile->name, "Main 4:4:4"))
> +        return VAProfileHEVCMain444;
> +    else if (!strcmp(profile->name, "Main 4:4:4 10"))
> +        return VAProfileHEVCMain444_10;
> +#else
> +    av_log(avctx, AV_LOG_WARNING, "HEVC profile %s is "
> +                        "not supported with this VA version.\n", 
> profile->name);
> +#endif
> +    return VAProfileNone;
> +}
>  /*
>   * Set *va_config and the frames_ref fields from the current codec parameters
>   * in avctx.
> @@ -447,24 +476,38 @@ static int vaapi_decode_make_config(AVCodecContext 
> *avctx,
>      matched_va_profile = VAProfileNone;
>      exact_match = 0;
>  
> -    for (i = 0; i < FF_ARRAY_ELEMS(vaapi_profile_map); i++) {
> -        int profile_match = 0;
> -        if (avctx->codec_id != vaapi_profile_map[i].codec_id)
> -            continue;
> -        if (avctx->profile == vaapi_profile_map[i].codec_profile ||
> -            vaapi_profile_map[i].codec_profile == FF_PROFILE_UNKNOWN)
> -            profile_match = 1;
> -        for (j = 0; j < profile_count; j++) {
> -            if (vaapi_profile_map[i].va_profile == profile_list[j]) {
> -                exact_match = profile_match;
> +    if (avctx->profile == FF_PROFILE_HEVC_REXT) {
> +        /* find the exact va_profile for HEVC_REXT */
> +        VAProfile va_profile = vaapi_decode_find_exact_profile(avctx);
> +        for (i = 0; i < profile_count; i++) {
> +            if (va_profile == profile_list[i]) {
> +                exact_match = 1;
> +                matched_va_profile = va_profile;
> +                matched_ff_profile = FF_PROFILE_HEVC_REXT;
>                  break;
>              }
>          }
> -        if (j < profile_count) {
> -            matched_va_profile = vaapi_profile_map[i].va_profile;
> -            matched_ff_profile = vaapi_profile_map[i].codec_profile;
> -            if (exact_match)
> -                break;
> +    } else {
> +        /* find the exact va_profile according to codec_id and profile */
> +        for (i = 0; i < FF_ARRAY_ELEMS(vaapi_profile_map); i++) {
> +            int profile_match = 0;
> +            if (avctx->codec_id != vaapi_profile_map[i].codec_id)
> +                continue;
> +            if (avctx->profile == vaapi_profile_map[i].codec_profile ||
> +                vaapi_profile_map[i].codec_profile == FF_PROFILE_UNKNOWN)
> +                profile_match = 1;
> +            for (j = 0; j < profile_count; j++) {
> +                if (vaapi_profile_map[i].va_profile == profile_list[j]) {
> +                    exact_match = profile_match;
> +                    break;
> +                }
> +            }
> +            if (j < profile_count) {
> +                matched_va_profile = vaapi_profile_map[i].va_profile;
> +                matched_ff_profile = vaapi_profile_map[i].codec_profile;
> +                if (exact_match)
> +                    break;
> +            }
>          }
>      }
>      av_freep(&profile_list);
> 

This misses compatible profiles, and it's still mashing the specific support 
into the generic code in a way I'm not particularly fond of.

Suppose you split the existing profile matching code inside the loop out into a 
new function, then add a new function pointer field to vaapi_profile_map[] 
(NULL for all existing entries) which redirects it to a different 
implementation in vaapi_hevc.c only for RExt?


Doesn't this also need to pass the SPS range extension fields to the decoder as 
well to actually support these profiles?  The intent is that if the hwaccel 
init has returned success then you believe the hardware definitely supports the 
stream and decoding will succeed - if it's not sure (e.g. it might fail if some 
feature is enabled), then it should return failure unless the PROFILE_MISMATCH 
flag is set to allow that case.

- Mark
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

Reply via email to