From 1e50bd129948d4da3d1d224e97f88ead342f0053 Mon Sep 17 00:00:00 2001 From: Shiz Date: Sat, 5 Apr 2025 04:12:05 +0200 Subject: [PATCH 3/3] hacks/ffmpeg-out: fix compatibility with ffmpeg 7.1 API --- hacks/ffmpeg-out.c | 105 +++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 96 insertions(+), 9 deletions(-) diff --git a/hacks/ffmpeg-out.c b/hacks/ffmpeg-out.c index 7520cb3..0d39323 100644 --- a/hacks/ffmpeg-out.c +++ b/hacks/ffmpeg-out.c @@ -37,6 +37,7 @@ /* No "diagnostic pop" because some macrose use c99 features. */ #endif +#include #include #include #include @@ -44,10 +45,13 @@ #if (LIBAVUTIL_VERSION_INT >= ((57<<16) | (28<<8) | 100)) # define HAVE_CH_LAYOUT #endif +#if (LIBAVCODEC_VERSION_INT >= ((61<<16) | (12<<8) | 100)) +# define HAVE_AVCODEC_GET_SUPPORTED_CONFIG +#endif struct av_stream { - AVCodec *codec; + const AVCodec *codec; AVStream *st; AVCodecContext *ctx; AVFrame *frame; @@ -132,6 +136,78 @@ guess_channel_layout (int channels) #endif /* !HAVE_CH_LAYOUT */ +#ifdef HAVE_AVCODEC_GET_SUPPORTED_CONFIG + +static const enum AVSampleFormat * +get_sample_formats (struct av_stream *st) +{ + const enum AVSampleFormat *fmts; + av_check (avcodec_get_supported_config (st->ctx, + st->codec, + AV_CODEC_CONFIG_SAMPLE_FORMAT, 0, + (const void **) &fmts, + NULL)); + return fmts; +} + +static const int * +get_sample_rates (struct av_stream *st) +{ + const int *rates; + av_check (avcodec_get_supported_config (st->ctx, + st->codec, + AV_CODEC_CONFIG_SAMPLE_RATE, 0, + (const void **) &rates, + NULL)); + return rates; +} + +static const AVChannelLayout * +get_channel_layouts (struct av_stream *st) +{ + const AVChannelLayout *layouts; + av_check (avcodec_get_supported_config (st->ctx, + st->codec, + AV_CODEC_CONFIG_CHANNEL_LAYOUT, 0, + (const void **) &layouts, + NULL)); + return layouts; +} + +#else /* !HAVE_AVCODEC_GET_SUPPORTED_CONFIG */ + +static const enum AVSampleFormat * +get_sample_formats (struct av_stream *st) +{ + return st->codec->sample_fmts; +} + +static const int * +get_sample_rates (struct av_stream *st) +{ + return st->codec->supported_samplerates; +} + +# ifdef HAVE_CH_LAYOUT + +static const AVChannelLayout * +get_channel_layouts (struct av_stream *st) +{ + return st->codec->ch_layouts; +} + +# else /* !HAVE_CH_LAYOUT */ + +static const int * +get_channel_layouts (struct av_stream *st) +{ + return st->codec->channel_layouts; +} + +# endif /* !HAVE_CH_LAYOUT */ + +#endif /* !HAVE_AVCODEC_GET_SUPPORTED_CONFIG */ + static void get_audio_frame (AVFormatContext *audio_fmt_ctx, @@ -292,6 +368,13 @@ ffmpeg_out_init (const char *outfile, const char *audiofile, const enum AVCodecID video_codec = AV_CODEC_ID_H264; const enum AVCodecID audio_codec = AV_CODEC_ID_AAC; const enum AVPixelFormat pix_fmt = AV_PIX_FMT_YUV420P; + const enum AVSampleFormat *sample_fmts = NULL; + const int *sample_rates = NULL; +#ifdef HAVE_CH_LAYOUT + const AVChannelLayout *channel_layouts = NULL; +#else + const int *channel_layouts = NULL; +#endif const unsigned framerate = 30; int audio_bitrate = 96000; const char *video_preset = (fast_p ? "ultrafast" : "veryslow"); @@ -356,19 +439,22 @@ ffmpeg_out_init (const char *outfile, const char *audiofile, NULL)); add_stream (&ffst->audio_ost, ffst->oc, audio_codec); + + sample_fmts = get_sample_formats (&ffst->audio_ost); ffst->audio_ost.ctx->sample_fmt = - (ffst->audio_ost.codec->sample_fmts - ? ffst->audio_ost.codec->sample_fmts[0] + (sample_fmts && sample_fmts[0] != AV_SAMPLE_FMT_NONE + ? sample_fmts[0] : AV_SAMPLE_FMT_FLTP); ffst->audio_ost.ctx->bit_rate = audio_bitrate; - if (! ffst->audio_ost.codec->supported_samplerates) + sample_rates = get_sample_rates (&ffst->audio_ost); + if (! sample_rates || sample_rates[0] == 0) { ffst->audio_ost.ctx->sample_rate = ffst->audio_ist.ctx->sample_rate; } else { - const int *r = ffst->audio_ost.codec->supported_samplerates; + const int *r = sample_rates; int best = *r; ++r; @@ -383,8 +469,9 @@ ffmpeg_out_init (const char *outfile, const char *audiofile, ffst->audio_ost.ctx->sample_rate = best; } + channel_layouts = get_channel_layouts (&ffst->audio_ost); # ifdef HAVE_CH_LAYOUT - if (! ffst->audio_ost.codec->ch_layouts) + if (! channel_layouts || ! av_channel_layout_check(&channel_layouts[0])) { if (! av_channel_layout_check(&ffst->audio_ist.ctx->ch_layout)) { @@ -400,7 +487,7 @@ ffmpeg_out_init (const char *outfile, const char *audiofile, else { /* XXX: This may or may not work. With AAC, it doesn't matter. */ - const AVChannelLayout *c = ffst->audio_ost.codec->ch_layouts; + const AVChannelLayout *c = channel_layouts; uint64_t best_lost = av_popcount64 (ffst->audio_ost.ctx->ch_layout.u.mask); uint64_t best_added = 0; @@ -427,7 +514,7 @@ ffmpeg_out_init (const char *outfile, const char *audiofile, av_channel_layout_from_mask (&ffst->audio_ost.ctx->ch_layout, best); } # else /* !HAVE_CH_LAYOUT */ - if (! ffst->audio_ost.codec->channel_layouts) + if (! channel_layouts || ! channel_layouts[0]) { if (! ffst->audio_ist.ctx->channel_layout) { @@ -443,7 +530,7 @@ ffmpeg_out_init (const char *outfile, const char *audiofile, else { /* XXX: This may or may not work. With AAC, it doesn't matter. */ - const uint64_t *c = ffst->audio_ost.codec->channel_layouts; + const uint64_t *c = channel_layouts; unsigned int best_lost = av_popcount64 (ffst->audio_ost.ctx->channel_layout); unsigned int best_added = 0; -- 2.48.1