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.
Showing the changes to libavcodec/vaapi_encode.c (1 of 8 files). Show all
Unified · Split
| @@ -1206,60 +1206,6 @@ fail: · 1205 unmodified lines | |||
| 1206 | return err; | 1206 | return err; |
| 1207 | } | 1207 | } |
| 1208 | 1208 | ||
| 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 | |||
| 1263 | static av_cold int vaapi_encode_init_rate_control(AVCodecContext *avctx) | 1209 | static av_cold int vaapi_encode_init_rate_control(AVCodecContext *avctx) |
| 1264 | { | 1210 | { |
| 1265 | VAAPIEncodeContext *ctx = avctx->priv_data; | 1211 | VAAPIEncodeContext *ctx = avctx->priv_data; |
| @@ -1498,6 +1444,66 @@ static av_cold int vaapi_encode_init_gop_structure(AVCodecContext *avctx) · 232 unmodified lines | |||
| 1498 | return 0; | 1444 | return 0; |
| 1499 | } | 1445 | } |
| 1500 | 1446 | ||
| 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 | |||
| 1501 | static av_cold int vaapi_encode_init_quality(AVCodecContext *avctx) | 1507 | static av_cold int vaapi_encode_init_quality(AVCodecContext *avctx) |
| 1502 | { | 1508 | { |
| 1503 | #if VA_CHECK_VERSION(0, 36, 0) | 1509 | #if VA_CHECK_VERSION(0, 36, 0) |
| @@ -1728,7 +1734,7 @@ av_cold int ff_vaapi_encode_init(AVCodecContext *avctx) · 224 unmodified lines | |||
| 1728 | if (err < 0) | 1734 | if (err < 0) |
| 1729 | goto fail; | 1735 | goto fail; |
| 1730 | 1736 | ||
| 1731 | err = vaapi_encode_config_attributes(avctx); | 1737 | err = vaapi_encode_init_packed_headers(avctx); |
| 1732 | if (err < 0) | 1738 | if (err < 0) |
| 1733 | goto fail; | 1739 | goto fail; |
| 1734 | 1740 | ||
| @@ -1817,7 +1823,8 @@ av_cold int ff_vaapi_encode_init(AVCodecContext *avctx) · 82 unmodified lines | |||
| 1817 | ctx->issue_mode = ISSUE_MODE_MAXIMISE_THROUGHPUT; | 1823 | ctx->issue_mode = ISSUE_MODE_MAXIMISE_THROUGHPUT; |
| 1818 | 1824 | ||
| 1819 | if (ctx->va_packed_headers & VA_ENC_PACKED_HEADER_SEQUENCE && | 1825 | 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) { | ||
| 1821 | char data[MAX_PARAM_BUFFER_SIZE]; | 1828 | char data[MAX_PARAM_BUFFER_SIZE]; |
| 1822 | size_t bit_len = 8 * sizeof(data); | 1829 | size_t bit_len = 8 * sizeof(data); |
| 1823 | 1830 | ||