diff options
author | Mark Thompson <sw@jkqxz.net> | 2016-09-18 14:59:59 +0100 |
---|---|---|
committer | Mark Thompson <sw@jkqxz.net> | 2016-11-21 22:13:41 +0000 |
commit | 478a4b7e6d3ec51ba80e77f6dc3df75d9f6de66b (patch) | |
tree | 4026b9badcfc843a2448d49ca9c1577d67e54b7a /libavcodec | |
parent | c8241e730f116f1c9cfc0b34110aa7f052e05332 (diff) |
vaapi_encode: Check packed header capabilities
This improves behaviour with drivers which do not support packed
headers, such as AMD VCE on mesa/gallium.
(cherry picked from commit 892bbbcdc171ff0d08d69636a240ffb95f54243c)
Diffstat (limited to 'libavcodec')
-rw-r--r-- | libavcodec/vaapi_encode.c | 36 | ||||
-rw-r--r-- | libavcodec/vaapi_encode.h | 3 | ||||
-rw-r--r-- | libavcodec/vaapi_encode_h264.c | 4 | ||||
-rw-r--r-- | libavcodec/vaapi_encode_h265.c | 3 | ||||
-rw-r--r-- | libavcodec/vaapi_encode_mjpeg.c | 15 |
5 files changed, 54 insertions, 7 deletions
diff --git a/libavcodec/vaapi_encode.c b/libavcodec/vaapi_encode.c index ddd0308492..0e17c5ad9a 100644 --- a/libavcodec/vaapi_encode.c +++ b/libavcodec/vaapi_encode.c @@ -237,7 +237,8 @@ static int vaapi_encode_issue(AVCodecContext *avctx, } if (pic->type == PICTURE_TYPE_IDR) { - if (ctx->codec->write_sequence_header) { + if (ctx->va_packed_headers & VA_ENC_PACKED_HEADER_SEQUENCE && + ctx->codec->write_sequence_header) { bit_len = 8 * sizeof(data); err = ctx->codec->write_sequence_header(avctx, data, &bit_len); if (err < 0) { @@ -253,7 +254,8 @@ static int vaapi_encode_issue(AVCodecContext *avctx, } } - if (ctx->codec->write_picture_header) { + if (ctx->va_packed_headers & VA_ENC_PACKED_HEADER_PICTURE && + ctx->codec->write_picture_header) { bit_len = 8 * sizeof(data); err = ctx->codec->write_picture_header(avctx, pic, data, &bit_len); if (err < 0) { @@ -289,7 +291,8 @@ static int vaapi_encode_issue(AVCodecContext *avctx, } } - if (ctx->codec->write_extra_header) { + if (ctx->va_packed_headers & VA_ENC_PACKED_HEADER_MISC && + ctx->codec->write_extra_header) { for (i = 0;; i++) { int type; bit_len = 8 * sizeof(data); @@ -336,7 +339,8 @@ static int vaapi_encode_issue(AVCodecContext *avctx, } } - if (ctx->codec->write_slice_header) { + if (ctx->va_packed_headers & VA_ENC_PACKED_HEADER_SLICE && + ctx->codec->write_slice_header) { bit_len = 8 * sizeof(data); err = ctx->codec->write_slice_header(avctx, pic, slice, data, &bit_len); @@ -930,9 +934,10 @@ static av_cold int vaapi_encode_config_attributes(AVCodecContext *avctx) VAProfile *profiles = NULL; VAEntrypoint *entrypoints = NULL; VAConfigAttrib attr[] = { - { VAConfigAttribRTFormat }, - { VAConfigAttribRateControl }, - { VAConfigAttribEncMaxRefFrames }, + { VAConfigAttribRTFormat }, + { VAConfigAttribRateControl }, + { VAConfigAttribEncMaxRefFrames }, + { VAConfigAttribEncPackedHeaders }, }; n = vaMaxNumProfiles(ctx->hwctx->display); @@ -1049,6 +1054,23 @@ static av_cold int vaapi_encode_config_attributes(AVCodecContext *avctx) } } break; + case VAConfigAttribEncPackedHeaders: + if (ctx->va_packed_headers & ~attr[i].value) { + // This isn't fatal, but packed headers are always + // preferable because they are under our control. + // When absent, the driver is generating them and some + // features may not work (e.g. VUI or SEI in H.264). + av_log(avctx, AV_LOG_WARNING, "Warning: some packed " + "headers are not supported (want %#x, got %#x).\n", + ctx->va_packed_headers, attr[i].value); + ctx->va_packed_headers &= attr[i].value; + } + ctx->config_attributes[ctx->nb_config_attributes++] = + (VAConfigAttrib) { + .type = VAConfigAttribEncPackedHeaders, + .value = ctx->va_packed_headers, + }; + break; default: av_assert0(0 && "Unexpected config attribute."); } diff --git a/libavcodec/vaapi_encode.h b/libavcodec/vaapi_encode.h index 4088897960..abce6b8ed8 100644 --- a/libavcodec/vaapi_encode.h +++ b/libavcodec/vaapi_encode.h @@ -101,6 +101,9 @@ typedef struct VAAPIEncodeContext { unsigned int va_rt_format; // Rate control mode. unsigned int va_rc_mode; + // Supported packed headers (initially the desired set, modified + // later to what is actually supported). + unsigned int va_packed_headers; // The required size of surfaces. This is probably the input // size (AVCodecContext.width|height) aligned up to whatever diff --git a/libavcodec/vaapi_encode_h264.c b/libavcodec/vaapi_encode_h264.c index 88fa566d66..9bcdc04d20 100644 --- a/libavcodec/vaapi_encode_h264.c +++ b/libavcodec/vaapi_encode_h264.c @@ -1221,6 +1221,10 @@ static av_cold int vaapi_encode_h264_init(AVCodecContext *avctx) else ctx->va_rc_mode = VA_RC_CQP; + ctx->va_packed_headers = + VA_ENC_PACKED_HEADER_SEQUENCE | // SPS and PPS. + VA_ENC_PACKED_HEADER_SLICE | // Slice headers. + VA_ENC_PACKED_HEADER_MISC; // SEI. ctx->surface_width = FFALIGN(avctx->width, 16); ctx->surface_height = FFALIGN(avctx->height, 16); diff --git a/libavcodec/vaapi_encode_h265.c b/libavcodec/vaapi_encode_h265.c index f3f0b4d2c0..4eeceb94bc 100644 --- a/libavcodec/vaapi_encode_h265.c +++ b/libavcodec/vaapi_encode_h265.c @@ -1251,6 +1251,9 @@ static av_cold int vaapi_encode_h265_init(AVCodecContext *avctx) else ctx->va_rc_mode = VA_RC_CQP; + ctx->va_packed_headers = + VA_ENC_PACKED_HEADER_SEQUENCE | // VPS, SPS and PPS. + VA_ENC_PACKED_HEADER_SLICE; // Slice headers. ctx->surface_width = FFALIGN(avctx->width, 16); ctx->surface_height = FFALIGN(avctx->height, 16); diff --git a/libavcodec/vaapi_encode_mjpeg.c b/libavcodec/vaapi_encode_mjpeg.c index 3ca902a6af..3afce28a10 100644 --- a/libavcodec/vaapi_encode_mjpeg.c +++ b/libavcodec/vaapi_encode_mjpeg.c @@ -345,6 +345,17 @@ static av_cold int vaapi_encode_mjpeg_configure(AVCodecContext *avctx) return AVERROR(EINVAL); } + // Hack: the implementation calls the JPEG image header (which we + // will use in the same way as a slice header) generic "raw data". + // Therefore, if after the packed header capability check we have + // PACKED_HEADER_RAW_DATA available, rewrite it as + // PACKED_HEADER_SLICE so that the header-writing code can do the + // right thing. + if (ctx->va_packed_headers & VA_ENC_PACKED_HEADER_RAW_DATA) { + ctx->va_packed_headers &= ~VA_ENC_PACKED_HEADER_RAW_DATA; + ctx->va_packed_headers |= VA_ENC_PACKED_HEADER_SLICE; + } + vaapi_encode_mjpeg_init_tables(avctx); return 0; @@ -380,6 +391,10 @@ static av_cold int vaapi_encode_mjpeg_init(AVCodecContext *avctx) ctx->va_rc_mode = VA_RC_CQP; + // The JPEG image header - see note above. + ctx->va_packed_headers = + VA_ENC_PACKED_HEADER_RAW_DATA; + ctx->surface_width = FFALIGN(avctx->width, 8); ctx->surface_height = FFALIGN(avctx->height, 8); |