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 | 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 | 1209 | static av_cold int vaapi_encode_init_rate_control(AVCodecContext *avctx) |
| 1264 | 1210 | { |
| 1265 | 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 | 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 | 1507 | static av_cold int vaapi_encode_init_quality(AVCodecContext *avctx) |
| 1502 | 1508 | { |
| 1503 | 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 | 1734 | if (err < 0) |
| 1729 | 1735 | goto fail; |
| 1730 | 1736 | |
| 1731 | − err = vaapi_encode_config_attributes(avctx); | |
| 1737 | + err = vaapi_encode_init_packed_headers(avctx); | |
| 1732 | 1738 | if (err < 0) |
| 1733 | 1739 | goto fail; |
| 1734 | 1740 | |
| @@ -1817,7 +1823,8 @@ av_cold int ff_vaapi_encode_init(AVCodecContext *avctx) · 82 unmodified lines | ||
| 1817 | 1823 | ctx->issue_mode = ISSUE_MODE_MAXIMISE_THROUGHPUT; |
| 1818 | 1824 | |
| 1819 | 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 | 1828 | char data[MAX_PARAM_BUFFER_SIZE]; |
| 1822 | 1829 | size_t bit_len = 8 * sizeof(data); |
| 1823 | 1830 | |