diff options
author | Mark Thompson <sw@jkqxz.net> | 2016-09-18 14:59:59 +0100 |
---|---|---|
committer | Mark Thompson <sw@jkqxz.net> | 2016-09-28 22:54:11 +0100 |
commit | 892bbbcdc171ff0d08d69636a240ffb95f54243c (patch) | |
tree | d9b1b85f004fe3b5c3b61ae1d41d2944c41af572 /libavcodec | |
parent | 80a5d05108cb218e8cd2e25c6621a3bfef0a832e (diff) | |
download | ffmpeg-892bbbcdc171ff0d08d69636a240ffb95f54243c.tar.gz |
vaapi_encode: Check packed header capabilities
This improves behaviour with drivers which do not support packed
headers, such as AMD VCE on mesa/gallium.
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 41d1a6ed17..7ec5340717 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 71f608751b..c47d979db2 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 d9b186816a..0cd966f662 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 f5e29443ef..7cd9782c20 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 8866dfba62..78d5e789f1 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); |