From d66b0b3dccc118600b83988173e6631ad661df51 Mon Sep 17 00:00:00 2001 From: Romain Vimont Date: Mon, 27 Feb 2023 21:41:27 +0100 Subject: [PATCH] Add compat support for FFmpeg < 5.1 The new chlayout API has been introduced in FFmpeg 5.1. Use the old channel_layout API on older versions. PR #3757 --- app/src/audio_player.c | 20 +++++++++++++++++--- app/src/compat.h | 7 +++++++ app/src/decoder.c | 5 +++++ app/src/recorder.c | 5 +++++ 4 files changed, 34 insertions(+), 3 deletions(-) diff --git a/app/src/audio_player.c b/app/src/audio_player.c index 78a8ffe1..de218f1e 100644 --- a/app/src/audio_player.c +++ b/app/src/audio_player.c @@ -286,11 +286,19 @@ static bool sc_audio_player_frame_sink_open(struct sc_frame_sink *sink, const AVCodecContext *ctx) { struct sc_audio_player *ap = DOWNCAST(sink); +#ifdef SCRCPY_LAVU_HAS_CHLAYOUT + assert(ctx->ch_layout.nb_channels > 0); + unsigned nb_channels = ctx->ch_layout.nb_channels; +#else + int tmp = av_get_channel_layout_nb_channels(ctx->channel_layout); + assert(tmp > 0); + unsigned nb_channels = tmp; +#endif SDL_AudioSpec desired = { .freq = ctx->sample_rate, .format = SC_SDL_SAMPLE_FMT, - .channels = ctx->ch_layout.nb_channels, + .channels = nb_channels, .samples = SC_AUDIO_OUTPUT_BUFFER_SAMPLES, .callback = sc_audio_player_sdl_callback, .userdata = ap, @@ -311,13 +319,19 @@ sc_audio_player_frame_sink_open(struct sc_frame_sink *sink, ap->swr_ctx = swr_ctx; assert(ctx->sample_rate > 0); - assert(ctx->ch_layout.nb_channels > 0); assert(!av_sample_fmt_is_planar(SC_AV_SAMPLE_FMT)); int out_bytes_per_sample = av_get_bytes_per_sample(SC_AV_SAMPLE_FMT); assert(out_bytes_per_sample > 0); +#ifdef SCRCPY_LAVU_HAS_CHLAYOUT av_opt_set_chlayout(swr_ctx, "in_chlayout", &ctx->ch_layout, 0); av_opt_set_chlayout(swr_ctx, "out_chlayout", &ctx->ch_layout, 0); +#else + av_opt_set_channel_layout(swr_ctx, "in_channel_layout", + ctx->channel_layout, 0); + av_opt_set_channel_layout(swr_ctx, "out_channel_layout", + ctx->channel_layout, 0); +#endif av_opt_set_int(swr_ctx, "in_sample_rate", ctx->sample_rate, 0); av_opt_set_int(swr_ctx, "out_sample_rate", ctx->sample_rate, 0); @@ -332,7 +346,7 @@ sc_audio_player_frame_sink_open(struct sc_frame_sink *sink, } ap->sample_rate = ctx->sample_rate; - ap->nb_channels = ctx->ch_layout.nb_channels; + ap->nb_channels = nb_channels; ap->out_bytes_per_sample = out_bytes_per_sample; ap->target_buffering = ap->target_buffering_delay * ap->sample_rate diff --git a/app/src/compat.h b/app/src/compat.h index ea44437d..22563421 100644 --- a/app/src/compat.h +++ b/app/src/compat.h @@ -37,6 +37,13 @@ # define SCRCPY_LAVF_HAS_AVFORMATCONTEXT_URL #endif +// Not documented in ffmpeg/doc/APIchanges, but the channel_layout API +// has been replaced by chlayout in FFmpeg commit +// f423497b455da06c1337846902c770028760e094. +#if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(57, 23, 100) +# define SCRCPY_LAVU_HAS_CHLAYOUT +#endif + #if SDL_VERSION_ATLEAST(2, 0, 6) // # define SCRCPY_SDL_HAS_HINT_TOUCH_MOUSE_EVENTS diff --git a/app/src/decoder.c b/app/src/decoder.c index 4384186d..e87cfd6b 100644 --- a/app/src/decoder.c +++ b/app/src/decoder.c @@ -26,8 +26,13 @@ sc_decoder_open(struct sc_decoder *decoder, const AVCodec *codec) { decoder->codec_ctx->pix_fmt = AV_PIX_FMT_YUV420P; } else { // Hardcoded audio properties +#ifdef SCRCPY_LAVU_HAS_CHLAYOUT decoder->codec_ctx->ch_layout = (AVChannelLayout) AV_CHANNEL_LAYOUT_STEREO; +#else + decoder->codec_ctx->channel_layout = AV_CH_LAYOUT_STEREO; + decoder->codec_ctx->channels = 2; +#endif decoder->codec_ctx->sample_rate = 48000; } diff --git a/app/src/recorder.c b/app/src/recorder.c index bd7c50f2..af5fe510 100644 --- a/app/src/recorder.c +++ b/app/src/recorder.c @@ -202,7 +202,12 @@ sc_recorder_wait_audio_stream(struct sc_recorder *recorder) { stream->codecpar->codec_type = AVMEDIA_TYPE_AUDIO; stream->codecpar->codec_id = codec->id; +#ifdef SCRCPY_LAVU_HAS_CHLAYOUT stream->codecpar->ch_layout.nb_channels = 2; +#else + stream->codecpar->channel_layout = AV_CH_LAYOUT_STEREO; + stream->codecpar->channels = 2; +#endif stream->codecpar->sample_rate = 48000; recorder->audio_stream_index = stream->index;