From 718462c5c1e2b6f3064f921c0800e45b8d5b84b8 Mon Sep 17 00:00:00 2001 From: Liao Junxuan Date: Fri, 28 Jun 2024 18:06:13 +0800 Subject: [PATCH] add support for ffmpeg 7.0 FF_API_OLD_CHANNEL_LAYOUT is removed in libavcodec 61. See https://patchwork.ffmpeg.org/project/ffmpeg/cover/20240125134425.374-1-jamrial@gmail.com/ . --- ffmpegaudio.cc | 33 ++++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/ffmpegaudio.cc b/ffmpegaudio.cc index a97d6dcad..5ef602ad8 100644 --- a/ffmpegaudio.cc +++ b/ffmpegaudio.cc @@ -118,6 +118,13 @@ struct DecoderContext bool play( QString & errorString ); bool normalizeAudio( AVFrame * frame, vector & samples ); void playFrame( AVFrame * frame ); + int nbChannels() { +#if LIBAVCODEC_VERSION_MAJOR >= 61 + return codecContext_->ch_layout.nb_channels; +#else + return codecContext_->channels; +#endif + } }; DecoderContext::DecoderContext( QByteArray const & audioData, QAtomicInt & isCancelled ): @@ -261,7 +268,7 @@ bool DecoderContext::openCodec( QString & errorString ) } gdDebug( "Codec open: %s: channels: %d, rate: %d, format: %s\n", codec_->long_name, - codecContext_->channels, codecContext_->sample_rate, av_get_sample_fmt_name( codecContext_->sample_fmt ) ); + nbChannels(), codecContext_->sample_rate, av_get_sample_fmt_name( codecContext_->sample_fmt ) ); if ( codecContext_->sample_fmt == AV_SAMPLE_FMT_S32 || codecContext_->sample_fmt == AV_SAMPLE_FMT_S32P || @@ -270,6 +277,21 @@ bool DecoderContext::openCodec( QString & errorString ) codecContext_->sample_fmt == AV_SAMPLE_FMT_DBL || codecContext_->sample_fmt == AV_SAMPLE_FMT_DBLP ) { +#if LIBAVCODEC_VERSION_MAJOR >= 61 + int ret = swr_alloc_set_opts2( &swr_, + &codecContext_->ch_layout, + AV_SAMPLE_FMT_S16, + codecContext_->sample_rate, + &codecContext_->ch_layout, + codecContext_->sample_fmt, + codecContext_->sample_rate, + 0, + NULL ); + if ( ret < 0 ) { + errorString = QObject::tr( "swr_alloc_set_opts2() failed: %1." ).arg( avErrorString( ret ) ); + return false; + } +#else swr_ = swr_alloc_set_opts( NULL, codecContext_->channel_layout, AV_SAMPLE_FMT_S16, @@ -279,6 +301,7 @@ bool DecoderContext::openCodec( QString & errorString ) codecContext_->sample_rate, 0, NULL ); +#endif swr_init( swr_ ); } @@ -351,7 +374,7 @@ bool DecoderContext::openOutputDevice( QString & errorString ) ao_sample_format aoSampleFormat; memset (&aoSampleFormat, 0, sizeof(aoSampleFormat) ); - aoSampleFormat.channels = codecContext_->channels; + aoSampleFormat.channels = nbChannels(); aoSampleFormat.rate = codecContext_->sample_rate; aoSampleFormat.byte_format = AO_FMT_NATIVE; aoSampleFormat.matrix = 0; @@ -520,7 +543,7 @@ static inline int32_t toInt32( double v ) bool DecoderContext::normalizeAudio( AVFrame * frame, vector & samples ) { int lineSize = 0; - int dataSize = av_samples_get_buffer_size( &lineSize, codecContext_->channels, + int dataSize = av_samples_get_buffer_size( &lineSize, nbChannels(), frame->nb_samples, codecContext_->sample_fmt, 1 ); // Portions from: https://code.google.com/p/lavfilters/source/browse/decoder/LAVAudio/LAVAudio.cpp @@ -542,7 +565,7 @@ bool DecoderContext::normalizeAudio( AVFrame * frame, vector & samples ) uint8_t * out = ( uint8_t * )&samples.front(); for ( int i = 0; i < frame->nb_samples; i++ ) { - for ( int ch = 0; ch < codecContext_->channels; ch++ ) + for ( int ch = 0; ch < nbChannels(); ch++ ) { *out++ = ( ( uint8_t * )frame->extended_data[ch] )[i]; } @@ -556,7 +579,7 @@ bool DecoderContext::normalizeAudio( AVFrame * frame, vector & samples ) int16_t * out = ( int16_t * )&samples.front(); for ( int i = 0; i < frame->nb_samples; i++ ) { - for ( int ch = 0; ch < codecContext_->channels; ch++ ) + for ( int ch = 0; ch < nbChannels(); ch++ ) { *out++ = ( ( int16_t * )frame->extended_data[ch] )[i]; }