FFmpeg: adapt to ffmpeg7 for dumping. (#248)

* FFmpeg: update layout api for ffmpeg 6.x and ffmpeg 7.

After ffmpeg 5.1, it is deprecated, and has been completely removed in ffmpeg 7.

Our current project is using 6.0 headers, modifying it will not have any side effects.

Since lavu 57.24.100(ffmpeg 5.1)

* FFmpeg: dynamic_library and dumping adapt to ffmpeg7.1.

But keeping support for older versions.

* externals/library-headers: update ffmpeg to 7.1
This commit is contained in:
kongfl888 K 2024-10-12 19:38:58 +08:00 committed by GitHub
parent 7d00f47c5e
commit cdce02607a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 64 additions and 15 deletions

@ -1 +1 @@
Subproject commit 3b3e28dbe6d033395ce2967fa8030825e7b89de7 Subproject commit 9fb99108ee5c630ca365c8fa4a11087b84e1f58b

View file

@ -27,7 +27,7 @@ static const std::unordered_map<AVOptionType, const char*> TypeNameMap{{
{AV_OPT_TYPE_STRING, QT_TR_NOOP("string")}, {AV_OPT_TYPE_STRING, QT_TR_NOOP("string")},
{AV_OPT_TYPE_DICT, QT_TR_NOOP("dictionary")}, {AV_OPT_TYPE_DICT, QT_TR_NOOP("dictionary")},
{AV_OPT_TYPE_VIDEO_RATE, QT_TR_NOOP("video rate")}, {AV_OPT_TYPE_VIDEO_RATE, QT_TR_NOOP("video rate")},
{AV_OPT_TYPE_CHANNEL_LAYOUT, QT_TR_NOOP("channel layout")}, {AV_OPT_TYPE_CHLAYOUT, QT_TR_NOOP("channel layout")},
}}; }};
static const std::unordered_map<AVOptionType, const char*> TypeDescriptionMap{{ static const std::unordered_map<AVOptionType, const char*> TypeDescriptionMap{{
@ -39,7 +39,7 @@ static const std::unordered_map<AVOptionType, const char*> TypeDescriptionMap{{
{AV_OPT_TYPE_DICT, {AV_OPT_TYPE_DICT,
QT_TR_NOOP("Comma-splitted list of &lt;key>=&lt;value>. Do not put spaces.")}, QT_TR_NOOP("Comma-splitted list of &lt;key>=&lt;value>. Do not put spaces.")},
{AV_OPT_TYPE_VIDEO_RATE, QT_TR_NOOP("&lt;num>/&lt;den>, or preset values like 'pal'.")}, {AV_OPT_TYPE_VIDEO_RATE, QT_TR_NOOP("&lt;num>/&lt;den>, or preset values like 'pal'.")},
{AV_OPT_TYPE_CHANNEL_LAYOUT, QT_TR_NOOP("Hexadecimal channel layout mask starting with '0x'.")}, {AV_OPT_TYPE_CHLAYOUT, QT_TR_NOOP("Hexadecimal channel layout mask starting with '0x'.")},
}}; }};
/// Get the preset values of an option. returns {display value, real value} /// Get the preset values of an option. returns {display value, real value}

View file

@ -65,6 +65,9 @@ avcodec_find_encoder_by_name_func avcodec_find_encoder_by_name;
avcodec_free_context_func avcodec_free_context; avcodec_free_context_func avcodec_free_context;
avcodec_get_class_func avcodec_get_class; avcodec_get_class_func avcodec_get_class;
avcodec_get_hw_config_func avcodec_get_hw_config; avcodec_get_hw_config_func avcodec_get_hw_config;
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(61, 13, 100) // lavc 61.13.100
avcodec_get_supported_config_func avcodec_get_supported_config;
#endif
avcodec_open2_func avcodec_open2; avcodec_open2_func avcodec_open2;
avcodec_parameters_from_context_func avcodec_parameters_from_context; avcodec_parameters_from_context_func avcodec_parameters_from_context;
avcodec_receive_frame_func avcodec_receive_frame; avcodec_receive_frame_func avcodec_receive_frame;
@ -232,6 +235,9 @@ static bool LoadAVCodec() {
LOAD_SYMBOL(avcodec, avcodec_free_context); LOAD_SYMBOL(avcodec, avcodec_free_context);
LOAD_SYMBOL(avcodec, avcodec_get_class); LOAD_SYMBOL(avcodec, avcodec_get_class);
LOAD_SYMBOL(avcodec, avcodec_get_hw_config); LOAD_SYMBOL(avcodec, avcodec_get_hw_config);
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(61, 13, 100) // lavc 61.13.100
LOAD_SYMBOL(avcodec, avcodec_get_supported_config);
#endif
LOAD_SYMBOL(avcodec, avcodec_open2); LOAD_SYMBOL(avcodec, avcodec_open2);
LOAD_SYMBOL(avcodec, avcodec_parameters_from_context); LOAD_SYMBOL(avcodec, avcodec_parameters_from_context);
LOAD_SYMBOL(avcodec, avcodec_receive_frame); LOAD_SYMBOL(avcodec, avcodec_receive_frame);

View file

@ -114,6 +114,10 @@ typedef const AVCodec* (*avcodec_find_encoder_by_name_func)(const char*);
typedef void (*avcodec_free_context_func)(AVCodecContext**); typedef void (*avcodec_free_context_func)(AVCodecContext**);
typedef const AVClass* (*avcodec_get_class_func)(); typedef const AVClass* (*avcodec_get_class_func)();
typedef const AVCodecHWConfig* (*avcodec_get_hw_config_func)(const AVCodec*, int); typedef const AVCodecHWConfig* (*avcodec_get_hw_config_func)(const AVCodec*, int);
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(61, 13, 100) // lavc 61.13.100
typedef int (*avcodec_get_supported_config_func)(const AVCodecContext*, const AVCodec*,
enum AVCodecConfig, unsigned, const void**, int*);
#endif
typedef int (*avcodec_open2_func)(AVCodecContext*, const AVCodec*, AVDictionary**); typedef int (*avcodec_open2_func)(AVCodecContext*, const AVCodec*, AVDictionary**);
typedef int (*avcodec_parameters_from_context_func)(AVCodecParameters* par, const AVCodecContext*); typedef int (*avcodec_parameters_from_context_func)(AVCodecParameters* par, const AVCodecContext*);
typedef int (*avcodec_receive_frame_func)(AVCodecContext*, AVFrame*); typedef int (*avcodec_receive_frame_func)(AVCodecContext*, AVFrame*);
@ -138,6 +142,9 @@ extern avcodec_find_encoder_by_name_func avcodec_find_encoder_by_name;
extern avcodec_free_context_func avcodec_free_context; extern avcodec_free_context_func avcodec_free_context;
extern avcodec_get_class_func avcodec_get_class; extern avcodec_get_class_func avcodec_get_class;
extern avcodec_get_hw_config_func avcodec_get_hw_config; extern avcodec_get_hw_config_func avcodec_get_hw_config;
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(61, 13, 100) // lavc 61.13.100
extern avcodec_get_supported_config_func avcodec_get_supported_config;
#endif
extern avcodec_open2_func avcodec_open2; extern avcodec_open2_func avcodec_open2;
extern avcodec_parameters_from_context_func avcodec_parameters_from_context; extern avcodec_parameters_from_context_func avcodec_parameters_from_context;
extern avcodec_receive_frame_func avcodec_receive_frame; extern avcodec_receive_frame_func avcodec_receive_frame;

View file

@ -171,12 +171,21 @@ bool FFmpegVideoStream::Init(FFmpegMuxer& muxer, const Layout::FramebufferLayout
codec_context->gop_size = 12; codec_context->gop_size = 12;
// Get pixel format for codec // Get pixel format for codec
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(61, 13, 100) // lavc 61.13.100
const enum AVPixelFormat* pix_fmts = NULL;
int ret = FFmpeg::avcodec_get_supported_config(NULL, codec, AV_CODEC_CONFIG_PIX_FORMAT, 0,
(const void**)&pix_fmts, NULL);
#else
const enum AVPixelFormat* pix_fmts = codec->pix_fmts;
int ret = 0;
#endif
auto options = ToAVDictionary(Settings::values.video_encoder_options); auto options = ToAVDictionary(Settings::values.video_encoder_options);
auto pixel_format_opt = FFmpeg::av_dict_get(options, "pixel_format", nullptr, 0); auto pixel_format_opt = FFmpeg::av_dict_get(options, "pixel_format", nullptr, 0);
if (pixel_format_opt) { if (pixel_format_opt) {
sw_pixel_format = FFmpeg::av_get_pix_fmt(pixel_format_opt->value); sw_pixel_format = FFmpeg::av_get_pix_fmt(pixel_format_opt->value);
} else if (codec->pix_fmts) { } else if (ret >= 0 && pix_fmts) {
sw_pixel_format = GetPixelFormat(codec_context.get(), codec->pix_fmts); sw_pixel_format = GetPixelFormat(codec_context.get(), pix_fmts);
} else { } else {
sw_pixel_format = AV_PIX_FMT_YUV420P; sw_pixel_format = AV_PIX_FMT_YUV420P;
} }
@ -285,11 +294,20 @@ void FFmpegVideoStream::ProcessFrame(VideoFrame& frame) {
} }
bool FFmpegVideoStream::InitHWContext(const AVCodec* codec) { bool FFmpegVideoStream::InitHWContext(const AVCodec* codec) {
for (std::size_t i = 0; codec->pix_fmts[i] != AV_PIX_FMT_NONE; ++i) { #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(61, 13, 100) // lavc 61.13.100
const enum AVPixelFormat* pix_fmts = NULL;
int ret = FFmpeg::avcodec_get_supported_config(NULL, codec, AV_CODEC_CONFIG_PIX_FORMAT, 0,
(const void**)&pix_fmts, NULL);
#else
const enum AVPixelFormat* pix_fmts = codec->pix_fmts;
int ret = 0;
#endif
for (std::size_t i = 0; (ret >= 0 && pix_fmts) && (pix_fmts[i] != AV_PIX_FMT_NONE); ++i) {
const AVCodecHWConfig* config; const AVCodecHWConfig* config;
for (int j = 0;; ++j) { for (int j = 0;; ++j) {
config = FFmpeg::avcodec_get_hw_config(codec, j); config = FFmpeg::avcodec_get_hw_config(codec, j);
if (!config || config->pix_fmt == codec->pix_fmts[i]) { if (!config || config->pix_fmt == pix_fmts[i]) {
break; break;
} }
} }
@ -303,7 +321,7 @@ bool FFmpegVideoStream::InitHWContext(const AVCodec* codec) {
continue; continue;
} }
codec_context->pix_fmt = codec->pix_fmts[i]; codec_context->pix_fmt = pix_fmts[i];
// Create HW device context // Create HW device context
AVBufferRef* hw_device_context; AVBufferRef* hw_device_context;
@ -351,7 +369,7 @@ bool FFmpegVideoStream::InitHWContext(const AVCodec* codec) {
AVHWFramesContext* hw_frames_context = AVHWFramesContext* hw_frames_context =
reinterpret_cast<AVHWFramesContext*>(hw_frames_context_ref->data); reinterpret_cast<AVHWFramesContext*>(hw_frames_context_ref->data);
hw_frames_context->format = codec->pix_fmts[i]; hw_frames_context->format = pix_fmts[i];
hw_frames_context->sw_format = sw_pixel_format; hw_frames_context->sw_format = sw_pixel_format;
hw_frames_context->width = codec_context->width; hw_frames_context->width = codec_context->width;
hw_frames_context->height = codec_context->height; hw_frames_context->height = codec_context->height;
@ -455,6 +473,7 @@ bool FFmpegAudioStream::Init(FFmpegMuxer& muxer) {
} }
frame_count = 0; frame_count = 0;
int ret;
// Initialize audio codec // Initialize audio codec
const AVCodec* codec = const AVCodec* codec =
@ -468,16 +487,33 @@ bool FFmpegAudioStream::Init(FFmpegMuxer& muxer) {
// Configure audio codec context // Configure audio codec context
codec_context->codec_type = AVMEDIA_TYPE_AUDIO; codec_context->codec_type = AVMEDIA_TYPE_AUDIO;
codec_context->bit_rate = Settings::values.audio_bitrate; codec_context->bit_rate = Settings::values.audio_bitrate;
if (codec->sample_fmts) {
codec_context->sample_fmt = codec->sample_fmts[0]; #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(61, 13, 100) // lavc 61.13.100
const enum AVSampleFormat* sample_fmts = NULL;
ret = FFmpeg::avcodec_get_supported_config(NULL, codec, AV_CODEC_CONFIG_SAMPLE_FORMAT, 0,
(const void**)&sample_fmts, NULL);
#else
const enum AVSampleFormat* sample_fmts = codec->sample_fmts;
ret = 0;
#endif
if (ret >= 0 && sample_fmts) {
codec_context->sample_fmt = sample_fmts[0];
} else { } else {
codec_context->sample_fmt = AV_SAMPLE_FMT_S16P; codec_context->sample_fmt = AV_SAMPLE_FMT_S16P;
} }
if (codec->supported_samplerates) { #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(61, 13, 100) // lavc 61.13.100
codec_context->sample_rate = codec->supported_samplerates[0]; const int* supported_samplerates = NULL;
ret = FFmpeg::avcodec_get_supported_config(NULL, codec, AV_CODEC_CONFIG_SAMPLE_RATE, 0,
(const void**)&supported_samplerates, NULL);
#else
const int* supported_samplerates = codec->supported_samplerates;
ret = 0;
#endif
if (ret >= 0 && supported_samplerates) {
codec_context->sample_rate = supported_samplerates[0];
// Prefer native sample rate if supported // Prefer native sample rate if supported
const int* ptr = codec->supported_samplerates; const int* ptr = supported_samplerates;
while ((*ptr)) { while ((*ptr)) {
if ((*ptr) == AudioCore::native_sample_rate) { if ((*ptr) == AudioCore::native_sample_rate) {
codec_context->sample_rate = AudioCore::native_sample_rate; codec_context->sample_rate = AudioCore::native_sample_rate;
@ -956,7 +992,7 @@ std::string FormatDefaultValue(const AVOption* option,
case AV_OPT_TYPE_VIDEO_RATE: { case AV_OPT_TYPE_VIDEO_RATE: {
return ToStdString(option->default_val.str); return ToStdString(option->default_val.str);
} }
case AV_OPT_TYPE_CHANNEL_LAYOUT: { case AV_OPT_TYPE_CHLAYOUT: {
return fmt::format("{:#x}", option->default_val.i64); return fmt::format("{:#x}", option->default_val.i64);
} }
default: default: