Message ID | 20180422152921.32510-11-sw@jkqxz.net |
---|---|
State | Superseded |
Headers | show |
On Sun, Apr 22, 2018 at 04:29:05PM +0100, Mark Thompson wrote: > Previously there was one fixed choice for each codec (e.g. H.265 -> Main > profile), and using anything else then required an explicit option from > the user. This changes to selecting the profile based on the input format > and the set of profiles actually supported by the driver (e.g. P010 input > will choose Main 10 profile for H.265 if the driver supports it). > > The entrypoint and render target format are also chosen dynamically in the > same way, removing those explicit selections from the per-codec code. > --- > doc/encoders.texi | 3 + > libavcodec/vaapi_encode.c | 261 +++++++++++++++++++++++++++++++--------- > libavcodec/vaapi_encode.h | 41 +++++-- > libavcodec/vaapi_encode_h264.c | 45 ++----- > libavcodec/vaapi_encode_h265.c | 43 +++---- > libavcodec/vaapi_encode_mjpeg.c | 13 +- > libavcodec/vaapi_encode_mpeg2.c | 36 ++---- > libavcodec/vaapi_encode_vp8.c | 11 +- > libavcodec/vaapi_encode_vp9.c | 34 ++---- > 9 files changed, 306 insertions(+), 181 deletions(-) breaks build on linux x86-64 ubuntu CC libavcodec/vaapi_encode.o libavcodec/vaapi_encode.c:1007:5: error: ‘VAEntrypointEncSliceLP’ undeclared here (not in a function) VAEntrypointEncSliceLP, ^ libavcodec/vaapi_encode.c:1011:5: error: initializer element is not constant VAEntrypointEncSliceLP, ^ libavcodec/vaapi_encode.c:1011:5: error: (near initialization for ‘vaapi_encode_entrypoints_low_power[0]’) make: *** [libavcodec/vaapi_encode.o] Error 1 [...]
On 23/04/18 03:54, Michael Niedermayer wrote: > On Sun, Apr 22, 2018 at 04:29:05PM +0100, Mark Thompson wrote: >> Previously there was one fixed choice for each codec (e.g. H.265 -> Main >> profile), and using anything else then required an explicit option from >> the user. This changes to selecting the profile based on the input format >> and the set of profiles actually supported by the driver (e.g. P010 input >> will choose Main 10 profile for H.265 if the driver supports it). >> >> The entrypoint and render target format are also chosen dynamically in the >> same way, removing those explicit selections from the per-codec code. >> --- >> doc/encoders.texi | 3 + >> libavcodec/vaapi_encode.c | 261 +++++++++++++++++++++++++++++++--------- >> libavcodec/vaapi_encode.h | 41 +++++-- >> libavcodec/vaapi_encode_h264.c | 45 ++----- >> libavcodec/vaapi_encode_h265.c | 43 +++---- >> libavcodec/vaapi_encode_mjpeg.c | 13 +- >> libavcodec/vaapi_encode_mpeg2.c | 36 ++---- >> libavcodec/vaapi_encode_vp8.c | 11 +- >> libavcodec/vaapi_encode_vp9.c | 34 ++---- >> 9 files changed, 306 insertions(+), 181 deletions(-) > > breaks build on linux x86-64 ubuntu > > CC libavcodec/vaapi_encode.o > libavcodec/vaapi_encode.c:1007:5: error: ‘VAEntrypointEncSliceLP’ undeclared here (not in a function) > VAEntrypointEncSliceLP, > ^ > libavcodec/vaapi_encode.c:1011:5: error: initializer element is not constant > VAEntrypointEncSliceLP, > ^ > libavcodec/vaapi_encode.c:1011:5: error: (near initialization for ‘vaapi_encode_entrypoints_low_power[0]’) > make: *** [libavcodec/vaapi_encode.o] Error 1 > > > [...] Right, that lost some of preprocessor checks around EncSliceLP in the refactoring. Fixed locally (don't include it in the normal list and don't include the low-power list at all in that case). I'll try to test again with more old versions to make sure there aren't any similar build failures lurking. Thanks, - Mark
> Previously there was one fixed choice for each codec (e.g. H.265 -> Main > profile), and using anything else then required an explicit option from > the user. This changes to selecting the profile based on the input format > and the set of profiles actually supported by the driver (e.g. P010 input > will choose Main 10 profile for H.265 if the driver supports it). > > The entrypoint and render target format are also chosen dynamically in the > same way, removing those explicit selections from the per-codec code. > --- > doc/encoders.texi | 3 + > libavcodec/vaapi_encode.c | 261 +++++++++++++++++++++++++++++++------ > --- > libavcodec/vaapi_encode.h | 41 +++++-- > libavcodec/vaapi_encode_h264.c | 45 ++----- > libavcodec/vaapi_encode_h265.c | 43 +++---- > libavcodec/vaapi_encode_mjpeg.c | 13 +- > libavcodec/vaapi_encode_mpeg2.c | 36 ++---- > libavcodec/vaapi_encode_vp8.c | 11 +- > libavcodec/vaapi_encode_vp9.c | 34 ++---- > 9 files changed, 306 insertions(+), 181 deletions(-) > > diff --git a/doc/encoders.texi b/doc/encoders.texi > index 7b095754d1..16be6359b3 100644 > --- a/doc/encoders.texi > +++ b/doc/encoders.texi > @@ -2565,6 +2565,9 @@ The following standard libavcodec options are used: > @option{bf} / @option{max_b_frames} > @item > @option{profile} > + > +If not set, this will be determined automatically from the format of the > input > +frames and the profiles supported by the driver. > @item > @option{level} > @item > diff --git a/libavcodec/vaapi_encode.c b/libavcodec/vaapi_encode.c > index 9c5cfc7a65..9c39bcdeff 100644 > --- a/libavcodec/vaapi_encode.c > +++ b/libavcodec/vaapi_encode.c > @@ -983,70 +983,237 @@ static av_cold void > vaapi_encode_add_global_param(AVCodecContext *avctx, > ++ctx->nb_global_params; > } > > -static av_cold int vaapi_encode_config_attributes(AVCodecContext *avctx) > +typedef struct VAAPIEncodeRTFormat { > + const char *name; > + unsigned int value; > + int depth; > + int log2_chroma_w; > + int log2_chroma_h; > +} VAAPIEncodeRTFormat; > + > +static const VAAPIEncodeRTFormat vaapi_encode_rt_formats[] = { > + { "YUV420", VA_RT_FORMAT_YUV420, 8, 1, 1 }, > + { "YUV422", VA_RT_FORMAT_YUV422, 8, 1, 0 }, > + { "YUV444", VA_RT_FORMAT_YUV444, 8, 0, 0 }, > + { "YUV411", VA_RT_FORMAT_YUV411, 8, 2, 0 }, > +#if VA_CHECK_VERSION(0, 38, 1) > + { "YUV420_10", VA_RT_FORMAT_YUV420_10BPP, 10, 1, 1 }, > +#endif > +}; > + > +static const VAEntrypoint vaapi_encode_entrypoints_normal[] = { > + VAEntrypointEncSlice, > + VAEntrypointEncPicture, > + VAEntrypointEncSliceLP, > + 0 > +}; > +static const VAEntrypoint vaapi_encode_entrypoints_low_power[] = { > + VAEntrypointEncSliceLP, > + 0 > +}; > + > +static av_cold int vaapi_encode_profile_entrypoint(AVCodecContext *avctx) > { > - VAAPIEncodeContext *ctx = avctx->priv_data; > + VAAPIEncodeContext *ctx = avctx->priv_data; > + VAProfile *va_profiles = NULL; > + VAEntrypoint *va_entrypoints = NULL; > VAStatus vas; > - int i, n, err; > - VAProfile *profiles = NULL; > - VAEntrypoint *entrypoints = NULL; > - VAConfigAttrib attr[] = { > - { VAConfigAttribRTFormat }, > - { VAConfigAttribRateControl }, > - { VAConfigAttribEncMaxRefFrames }, > - { VAConfigAttribEncPackedHeaders }, > - }; > + const VAEntrypoint *usable_entrypoints; > + const VAAPIEncodeProfile *profile; > + const AVPixFmtDescriptor *desc; > + VAConfigAttrib rt_format_attr; > + const VAAPIEncodeRTFormat *rt_format; > + int i, j, n, depth, err; > + > + > + if (ctx->low_power) { > +#if VA_CHECK_VERSION(0, 39, 2) > + usable_entrypoints = vaapi_encode_entrypoints_low_power; > +#else > + av_log(avctx, AV_LOG_ERROR, "Low-power encoding is not " > + "supported with this VAAPI version.\n"); > + return AVERROR(EINVAL); > +#endif > + } else { > + usable_entrypoints = vaapi_encode_entrypoints_normal; > + } > + > + desc = av_pix_fmt_desc_get(ctx->input_frames->sw_format); > + if (!desc) { > + av_log(avctx, AV_LOG_ERROR, "Invalid input pixfmt (%d).\n", > + ctx->input_frames->sw_format); > + return AVERROR(EINVAL); > + } > + depth = desc->comp[0].depth; > + for (i = 1; i < desc->nb_components; i++) { > + if (desc->comp[i].depth != depth) { > + av_log(avctx, AV_LOG_ERROR, "Invalid input pixfmt (%s).\n", > + desc->name); > + return AVERROR(EINVAL); > + } > + } > + av_log(avctx, AV_LOG_VERBOSE, "Input surface format is %s.\n", > + desc->name); > > n = vaMaxNumProfiles(ctx->hwctx->display); > - profiles = av_malloc_array(n, sizeof(VAProfile)); > - if (!profiles) { > + va_profiles = av_malloc_array(n, sizeof(VAProfile)); > + if (!va_profiles) { > err = AVERROR(ENOMEM); > goto fail; > } > - vas = vaQueryConfigProfiles(ctx->hwctx->display, profiles, &n); > + vas = vaQueryConfigProfiles(ctx->hwctx->display, va_profiles, &n); > if (vas != VA_STATUS_SUCCESS) { > - av_log(ctx, AV_LOG_ERROR, "Failed to query profiles: %d (%s).\n", > + av_log(avctx, AV_LOG_ERROR, "Failed to query profiles: %d (%s).\n", > vas, vaErrorStr(vas)); > - err = AVERROR(ENOSYS); > + err = AVERROR_EXTERNAL; > goto fail; > } > - for (i = 0; i < n; i++) { > - if (profiles[i] == ctx->va_profile) > - break; > + > + av_assert0(ctx->codec->profiles); > + for (i = 0; (ctx->codec->profiles[i].av_profile != > + FF_PROFILE_UNKNOWN); i++) { > + profile = &ctx->codec->profiles[i]; > + if (depth != profile->depth || > + desc->log2_chroma_w != profile->log2_chroma_w || > + desc->log2_chroma_h != profile->log2_chroma_h) > + continue; > + if (avctx->profile != profile->av_profile && > + avctx->profile != FF_PROFILE_UNKNOWN) > + continue; > + > + for (j = 0; j < n; j++) { > + if (va_profiles[j] == profile->va_profile) > + break; > + } > + if (j >= n) { > + av_log(avctx, AV_LOG_VERBOSE, "Matching profile %d is " > + "not supported by driver.\n", profile->va_profile); > + continue; > + } > + > + ctx->profile = profile; > + break; > } > - if (i >= n) { > - av_log(ctx, AV_LOG_ERROR, "Encoding profile not found (%d).\n", > - ctx->va_profile); > - err = AVERROR(ENOSYS); > - goto fail; > + if (!ctx->profile) { > + av_log(avctx, AV_LOG_ERROR, "No usable encoding profile found.\n"); > + return AVERROR(ENOSYS); > } > > + avctx->profile = profile->av_profile; > + ctx->va_profile = profile->va_profile; > +#if VA_CHECK_VERSION(1, 0, 0) > + av_log(avctx, AV_LOG_VERBOSE, "Using VAAPI profile %s (%d).\n", > + vaProfileStr(ctx->va_profile), ctx->va_profile); > +#else > + av_log(avctx, AV_LOG_VERBOSE, "Using VAAPI profile %d.\n", > + ctx->va_profile); > +#endif > + > n = vaMaxNumEntrypoints(ctx->hwctx->display); > - entrypoints = av_malloc_array(n, sizeof(VAEntrypoint)); > - if (!entrypoints) { > + va_entrypoints = av_malloc_array(n, sizeof(VAEntrypoint)); > + if (!va_entrypoints) { > err = AVERROR(ENOMEM); > goto fail; > } > vas = vaQueryConfigEntrypoints(ctx->hwctx->display, ctx->va_profile, > - entrypoints, &n); > + va_entrypoints, &n); > if (vas != VA_STATUS_SUCCESS) { > - av_log(ctx, AV_LOG_ERROR, "Failed to query entrypoints for " > + av_log(avctx, AV_LOG_ERROR, "Failed to query entrypoints for " > "profile %u: %d (%s).\n", ctx->va_profile, > vas, vaErrorStr(vas)); > - err = AVERROR(ENOSYS); > + err = AVERROR_EXTERNAL; > goto fail; > } > + > for (i = 0; i < n; i++) { > - if (entrypoints[i] == ctx->va_entrypoint) > + for (j = 0; usable_entrypoints[j]; j++) { > + if (va_entrypoints[i] == usable_entrypoints[j]) > + break; > + } > + if (usable_entrypoints[j]) > break; > } > if (i >= n) { > - av_log(ctx, AV_LOG_ERROR, "Encoding entrypoint not found " > - "(%d / %d).\n", ctx->va_profile, ctx->va_entrypoint); > + av_log(avctx, AV_LOG_ERROR, "No usable encoding entrypoint found " > + "for profile %d.\n", ctx->va_profile); > err = AVERROR(ENOSYS); > goto fail; > } > > + ctx->va_entrypoint = va_entrypoints[i]; > +#if VA_CHECK_VERSION(1, 0, 0) > + av_log(avctx, AV_LOG_VERBOSE, "Using VAAPI entrypoint %s (%d).\n", > + vaEntrypointStr(ctx->va_entrypoint), ctx->va_entrypoint); > +#else > + av_log(avctx, AV_LOG_VERBOSE, "Using VAAPI entrypoint %d.\n", > + ctx->va_entrypoint); > +#endif > + > + for (i = 0; i < FF_ARRAY_ELEMS(vaapi_encode_rt_formats); i++) { > + rt_format = &vaapi_encode_rt_formats[i]; > + if (rt_format->depth == depth && > + rt_format->log2_chroma_w == profile->log2_chroma_w && > + rt_format->log2_chroma_h == profile->log2_chroma_h) > + break; > + } > + if (i >= FF_ARRAY_ELEMS(vaapi_encode_rt_formats)) { > + av_log(avctx, AV_LOG_ERROR, "No usable render target format " > + "found for profile %d entrypoint %d.\n", > + ctx->va_profile, ctx->va_entrypoint); > + err = AVERROR(ENOSYS); > + goto fail; > + } > + > + rt_format_attr = (VAConfigAttrib) { VAConfigAttribRTFormat }; > + vas = vaGetConfigAttributes(ctx->hwctx->display, > + ctx->va_profile, ctx->va_entrypoint, > + &rt_format_attr, 1); > + if (vas != VA_STATUS_SUCCESS) { > + av_log(avctx, AV_LOG_ERROR, "Failed to query RT format " > + "config attribute: %d (%s).\n", vas, vaErrorStr(vas)); > + err = AVERROR_EXTERNAL; > + goto fail; > + } > + > + if (rt_format_attr.value == VA_ATTRIB_NOT_SUPPORTED) { > + av_log(avctx, AV_LOG_VERBOSE, "RT format config attribute not " > + "supported by driver: assuming surface RT format %s " > + "is valid.\n", rt_format->name); > + } else if (!(rt_format_attr.value & rt_format->value)) { > + av_log(avctx, AV_LOG_ERROR, "Surface RT format %s not supported " > + "by driver for encoding profile %d entrypoint %d.\n", > + rt_format->name, ctx->va_profile, ctx->va_entrypoint); > + err = AVERROR(ENOSYS); > + goto fail; > + } else { > + av_log(avctx, AV_LOG_VERBOSE, "Using VAAPI render target " > + "format %s (%#x).\n", rt_format->name, rt_format->value); > + ctx->config_attributes[ctx->nb_config_attributes++] = > + (VAConfigAttrib) { > + .type = VAConfigAttribRTFormat, > + .value = rt_format->value, > + }; > + } > + > + err = 0; > +fail: > + av_freep(&va_profiles); > + av_freep(&va_entrypoints); > + return err; > +} > + > +static av_cold int vaapi_encode_config_attributes(AVCodecContext *avctx) > +{ > + VAAPIEncodeContext *ctx = avctx->priv_data; > + VAStatus vas; > + int i; > + > + VAConfigAttrib attr[] = { > + { VAConfigAttribRateControl }, > + { VAConfigAttribEncMaxRefFrames }, > + { VAConfigAttribEncPackedHeaders }, > + }; > + > vas = vaGetConfigAttributes(ctx->hwctx->display, > ctx->va_profile, ctx->va_entrypoint, > attr, FF_ARRAY_ELEMS(attr)); > @@ -1066,20 +1233,6 @@ static av_cold int > vaapi_encode_config_attributes(AVCodecContext *avctx) > continue; > } > switch (attr[i].type) { > - case VAConfigAttribRTFormat: > - if (!(ctx->va_rt_format & attr[i].value)) { > - av_log(avctx, AV_LOG_ERROR, "Surface RT format %#x " > - "is not supported (mask %#x).\n", > - ctx->va_rt_format, attr[i].value); > - err = AVERROR(EINVAL); > - goto fail; > - } > - ctx->config_attributes[ctx->nb_config_attributes++] = > - (VAConfigAttrib) { > - .type = VAConfigAttribRTFormat, > - .value = ctx->va_rt_format, > - }; > - break; > case VAConfigAttribRateControl: > // Hack for backward compatibility: CBR was the only > // usable RC mode for a long time, so old drivers will > @@ -1098,8 +1251,7 @@ static av_cold int > vaapi_encode_config_attributes(AVCodecContext *avctx) > av_log(avctx, AV_LOG_ERROR, "Rate control mode %#x " > "is not supported (mask: %#x).\n", > ctx->va_rc_mode, attr[i].value); > - err = AVERROR(EINVAL); > - goto fail; > + return AVERROR(EINVAL); > } > ctx->config_attributes[ctx->nb_config_attributes++] = > (VAConfigAttrib) { > @@ -1115,8 +1267,7 @@ static av_cold int > vaapi_encode_config_attributes(AVCodecContext *avctx) > if (avctx->gop_size > 1 && ref_l0 < 1) { > av_log(avctx, AV_LOG_ERROR, "P frames are not " > "supported (%#x).\n", attr[i].value); > - err = AVERROR(EINVAL); > - goto fail; > + return AVERROR(EINVAL); > } > if (avctx->max_b_frames > 0 && ref_l1 < 1) { > av_log(avctx, AV_LOG_WARNING, "B frames are not " > @@ -1148,11 +1299,7 @@ static av_cold int > vaapi_encode_config_attributes(AVCodecContext *avctx) > } > } > > - err = 0; > -fail: > - av_freep(&profiles); > - av_freep(&entrypoints); > - return err; > + return 0; > } > > static av_cold int vaapi_encode_init_rate_control(AVCodecContext *avctx) > @@ -1407,6 +1554,10 @@ av_cold int ff_vaapi_encode_init(AVCodecContext *avctx) > ctx->device = (AVHWDeviceContext*)ctx->device_ref->data; > ctx->hwctx = ctx->device->hwctx; > > + err = vaapi_encode_profile_entrypoint(avctx); > + if (err < 0) > + goto fail; > + > err = vaapi_encode_config_attributes(avctx); > if (err < 0) > goto fail; > diff --git a/libavcodec/vaapi_encode.h b/libavcodec/vaapi_encode.h > index 54dc4a475e..2b909d4d6b 100644 > --- a/libavcodec/vaapi_encode.h > +++ b/libavcodec/vaapi_encode.h > @@ -23,6 +23,10 @@ > > #include <va/va.h> > > +#if VA_CHECK_VERSION(1, 0, 0) > +#include <va/va_str.h> > +#endif > + > #include "libavutil/hwcontext.h" > #include "libavutil/hwcontext_vaapi.h" > > @@ -86,18 +90,30 @@ typedef struct VAAPIEncodePicture { > VAAPIEncodeSlice *slices; > } VAAPIEncodePicture; > > +typedef struct VAAPIEncodeProfile { > + // lavc profile value (FF_PROFILE_*). > + int av_profile; > + // Supported bit depth. > + int depth; > + // Chroma subsampling in width dimension. > + int log2_chroma_w; > + // Chroma subsampling in height dimension. > + int log2_chroma_h; > + // VAAPI profile value. > + VAProfile va_profile; > +} VAAPIEncodeProfile; > + > typedef struct VAAPIEncodeContext { > const AVClass *class; > > // Codec-specific hooks. > const struct VAAPIEncodeType *codec; > > - // Encoding profile (VAProfileXXX). > - VAProfile va_profile; > - // Encoding entrypoint (usually VAEntryointEncSlice). > - VAEntrypoint va_entrypoint; > - // Surface colour/sampling format (usually VA_RT_FORMAT_YUV420). > - unsigned int va_rt_format; > + // Global options. > + > + // Use low power encoding mode. > + int low_power; > + > // Rate control mode. > unsigned int va_rc_mode; > // Supported packed headers (initially the desired set, modified > @@ -113,6 +129,14 @@ typedef struct VAAPIEncodeContext { > // Everything above this point must be set before calling > // ff_vaapi_encode_init(). > > + // Chosen encoding profile details. > + const VAAPIEncodeProfile *profile; > + > + // Encoding profile (VAProfile*). > + VAProfile va_profile; > + // Encoding entrypoint (VAEntryoint*). > + VAEntrypoint va_entrypoint; > + > // Configuration attributes to use when creating va_config. > VAConfigAttrib config_attributes[MAX_CONFIG_ATTRIBUTES]; > int nb_config_attributes; > @@ -204,8 +228,11 @@ typedef struct VAAPIEncodeContext { > int end_of_stream; > } VAAPIEncodeContext; > > - > typedef struct VAAPIEncodeType { > + // List of supported profiles and corresponding VAAPI profiles. > + // (Must end with FF_PROFILE_UNKNOWN.) > + const VAAPIEncodeProfile *profiles; > + > // Perform any extra codec-specific configuration after the > // codec context is initialised (set up the private data and > // add any necessary global parameters). > diff --git a/libavcodec/vaapi_encode_h264.c b/libavcodec/vaapi_encode_h264.c > index 8396683789..93dc51eb40 100644 > --- a/libavcodec/vaapi_encode_h264.c > +++ b/libavcodec/vaapi_encode_h264.c > @@ -863,7 +863,17 @@ static av_cold int > vaapi_encode_h264_configure(AVCodecContext *avctx) > return 0; > } > > +static const VAAPIEncodeProfile vaapi_encode_h264_profiles[] = { > + { FF_PROFILE_H264_HIGH, 8, 1, 1, VAProfileH264High }, > + { FF_PROFILE_H264_MAIN, 8, 1, 1, VAProfileH264Main }, > + { FF_PROFILE_H264_CONSTRAINED_BASELINE, > + 8, 1, 1, VAProfileH264ConstrainedBaseline }, > + { FF_PROFILE_UNKNOWN } > +}; > + > static const VAAPIEncodeType vaapi_encode_type_h264 = { > + .profiles = vaapi_encode_h264_profiles, > + > .configure = &vaapi_encode_h264_configure, > > .sequence_params_size = sizeof(VAEncSequenceParameterBufferH264), > @@ -896,30 +906,17 @@ static av_cold int vaapi_encode_h264_init(AVCodecContext > *avctx) > if (avctx->level == FF_LEVEL_UNKNOWN) > avctx->level = priv->level; > > + // Reject unsupported profiles. > switch (avctx->profile) { > case FF_PROFILE_H264_BASELINE: > av_log(avctx, AV_LOG_WARNING, "H.264 baseline profile is not " > "supported, using constrained baseline profile instead.\n"); > avctx->profile = FF_PROFILE_H264_CONSTRAINED_BASELINE; > - case FF_PROFILE_H264_CONSTRAINED_BASELINE: > - ctx->va_profile = VAProfileH264ConstrainedBaseline; > - if (avctx->max_b_frames != 0) { > - avctx->max_b_frames = 0; > - av_log(avctx, AV_LOG_WARNING, "H.264 constrained baseline profile > " > - "doesn't support encoding with B frames, disabling > them.\n"); > - } > - break; > - case FF_PROFILE_H264_MAIN: > - ctx->va_profile = VAProfileH264Main; > break; > case FF_PROFILE_H264_EXTENDED: > av_log(avctx, AV_LOG_ERROR, "H.264 extended profile " > "is not supported.\n"); > return AVERROR_PATCHWELCOME; > - case FF_PROFILE_UNKNOWN: > - case FF_PROFILE_H264_HIGH: > - ctx->va_profile = VAProfileH264High; > - break; > case FF_PROFILE_H264_HIGH_10: > case FF_PROFILE_H264_HIGH_10_INTRA: > av_log(avctx, AV_LOG_ERROR, "H.264 10-bit profiles " > @@ -934,25 +931,9 @@ static av_cold int vaapi_encode_h264_init(AVCodecContext > *avctx) > av_log(avctx, AV_LOG_ERROR, "H.264 non-4:2:0 profiles " > "are not supported.\n"); > return AVERROR_PATCHWELCOME; > - default: > - av_log(avctx, AV_LOG_ERROR, "Unknown H.264 profile %d.\n", > - avctx->profile); > - return AVERROR(EINVAL); > - } > - if (priv->low_power) { > -#if VA_CHECK_VERSION(0, 39, 2) > - ctx->va_entrypoint = VAEntrypointEncSliceLP; > -#else > - av_log(avctx, AV_LOG_ERROR, "Low-power encoding is not " > - "supported with this VAAPI version.\n"); > - return AVERROR(EINVAL); > -#endif > - } else { > - ctx->va_entrypoint = VAEntrypointEncSlice; > } > > - // Only 8-bit encode is supported. > - ctx->va_rt_format = VA_RT_FORMAT_YUV420; > + ctx->low_power = priv->low_power; > > if (avctx->bit_rate > 0) { > if (avctx->rc_max_rate == avctx->bit_rate) > @@ -1021,7 +1002,7 @@ static const AVOption vaapi_encode_h264_options[] = { > > { "profile", "Set profile (profile_idc and constraint_set*_flag)", > OFFSET(profile), AV_OPT_TYPE_INT, > - { .i64 = FF_PROFILE_H264_HIGH }, 0x0000, 0xffff, FLAGS, "profile" }, > + { .i64 = FF_PROFILE_UNKNOWN }, FF_PROFILE_UNKNOWN, 0xffff, FLAGS, > "profile" }, > > #define PROFILE(name, value) name, NULL, 0, AV_OPT_TYPE_CONST, \ > { .i64 = value }, 0, 0, FLAGS, "profile" > diff --git a/libavcodec/vaapi_encode_h265.c b/libavcodec/vaapi_encode_h265.c > index 5529ee5a03..e01bdcf6b4 100644 > --- a/libavcodec/vaapi_encode_h265.c > +++ b/libavcodec/vaapi_encode_h265.c > @@ -875,7 +875,25 @@ static av_cold int > vaapi_encode_h265_configure(AVCodecContext *avctx) > return 0; > } > > +static const VAAPIEncodeProfile vaapi_encode_h265_profiles[] = { > + { FF_PROFILE_HEVC_MAIN, 8, 1, 1, VAProfileHEVCMain }, > +#if VA_CHECK_VERSION(0, 37, 0) > + { FF_PROFILE_HEVC_MAIN_10, 10, 1, 1, VAProfileHEVCMain10 }, > +#endif > +#if VA_CHECK_VERSION(1, 2, 0) > + { FF_PROFILE_HEVC_REXT, 12, 1, 1, VAProfileHEVCMain12 }, > + { FF_PROFILE_HEVC_REXT, 10, 1, 0, VAProfileHEVCMain422_10 }, > + { FF_PROFILE_HEVC_REXT, 12, 1, 0, VAProfileHEVCMain422_12 }, > + { FF_PROFILE_HEVC_REXT, 8, 0, 0, VAProfileHEVCMain444 }, > + { FF_PROFILE_HEVC_REXT, 10, 0, 0, VAProfileHEVCMain444_10 }, > + { FF_PROFILE_HEVC_REXT, 12, 0, 0, VAProfileHEVCMain444_12 }, > +#endif VA API 1.2 is not released yet, currently only structures for decoding are added . It would be better to include the above profiles in a separate patch in the future. > + { FF_PROFILE_UNKNOWN } > +}; > + > static const VAAPIEncodeType vaapi_encode_type_h265 = { > + .profiles = vaapi_encode_h265_profiles, > + > .configure = &vaapi_encode_h265_configure, > > .sequence_params_size = sizeof(VAEncSequenceParameterBufferHEVC), > @@ -906,29 +924,6 @@ static av_cold int vaapi_encode_h265_init(AVCodecContext > *avctx) > if (avctx->level == FF_LEVEL_UNKNOWN) > avctx->level = priv->level; > > - switch (avctx->profile) { > - case FF_PROFILE_HEVC_MAIN: > - case FF_PROFILE_UNKNOWN: > - ctx->va_profile = VAProfileHEVCMain; > - ctx->va_rt_format = VA_RT_FORMAT_YUV420; > - break; > - case FF_PROFILE_HEVC_MAIN_10: > -#ifdef VA_RT_FORMAT_YUV420_10BPP > - ctx->va_profile = VAProfileHEVCMain10; > - ctx->va_rt_format = VA_RT_FORMAT_YUV420_10BPP; > - break; > -#else > - av_log(avctx, AV_LOG_ERROR, "10-bit encoding is not " > - "supported with this VAAPI version.\n"); > - return AVERROR(ENOSYS); > -#endif > - default: > - av_log(avctx, AV_LOG_ERROR, "Unknown H.265 profile %d.\n", > - avctx->profile); > - return AVERROR(EINVAL); > - } > - ctx->va_entrypoint = VAEntrypointEncSlice; > - > if (avctx->bit_rate > 0) { > if (avctx->rc_max_rate == avctx->bit_rate) > ctx->va_rc_mode = VA_RC_CBR; > @@ -967,7 +962,7 @@ static const AVOption vaapi_encode_h265_options[] = { > > { "profile", "Set profile (general_profile_idc)", > OFFSET(profile), AV_OPT_TYPE_INT, > - { .i64 = FF_PROFILE_HEVC_MAIN }, 0x00, 0xff, FLAGS, "profile" }, > + { .i64 = FF_PROFILE_UNKNOWN }, FF_PROFILE_UNKNOWN, 0xff, FLAGS, > "profile" }, > > #define PROFILE(name, value) name, NULL, 0, AV_OPT_TYPE_CONST, \ > { .i64 = value }, 0, 0, FLAGS, "profile" > diff --git a/libavcodec/vaapi_encode_mjpeg.c b/libavcodec/vaapi_encode_mjpeg.c > index 481981a71c..3baf5c8915 100644 > --- a/libavcodec/vaapi_encode_mjpeg.c > +++ b/libavcodec/vaapi_encode_mjpeg.c > @@ -359,7 +359,15 @@ static av_cold int > vaapi_encode_mjpeg_configure(AVCodecContext *avctx) > return 0; > } > > +static const VAAPIEncodeProfile vaapi_encode_mjpeg_profiles[] = { > + { FF_PROFILE_MJPEG_HUFFMAN_BASELINE_DCT, > + 8, 1, 1, VAProfileJPEGBaseline }, > + { FF_PROFILE_UNKNOWN } > +}; > + > static const VAAPIEncodeType vaapi_encode_type_mjpeg = { > + .profiles = vaapi_encode_mjpeg_profiles, > + > .configure = &vaapi_encode_mjpeg_configure, > > .picture_params_size = sizeof(VAEncPictureParameterBufferJPEG), > @@ -380,11 +388,6 @@ static av_cold int vaapi_encode_mjpeg_init(AVCodecContext > *avctx) > > ctx->codec = &vaapi_encode_type_mjpeg; > > - ctx->va_profile = VAProfileJPEGBaseline; > - ctx->va_entrypoint = VAEntrypointEncPicture; > - > - ctx->va_rt_format = VA_RT_FORMAT_YUV420; > - > ctx->va_rc_mode = VA_RC_CQP; > > // The JPEG image header - see note above. > diff --git a/libavcodec/vaapi_encode_mpeg2.c b/libavcodec/vaapi_encode_mpeg2.c > index 72c838d774..b995a4b8b8 100644 > --- a/libavcodec/vaapi_encode_mpeg2.c > +++ b/libavcodec/vaapi_encode_mpeg2.c > @@ -552,7 +552,15 @@ static av_cold int > vaapi_encode_mpeg2_configure(AVCodecContext *avctx) > return 0; > } > > +static const VAAPIEncodeProfile vaapi_encode_mpeg2_profiles[] = { > + { FF_PROFILE_MPEG2_MAIN, 8, 1, 1, VAProfileMPEG2Main }, > + { FF_PROFILE_MPEG2_SIMPLE, 8, 1, 1, VAProfileMPEG2Simple }, > + { FF_PROFILE_UNKNOWN } > +}; > + > static const VAAPIEncodeType vaapi_encode_type_mpeg2 = { > + .profiles = vaapi_encode_mpeg2_profiles, > + > .configure = &vaapi_encode_mpeg2_configure, > > .sequence_params_size = sizeof(VAEncSequenceParameterBufferMPEG2), > @@ -577,31 +585,6 @@ static av_cold int vaapi_encode_mpeg2_init(AVCodecContext > *avctx) > > ctx->codec = &vaapi_encode_type_mpeg2; > > - switch (avctx->profile) { > - case FF_PROFILE_MPEG2_SIMPLE: > - ctx->va_profile = VAProfileMPEG2Simple; > - break; > - case FF_PROFILE_MPEG2_MAIN: > - ctx->va_profile = VAProfileMPEG2Main; > - break; > - case FF_PROFILE_MPEG2_422: > - av_log(avctx, AV_LOG_ERROR, "MPEG-2 4:2:2 profile " > - "is not supported.\n"); > - return AVERROR_PATCHWELCOME; > - case FF_PROFILE_MPEG2_HIGH: > - av_log(avctx, AV_LOG_ERROR, "MPEG-2 high profile " > - "is not supported.\n"); > - return AVERROR_PATCHWELCOME; > - case FF_PROFILE_MPEG2_SS: > - case FF_PROFILE_MPEG2_SNR_SCALABLE: > - av_log(avctx, AV_LOG_ERROR, "MPEG-2 scalable profiles " > - "are not supported.\n"); > - return AVERROR_PATCHWELCOME; > - default: > - av_log(avctx, AV_LOG_ERROR, "Unknown MPEG-2 profile %d.\n", > - avctx->profile); > - return AVERROR(EINVAL); > - } > switch (avctx->level) { > case 4: // High > case 6: // High 1440 > @@ -620,8 +603,6 @@ static av_cold int vaapi_encode_mpeg2_init(AVCodecContext > *avctx) > return AVERROR(EINVAL); > } > > - ctx->va_entrypoint = VAEntrypointEncSlice; > - ctx->va_rt_format = VA_RT_FORMAT_YUV420; > ctx->va_rc_mode = VA_RC_CQP; > > ctx->va_packed_headers = VA_ENC_PACKED_HEADER_SEQUENCE | > @@ -644,7 +625,6 @@ static av_cold int vaapi_encode_mpeg2_close(AVCodecContext > *avctx) > } > > static const AVCodecDefault vaapi_encode_mpeg2_defaults[] = { > - { "profile", "4" }, > { "level", "4" }, > { "bf", "1" }, > { "g", "120" }, > diff --git a/libavcodec/vaapi_encode_vp8.c b/libavcodec/vaapi_encode_vp8.c > index 05c9d03a38..2191e00ef4 100644 > --- a/libavcodec/vaapi_encode_vp8.c > +++ b/libavcodec/vaapi_encode_vp8.c > @@ -173,7 +173,14 @@ static av_cold int > vaapi_encode_vp8_configure(AVCodecContext *avctx) > return 0; > } > > +static const VAAPIEncodeProfile vaapi_encode_vp8_profiles[] = { > + { 0 /* VP8 has no profiles */, 8, 1, 1, VAProfileVP8Version0_3 }, > + { FF_PROFILE_UNKNOWN } > +}; > + > static const VAAPIEncodeType vaapi_encode_type_vp8 = { > + .profiles = vaapi_encode_vp8_profiles, > + > .configure = &vaapi_encode_vp8_configure, > > .sequence_params_size = sizeof(VAEncSequenceParameterBufferVP8), > @@ -196,10 +203,6 @@ static av_cold int vaapi_encode_vp8_init(AVCodecContext > *avctx) > > ctx->codec = &vaapi_encode_type_vp8; > > - ctx->va_profile = VAProfileVP8Version0_3; > - ctx->va_entrypoint = VAEntrypointEncSlice; > - ctx->va_rt_format = VA_RT_FORMAT_YUV420; > - > if (avctx->flags & AV_CODEC_FLAG_QSCALE) { > ctx->va_rc_mode = VA_RC_CQP; > } else if (avctx->bit_rate > 0) { > diff --git a/libavcodec/vaapi_encode_vp9.c b/libavcodec/vaapi_encode_vp9.c > index bf99597e4c..8091ae87e9 100644 > --- a/libavcodec/vaapi_encode_vp9.c > +++ b/libavcodec/vaapi_encode_vp9.c > @@ -203,7 +203,15 @@ static av_cold int > vaapi_encode_vp9_configure(AVCodecContext *avctx) > return 0; > } > > +static const VAAPIEncodeProfile vaapi_encode_vp9_profiles[] = { > + { FF_PROFILE_VP9_0, 8, 1, 1, VAProfileVP9Profile0 }, > + { FF_PROFILE_VP9_2, 10, 1, 1, VAProfileVP9Profile2 }, > + { FF_PROFILE_UNKNOWN } > +}; > + > static const VAAPIEncodeType vaapi_encode_type_vp9 = { > + .profiles = vaapi_encode_vp9_profiles, > + > .configure = &vaapi_encode_vp9_configure, > > .sequence_params_size = sizeof(VAEncSequenceParameterBufferVP9), > @@ -219,31 +227,6 @@ static av_cold int vaapi_encode_vp9_init(AVCodecContext > *avctx) > > ctx->codec = &vaapi_encode_type_vp9; > > - switch (avctx->profile) { > - case FF_PROFILE_VP9_0: > - case FF_PROFILE_UNKNOWN: > - ctx->va_profile = VAProfileVP9Profile0; > - ctx->va_rt_format = VA_RT_FORMAT_YUV420; > - break; > - case FF_PROFILE_VP9_1: > - av_log(avctx, AV_LOG_ERROR, "VP9 profile 1 is not " > - "supported.\n"); > - return AVERROR_PATCHWELCOME; > - case FF_PROFILE_VP9_2: > - ctx->va_profile = VAProfileVP9Profile2; > - ctx->va_rt_format = VA_RT_FORMAT_YUV420_10BPP; > - break; > - case FF_PROFILE_VP9_3: > - av_log(avctx, AV_LOG_ERROR, "VP9 profile 3 is not " > - "supported.\n"); > - return AVERROR_PATCHWELCOME; > - default: > - av_log(avctx, AV_LOG_ERROR, "Unknown VP9 profile %d.\n", > - avctx->profile); > - return AVERROR(EINVAL); > - } > - ctx->va_entrypoint = VAEntrypointEncSlice; > - > if (avctx->flags & AV_CODEC_FLAG_QSCALE) { > ctx->va_rc_mode = VA_RC_CQP; > } else if (avctx->bit_rate > 0) { > @@ -276,7 +259,6 @@ static const AVOption vaapi_encode_vp9_options[] = { > }; > > static const AVCodecDefault vaapi_encode_vp9_defaults[] = { > - { "profile", "0" }, > { "b", "0" }, > { "bf", "0" }, > { "g", "250" },
On 25/04/18 09:43, Xiang, Haihao wrote:>> Previously there was one fixed choice for each codec (e.g. H.265 -> Main >> profile), and using anything else then required an explicit option from >> the user. This changes to selecting the profile based on the input format >> and the set of profiles actually supported by the driver (e.g. P010 input >> will choose Main 10 profile for H.265 if the driver supports it). >> >> The entrypoint and render target format are also chosen dynamically in the >> same way, removing those explicit selections from the per-codec code. >> --- >> doc/encoders.texi | 3 + >> libavcodec/vaapi_encode.c | 261 +++++++++++++++++++++++++++++++------ >> --- >> libavcodec/vaapi_encode.h | 41 +++++-- >> libavcodec/vaapi_encode_h264.c | 45 ++----- >> libavcodec/vaapi_encode_h265.c | 43 +++---- >> libavcodec/vaapi_encode_mjpeg.c | 13 +- >> libavcodec/vaapi_encode_mpeg2.c | 36 ++---- >> libavcodec/vaapi_encode_vp8.c | 11 +- >> libavcodec/vaapi_encode_vp9.c | 34 ++---- >> 9 files changed, 306 insertions(+), 181 deletions(-) >> >> ... >> diff --git a/libavcodec/vaapi_encode_h265.c b/libavcodec/vaapi_encode_h265.c >> index 5529ee5a03..e01bdcf6b4 100644 >> --- a/libavcodec/vaapi_encode_h265.c >> +++ b/libavcodec/vaapi_encode_h265.c >> @@ -875,7 +875,25 @@ static av_cold int >> vaapi_encode_h265_configure(AVCodecContext *avctx) >> return 0; >> } >> >> +static const VAAPIEncodeProfile vaapi_encode_h265_profiles[] = { >> + { FF_PROFILE_HEVC_MAIN, 8, 1, 1, VAProfileHEVCMain }, >> +#if VA_CHECK_VERSION(0, 37, 0) >> + { FF_PROFILE_HEVC_MAIN_10, 10, 1, 1, VAProfileHEVCMain10 }, >> +#endif >> +#if VA_CHECK_VERSION(1, 2, 0) >> + { FF_PROFILE_HEVC_REXT, 12, 1, 1, VAProfileHEVCMain12 }, >> + { FF_PROFILE_HEVC_REXT, 10, 1, 0, VAProfileHEVCMain422_10 }, >> + { FF_PROFILE_HEVC_REXT, 12, 1, 0, VAProfileHEVCMain422_12 }, >> + { FF_PROFILE_HEVC_REXT, 8, 0, 0, VAProfileHEVCMain444 }, >> + { FF_PROFILE_HEVC_REXT, 10, 0, 0, VAProfileHEVCMain444_10 }, >> + { FF_PROFILE_HEVC_REXT, 12, 0, 0, VAProfileHEVCMain444_12 }, >> +#endif > > VA API 1.2 is not released yet, currently only structures for decoding are added > . It would be better to include the above profiles in a separate patch in the > future. That's fair, removed for now. (They couldn't be chosen anyway, but not having them at all is more sensible.) Thanks, - Mark
diff --git a/doc/encoders.texi b/doc/encoders.texi index 7b095754d1..16be6359b3 100644 --- a/doc/encoders.texi +++ b/doc/encoders.texi @@ -2565,6 +2565,9 @@ The following standard libavcodec options are used: @option{bf} / @option{max_b_frames} @item @option{profile} + +If not set, this will be determined automatically from the format of the input +frames and the profiles supported by the driver. @item @option{level} @item diff --git a/libavcodec/vaapi_encode.c b/libavcodec/vaapi_encode.c index 9c5cfc7a65..9c39bcdeff 100644 --- a/libavcodec/vaapi_encode.c +++ b/libavcodec/vaapi_encode.c @@ -983,70 +983,237 @@ static av_cold void vaapi_encode_add_global_param(AVCodecContext *avctx, ++ctx->nb_global_params; } -static av_cold int vaapi_encode_config_attributes(AVCodecContext *avctx) +typedef struct VAAPIEncodeRTFormat { + const char *name; + unsigned int value; + int depth; + int log2_chroma_w; + int log2_chroma_h; +} VAAPIEncodeRTFormat; + +static const VAAPIEncodeRTFormat vaapi_encode_rt_formats[] = { + { "YUV420", VA_RT_FORMAT_YUV420, 8, 1, 1 }, + { "YUV422", VA_RT_FORMAT_YUV422, 8, 1, 0 }, + { "YUV444", VA_RT_FORMAT_YUV444, 8, 0, 0 }, + { "YUV411", VA_RT_FORMAT_YUV411, 8, 2, 0 }, +#if VA_CHECK_VERSION(0, 38, 1) + { "YUV420_10", VA_RT_FORMAT_YUV420_10BPP, 10, 1, 1 }, +#endif +}; + +static const VAEntrypoint vaapi_encode_entrypoints_normal[] = { + VAEntrypointEncSlice, + VAEntrypointEncPicture, + VAEntrypointEncSliceLP, + 0 +}; +static const VAEntrypoint vaapi_encode_entrypoints_low_power[] = { + VAEntrypointEncSliceLP, + 0 +}; + +static av_cold int vaapi_encode_profile_entrypoint(AVCodecContext *avctx) { - VAAPIEncodeContext *ctx = avctx->priv_data; + VAAPIEncodeContext *ctx = avctx->priv_data; + VAProfile *va_profiles = NULL; + VAEntrypoint *va_entrypoints = NULL; VAStatus vas; - int i, n, err; - VAProfile *profiles = NULL; - VAEntrypoint *entrypoints = NULL; - VAConfigAttrib attr[] = { - { VAConfigAttribRTFormat }, - { VAConfigAttribRateControl }, - { VAConfigAttribEncMaxRefFrames }, - { VAConfigAttribEncPackedHeaders }, - }; + const VAEntrypoint *usable_entrypoints; + const VAAPIEncodeProfile *profile; + const AVPixFmtDescriptor *desc; + VAConfigAttrib rt_format_attr; + const VAAPIEncodeRTFormat *rt_format; + int i, j, n, depth, err; + + + if (ctx->low_power) { +#if VA_CHECK_VERSION(0, 39, 2) + usable_entrypoints = vaapi_encode_entrypoints_low_power; +#else + av_log(avctx, AV_LOG_ERROR, "Low-power encoding is not " + "supported with this VAAPI version.\n"); + return AVERROR(EINVAL); +#endif + } else { + usable_entrypoints = vaapi_encode_entrypoints_normal; + } + + desc = av_pix_fmt_desc_get(ctx->input_frames->sw_format); + if (!desc) { + av_log(avctx, AV_LOG_ERROR, "Invalid input pixfmt (%d).\n", + ctx->input_frames->sw_format); + return AVERROR(EINVAL); + } + depth = desc->comp[0].depth; + for (i = 1; i < desc->nb_components; i++) { + if (desc->comp[i].depth != depth) { + av_log(avctx, AV_LOG_ERROR, "Invalid input pixfmt (%s).\n", + desc->name); + return AVERROR(EINVAL); + } + } + av_log(avctx, AV_LOG_VERBOSE, "Input surface format is %s.\n", + desc->name); n = vaMaxNumProfiles(ctx->hwctx->display); - profiles = av_malloc_array(n, sizeof(VAProfile)); - if (!profiles) { + va_profiles = av_malloc_array(n, sizeof(VAProfile)); + if (!va_profiles) { err = AVERROR(ENOMEM); goto fail; } - vas = vaQueryConfigProfiles(ctx->hwctx->display, profiles, &n); + vas = vaQueryConfigProfiles(ctx->hwctx->display, va_profiles, &n); if (vas != VA_STATUS_SUCCESS) { - av_log(ctx, AV_LOG_ERROR, "Failed to query profiles: %d (%s).\n", + av_log(avctx, AV_LOG_ERROR, "Failed to query profiles: %d (%s).\n", vas, vaErrorStr(vas)); - err = AVERROR(ENOSYS); + err = AVERROR_EXTERNAL; goto fail; } - for (i = 0; i < n; i++) { - if (profiles[i] == ctx->va_profile) - break; + + av_assert0(ctx->codec->profiles); + for (i = 0; (ctx->codec->profiles[i].av_profile != + FF_PROFILE_UNKNOWN); i++) { + profile = &ctx->codec->profiles[i]; + if (depth != profile->depth || + desc->log2_chroma_w != profile->log2_chroma_w || + desc->log2_chroma_h != profile->log2_chroma_h) + continue; + if (avctx->profile != profile->av_profile && + avctx->profile != FF_PROFILE_UNKNOWN) + continue; + + for (j = 0; j < n; j++) { + if (va_profiles[j] == profile->va_profile) + break; + } + if (j >= n) { + av_log(avctx, AV_LOG_VERBOSE, "Matching profile %d is " + "not supported by driver.\n", profile->va_profile); + continue; + } + + ctx->profile = profile; + break; } - if (i >= n) { - av_log(ctx, AV_LOG_ERROR, "Encoding profile not found (%d).\n", - ctx->va_profile); - err = AVERROR(ENOSYS); - goto fail; + if (!ctx->profile) { + av_log(avctx, AV_LOG_ERROR, "No usable encoding profile found.\n"); + return AVERROR(ENOSYS); } + avctx->profile = profile->av_profile; + ctx->va_profile = profile->va_profile; +#if VA_CHECK_VERSION(1, 0, 0) + av_log(avctx, AV_LOG_VERBOSE, "Using VAAPI profile %s (%d).\n", + vaProfileStr(ctx->va_profile), ctx->va_profile); +#else + av_log(avctx, AV_LOG_VERBOSE, "Using VAAPI profile %d.\n", + ctx->va_profile); +#endif + n = vaMaxNumEntrypoints(ctx->hwctx->display); - entrypoints = av_malloc_array(n, sizeof(VAEntrypoint)); - if (!entrypoints) { + va_entrypoints = av_malloc_array(n, sizeof(VAEntrypoint)); + if (!va_entrypoints) { err = AVERROR(ENOMEM); goto fail; } vas = vaQueryConfigEntrypoints(ctx->hwctx->display, ctx->va_profile, - entrypoints, &n); + va_entrypoints, &n); if (vas != VA_STATUS_SUCCESS) { - av_log(ctx, AV_LOG_ERROR, "Failed to query entrypoints for " + av_log(avctx, AV_LOG_ERROR, "Failed to query entrypoints for " "profile %u: %d (%s).\n", ctx->va_profile, vas, vaErrorStr(vas)); - err = AVERROR(ENOSYS); + err = AVERROR_EXTERNAL; goto fail; } + for (i = 0; i < n; i++) { - if (entrypoints[i] == ctx->va_entrypoint) + for (j = 0; usable_entrypoints[j]; j++) { + if (va_entrypoints[i] == usable_entrypoints[j]) + break; + } + if (usable_entrypoints[j]) break; } if (i >= n) { - av_log(ctx, AV_LOG_ERROR, "Encoding entrypoint not found " - "(%d / %d).\n", ctx->va_profile, ctx->va_entrypoint); + av_log(avctx, AV_LOG_ERROR, "No usable encoding entrypoint found " + "for profile %d.\n", ctx->va_profile); err = AVERROR(ENOSYS); goto fail; } + ctx->va_entrypoint = va_entrypoints[i]; +#if VA_CHECK_VERSION(1, 0, 0) + av_log(avctx, AV_LOG_VERBOSE, "Using VAAPI entrypoint %s (%d).\n", + vaEntrypointStr(ctx->va_entrypoint), ctx->va_entrypoint); +#else + av_log(avctx, AV_LOG_VERBOSE, "Using VAAPI entrypoint %d.\n", + ctx->va_entrypoint); +#endif + + for (i = 0; i < FF_ARRAY_ELEMS(vaapi_encode_rt_formats); i++) { + rt_format = &vaapi_encode_rt_formats[i]; + if (rt_format->depth == depth && + rt_format->log2_chroma_w == profile->log2_chroma_w && + rt_format->log2_chroma_h == profile->log2_chroma_h) + break; + } + if (i >= FF_ARRAY_ELEMS(vaapi_encode_rt_formats)) { + av_log(avctx, AV_LOG_ERROR, "No usable render target format " + "found for profile %d entrypoint %d.\n", + ctx->va_profile, ctx->va_entrypoint); + err = AVERROR(ENOSYS); + goto fail; + } + + rt_format_attr = (VAConfigAttrib) { VAConfigAttribRTFormat }; + vas = vaGetConfigAttributes(ctx->hwctx->display, + ctx->va_profile, ctx->va_entrypoint, + &rt_format_attr, 1); + if (vas != VA_STATUS_SUCCESS) { + av_log(avctx, AV_LOG_ERROR, "Failed to query RT format " + "config attribute: %d (%s).\n", vas, vaErrorStr(vas)); + err = AVERROR_EXTERNAL; + goto fail; + } + + if (rt_format_attr.value == VA_ATTRIB_NOT_SUPPORTED) { + av_log(avctx, AV_LOG_VERBOSE, "RT format config attribute not " + "supported by driver: assuming surface RT format %s " + "is valid.\n", rt_format->name); + } else if (!(rt_format_attr.value & rt_format->value)) { + av_log(avctx, AV_LOG_ERROR, "Surface RT format %s not supported " + "by driver for encoding profile %d entrypoint %d.\n", + rt_format->name, ctx->va_profile, ctx->va_entrypoint); + err = AVERROR(ENOSYS); + goto fail; + } else { + av_log(avctx, AV_LOG_VERBOSE, "Using VAAPI render target " + "format %s (%#x).\n", rt_format->name, rt_format->value); + ctx->config_attributes[ctx->nb_config_attributes++] = + (VAConfigAttrib) { + .type = VAConfigAttribRTFormat, + .value = rt_format->value, + }; + } + + err = 0; +fail: + av_freep(&va_profiles); + av_freep(&va_entrypoints); + return err; +} + +static av_cold int vaapi_encode_config_attributes(AVCodecContext *avctx) +{ + VAAPIEncodeContext *ctx = avctx->priv_data; + VAStatus vas; + int i; + + VAConfigAttrib attr[] = { + { VAConfigAttribRateControl }, + { VAConfigAttribEncMaxRefFrames }, + { VAConfigAttribEncPackedHeaders }, + }; + vas = vaGetConfigAttributes(ctx->hwctx->display, ctx->va_profile, ctx->va_entrypoint, attr, FF_ARRAY_ELEMS(attr)); @@ -1066,20 +1233,6 @@ static av_cold int vaapi_encode_config_attributes(AVCodecContext *avctx) continue; } switch (attr[i].type) { - case VAConfigAttribRTFormat: - if (!(ctx->va_rt_format & attr[i].value)) { - av_log(avctx, AV_LOG_ERROR, "Surface RT format %#x " - "is not supported (mask %#x).\n", - ctx->va_rt_format, attr[i].value); - err = AVERROR(EINVAL); - goto fail; - } - ctx->config_attributes[ctx->nb_config_attributes++] = - (VAConfigAttrib) { - .type = VAConfigAttribRTFormat, - .value = ctx->va_rt_format, - }; - break; case VAConfigAttribRateControl: // Hack for backward compatibility: CBR was the only // usable RC mode for a long time, so old drivers will @@ -1098,8 +1251,7 @@ static av_cold int vaapi_encode_config_attributes(AVCodecContext *avctx) av_log(avctx, AV_LOG_ERROR, "Rate control mode %#x " "is not supported (mask: %#x).\n", ctx->va_rc_mode, attr[i].value); - err = AVERROR(EINVAL); - goto fail; + return AVERROR(EINVAL); } ctx->config_attributes[ctx->nb_config_attributes++] = (VAConfigAttrib) { @@ -1115,8 +1267,7 @@ static av_cold int vaapi_encode_config_attributes(AVCodecContext *avctx) if (avctx->gop_size > 1 && ref_l0 < 1) { av_log(avctx, AV_LOG_ERROR, "P frames are not " "supported (%#x).\n", attr[i].value); - err = AVERROR(EINVAL); - goto fail; + return AVERROR(EINVAL); } if (avctx->max_b_frames > 0 && ref_l1 < 1) { av_log(avctx, AV_LOG_WARNING, "B frames are not " @@ -1148,11 +1299,7 @@ static av_cold int vaapi_encode_config_attributes(AVCodecContext *avctx) } } - err = 0; -fail: - av_freep(&profiles); - av_freep(&entrypoints); - return err; + return 0; } static av_cold int vaapi_encode_init_rate_control(AVCodecContext *avctx) @@ -1407,6 +1554,10 @@ av_cold int ff_vaapi_encode_init(AVCodecContext *avctx) ctx->device = (AVHWDeviceContext*)ctx->device_ref->data; ctx->hwctx = ctx->device->hwctx; + err = vaapi_encode_profile_entrypoint(avctx); + if (err < 0) + goto fail; + err = vaapi_encode_config_attributes(avctx); if (err < 0) goto fail; diff --git a/libavcodec/vaapi_encode.h b/libavcodec/vaapi_encode.h index 54dc4a475e..2b909d4d6b 100644 --- a/libavcodec/vaapi_encode.h +++ b/libavcodec/vaapi_encode.h @@ -23,6 +23,10 @@ #include <va/va.h> +#if VA_CHECK_VERSION(1, 0, 0) +#include <va/va_str.h> +#endif + #include "libavutil/hwcontext.h" #include "libavutil/hwcontext_vaapi.h" @@ -86,18 +90,30 @@ typedef struct VAAPIEncodePicture { VAAPIEncodeSlice *slices; } VAAPIEncodePicture; +typedef struct VAAPIEncodeProfile { + // lavc profile value (FF_PROFILE_*). + int av_profile; + // Supported bit depth. + int depth; + // Chroma subsampling in width dimension. + int log2_chroma_w; + // Chroma subsampling in height dimension. + int log2_chroma_h; + // VAAPI profile value. + VAProfile va_profile; +} VAAPIEncodeProfile; + typedef struct VAAPIEncodeContext { const AVClass *class; // Codec-specific hooks. const struct VAAPIEncodeType *codec; - // Encoding profile (VAProfileXXX). - VAProfile va_profile; - // Encoding entrypoint (usually VAEntryointEncSlice). - VAEntrypoint va_entrypoint; - // Surface colour/sampling format (usually VA_RT_FORMAT_YUV420). - unsigned int va_rt_format; + // Global options. + + // Use low power encoding mode. + int low_power; + // Rate control mode. unsigned int va_rc_mode; // Supported packed headers (initially the desired set, modified @@ -113,6 +129,14 @@ typedef struct VAAPIEncodeContext { // Everything above this point must be set before calling // ff_vaapi_encode_init(). + // Chosen encoding profile details. + const VAAPIEncodeProfile *profile; + + // Encoding profile (VAProfile*). + VAProfile va_profile; + // Encoding entrypoint (VAEntryoint*). + VAEntrypoint va_entrypoint; + // Configuration attributes to use when creating va_config. VAConfigAttrib config_attributes[MAX_CONFIG_ATTRIBUTES]; int nb_config_attributes; @@ -204,8 +228,11 @@ typedef struct VAAPIEncodeContext { int end_of_stream; } VAAPIEncodeContext; - typedef struct VAAPIEncodeType { + // List of supported profiles and corresponding VAAPI profiles. + // (Must end with FF_PROFILE_UNKNOWN.) + const VAAPIEncodeProfile *profiles; + // Perform any extra codec-specific configuration after the // codec context is initialised (set up the private data and // add any necessary global parameters). diff --git a/libavcodec/vaapi_encode_h264.c b/libavcodec/vaapi_encode_h264.c index 8396683789..93dc51eb40 100644 --- a/libavcodec/vaapi_encode_h264.c +++ b/libavcodec/vaapi_encode_h264.c @@ -863,7 +863,17 @@ static av_cold int vaapi_encode_h264_configure(AVCodecContext *avctx) return 0; } +static const VAAPIEncodeProfile vaapi_encode_h264_profiles[] = { + { FF_PROFILE_H264_HIGH, 8, 1, 1, VAProfileH264High }, + { FF_PROFILE_H264_MAIN, 8, 1, 1, VAProfileH264Main }, + { FF_PROFILE_H264_CONSTRAINED_BASELINE, + 8, 1, 1, VAProfileH264ConstrainedBaseline }, + { FF_PROFILE_UNKNOWN } +}; + static const VAAPIEncodeType vaapi_encode_type_h264 = { + .profiles = vaapi_encode_h264_profiles, + .configure = &vaapi_encode_h264_configure, .sequence_params_size = sizeof(VAEncSequenceParameterBufferH264), @@ -896,30 +906,17 @@ static av_cold int vaapi_encode_h264_init(AVCodecContext *avctx) if (avctx->level == FF_LEVEL_UNKNOWN) avctx->level = priv->level; + // Reject unsupported profiles. switch (avctx->profile) { case FF_PROFILE_H264_BASELINE: av_log(avctx, AV_LOG_WARNING, "H.264 baseline profile is not " "supported, using constrained baseline profile instead.\n"); avctx->profile = FF_PROFILE_H264_CONSTRAINED_BASELINE; - case FF_PROFILE_H264_CONSTRAINED_BASELINE: - ctx->va_profile = VAProfileH264ConstrainedBaseline; - if (avctx->max_b_frames != 0) { - avctx->max_b_frames = 0; - av_log(avctx, AV_LOG_WARNING, "H.264 constrained baseline profile " - "doesn't support encoding with B frames, disabling them.\n"); - } - break; - case FF_PROFILE_H264_MAIN: - ctx->va_profile = VAProfileH264Main; break; case FF_PROFILE_H264_EXTENDED: av_log(avctx, AV_LOG_ERROR, "H.264 extended profile " "is not supported.\n"); return AVERROR_PATCHWELCOME; - case FF_PROFILE_UNKNOWN: - case FF_PROFILE_H264_HIGH: - ctx->va_profile = VAProfileH264High; - break; case FF_PROFILE_H264_HIGH_10: case FF_PROFILE_H264_HIGH_10_INTRA: av_log(avctx, AV_LOG_ERROR, "H.264 10-bit profiles " @@ -934,25 +931,9 @@ static av_cold int vaapi_encode_h264_init(AVCodecContext *avctx) av_log(avctx, AV_LOG_ERROR, "H.264 non-4:2:0 profiles " "are not supported.\n"); return AVERROR_PATCHWELCOME; - default: - av_log(avctx, AV_LOG_ERROR, "Unknown H.264 profile %d.\n", - avctx->profile); - return AVERROR(EINVAL); - } - if (priv->low_power) { -#if VA_CHECK_VERSION(0, 39, 2) - ctx->va_entrypoint = VAEntrypointEncSliceLP; -#else - av_log(avctx, AV_LOG_ERROR, "Low-power encoding is not " - "supported with this VAAPI version.\n"); - return AVERROR(EINVAL); -#endif - } else { - ctx->va_entrypoint = VAEntrypointEncSlice; } - // Only 8-bit encode is supported. - ctx->va_rt_format = VA_RT_FORMAT_YUV420; + ctx->low_power = priv->low_power; if (avctx->bit_rate > 0) { if (avctx->rc_max_rate == avctx->bit_rate) @@ -1021,7 +1002,7 @@ static const AVOption vaapi_encode_h264_options[] = { { "profile", "Set profile (profile_idc and constraint_set*_flag)", OFFSET(profile), AV_OPT_TYPE_INT, - { .i64 = FF_PROFILE_H264_HIGH }, 0x0000, 0xffff, FLAGS, "profile" }, + { .i64 = FF_PROFILE_UNKNOWN }, FF_PROFILE_UNKNOWN, 0xffff, FLAGS, "profile" }, #define PROFILE(name, value) name, NULL, 0, AV_OPT_TYPE_CONST, \ { .i64 = value }, 0, 0, FLAGS, "profile" diff --git a/libavcodec/vaapi_encode_h265.c b/libavcodec/vaapi_encode_h265.c index 5529ee5a03..e01bdcf6b4 100644 --- a/libavcodec/vaapi_encode_h265.c +++ b/libavcodec/vaapi_encode_h265.c @@ -875,7 +875,25 @@ static av_cold int vaapi_encode_h265_configure(AVCodecContext *avctx) return 0; } +static const VAAPIEncodeProfile vaapi_encode_h265_profiles[] = { + { FF_PROFILE_HEVC_MAIN, 8, 1, 1, VAProfileHEVCMain }, +#if VA_CHECK_VERSION(0, 37, 0) + { FF_PROFILE_HEVC_MAIN_10, 10, 1, 1, VAProfileHEVCMain10 }, +#endif +#if VA_CHECK_VERSION(1, 2, 0) + { FF_PROFILE_HEVC_REXT, 12, 1, 1, VAProfileHEVCMain12 }, + { FF_PROFILE_HEVC_REXT, 10, 1, 0, VAProfileHEVCMain422_10 }, + { FF_PROFILE_HEVC_REXT, 12, 1, 0, VAProfileHEVCMain422_12 }, + { FF_PROFILE_HEVC_REXT, 8, 0, 0, VAProfileHEVCMain444 }, + { FF_PROFILE_HEVC_REXT, 10, 0, 0, VAProfileHEVCMain444_10 }, + { FF_PROFILE_HEVC_REXT, 12, 0, 0, VAProfileHEVCMain444_12 }, +#endif + { FF_PROFILE_UNKNOWN } +}; + static const VAAPIEncodeType vaapi_encode_type_h265 = { + .profiles = vaapi_encode_h265_profiles, + .configure = &vaapi_encode_h265_configure, .sequence_params_size = sizeof(VAEncSequenceParameterBufferHEVC), @@ -906,29 +924,6 @@ static av_cold int vaapi_encode_h265_init(AVCodecContext *avctx) if (avctx->level == FF_LEVEL_UNKNOWN) avctx->level = priv->level; - switch (avctx->profile) { - case FF_PROFILE_HEVC_MAIN: - case FF_PROFILE_UNKNOWN: - ctx->va_profile = VAProfileHEVCMain; - ctx->va_rt_format = VA_RT_FORMAT_YUV420; - break; - case FF_PROFILE_HEVC_MAIN_10: -#ifdef VA_RT_FORMAT_YUV420_10BPP - ctx->va_profile = VAProfileHEVCMain10; - ctx->va_rt_format = VA_RT_FORMAT_YUV420_10BPP; - break; -#else - av_log(avctx, AV_LOG_ERROR, "10-bit encoding is not " - "supported with this VAAPI version.\n"); - return AVERROR(ENOSYS); -#endif - default: - av_log(avctx, AV_LOG_ERROR, "Unknown H.265 profile %d.\n", - avctx->profile); - return AVERROR(EINVAL); - } - ctx->va_entrypoint = VAEntrypointEncSlice; - if (avctx->bit_rate > 0) { if (avctx->rc_max_rate == avctx->bit_rate) ctx->va_rc_mode = VA_RC_CBR; @@ -967,7 +962,7 @@ static const AVOption vaapi_encode_h265_options[] = { { "profile", "Set profile (general_profile_idc)", OFFSET(profile), AV_OPT_TYPE_INT, - { .i64 = FF_PROFILE_HEVC_MAIN }, 0x00, 0xff, FLAGS, "profile" }, + { .i64 = FF_PROFILE_UNKNOWN }, FF_PROFILE_UNKNOWN, 0xff, FLAGS, "profile" }, #define PROFILE(name, value) name, NULL, 0, AV_OPT_TYPE_CONST, \ { .i64 = value }, 0, 0, FLAGS, "profile" diff --git a/libavcodec/vaapi_encode_mjpeg.c b/libavcodec/vaapi_encode_mjpeg.c index 481981a71c..3baf5c8915 100644 --- a/libavcodec/vaapi_encode_mjpeg.c +++ b/libavcodec/vaapi_encode_mjpeg.c @@ -359,7 +359,15 @@ static av_cold int vaapi_encode_mjpeg_configure(AVCodecContext *avctx) return 0; } +static const VAAPIEncodeProfile vaapi_encode_mjpeg_profiles[] = { + { FF_PROFILE_MJPEG_HUFFMAN_BASELINE_DCT, + 8, 1, 1, VAProfileJPEGBaseline }, + { FF_PROFILE_UNKNOWN } +}; + static const VAAPIEncodeType vaapi_encode_type_mjpeg = { + .profiles = vaapi_encode_mjpeg_profiles, + .configure = &vaapi_encode_mjpeg_configure, .picture_params_size = sizeof(VAEncPictureParameterBufferJPEG), @@ -380,11 +388,6 @@ static av_cold int vaapi_encode_mjpeg_init(AVCodecContext *avctx) ctx->codec = &vaapi_encode_type_mjpeg; - ctx->va_profile = VAProfileJPEGBaseline; - ctx->va_entrypoint = VAEntrypointEncPicture; - - ctx->va_rt_format = VA_RT_FORMAT_YUV420; - ctx->va_rc_mode = VA_RC_CQP; // The JPEG image header - see note above. diff --git a/libavcodec/vaapi_encode_mpeg2.c b/libavcodec/vaapi_encode_mpeg2.c index 72c838d774..b995a4b8b8 100644 --- a/libavcodec/vaapi_encode_mpeg2.c +++ b/libavcodec/vaapi_encode_mpeg2.c @@ -552,7 +552,15 @@ static av_cold int vaapi_encode_mpeg2_configure(AVCodecContext *avctx) return 0; } +static const VAAPIEncodeProfile vaapi_encode_mpeg2_profiles[] = { + { FF_PROFILE_MPEG2_MAIN, 8, 1, 1, VAProfileMPEG2Main }, + { FF_PROFILE_MPEG2_SIMPLE, 8, 1, 1, VAProfileMPEG2Simple }, + { FF_PROFILE_UNKNOWN } +}; + static const VAAPIEncodeType vaapi_encode_type_mpeg2 = { + .profiles = vaapi_encode_mpeg2_profiles, + .configure = &vaapi_encode_mpeg2_configure, .sequence_params_size = sizeof(VAEncSequenceParameterBufferMPEG2), @@ -577,31 +585,6 @@ static av_cold int vaapi_encode_mpeg2_init(AVCodecContext *avctx) ctx->codec = &vaapi_encode_type_mpeg2; - switch (avctx->profile) { - case FF_PROFILE_MPEG2_SIMPLE: - ctx->va_profile = VAProfileMPEG2Simple; - break; - case FF_PROFILE_MPEG2_MAIN: - ctx->va_profile = VAProfileMPEG2Main; - break; - case FF_PROFILE_MPEG2_422: - av_log(avctx, AV_LOG_ERROR, "MPEG-2 4:2:2 profile " - "is not supported.\n"); - return AVERROR_PATCHWELCOME; - case FF_PROFILE_MPEG2_HIGH: - av_log(avctx, AV_LOG_ERROR, "MPEG-2 high profile " - "is not supported.\n"); - return AVERROR_PATCHWELCOME; - case FF_PROFILE_MPEG2_SS: - case FF_PROFILE_MPEG2_SNR_SCALABLE: - av_log(avctx, AV_LOG_ERROR, "MPEG-2 scalable profiles " - "are not supported.\n"); - return AVERROR_PATCHWELCOME; - default: - av_log(avctx, AV_LOG_ERROR, "Unknown MPEG-2 profile %d.\n", - avctx->profile); - return AVERROR(EINVAL); - } switch (avctx->level) { case 4: // High case 6: // High 1440 @@ -620,8 +603,6 @@ static av_cold int vaapi_encode_mpeg2_init(AVCodecContext *avctx) return AVERROR(EINVAL); } - ctx->va_entrypoint = VAEntrypointEncSlice; - ctx->va_rt_format = VA_RT_FORMAT_YUV420; ctx->va_rc_mode = VA_RC_CQP; ctx->va_packed_headers = VA_ENC_PACKED_HEADER_SEQUENCE | @@ -644,7 +625,6 @@ static av_cold int vaapi_encode_mpeg2_close(AVCodecContext *avctx) } static const AVCodecDefault vaapi_encode_mpeg2_defaults[] = { - { "profile", "4" }, { "level", "4" }, { "bf", "1" }, { "g", "120" }, diff --git a/libavcodec/vaapi_encode_vp8.c b/libavcodec/vaapi_encode_vp8.c index 05c9d03a38..2191e00ef4 100644 --- a/libavcodec/vaapi_encode_vp8.c +++ b/libavcodec/vaapi_encode_vp8.c @@ -173,7 +173,14 @@ static av_cold int vaapi_encode_vp8_configure(AVCodecContext *avctx) return 0; } +static const VAAPIEncodeProfile vaapi_encode_vp8_profiles[] = { + { 0 /* VP8 has no profiles */, 8, 1, 1, VAProfileVP8Version0_3 }, + { FF_PROFILE_UNKNOWN } +}; + static const VAAPIEncodeType vaapi_encode_type_vp8 = { + .profiles = vaapi_encode_vp8_profiles, + .configure = &vaapi_encode_vp8_configure, .sequence_params_size = sizeof(VAEncSequenceParameterBufferVP8), @@ -196,10 +203,6 @@ static av_cold int vaapi_encode_vp8_init(AVCodecContext *avctx) ctx->codec = &vaapi_encode_type_vp8; - ctx->va_profile = VAProfileVP8Version0_3; - ctx->va_entrypoint = VAEntrypointEncSlice; - ctx->va_rt_format = VA_RT_FORMAT_YUV420; - if (avctx->flags & AV_CODEC_FLAG_QSCALE) { ctx->va_rc_mode = VA_RC_CQP; } else if (avctx->bit_rate > 0) { diff --git a/libavcodec/vaapi_encode_vp9.c b/libavcodec/vaapi_encode_vp9.c index bf99597e4c..8091ae87e9 100644 --- a/libavcodec/vaapi_encode_vp9.c +++ b/libavcodec/vaapi_encode_vp9.c @@ -203,7 +203,15 @@ static av_cold int vaapi_encode_vp9_configure(AVCodecContext *avctx) return 0; } +static const VAAPIEncodeProfile vaapi_encode_vp9_profiles[] = { + { FF_PROFILE_VP9_0, 8, 1, 1, VAProfileVP9Profile0 }, + { FF_PROFILE_VP9_2, 10, 1, 1, VAProfileVP9Profile2 }, + { FF_PROFILE_UNKNOWN } +}; + static const VAAPIEncodeType vaapi_encode_type_vp9 = { + .profiles = vaapi_encode_vp9_profiles, + .configure = &vaapi_encode_vp9_configure, .sequence_params_size = sizeof(VAEncSequenceParameterBufferVP9), @@ -219,31 +227,6 @@ static av_cold int vaapi_encode_vp9_init(AVCodecContext *avctx) ctx->codec = &vaapi_encode_type_vp9; - switch (avctx->profile) { - case FF_PROFILE_VP9_0: - case FF_PROFILE_UNKNOWN: - ctx->va_profile = VAProfileVP9Profile0; - ctx->va_rt_format = VA_RT_FORMAT_YUV420; - break; - case FF_PROFILE_VP9_1: - av_log(avctx, AV_LOG_ERROR, "VP9 profile 1 is not " - "supported.\n"); - return AVERROR_PATCHWELCOME; - case FF_PROFILE_VP9_2: - ctx->va_profile = VAProfileVP9Profile2; - ctx->va_rt_format = VA_RT_FORMAT_YUV420_10BPP; - break; - case FF_PROFILE_VP9_3: - av_log(avctx, AV_LOG_ERROR, "VP9 profile 3 is not " - "supported.\n"); - return AVERROR_PATCHWELCOME; - default: - av_log(avctx, AV_LOG_ERROR, "Unknown VP9 profile %d.\n", - avctx->profile); - return AVERROR(EINVAL); - } - ctx->va_entrypoint = VAEntrypointEncSlice; - if (avctx->flags & AV_CODEC_FLAG_QSCALE) { ctx->va_rc_mode = VA_RC_CQP; } else if (avctx->bit_rate > 0) { @@ -276,7 +259,6 @@ static const AVOption vaapi_encode_vp9_options[] = { }; static const AVCodecDefault vaapi_encode_vp9_defaults[] = { - { "profile", "0" }, { "b", "0" }, { "bf", "0" }, { "g", "250" },