| 1509 | } |
| 1510 | |
| 1511 | std::unique_ptr<avcodec_encode_session_t> make_avcodec_encode_session( |
| 1512 | platf::display_t *disp, |
| 1513 | const encoder_t &encoder, |
| 1514 | const config_t &config, |
| 1515 | int width, |
| 1516 | int height, |
| 1517 | std::unique_ptr<platf::avcodec_encode_device_t> encode_device |
| 1518 | ) { |
| 1519 | auto platform_formats = dynamic_cast<const encoder_platform_formats_avcodec *>(encoder.platform_formats.get()); |
| 1520 | if (!platform_formats) { |
| 1521 | return nullptr; |
| 1522 | } |
| 1523 | |
| 1524 | bool hardware = platform_formats->avcodec_base_dev_type != AV_HWDEVICE_TYPE_NONE; |
| 1525 | |
| 1526 | auto &video_format = encoder.codec_from_config(config); |
| 1527 | if (!video_format[encoder_t::PASSED] || !disp->is_codec_supported(video_format.name, config)) { |
| 1528 | BOOST_LOG(error) << encoder.name << ": "sv << video_format.name << " mode not supported"sv; |
| 1529 | return nullptr; |
| 1530 | } |
| 1531 | |
| 1532 | if (config.dynamicRange && !video_format[encoder_t::DYNAMIC_RANGE]) { |
| 1533 | BOOST_LOG(error) << video_format.name << ": dynamic range not supported"sv; |
| 1534 | return nullptr; |
| 1535 | } |
| 1536 | |
| 1537 | if (config.chromaSamplingType == 1 && !video_format[encoder_t::YUV444]) { |
| 1538 | BOOST_LOG(error) << video_format.name << ": YUV 4:4:4 not supported"sv; |
| 1539 | return nullptr; |
| 1540 | } |
| 1541 | |
| 1542 | auto codec = avcodec_find_encoder_by_name(video_format.name.c_str()); |
| 1543 | if (!codec) { |
| 1544 | BOOST_LOG(error) << "Couldn't open ["sv << video_format.name << ']'; |
| 1545 | |
| 1546 | return nullptr; |
| 1547 | } |
| 1548 | |
| 1549 | auto colorspace = encode_device->colorspace; |
| 1550 | auto sw_fmt = (colorspace.bit_depth == 8 && config.chromaSamplingType == 0) ? platform_formats->avcodec_pix_fmt_8bit : |
| 1551 | (colorspace.bit_depth == 8 && config.chromaSamplingType == 1) ? platform_formats->avcodec_pix_fmt_yuv444_8bit : |
| 1552 | (colorspace.bit_depth == 10 && config.chromaSamplingType == 0) ? platform_formats->avcodec_pix_fmt_10bit : |
| 1553 | (colorspace.bit_depth == 10 && config.chromaSamplingType == 1) ? platform_formats->avcodec_pix_fmt_yuv444_10bit : |
| 1554 | AV_PIX_FMT_NONE; |
| 1555 | |
| 1556 | // Allow up to 1 retry to apply the set of fallback options. |
| 1557 | // |
| 1558 | // Note: If we later end up needing multiple sets of |
| 1559 | // fallback options, we may need to allow more retries |
| 1560 | // to try applying each set. |
| 1561 | avcodec_ctx_t ctx; |
| 1562 | for (int retries = 0; retries < 2; retries++) { |
| 1563 | ctx.reset(avcodec_alloc_context3(codec)); |
| 1564 | ctx->width = config.width; |
| 1565 | ctx->height = config.height; |
| 1566 | ctx->time_base = AVRational {1, config.framerate}; |
| 1567 | ctx->framerate = AVRational {config.framerate, 1}; |
| 1568 |
no test coverage detected