History

vaapi_encode: Clean up the packed header configuration

Add a larger warning more clearly explaining the consequences of missing packed header support in the driver. Also only write the extradata if the user actually requests it via the GLOBAL_HEADER flag.

Mark Thompson committed 8 years ago

Commit 851a63c1 parent bf726c28 files · +80 −68Browse files

Unified · Split

8 files
  1. libavcodec/vaapi_encode.c +63 −56
  2. libavcodec/vaapi_encode.h +4 −3
  3. libavcodec/vaapi_encode_h264.c +1 −1
  4. libavcodec/vaapi_encode_h265.c +1 −1
  5. libavcodec/vaapi_encode_mjpeg.c +1 −1
  6. libavcodec/vaapi_encode_mpeg2.c +2 −2
  7. libavcodec/vaapi_encode_vp8.c +4 −2
  8. libavcodec/vaapi_encode_vp9.c +4 −2
libavcodec/vaapi_encode.c+63−56
@@ -1206,60 +1206,6 @@ fail: · 1205 unmodified lines
12061206 return err;
12071207 }
12081208
1209−static av_cold int vaapi_encode_config_attributes(AVCodecContext *avctx)
1210−{
1211− VAAPIEncodeContext *ctx = avctx->priv_data;
1212− VAStatus vas;
1213− int i;
1214−
1215− VAConfigAttrib attr[] = {
1216− { VAConfigAttribEncPackedHeaders },
1217− };
1218−
1219− vas = vaGetConfigAttributes(ctx->hwctx->display,
1220− ctx->va_profile, ctx->va_entrypoint,
1221− attr, FF_ARRAY_ELEMS(attr));
1222− if (vas != VA_STATUS_SUCCESS) {
1223− av_log(avctx, AV_LOG_ERROR, "Failed to fetch config "
1224− "attributes: %d (%s).\n", vas, vaErrorStr(vas));
1225− return AVERROR(EINVAL);
1226− }
1227−
1228− for (i = 0; i < FF_ARRAY_ELEMS(attr); i++) {
1229− if (attr[i].value == VA_ATTRIB_NOT_SUPPORTED) {
1230− // Unfortunately we have to treat this as "don't know" and hope
1231− // for the best, because the Intel MJPEG encoder returns this
1232− // for all the interesting attributes.
1233− av_log(avctx, AV_LOG_DEBUG, "Attribute (%d) is not supported.\n",
1234− attr[i].type);
1235− continue;
1236− }
1237− switch (attr[i].type) {
1238− case VAConfigAttribEncPackedHeaders:
1239− if (ctx->va_packed_headers & ~attr[i].value) {
1240− // This isn't fatal, but packed headers are always
1241− // preferable because they are under our control.
1242− // When absent, the driver is generating them and some
1243− // features may not work (e.g. VUI or SEI in H.264).
1244− av_log(avctx, AV_LOG_WARNING, "Warning: some packed "
1245− "headers are not supported (want %#x, got %#x).\n",
1246− ctx->va_packed_headers, attr[i].value);
1247− ctx->va_packed_headers &= attr[i].value;
1248− }
1249− ctx->config_attributes[ctx->nb_config_attributes++] =
1250− (VAConfigAttrib) {
1251− .type = VAConfigAttribEncPackedHeaders,
1252− .value = ctx->va_packed_headers,
1253− };
1254− break;
1255− default:
1256− av_assert0(0 && "Unexpected config attribute.");
1257− }
1258− }
1259−
1260− return 0;
1261−}
1262−
12631209 static av_cold int vaapi_encode_init_rate_control(AVCodecContext *avctx)
12641210 {
12651211 VAAPIEncodeContext *ctx = avctx->priv_data;
@@ -1498,6 +1444,66 @@ static av_cold int vaapi_encode_init_gop_structure(AVCodecContext *avctx) · 232 unmodified lines
14981444 return 0;
14991445 }
15001446
1447+static av_cold int vaapi_encode_init_packed_headers(AVCodecContext *avctx)
1448+{
1449+ VAAPIEncodeContext *ctx = avctx->priv_data;
1450+ VAStatus vas;
1451+ VAConfigAttrib attr = { VAConfigAttribEncPackedHeaders };
1452+
1453+ vas = vaGetConfigAttributes(ctx->hwctx->display,
1454+ ctx->va_profile,
1455+ ctx->va_entrypoint,
1456+ &attr, 1);
1457+ if (vas != VA_STATUS_SUCCESS) {
1458+ av_log(avctx, AV_LOG_ERROR, "Failed to query packed headers "
1459+ "attribute: %d (%s).\n", vas, vaErrorStr(vas));
1460+ return AVERROR_EXTERNAL;
1461+ }
1462+
1463+ if (attr.value == VA_ATTRIB_NOT_SUPPORTED) {
1464+ if (ctx->desired_packed_headers) {
1465+ av_log(avctx, AV_LOG_WARNING, "Driver does not support any "
1466+ "packed headers (wanted %#x).\n",
1467+ ctx->desired_packed_headers);
1468+ } else {
1469+ av_log(avctx, AV_LOG_VERBOSE, "Driver does not support any "
1470+ "packed headers (none wanted).\n");
1471+ }
1472+ ctx->va_packed_headers = 0;
1473+ } else {
1474+ if (ctx->desired_packed_headers & ~attr.value) {
1475+ av_log(avctx, AV_LOG_WARNING, "Driver does not support some "
1476+ "wanted packed headers (wanted %#x, found %#x).\n",
1477+ ctx->desired_packed_headers, attr.value);
1478+ } else {
1479+ av_log(avctx, AV_LOG_VERBOSE, "All wanted packed headers "
1480+ "available (wanted %#x, found %#x).\n",
1481+ ctx->desired_packed_headers, attr.value);
1482+ }
1483+ ctx->va_packed_headers = ctx->desired_packed_headers & attr.value;
1484+ }
1485+
1486+ if (ctx->va_packed_headers) {
1487+ ctx->config_attributes[ctx->nb_config_attributes++] =
1488+ (VAConfigAttrib) {
1489+ .type = VAConfigAttribEncPackedHeaders,
1490+ .value = ctx->va_packed_headers,
1491+ };
1492+ }
1493+
1494+ if ( (ctx->desired_packed_headers & VA_ENC_PACKED_HEADER_SEQUENCE) &&
1495+ !(ctx->va_packed_headers & VA_ENC_PACKED_HEADER_SEQUENCE) &&
1496+ (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER)) {
1497+ av_log(avctx, AV_LOG_WARNING, "Driver does not support packed "
1498+ "sequence headers, but a global header is requested.\n");
1499+ av_log(avctx, AV_LOG_WARNING, "No global header will be written: "
1500+ "this may result in a stream which is not usable for some "
1501+ "purposes (e.g. not muxable to some containers).\n");
1502+ }
1503+
1504+ return 0;
1505+}
1506+
15011507 static av_cold int vaapi_encode_init_quality(AVCodecContext *avctx)
15021508 {
15031509 #if VA_CHECK_VERSION(0, 36, 0)
@@ -1728,7 +1734,7 @@ av_cold int ff_vaapi_encode_init(AVCodecContext *avctx) · 224 unmodified lines
17281734 if (err < 0)
17291735 goto fail;
17301736
1731− err = vaapi_encode_config_attributes(avctx);
1737+ err = vaapi_encode_init_packed_headers(avctx);
17321738 if (err < 0)
17331739 goto fail;
17341740
@@ -1817,7 +1823,8 @@ av_cold int ff_vaapi_encode_init(AVCodecContext *avctx) · 82 unmodified lines
18171823 ctx->issue_mode = ISSUE_MODE_MAXIMISE_THROUGHPUT;
18181824
18191825 if (ctx->va_packed_headers & VA_ENC_PACKED_HEADER_SEQUENCE &&
1820− ctx->codec->write_sequence_header) {
1826+ ctx->codec->write_sequence_header &&
1827+ avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) {
18211828 char data[MAX_PARAM_BUFFER_SIZE];
18221829 size_t bit_len = 8 * sizeof(data);
18231830
libavcodec/vaapi_encode.h+4−3
@@ -116,9 +116,8 @@ typedef struct VAAPIEncodeContext { · 115 unmodified lines
116116 // Use low power encoding mode.
117117 int low_power;
118118
119− // Supported packed headers (initially the desired set, modified
120− // later to what is actually supported).
121− unsigned int va_packed_headers;
119+ // Desired packed headers.
120+ unsigned int desired_packed_headers;
122121
123122 // The required size of surfaces. This is probably the input
124123 // size (AVCodecContext.width|height) aligned up to whatever
@@ -140,6 +139,8 @@ typedef struct VAAPIEncodeContext { · 15 unmodified lines
140139 unsigned int va_rc_mode;
141140 // Bitrate for codec-specific encoder parameters.
142141 unsigned int va_bit_rate;
142+ // Packed headers which will actually be sent.
143+ unsigned int va_packed_headers;
143144
144145 // Configuration attributes to use when creating va_config.
145146 VAConfigAttrib config_attributes[MAX_CONFIG_ATTRIBUTES];
libavcodec/vaapi_encode_h264.c+1−1
@@ -930,7 +930,7 @@ static av_cold int vaapi_encode_h264_init(AVCodecContext *avctx) · 929 unmodified lines
930930 return AVERROR_PATCHWELCOME;
931931 }
932932
933− ctx->va_packed_headers =
933+ ctx->desired_packed_headers =
934934 VA_ENC_PACKED_HEADER_SEQUENCE | // SPS and PPS.
935935 VA_ENC_PACKED_HEADER_SLICE | // Slice headers.
936936 VA_ENC_PACKED_HEADER_MISC; // SEI.
libavcodec/vaapi_encode_h265.c+1−1
@@ -1064,7 +1064,7 @@ static av_cold int vaapi_encode_h265_init(AVCodecContext *avctx) · 1063 unmodified lines
10641064 if (avctx->level == FF_LEVEL_UNKNOWN)
10651065 avctx->level = priv->level;
10661066
1067− ctx->va_packed_headers =
1067+ ctx->desired_packed_headers =
10681068 VA_ENC_PACKED_HEADER_SEQUENCE | // VPS, SPS and PPS.
10691069 VA_ENC_PACKED_HEADER_SLICE | // Slice headers.
10701070 VA_ENC_PACKED_HEADER_MISC; // SEI
libavcodec/vaapi_encode_mjpeg.c+1−1
@@ -389,7 +389,7 @@ static av_cold int vaapi_encode_mjpeg_init(AVCodecContext *avctx) · 388 unmodified lines
389389 ctx->codec = &vaapi_encode_type_mjpeg;
390390
391391 // The JPEG image header - see note above.
392− ctx->va_packed_headers =
392+ ctx->desired_packed_headers =
393393 VA_ENC_PACKED_HEADER_RAW_DATA;
394394
395395 ctx->surface_width = FFALIGN(avctx->width, 8);
libavcodec/vaapi_encode_mpeg2.c+2−2
@@ -615,8 +615,8 @@ static av_cold int vaapi_encode_mpeg2_init(AVCodecContext *avctx) · 614 unmodified lines
615615 return AVERROR(EINVAL);
616616 }
617617
618− ctx->va_packed_headers = VA_ENC_PACKED_HEADER_SEQUENCE |
619− VA_ENC_PACKED_HEADER_PICTURE;
618+ ctx->desired_packed_headers = VA_ENC_PACKED_HEADER_SEQUENCE |
619+ VA_ENC_PACKED_HEADER_PICTURE;
620620
621621 ctx->surface_width = FFALIGN(avctx->width, 16);
622622 ctx->surface_height = FFALIGN(avctx->height, 16);
libavcodec/vaapi_encode_vp8.c+4−2
@@ -200,8 +200,10 @@ static av_cold int vaapi_encode_vp8_init(AVCodecContext *avctx) · 199 unmodified lines
200200
201201 ctx->codec = &vaapi_encode_type_vp8;
202202
203− // Packed headers are not currently supported.
204− ctx->va_packed_headers = 0;
203+ // No packed headers are currently desired. VP8 has no metadata
204+ // which would be useful to write, and no existing driver supports
205+ // adding them anyway.
206+ ctx->desired_packed_headers = 0;
205207
206208 ctx->surface_width = FFALIGN(avctx->width, 16);
207209 ctx->surface_height = FFALIGN(avctx->height, 16);
libavcodec/vaapi_encode_vp9.c+4−2
@@ -228,8 +228,10 @@ static av_cold int vaapi_encode_vp9_init(AVCodecContext *avctx) · 227 unmodified lines
228228
229229 ctx->codec = &vaapi_encode_type_vp9;
230230
231− // Packed headers are not currently supported.
232− ctx->va_packed_headers = 0;
231+ // No packed headers are currently desired. They could be written,
232+ // but there isn't any reason to do so - the one usable driver (i965)
233+ // can write its own headers and there is no metadata to include.
234+ ctx->desired_packed_headers = 0;
233235
234236 // Surfaces must be aligned to superblock boundaries.
235237 ctx->surface_width = FFALIGN(avctx->width, 64);

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t