[FFmpeg-devel] [PATCH, v4] lavc/vaapi_decode: find exact va_profile for HEVC_REXT
Fu, Linjie
linjie.fu at intel.com
Wed Apr 10 12:16:57 EEST 2019
> -----Original Message-----
> From: ffmpeg-devel [mailto:ffmpeg-devel-bounces at ffmpeg.org] On Behalf
> Of Mark Thompson
> Sent: Wednesday, April 10, 2019 07:20
> To: ffmpeg-devel at ffmpeg.org
> Subject: Re: [FFmpeg-devel] [PATCH, v4] lavc/vaapi_decode: find exact
> va_profile for HEVC_REXT
>
> 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.
I'm trying to avoid the repeated value passing code from these two structures, and wonder if it's acceptable in community.
Well, will find some other ways to pass the flags.
>
> > 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.fu at 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.
Opus, this should be checked, thanks.
> > +
> > +#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.
>
Did you mean "general_profile_compatibility_flag[]"?
general_profile_compatibility_flags are also taken into account and used in ff_h265_get_profile();
> 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?
>
Will try to move the code, thanks for the advice.
>
> 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.
More information about the ffmpeg-devel
mailing list