Allow setting the mode explicitly, and try to make a sensible choice given the available parameters if not.
Showing the changes to libavcodec/vaapi_encode.c (1 of 3 files). Show all
Unified · Split
| @@ -1283,17 +1283,42 @@ fail: · 1282 unmodified lines | ||
| 1283 | 1283 | return err; |
| 1284 | 1284 | } |
| 1285 | 1285 | |
| 1286 | +static const VAAPIEncodeRCMode vaapi_encode_rc_modes[] = { | |
| 1287 | + // Bitrate Quality | |
| 1288 | + // | Maxrate | HRD/VBV | |
| 1289 | + { 0 }, // | | | | | |
| 1290 | + { RC_MODE_CQP, "CQP", 1, VA_RC_CQP, 0, 0, 1, 0 }, | |
| 1291 | + { RC_MODE_CBR, "CBR", 1, VA_RC_CBR, 1, 0, 0, 1 }, | |
| 1292 | + { RC_MODE_VBR, "VBR", 1, VA_RC_VBR, 1, 1, 0, 1 }, | |
| 1293 | +#if VA_CHECK_VERSION(1, 1, 0) | |
| 1294 | + { RC_MODE_ICQ, "ICQ", 1, VA_RC_ICQ, 0, 0, 1, 0 }, | |
| 1295 | +#else | |
| 1296 | + { RC_MODE_ICQ, "ICQ", 0 }, | |
| 1297 | +#endif | |
| 1298 | +#if VA_CHECK_VERSION(1, 3, 0) | |
| 1299 | + { RC_MODE_QVBR, "QVBR", 1, VA_RC_QVBR, 1, 1, 1, 1 }, | |
| 1300 | + { RC_MODE_AVBR, "AVBR", 0, VA_RC_AVBR, 1, 0, 0, 0 }, | |
| 1301 | +#else | |
| 1302 | + { RC_MODE_QVBR, "QVBR", 0 }, | |
| 1303 | + { RC_MODE_AVBR, "AVBR", 0 }, | |
| 1304 | +#endif | |
| 1305 | +}; | |
| 1306 | + | |
| 1286 | 1307 | static av_cold int vaapi_encode_init_rate_control(AVCodecContext *avctx) |
| 1287 | 1308 | { |
| 1288 | 1309 | VAAPIEncodeContext *ctx = avctx->priv_data; |
| 1310 | + uint32_t supported_va_rc_modes; | |
| 1311 | + const VAAPIEncodeRCMode *rc_mode; | |
| 1289 | 1312 | int64_t rc_bits_per_second; |
| 1290 | 1313 | int rc_target_percentage; |
| 1291 | 1314 | int rc_window_size; |
| 1315 | + int rc_quality; | |
| 1292 | 1316 | int64_t hrd_buffer_size; |
| 1293 | 1317 | int64_t hrd_initial_buffer_fullness; |
| 1294 | 1318 | int fr_num, fr_den; |
| 1295 | 1319 | VAConfigAttrib rc_attr = { VAConfigAttribRateControl }; |
| 1296 | 1320 | VAStatus vas; |
| 1321 | + char supported_rc_modes_string[64]; | |
| 1297 | 1322 | |
| 1298 | 1323 | vas = vaGetConfigAttributes(ctx->hwctx->display, |
| 1299 | 1324 | ctx->va_profile, ctx->va_entrypoint, |
| @@ -1303,119 +1328,213 @@ static av_cold int vaapi_encode_init_rate_control(AVCodecContext *avctx) · 3 unmodified lines | ||
| 1303 | 1328 | "config attribute: %d (%s).\n", vas, vaErrorStr(vas)); |
| 1304 | 1329 | return AVERROR_EXTERNAL; |
| 1305 | 1330 | } |
| 1306 | − | |
| 1307 | 1331 | if (rc_attr.value == VA_ATTRIB_NOT_SUPPORTED) { |
| 1308 | 1332 | av_log(avctx, AV_LOG_VERBOSE, "Driver does not report any " |
| 1309 | − "supported rate control modes: assuming constant-quality.\n"); | |
| 1310 | − ctx->va_rc_mode = VA_RC_CQP; | |
| 1311 | − return 0; | |
| 1312 | − } | |
| 1313 | − if (ctx->codec->flags & FLAG_CONSTANT_QUALITY_ONLY || | |
| 1314 | − avctx->flags & AV_CODEC_FLAG_QSCALE || | |
| 1315 | − avctx->bit_rate <= 0) { | |
| 1316 | − if (rc_attr.value & VA_RC_CQP) { | |
| 1317 | − av_log(avctx, AV_LOG_VERBOSE, "Using constant-quality mode.\n"); | |
| 1318 | − ctx->va_rc_mode = VA_RC_CQP; | |
| 1319 | − if (avctx->bit_rate > 0 || avctx->rc_max_rate > 0) { | |
| 1320 | − av_log(avctx, AV_LOG_WARNING, "Bitrate target parameters " | |
| 1321 | − "ignored in constant-quality mode.\n"); | |
| 1333 | + "supported rate control modes: assuming CQP only.\n"); | |
| 1334 | + supported_va_rc_modes = VA_RC_CQP; | |
| 1335 | + strcpy(supported_rc_modes_string, "unknown"); | |
| 1336 | + } else { | |
| 1337 | + char *str = supported_rc_modes_string; | |
| 1338 | + size_t len = sizeof(supported_rc_modes_string); | |
| 1339 | + int i, first = 1, res; | |
| 1340 | + | |
| 1341 | + supported_va_rc_modes = rc_attr.value; | |
| 1342 | + for (i = 0; i < FF_ARRAY_ELEMS(vaapi_encode_rc_modes); i++) { | |
| 1343 | + rc_mode = &vaapi_encode_rc_modes[i]; | |
| 1344 | + if (supported_va_rc_modes & rc_mode->va_mode) { | |
| 1345 | + res = snprintf(str, len, "%s%s", | |
| 1346 | + first ? "" : ", ", rc_mode->name); | |
| 1347 | + first = 0; | |
| 1348 | + if (res < 0) { | |
| 1349 | + *str = 0; | |
| 1350 | + break; | |
| 1351 | + } | |
| 1352 | + len -= res; | |
| 1353 | + str += res; | |
| 1354 | + if (len == 0) | |
| 1355 | + break; | |
| 1322 | 1356 | } |
| 1323 | − return 0; | |
| 1324 | − } else { | |
| 1325 | − av_log(avctx, AV_LOG_ERROR, "Driver does not support " | |
| 1326 | − "constant-quality mode (%#x).\n", rc_attr.value); | |
| 1327 | − return AVERROR(EINVAL); | |
| 1328 | 1357 | } |
| 1329 | − } | |
| 1330 | 1358 | |
| 1331 | − if (!(rc_attr.value & (VA_RC_CBR | VA_RC_VBR))) { | |
| 1332 | − av_log(avctx, AV_LOG_ERROR, "Driver does not support any " | |
| 1333 | − "bitrate-targetted rate control modes.\n"); | |
| 1334 | − return AVERROR(EINVAL); | |
| 1359 | + av_log(avctx, AV_LOG_DEBUG, "Driver supports RC modes %s.\n", | |
| 1360 | + supported_rc_modes_string); | |
| 1361 | + } | |
| 1362 | + | |
| 1363 | + // Rate control mode selection: | |
| 1364 | + // * If the user has set a mode explicitly with the rc_mode option, | |
| 1365 | + // use it and fail if it is not available. | |
| 1366 | + // * If an explicit QP option has been set, use CQP. | |
| 1367 | + // * If the codec is CQ-only, use CQP. | |
| 1368 | + // * If the QSCALE avcodec option is set, use CQP. | |
| 1369 | + // * If bitrate and quality are both set, try QVBR. | |
| 1370 | + // * If quality is set, try ICQ, then CQP. | |
| 1371 | + // * If bitrate and maxrate are set and have the same value, try CBR. | |
| 1372 | + // * If a bitrate is set, try AVBR, then VBR, then CBR. | |
| 1373 | + // * If no bitrate is set, try ICQ, then CQP. | |
| 1374 | + | |
| 1375 | +#define TRY_RC_MODE(mode, fail) do { \ | |
| 1376 | + rc_mode = &vaapi_encode_rc_modes[mode]; \ | |
| 1377 | + if (!(rc_mode->va_mode & supported_va_rc_modes)) { \ | |
| 1378 | + if (fail) { \ | |
| 1379 | + av_log(avctx, AV_LOG_ERROR, "Driver does not support %s " \ | |
| 1380 | + "RC mode (supported modes: %s).\n", rc_mode->name, \ | |
| 1381 | + supported_rc_modes_string); \ | |
| 1382 | + return AVERROR(EINVAL); \ | |
| 1383 | + } \ | |
| 1384 | + av_log(avctx, AV_LOG_DEBUG, "Driver does not support %s " \ | |
| 1385 | + "RC mode.\n", rc_mode->name); \ | |
| 1386 | + rc_mode = NULL; \ | |
| 1387 | + } else { \ | |
| 1388 | + goto rc_mode_found; \ | |
| 1389 | + } \ | |
| 1390 | + } while (0) | |
| 1391 | + | |
| 1392 | + if (ctx->explicit_rc_mode) | |
| 1393 | + TRY_RC_MODE(ctx->explicit_rc_mode, 1); | |
| 1394 | + | |
| 1395 | + if (ctx->explicit_qp) | |
| 1396 | + TRY_RC_MODE(RC_MODE_CQP, 1); | |
| 1397 | + | |
| 1398 | + if (ctx->codec->flags & FLAG_CONSTANT_QUALITY_ONLY) | |
| 1399 | + TRY_RC_MODE(RC_MODE_CQP, 1); | |
| 1400 | + | |
| 1401 | + if (avctx->flags & AV_CODEC_FLAG_QSCALE) | |
| 1402 | + TRY_RC_MODE(RC_MODE_CQP, 1); | |
| 1403 | + | |
| 1404 | + if (avctx->bit_rate > 0 && avctx->global_quality > 0) | |
| 1405 | + TRY_RC_MODE(RC_MODE_QVBR, 0); | |
| 1406 | + | |
| 1407 | + if (avctx->global_quality > 0) { | |
| 1408 | + TRY_RC_MODE(RC_MODE_ICQ, 0); | |
| 1409 | + TRY_RC_MODE(RC_MODE_CQP, 0); | |
| 1410 | + } | |
| 1411 | + | |
| 1412 | + if (avctx->bit_rate > 0 && avctx->rc_max_rate == avctx->bit_rate) | |
| 1413 | + TRY_RC_MODE(RC_MODE_CBR, 0); | |
| 1414 | + | |
| 1415 | + if (avctx->bit_rate > 0) { | |
| 1416 | + TRY_RC_MODE(RC_MODE_AVBR, 0); | |
| 1417 | + TRY_RC_MODE(RC_MODE_VBR, 0); | |
| 1418 | + TRY_RC_MODE(RC_MODE_CBR, 0); | |
| 1419 | + } else { | |
| 1420 | + TRY_RC_MODE(RC_MODE_ICQ, 0); | |
| 1421 | + TRY_RC_MODE(RC_MODE_CQP, 0); | |
| 1335 | 1422 | } |
| 1336 | 1423 | |
| 1337 | − if (avctx->rc_buffer_size) | |
| 1338 | − hrd_buffer_size = avctx->rc_buffer_size; | |
| 1339 | − else if (avctx->rc_max_rate > 0) | |
| 1340 | − hrd_buffer_size = avctx->rc_max_rate; | |
| 1341 | − else | |
| 1342 | − hrd_buffer_size = avctx->bit_rate; | |
| 1343 | − if (avctx->rc_initial_buffer_occupancy) { | |
| 1344 | − if (avctx->rc_initial_buffer_occupancy > hrd_buffer_size) { | |
| 1345 | − av_log(avctx, AV_LOG_ERROR, "Invalid RC buffer settings: " | |
| 1346 | − "must have initial buffer size (%d) < " | |
| 1347 | − "buffer size (%"PRId64").\n", | |
| 1348 | − avctx->rc_initial_buffer_occupancy, hrd_buffer_size); | |
| 1424 | + av_log(avctx, AV_LOG_ERROR, "Driver does not support any " | |
| 1425 | + "RC mode compatible with selected options " | |
| 1426 | + "(supported modes: %s).\n", supported_rc_modes_string); | |
| 1427 | + return AVERROR(EINVAL); | |
| 1428 | + | |
| 1429 | +rc_mode_found: | |
| 1430 | + if (rc_mode->bitrate) { | |
| 1431 | + if (avctx->bit_rate <= 0) { | |
| 1432 | + av_log(avctx, AV_LOG_ERROR, "Bitrate must be set for %s " | |
| 1433 | + "RC mode.\n", rc_mode->name); | |
| 1349 | 1434 | return AVERROR(EINVAL); |
| 1350 | 1435 | } |
| 1351 | − hrd_initial_buffer_fullness = avctx->rc_initial_buffer_occupancy; | |
| 1352 | − } else { | |
| 1353 | − hrd_initial_buffer_fullness = hrd_buffer_size * 3 / 4; | |
| 1354 | − } | |
| 1355 | 1436 | |
| 1356 | − if (avctx->rc_max_rate && avctx->rc_max_rate < avctx->bit_rate) { | |
| 1357 | − av_log(avctx, AV_LOG_ERROR, "Invalid bitrate settings: must have " | |
| 1358 | − "bitrate (%"PRId64") <= maxrate (%"PRId64").\n", | |
| 1359 | − avctx->bit_rate, avctx->rc_max_rate); | |
| 1360 | − return AVERROR(EINVAL); | |
| 1361 | − } | |
| 1437 | + if (rc_mode->mode == RC_MODE_AVBR) { | |
| 1438 | + // For maximum confusion AVBR is hacked into the existing API | |
| 1439 | + // by overloading some of the fields with completely different | |
| 1440 | + // meanings. | |
| 1362 | 1441 | |
| 1363 | − if (avctx->rc_max_rate > avctx->bit_rate) { | |
| 1364 | − if (!(rc_attr.value & VA_RC_VBR)) { | |
| 1365 | − av_log(avctx, AV_LOG_WARNING, "Driver does not support " | |
| 1366 | − "VBR mode (%#x), using CBR mode instead.\n", | |
| 1367 | − rc_attr.value); | |
| 1368 | − ctx->va_rc_mode = VA_RC_CBR; | |
| 1442 | + // Target percentage does not apply in AVBR mode. | |
| 1443 | + rc_bits_per_second = avctx->bit_rate; | |
| 1369 | 1444 | |
| 1370 | − rc_bits_per_second = avctx->bit_rate; | |
| 1445 | + // Accuracy tolerance range for meeting the specified target | |
| 1446 | + // bitrate. It's very unclear how this is actually intended | |
| 1447 | + // to work - since we do want to get the specified bitrate, | |
| 1448 | + // set the accuracy to 100% for now. | |
| 1371 | 1449 | rc_target_percentage = 100; |
| 1372 | − } else { | |
| 1373 | − ctx->va_rc_mode = VA_RC_VBR; | |
| 1374 | 1450 | |
| 1375 | − rc_bits_per_second = avctx->rc_max_rate; | |
| 1376 | − rc_target_percentage = (avctx->bit_rate * 100) / | |
| 1377 | − avctx->rc_max_rate; | |
| 1378 | − } | |
| 1379 | − | |
| 1380 | − } else if (avctx->rc_max_rate == avctx->bit_rate) { | |
| 1381 | − if (!(rc_attr.value & VA_RC_CBR)) { | |
| 1382 | − av_log(avctx, AV_LOG_WARNING, "Driver does not support " | |
| 1383 | − "CBR mode (%#x), using VBR mode instead.\n", | |
| 1384 | − rc_attr.value); | |
| 1385 | − ctx->va_rc_mode = VA_RC_VBR; | |
| 1451 | + // Convergence period in frames. The GOP size reflects the | |
| 1452 | + // user's intended block size for cutting, so reusing that | |
| 1453 | + // as the convergence period seems a reasonable default. | |
| 1454 | + rc_window_size = avctx->gop_size > 0 ? avctx->gop_size : 60; | |
| 1455 | + | |
| 1456 | + } else if (rc_mode->maxrate) { | |
| 1457 | + if (avctx->rc_max_rate > 0) { | |
| 1458 | + if (avctx->rc_max_rate < avctx->bit_rate) { | |
| 1459 | + av_log(avctx, AV_LOG_ERROR, "Invalid bitrate settings: " | |
| 1460 | + "bitrate (%"PRId64") must not be greater than " | |
| 1461 | + "maxrate (%"PRId64").\n", avctx->bit_rate, | |
| 1462 | + avctx->rc_max_rate); | |
| 1463 | + return AVERROR(EINVAL); | |
| 1464 | + } | |
| 1465 | + rc_bits_per_second = avctx->rc_max_rate; | |
| 1466 | + rc_target_percentage = (avctx->bit_rate * 100) / | |
| 1467 | + avctx->rc_max_rate; | |
| 1468 | + } else { | |
| 1469 | + // We only have a target bitrate, but this mode requires | |
| 1470 | + // that a maximum rate be supplied as well. Since the | |
| 1471 | + // user does not want this to be a constraint, arbitrarily | |
| 1472 | + // pick a maximum rate of double the target rate. | |
| 1473 | + rc_bits_per_second = 2 * avctx->bit_rate; | |
| 1474 | + rc_target_percentage = 50; | |
| 1475 | + } | |
| 1386 | 1476 | } else { |
| 1387 | − ctx->va_rc_mode = VA_RC_CBR; | |
| 1477 | + if (avctx->rc_max_rate > avctx->bit_rate) { | |
| 1478 | + av_log(avctx, AV_LOG_WARNING, "Max bitrate is ignored " | |
| 1479 | + "in %s RC mode.\n", rc_mode->name); | |
| 1480 | + } | |
| 1481 | + rc_bits_per_second = avctx->bit_rate; | |
| 1482 | + rc_target_percentage = 100; | |
| 1388 | 1483 | } |
| 1389 | − | |
| 1390 | − rc_bits_per_second = avctx->bit_rate; | |
| 1484 | + } else { | |
| 1485 | + rc_bits_per_second = 0; | |
| 1391 | 1486 | rc_target_percentage = 100; |
| 1487 | + } | |
| 1392 | 1488 | |
| 1489 | + if (rc_mode->quality) { | |
| 1490 | + if (ctx->explicit_qp) { | |
| 1491 | + rc_quality = ctx->explicit_qp; | |
| 1492 | + } else if (avctx->global_quality > 0) { | |
| 1493 | + rc_quality = avctx->global_quality; | |
| 1494 | + } else { | |
| 1495 | + rc_quality = ctx->codec->default_quality; | |
| 1496 | + av_log(avctx, AV_LOG_WARNING, "No quality level set; " | |
| 1497 | + "using default (%d).\n", rc_quality); | |
| 1498 | + } | |
| 1393 | 1499 | } else { |
| 1394 | − if (rc_attr.value & VA_RC_VBR) { | |
| 1395 | − ctx->va_rc_mode = VA_RC_VBR; | |
| 1396 | − | |
| 1397 | − // We only have a target bitrate, but VAAPI requires that a | |
| 1398 | − // maximum rate be supplied as well. Since the user has | |
| 1399 | − // offered no particular constraint, arbitrarily pick a | |
| 1400 | − // maximum rate of double the target rate. | |
| 1401 | − rc_bits_per_second = 2 * avctx->bit_rate; | |
| 1402 | − rc_target_percentage = 50; | |
| 1500 | + rc_quality = 0; | |
| 1501 | + } | |
| 1502 | + | |
| 1503 | + if (rc_mode->hrd) { | |
| 1504 | + if (avctx->rc_buffer_size) | |
| 1505 | + hrd_buffer_size = avctx->rc_buffer_size; | |
| 1506 | + else if (avctx->rc_max_rate > 0) | |
| 1507 | + hrd_buffer_size = avctx->rc_max_rate; | |
| 1508 | + else | |
| 1509 | + hrd_buffer_size = avctx->bit_rate; | |
| 1510 | + if (avctx->rc_initial_buffer_occupancy) { | |
| 1511 | + if (avctx->rc_initial_buffer_occupancy > hrd_buffer_size) { | |
| 1512 | + av_log(avctx, AV_LOG_ERROR, "Invalid RC buffer settings: " | |
| 1513 | + "must have initial buffer size (%d) <= " | |
| 1514 | + "buffer size (%"PRId64").\n", | |
| 1515 | + avctx->rc_initial_buffer_occupancy, hrd_buffer_size); | |
| 1516 | + return AVERROR(EINVAL); | |
| 1517 | + } | |
| 1518 | + hrd_initial_buffer_fullness = avctx->rc_initial_buffer_occupancy; | |
| 1403 | 1519 | } else { |
| 1404 | − ctx->va_rc_mode = VA_RC_CBR; | |
| 1520 | + hrd_initial_buffer_fullness = hrd_buffer_size * 3 / 4; | |
| 1521 | + } | |
| 1405 | 1522 | |
| 1406 | − rc_bits_per_second = avctx->bit_rate; | |
| 1407 | − rc_target_percentage = 100; | |
| 1523 | + rc_window_size = (hrd_buffer_size * 1000) / rc_bits_per_second; | |
| 1524 | + } else { | |
| 1525 | + if (avctx->rc_buffer_size || avctx->rc_initial_buffer_occupancy) { | |
| 1526 | + av_log(avctx, AV_LOG_WARNING, "Buffering settings are ignored " | |
| 1527 | + "in %s RC mode.\n", rc_mode->name); | |
| 1408 | 1528 | } |
| 1409 | − } | |
| 1410 | 1529 | |
| 1411 | − rc_window_size = (hrd_buffer_size * 1000) / rc_bits_per_second; | |
| 1530 | + hrd_buffer_size = 0; | |
| 1531 | + hrd_initial_buffer_fullness = 0; | |
| 1412 | 1532 | |
| 1413 | − av_log(avctx, AV_LOG_VERBOSE, "RC mode: %s, %d%% of %"PRId64" bps " | |
| 1414 | − "over %d ms.\n", ctx->va_rc_mode == VA_RC_VBR ? "VBR" : "CBR", | |
| 1415 | − rc_target_percentage, rc_bits_per_second, rc_window_size); | |
| 1416 | − av_log(avctx, AV_LOG_VERBOSE, "RC buffer: %"PRId64" bits, " | |
| 1417 | − "initial fullness %"PRId64" bits.\n", | |
| 1418 | − hrd_buffer_size, hrd_initial_buffer_fullness); | |
| 1533 | + if (rc_mode->mode != RC_MODE_AVBR) { | |
| 1534 | + // Already set (with completely different meaning) for AVBR. | |
| 1535 | + rc_window_size = 1000; | |
| 1536 | + } | |
| 1537 | + } | |
| 1419 | 1538 | |
| 1420 | 1539 | if (rc_bits_per_second > UINT32_MAX || |
| 1421 | 1540 | hrd_buffer_size > UINT32_MAX || |
| @@ -1425,36 +1544,70 @@ static av_cold int vaapi_encode_init_rate_control(AVCodecContext *avctx) · 3 unmodified lines | ||
| 1425 | 1544 | return AVERROR(EINVAL); |
| 1426 | 1545 | } |
| 1427 | 1546 | |
| 1547 | + ctx->rc_mode = rc_mode; | |
| 1548 | + ctx->rc_quality = rc_quality; | |
| 1549 | + ctx->va_rc_mode = rc_mode->va_mode; | |
| 1428 | 1550 | ctx->va_bit_rate = rc_bits_per_second; |
| 1429 | 1551 | |
| 1430 | − ctx->config_attributes[ctx->nb_config_attributes++] = | |
| 1431 | − (VAConfigAttrib) { | |
| 1432 | − .type = VAConfigAttribRateControl, | |
| 1433 | − .value = ctx->va_rc_mode, | |
| 1434 | − }; | |
| 1552 | + av_log(avctx, AV_LOG_VERBOSE, "RC mode: %s.\n", rc_mode->name); | |
| 1553 | + if (rc_attr.value == VA_ATTRIB_NOT_SUPPORTED) { | |
| 1554 | + // This driver does not want the RC mode attribute to be set. | |
| 1555 | + } else { | |
| 1556 | + ctx->config_attributes[ctx->nb_config_attributes++] = | |
| 1557 | + (VAConfigAttrib) { | |
| 1558 | + .type = VAConfigAttribRateControl, | |
| 1559 | + .value = ctx->va_rc_mode, | |
| 1560 | + }; | |
| 1561 | + } | |
| 1435 | 1562 | |
| 1436 | − ctx->rc_params.misc.type = VAEncMiscParameterTypeRateControl; | |
| 1437 | − ctx->rc_params.rc = (VAEncMiscParameterRateControl) { | |
| 1438 | − .bits_per_second = rc_bits_per_second, | |
| 1439 | − .target_percentage = rc_target_percentage, | |
| 1440 | − .window_size = rc_window_size, | |
| 1441 | − .initial_qp = 0, | |
| 1442 | − .min_qp = (avctx->qmin > 0 ? avctx->qmin : 0), | |
| 1443 | − .basic_unit_size = 0, | |
| 1563 | + if (rc_mode->quality) | |
| 1564 | + av_log(avctx, AV_LOG_VERBOSE, "RC quality: %d.\n", rc_quality); | |
| 1565 | + | |
| 1566 | + if (rc_mode->va_mode != VA_RC_CQP) { | |
| 1567 | + if (rc_mode->mode == RC_MODE_AVBR) { | |
| 1568 | + av_log(avctx, AV_LOG_VERBOSE, "RC target: %"PRId64" bps " | |
| 1569 | + "converging in %d frames with %d%% accuracy.\n", | |
| 1570 | + rc_bits_per_second, rc_window_size, | |
| 1571 | + rc_target_percentage); | |
| 1572 | + } else if (rc_mode->bitrate) { | |
| 1573 | + av_log(avctx, AV_LOG_VERBOSE, "RC target: %d%% of " | |
| 1574 | + "%"PRId64" bps over %d ms.\n", rc_target_percentage, | |
| 1575 | + rc_bits_per_second, rc_window_size); | |
| 1576 | + } | |
| 1577 | + | |
| 1578 | + ctx->rc_params.misc.type = VAEncMiscParameterTypeRateControl; | |
| 1579 | + ctx->rc_params.rc = (VAEncMiscParameterRateControl) { | |
| 1580 | + .bits_per_second = rc_bits_per_second, | |
| 1581 | + .target_percentage = rc_target_percentage, | |
| 1582 | + .window_size = rc_window_size, | |
| 1583 | + .initial_qp = 0, | |
| 1584 | + .min_qp = (avctx->qmin > 0 ? avctx->qmin : 0), | |
| 1585 | + .basic_unit_size = 0, | |
| 1444 | 1586 | #if VA_CHECK_VERSION(1, 1, 0) |
| 1445 | − .max_qp = (avctx->qmax > 0 ? avctx->qmax : 0), | |
| 1587 | + .ICQ_quality_factor = av_clip(rc_quality, 1, 51), | |
| 1588 | + .max_qp = (avctx->qmax > 0 ? avctx->qmax : 0), | |
| 1446 | 1589 | #endif |
| 1447 | − }; | |
| 1448 | − vaapi_encode_add_global_param(avctx, &ctx->rc_params.misc, | |
| 1449 | − sizeof(ctx->rc_params)); | |
| 1590 | +#if VA_CHECK_VERSION(1, 3, 0) | |
| 1591 | + .quality_factor = rc_quality, | |
| 1592 | +#endif | |
| 1593 | + }; | |
| 1594 | + vaapi_encode_add_global_param(avctx, &ctx->rc_params.misc, | |
| 1595 | + sizeof(ctx->rc_params)); | |
| 1596 | + } | |
| 1450 | 1597 | |
| 1451 | − ctx->hrd_params.misc.type = VAEncMiscParameterTypeHRD; | |
| 1452 | − ctx->hrd_params.hrd = (VAEncMiscParameterHRD) { | |
| 1453 | − .initial_buffer_fullness = hrd_initial_buffer_fullness, | |
| 1454 | − .buffer_size = hrd_buffer_size, | |
| 1455 | − }; | |
| 1456 | − vaapi_encode_add_global_param(avctx, &ctx->hrd_params.misc, | |
| 1457 | − sizeof(ctx->hrd_params)); | |
| 1598 | + if (rc_mode->hrd) { | |
| 1599 | + av_log(avctx, AV_LOG_VERBOSE, "RC buffer: %"PRId64" bits, " | |
| 1600 | + "initial fullness %"PRId64" bits.\n", | |
| 1601 | + hrd_buffer_size, hrd_initial_buffer_fullness); | |
| 1602 | + | |
| 1603 | + ctx->hrd_params.misc.type = VAEncMiscParameterTypeHRD; | |
| 1604 | + ctx->hrd_params.hrd = (VAEncMiscParameterHRD) { | |
| 1605 | + .initial_buffer_fullness = hrd_initial_buffer_fullness, | |
| 1606 | + .buffer_size = hrd_buffer_size, | |
| 1607 | + }; | |
| 1608 | + vaapi_encode_add_global_param(avctx, &ctx->hrd_params.misc, | |
| 1609 | + sizeof(ctx->hrd_params)); | |
| 1610 | + } | |
| 1458 | 1611 | |
| 1459 | 1612 | if (avctx->framerate.num > 0 && avctx->framerate.den > 0) |
| 1460 | 1613 | av_reduce(&fr_num, &fr_den, |
| @@ -1463,6 +1616,9 @@ static av_cold int vaapi_encode_init_rate_control(AVCodecContext *avctx) · 2 unmodified lines | ||
| 1463 | 1616 | av_reduce(&fr_num, &fr_den, |
| 1464 | 1617 | avctx->time_base.den, avctx->time_base.num, 65535); |
| 1465 | 1618 | |
| 1619 | + av_log(avctx, AV_LOG_VERBOSE, "RC framerate: %d/%d (%.2f fps).\n", | |
| 1620 | + fr_num, fr_den, (double)fr_num / fr_den); | |
| 1621 | + | |
| 1466 | 1622 | ctx->fr_params.misc.type = VAEncMiscParameterTypeFrameRate; |
| 1467 | 1623 | ctx->fr_params.fr.framerate = (unsigned int)fr_den << 16 | fr_num; |
| 1468 | 1624 | |