History

vaapi_encode: Clean up rate control configuration

Query which modes are supported and select between VBR and CBR based on that - this removes all of the codec-specific rate control mode selection code.

Mark Thompson committed 8 years ago

Commit af532c91 parent 2562dd99 files · +145 −114Browse files

Showing the changes to libavcodec/vaapi_encode.c (1 of 9 files). Show all

Unified · Split

libavcodec/vaapi_encode.c+130−51
@@ -1213,7 +1213,6 @@ static av_cold int vaapi_encode_config_attributes(AVCodecContext *avctx) · 1212 unmodified lines
12131213 int i;
12141214
12151215 VAConfigAttrib attr[] = {
1216− { VAConfigAttribRateControl },
12171216 { VAConfigAttribEncMaxRefFrames },
12181217 { VAConfigAttribEncPackedHeaders },
12191218 };
@@ -1237,32 +1236,6 @@ static av_cold int vaapi_encode_config_attributes(AVCodecContext *avctx) · 17 unmodified lines
12371236 continue;
12381237 }
12391238 switch (attr[i].type) {
1240− case VAConfigAttribRateControl:
1241− // Hack for backward compatibility: CBR was the only
1242− // usable RC mode for a long time, so old drivers will
1243− // only have it. Normal default options may now choose
1244− // VBR and then fail, however, so override it here with
1245− // CBR if that is the only supported mode.
1246− if (ctx->va_rc_mode == VA_RC_VBR &&
1247− !(attr[i].value & VA_RC_VBR) &&
1248− (attr[i].value & VA_RC_CBR)) {
1249− av_log(avctx, AV_LOG_WARNING, "VBR rate control is "
1250− "not supported with this driver version; "
1251− "using CBR instead.\n");
1252− ctx->va_rc_mode = VA_RC_CBR;
1253− }
1254− if (!(ctx->va_rc_mode & attr[i].value)) {
1255− av_log(avctx, AV_LOG_ERROR, "Rate control mode %#x "
1256− "is not supported (mask: %#x).\n",
1257− ctx->va_rc_mode, attr[i].value);
1258− return AVERROR(EINVAL);
1259− }
1260− ctx->config_attributes[ctx->nb_config_attributes++] =
1261− (VAConfigAttrib) {
1262− .type = VAConfigAttribRateControl,
1263− .value = ctx->va_rc_mode,
1264− };
1265− break;
12661239 case VAConfigAttribEncMaxRefFrames:
12671240 {
12681241 unsigned int ref_l0 = attr[i].value & 0xffff;
@@ -1309,44 +1282,152 @@ static av_cold int vaapi_encode_config_attributes(AVCodecContext *avctx) · 40 unmodified lines
13091282 static av_cold int vaapi_encode_init_rate_control(AVCodecContext *avctx)
13101283 {
13111284 VAAPIEncodeContext *ctx = avctx->priv_data;
1312− int rc_bits_per_second;
1313− int rc_target_percentage;
1314− int rc_window_size;
1315− int hrd_buffer_size;
1316− int hrd_initial_buffer_fullness;
1285+ int64_t rc_bits_per_second;
1286+ int rc_target_percentage;
1287+ int rc_window_size;
1288+ int64_t hrd_buffer_size;
1289+ int64_t hrd_initial_buffer_fullness;
13171290 int fr_num, fr_den;
1291+ VAConfigAttrib rc_attr = { VAConfigAttribRateControl };
1292+ VAStatus vas;
1293+
1294+ vas = vaGetConfigAttributes(ctx->hwctx->display,
1295+ ctx->va_profile, ctx->va_entrypoint,
1296+ &rc_attr, 1);
1297+ if (vas != VA_STATUS_SUCCESS) {
1298+ av_log(avctx, AV_LOG_ERROR, "Failed to query rate control "
1299+ "config attribute: %d (%s).\n", vas, vaErrorStr(vas));
1300+ return AVERROR_EXTERNAL;
1301+ }
1302+
1303+ if (rc_attr.value == VA_ATTRIB_NOT_SUPPORTED) {
1304+ av_log(avctx, AV_LOG_VERBOSE, "Driver does not report any "
1305+ "supported rate control modes: assuming constant-quality.\n");
1306+ ctx->va_rc_mode = VA_RC_CQP;
1307+ return 0;
1308+ }
1309+ if (avctx->flags & AV_CODEC_FLAG_QSCALE ||
1310+ avctx->bit_rate <= 0) {
1311+ if (rc_attr.value & VA_RC_CQP) {
1312+ av_log(avctx, AV_LOG_VERBOSE, "Using constant-quality mode.\n");
1313+ ctx->va_rc_mode = VA_RC_CQP;
1314+ if (avctx->bit_rate > 0 || avctx->rc_max_rate > 0) {
1315+ av_log(avctx, AV_LOG_WARNING, "Bitrate target parameters "
1316+ "ignored in constant-quality mode.\n");
1317+ }
1318+ return 0;
1319+ } else {
1320+ av_log(avctx, AV_LOG_ERROR, "Driver does not support "
1321+ "constant-quality mode (%#x).\n", rc_attr.value);
1322+ return AVERROR(EINVAL);
1323+ }
1324+ }
13181325
1319− if (avctx->bit_rate > INT32_MAX) {
1320− av_log(avctx, AV_LOG_ERROR, "Target bitrate of 2^31 bps or "
1321− "higher is not supported.\n");
1326+ if (!(rc_attr.value & (VA_RC_CBR | VA_RC_VBR))) {
1327+ av_log(avctx, AV_LOG_ERROR, "Driver does not support any "
1328+ "bitrate-targetted rate control modes.\n");
13221329 return AVERROR(EINVAL);
13231330 }
13241331
13251332 if (avctx->rc_buffer_size)
13261333 hrd_buffer_size = avctx->rc_buffer_size;
1334+ else if (avctx->rc_max_rate > 0)
1335+ hrd_buffer_size = avctx->rc_max_rate;
13271336 else
13281337 hrd_buffer_size = avctx->bit_rate;
1329− if (avctx->rc_initial_buffer_occupancy)
1338+ if (avctx->rc_initial_buffer_occupancy) {
1339+ if (avctx->rc_initial_buffer_occupancy > hrd_buffer_size) {
1340+ av_log(avctx, AV_LOG_ERROR, "Invalid RC buffer settings: "
1341+ "must have initial buffer size (%d) < "
1342+ "buffer size (%"PRId64").\n",
1343+ avctx->rc_initial_buffer_occupancy, hrd_buffer_size);
1344+ return AVERROR(EINVAL);
1345+ }
13301346 hrd_initial_buffer_fullness = avctx->rc_initial_buffer_occupancy;
1331− else
1347+ } else {
13321348 hrd_initial_buffer_fullness = hrd_buffer_size * 3 / 4;
1349+ }
1350+
1351+ if (avctx->rc_max_rate && avctx->rc_max_rate < avctx->bit_rate) {
1352+ av_log(avctx, AV_LOG_ERROR, "Invalid bitrate settings: must have "
1353+ "bitrate (%"PRId64") <= maxrate (%"PRId64").\n",
1354+ avctx->bit_rate, avctx->rc_max_rate);
1355+ return AVERROR(EINVAL);
1356+ }
1357+
1358+ if (avctx->rc_max_rate > avctx->bit_rate) {
1359+ if (!(rc_attr.value & VA_RC_VBR)) {
1360+ av_log(avctx, AV_LOG_WARNING, "Driver does not support "
1361+ "VBR mode (%#x), using CBR mode instead.\n",
1362+ rc_attr.value);
1363+ ctx->va_rc_mode = VA_RC_CBR;
1364+
1365+ rc_bits_per_second = avctx->bit_rate;
1366+ rc_target_percentage = 100;
1367+ } else {
1368+ ctx->va_rc_mode = VA_RC_VBR;
1369+
1370+ rc_bits_per_second = avctx->rc_max_rate;
1371+ rc_target_percentage = (avctx->bit_rate * 100) /
1372+ avctx->rc_max_rate;
1373+ }
1374+
1375+ } else if (avctx->rc_max_rate == avctx->bit_rate) {
1376+ if (!(rc_attr.value & VA_RC_CBR)) {
1377+ av_log(avctx, AV_LOG_WARNING, "Driver does not support "
1378+ "CBR mode (%#x), using VBR mode instead.\n",
1379+ rc_attr.value);
1380+ ctx->va_rc_mode = VA_RC_VBR;
1381+ } else {
1382+ ctx->va_rc_mode = VA_RC_CBR;
1383+ }
13331384
1334− if (ctx->va_rc_mode == VA_RC_CBR) {
13351385 rc_bits_per_second = avctx->bit_rate;
13361386 rc_target_percentage = 100;
1337− rc_window_size = 1000;
1387+
13381388 } else {
1339− if (avctx->rc_max_rate < avctx->bit_rate) {
1340− // Max rate is unset or invalid, just use the normal bitrate.
1389+ if (rc_attr.value & VA_RC_VBR) {
1390+ ctx->va_rc_mode = VA_RC_VBR;
1391+
1392+ // We only have a target bitrate, but VAAPI requires that a
1393+ // maximum rate be supplied as well. Since the user has
1394+ // offered no particular constraint, arbitrarily pick a
1395+ // maximum rate of double the target rate.
1396+ rc_bits_per_second = 2 * avctx->bit_rate;
1397+ rc_target_percentage = 50;
1398+ } else {
1399+ ctx->va_rc_mode = VA_RC_CBR;
1400+
13411401 rc_bits_per_second = avctx->bit_rate;
13421402 rc_target_percentage = 100;
1343− } else {
1344− rc_bits_per_second = avctx->rc_max_rate;
1345− rc_target_percentage = (avctx->bit_rate * 100) / rc_bits_per_second;
13461403 }
1347− rc_window_size = (hrd_buffer_size * 1000) / avctx->bit_rate;
13481404 }
13491405
1406+ rc_window_size = (hrd_buffer_size * 1000) / rc_bits_per_second;
1407+
1408+ av_log(avctx, AV_LOG_VERBOSE, "RC mode: %s, %d%% of %"PRId64" bps "
1409+ "over %d ms.\n", ctx->va_rc_mode == VA_RC_VBR ? "VBR" : "CBR",
1410+ rc_target_percentage, rc_bits_per_second, rc_window_size);
1411+ av_log(avctx, AV_LOG_VERBOSE, "RC buffer: %"PRId64" bits, "
1412+ "initial fullness %"PRId64" bits.\n",
1413+ hrd_buffer_size, hrd_initial_buffer_fullness);
1414+
1415+ if (rc_bits_per_second > UINT32_MAX ||
1416+ hrd_buffer_size > UINT32_MAX ||
1417+ hrd_initial_buffer_fullness > UINT32_MAX) {
1418+ av_log(avctx, AV_LOG_ERROR, "RC parameters of 2^32 or "
1419+ "greater are not supported by VAAPI.\n");
1420+ return AVERROR(EINVAL);
1421+ }
1422+
1423+ ctx->va_bit_rate = rc_bits_per_second;
1424+
1425+ ctx->config_attributes[ctx->nb_config_attributes++] =
1426+ (VAConfigAttrib) {
1427+ .type = VAConfigAttribRateControl,
1428+ .value = ctx->va_rc_mode,
1429+ };
1430+
13501431 ctx->rc_params.misc.type = VAEncMiscParameterTypeRateControl;
13511432 ctx->rc_params.rc = (VAEncMiscParameterRateControl) {
13521433 .bits_per_second = rc_bits_per_second,
@@ -1607,6 +1688,10 @@ av_cold int ff_vaapi_encode_init(AVCodecContext *avctx) · 254 unmodified lines
16071688 if (err < 0)
16081689 goto fail;
16091690
1691+ err = vaapi_encode_init_rate_control(avctx);
1692+ if (err < 0)
1693+ goto fail;
1694+
16101695 err = vaapi_encode_config_attributes(avctx);
16111696 if (err < 0)
16121697 goto fail;
@@ -1654,12 +1739,6 @@ av_cold int ff_vaapi_encode_init(AVCodecContext *avctx) · 41 unmodified lines
16541739 goto fail;
16551740 }
16561741
1657− if (ctx->va_rc_mode & ~VA_RC_CQP) {
1658− err = vaapi_encode_init_rate_control(avctx);
1659− if (err < 0)
1660− goto fail;
1661− }
1662−
16631742 if (ctx->codec->configure) {
16641743 err = ctx->codec->configure(avctx);
16651744 if (err < 0)

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