git: 915391ac40ad - main - multimedia/kodi: Add patch to support FFmpeg 6

From: Daniel Engberg <diizzy_at_FreeBSD.org>
Date: Thu, 27 Apr 2023 12:04:19 UTC
The branch main has been updated by diizzy:

URL: https://cgit.FreeBSD.org/ports/commit/?id=915391ac40ad0175583f572d999680f5ae8397bc

commit 915391ac40ad0175583f572d999680f5ae8397bc
Author:     Daniel Engberg <diizzy@FreeBSD.org>
AuthorDate: 2023-04-27 10:43:32 +0000
Commit:     Daniel Engberg <diizzy@FreeBSD.org>
CommitDate: 2023-04-27 12:01:44 +0000

    multimedia/kodi: Add patch to support FFmpeg 6
    
    Add patch from maintainer
    
    PR:             270237
    Reviewed by:    yrzh <yzrh@noema.org> (maintainer)
---
 multimedia/kodi/files/patch-ffmpeg6-support | 2150 +++++++++++++++++++++++++++
 1 file changed, 2150 insertions(+)

diff --git a/multimedia/kodi/files/patch-ffmpeg6-support b/multimedia/kodi/files/patch-ffmpeg6-support
new file mode 100644
index 000000000000..2ab9cbc27a3d
--- /dev/null
+++ b/multimedia/kodi/files/patch-ffmpeg6-support
@@ -0,0 +1,2150 @@
+diff -urN cmake/modules/FindFFMPEG.cmake.orig cmake/modules/FindFFMPEG.cmake
+--- cmake/modules/FindFFMPEG.cmake.orig	2023-03-11 22:16:38.000000000 +0000
++++ cmake/modules/FindFFMPEG.cmake	2023-04-19 10:01:30.831589000 +0000
+@@ -151,14 +151,14 @@
+   set(REQUIRED_FFMPEG_VERSION undef)
+ else()
+   # required ffmpeg library versions
+-  set(REQUIRED_FFMPEG_VERSION 4.4.1)
+-  set(_avcodec_ver ">=58.134.100")
+-  set(_avfilter_ver ">=7.110.100")
+-  set(_avformat_ver ">=58.76.100")
+-  set(_avutil_ver ">=56.70.100")
+-  set(_postproc_ver ">=55.9.100")
+-  set(_swresample_ver ">=3.9.100")
+-  set(_swscale_ver ">=5.9.100")
++  set(REQUIRED_FFMPEG_VERSION 6.0.0)
++  set(_avcodec_ver ">=60.2.100")
++  set(_avfilter_ver ">=9.3.100")
++  set(_avformat_ver ">=60.3.100")
++  set(_avutil_ver ">=58.2.100")
++  set(_postproc_ver ">=57.1.100")
++  set(_swresample_ver ">=4.10.100")
++  set(_swscale_ver ">=7.1.100")
+ endif()
+ 
+ # Allows building with external ffmpeg not found in system paths,
+diff -urN tools/buildsteps/windows/patches/0001-ffmpeg-windows-configure-detect-openssl.patch.orig tools/buildsteps/windows/patches/0001-ffmpeg-windows-configure-detect-openssl.patch
+--- tools/buildsteps/windows/patches/0001-ffmpeg-windows-configure-detect-openssl.patch.orig	2023-03-11 22:16:38.000000000 +0000
++++ tools/buildsteps/windows/patches/0001-ffmpeg-windows-configure-detect-openssl.patch	2023-04-19 10:01:22.854832000 +0000
+@@ -11,7 +11,7 @@
+ index d7a3f507e8..4b85e881b1 100755
+ --- a/configure
+ +++ b/configure
+-@@ -6530,6 +6530,8 @@ enabled openssl           && { check_pkg_config openssl openssl openssl/ssl.h OP
++@@ -6728,6 +6728,8 @@ enabled openssl           && { check_pkg_config openssl openssl openssl/ssl.h OP
+                                 check_lib openssl openssl/ssl.h SSL_library_init -lssl -lcrypto ||
+                                 check_lib openssl openssl/ssl.h SSL_library_init -lssl32 -leay32 ||
+                                 check_lib openssl openssl/ssl.h SSL_library_init -lssl -lcrypto -lws2_32 -lgdi32 ||
+diff -urN tools/buildsteps/windows/patches/0002-ffmpeg-windows-configure-fix-zlib-conflict.patch.orig tools/buildsteps/windows/patches/0002-ffmpeg-windows-configure-fix-zlib-conflict.patch
+--- tools/buildsteps/windows/patches/0002-ffmpeg-windows-configure-fix-zlib-conflict.patch.orig	2023-03-11 22:16:38.000000000 +0000
++++ tools/buildsteps/windows/patches/0002-ffmpeg-windows-configure-fix-zlib-conflict.patch	2023-04-19 10:01:22.854952000 +0000
+@@ -11,16 +11,16 @@
+ index 4b85e881b1..da457705d1 100755
+ --- a/configure
+ +++ b/configure
+-@@ -7627,6 +7627,9 @@ print_config CONFIG_ "$config_files" $CONFIG_LIST       \
++@@ -7825,6 +7825,9 @@ print_config CONFIG_ "$config_files" $CONFIG_LIST       \
++ print_config CONFIG_ "$config_files" $CONFIG_LIST       \
+                                       $CONFIG_EXTRA      \
+-                                      $ALL_COMPONENTS    \
+  
+ +echo "#if defined(HAVE_UNISTD_H) && HAVE_UNISTD_H == 0" >> $TMPH
+ +echo "#undef HAVE_UNISTD_H" >> $TMPH
+ +echo "#endif" >> $TMPH
+  echo "#endif /* FFMPEG_CONFIG_H */" >> $TMPH
+- echo "endif # FFMPEG_CONFIG_MAK" >> ffbuild/config.mak
+  
++ # Do not overwrite an unchanged config.h to avoid superfluous rebuilds.
+ -- 
+ 2.29.2
+ 
+diff -urN tools/buildsteps/windows/patches/0003-ffmpeg-windows-configure-allow-building-static.patch.orig tools/buildsteps/windows/patches/0003-ffmpeg-windows-configure-allow-building-static.patch
+--- tools/buildsteps/windows/patches/0003-ffmpeg-windows-configure-allow-building-static.patch.orig	2023-03-11 22:16:38.000000000 +0000
++++ tools/buildsteps/windows/patches/0003-ffmpeg-windows-configure-allow-building-static.patch	2023-04-19 10:01:22.855081000 +0000
+@@ -11,7 +11,7 @@
+ index da457705d1..e3a8f45ff4 100755
+ --- a/configure
+ +++ b/configure
+-@@ -5440,6 +5440,8 @@ case $target_os in
++@@ -5566,6 +5566,8 @@ case $target_os in
+          enabled shared && ! enabled small && test_cmd $windres --version && enable gnu_windres
+          enabled x86_32 && check_ldflags -Wl,--large-address-aware
+          shlibdir_default="$bindir_default"
+@@ -20,7 +20,7 @@
+          SLIBPREF=""
+          SLIBSUF=".dll"
+          SLIBNAME_WITH_VERSION='$(SLIBPREF)$(FULLNAME)-$(LIBVERSION)$(SLIBSUF)'
+-@@ -5489,6 +5491,8 @@ case $target_os in
++@@ -5615,6 +5617,8 @@ case $target_os in
+          fi
+          enabled x86_32 && check_ldflags -LARGEADDRESSAWARE
+          shlibdir_default="$bindir_default"
+diff -urN tools/buildsteps/windows/patches/0004-ffmpeg-windows-configure-detect-libdav1d.patch.orig tools/buildsteps/windows/patches/0004-ffmpeg-windows-configure-detect-libdav1d.patch
+--- tools/buildsteps/windows/patches/0004-ffmpeg-windows-configure-detect-libdav1d.patch.orig	2023-03-11 22:16:38.000000000 +0000
++++ tools/buildsteps/windows/patches/0004-ffmpeg-windows-configure-detect-libdav1d.patch	2023-04-19 10:01:22.855205000 +0000
+@@ -11,7 +11,7 @@
+ index e3a8f45ff4..983d7e1078 100755
+ --- a/configure
+ +++ b/configure
+-@@ -6358,7 +6358,7 @@ enabled libcelt           && require libcelt celt/celt.h celt_decode -lcelt0 &&
++@@ -6541,7 +6541,7 @@ enabled libcelt           && require libcelt celt/celt.h celt_decode -lcelt0 &&
+                                 die "ERROR: libcelt must be installed and version must be >= 0.11.0."; }
+  enabled libcaca           && require_pkg_config libcaca caca caca.h caca_create_canvas
+  enabled libcodec2         && require libcodec2 codec2/codec2.h codec2_create -lcodec2
+diff -urN tools/depends/target/ffmpeg/CMakeLists.txt.orig tools/depends/target/ffmpeg/CMakeLists.txt
+--- tools/depends/target/ffmpeg/CMakeLists.txt.orig	2023-03-11 22:16:38.000000000 +0000
++++ tools/depends/target/ffmpeg/CMakeLists.txt	2023-04-19 10:01:22.854687000 +0000
+@@ -92,6 +92,7 @@
+ elseif(CORE_SYSTEM_NAME STREQUAL darwin_embedded)
+   list(APPEND ffmpeg_conf --disable-crystalhd
+                           --enable-videotoolbox
++                          --disable-filter=yadif_videotoolbox
+                           --target-os=darwin
+               )
+ elseif(CORE_SYSTEM_NAME STREQUAL osx)
+diff -urN tools/depends/target/ffmpeg/FFMPEG-VERSION.orig tools/depends/target/ffmpeg/FFMPEG-VERSION
+--- tools/depends/target/ffmpeg/FFMPEG-VERSION.orig	2023-03-11 22:16:38.000000000 +0000
++++ tools/depends/target/ffmpeg/FFMPEG-VERSION	2023-04-19 10:02:41.108169000 +0000
+@@ -1,5 +1,5 @@
+ LIBNAME=ffmpeg
+-BASE_URL=https://github.com/xbmc/FFmpeg
+-VERSION=4.4.1-Nexus-Alpha1
++VERSION=6.0
+ ARCHIVE=$(LIBNAME)-$(VERSION).tar.gz
+-SHA512=8beb04d577b5251e74b0d52f4d130997a8ba94bbd488c7c8309e6b45095c27807e150212888ce3a384b23dff52f8df1a7bde5407bae924ddc363f8125c0616c5
++SHA512=b3214328f2792364353f38c6b46a71d4970c071d8656b20780abf0e02950167d0933eae825c09102cf8fb19fc679ac444bf1f41a448b624eaa5ea6b0f0bdf4f5
++
+diff -urN xbmc/cdrip/EncoderFFmpeg.cpp.orig xbmc/cdrip/EncoderFFmpeg.cpp
+--- xbmc/cdrip/EncoderFFmpeg.cpp.orig	2023-03-11 22:16:38.000000000 +0000
++++ xbmc/cdrip/EncoderFFmpeg.cpp	2023-04-19 10:01:22.848595000 +0000
+@@ -11,6 +11,7 @@
+ #include "ServiceBroker.h"
+ #include "addons/Addon.h"
+ #include "addons/AddonManager.h"
++#include "cores/FFmpeg.h"
+ #include "settings/Settings.h"
+ #include "settings/SettingsComponent.h"
+ #include "utils/StringUtils.h"
+@@ -19,24 +20,9 @@
+ #include "utils/log.h"
+ 
+ using namespace KODI::CDRIP;
++using FFMPEG_HELP_TOOLS::FFMpegErrorToString;
++using FFMPEG_HELP_TOOLS::FFMpegException;
+ 
+-namespace
+-{
+-
+-struct EncoderException : public std::exception
+-{
+-  std::string s;
+-  template<typename... Args>
+-  EncoderException(const std::string& fmt, Args&&... args)
+-    : s(StringUtils::Format(fmt, std::forward<Args>(args)...))
+-  {
+-  }
+-  ~EncoderException() throw() {} // Updated
+-  const char* what() const throw() { return s.c_str(); }
+-};
+-
+-} /* namespace */
+-
+ bool CEncoderFFmpeg::Init()
+ {
+   try
+@@ -54,7 +40,7 @@
+     }
+     else
+     {
+-      throw EncoderException("Could not get add-on: {}", addonId);
++      throw FFMpegException("Could not get add-on: {}", addonId);
+     }
+ 
+     // Hack fix about PTS on generated files.
+@@ -66,50 +52,50 @@
+     else if (addonId == "audioencoder.kodi.builtin.wma")
+       m_samplesCountMultiply = 1000;
+     else
+-      throw EncoderException("Internal add-on id \"{}\" not known as usable", addonId);
++      throw FFMpegException("Internal add-on id \"{}\" not known as usable", addonId);
+ 
+     const std::string filename = URIUtils::GetFileName(m_strFile);
+ 
+     m_formatCtx = avformat_alloc_context();
+     if (!m_formatCtx)
+-      throw EncoderException("Could not allocate output format context");
++      throw FFMpegException("Could not allocate output format context");
+ 
+     m_bcBuffer = static_cast<uint8_t*>(av_malloc(BUFFER_SIZE + AV_INPUT_BUFFER_PADDING_SIZE));
+     if (!m_bcBuffer)
+-      throw EncoderException("Could not allocate buffer");
++      throw FFMpegException("Could not allocate buffer");
+ 
+     m_formatCtx->pb = avio_alloc_context(m_bcBuffer, BUFFER_SIZE, AVIO_FLAG_WRITE, this, nullptr,
+                                          avio_write_callback, avio_seek_callback);
+     if (!m_formatCtx->pb)
+-      throw EncoderException("Failed to allocate ByteIOContext");
++      throw FFMpegException("Failed to allocate ByteIOContext");
+ 
+     /* Guess the desired container format based on the file extension. */
+     m_formatCtx->oformat = av_guess_format(nullptr, filename.c_str(), nullptr);
+     if (!m_formatCtx->oformat)
+-      throw EncoderException("Could not find output file format");
++      throw FFMpegException("Could not find output file format");
+ 
+     m_formatCtx->url = av_strdup(filename.c_str());
+     if (!m_formatCtx->url)
+-      throw EncoderException("Could not allocate url");
++      throw FFMpegException("Could not allocate url");
+ 
+     /* Find the encoder to be used by its name. */
+-    AVCodec* codec = avcodec_find_encoder(m_formatCtx->oformat->audio_codec);
++    const AVCodec* codec = avcodec_find_encoder(m_formatCtx->oformat->audio_codec);
+     if (!codec)
+-      throw EncoderException("Unable to find a suitable FFmpeg encoder");
++      throw FFMpegException("Unable to find a suitable FFmpeg encoder");
+ 
+     /* Create a new audio stream in the output file container. */
+     m_stream = avformat_new_stream(m_formatCtx, nullptr);
+     if (!m_stream)
+-      throw EncoderException("Failed to allocate AVStream context");
++      throw FFMpegException("Failed to allocate AVStream context");
+ 
+     m_codecCtx = avcodec_alloc_context3(codec);
+     if (!m_codecCtx)
+-      throw EncoderException("Failed to allocate the encoder context");
++      throw FFMpegException("Failed to allocate the encoder context");
+ 
+     /* Set the basic encoder parameters.
+      * The input file's sample rate is used to avoid a sample rate conversion. */
+-    m_codecCtx->channels = m_iInChannels;
+-    m_codecCtx->channel_layout = av_get_default_channel_layout(m_iInChannels);
++    av_channel_layout_uninit(&m_codecCtx->ch_layout);
++    av_channel_layout_default(&m_codecCtx->ch_layout, m_iInChannels);
+     m_codecCtx->sample_rate = m_iInSampleRate;
+     m_codecCtx->sample_fmt = codec->sample_fmts[0];
+     m_codecCtx->bit_rate = bitrate;
+@@ -128,14 +114,14 @@
+ 
+     int err = avcodec_open2(m_codecCtx, codec, nullptr);
+     if (err < 0)
+-      throw EncoderException("Failed to open the codec {} (error '{}')",
+-                             codec->long_name ? codec->long_name : codec->name,
+-                             FFmpegErrorToString(err));
++      throw FFMpegException("Failed to open the codec {} (error '{}')",
++                            codec->long_name ? codec->long_name : codec->name,
++                            FFMpegErrorToString(err));
+ 
+     err = avcodec_parameters_from_context(m_stream->codecpar, m_codecCtx);
+     if (err < 0)
+-      throw EncoderException("Failed to copy encoder parameters to output stream (error '{}')",
+-                             FFmpegErrorToString(err));
++      throw FFMpegException("Failed to copy encoder parameters to output stream (error '{}')",
++                            FFMpegErrorToString(err));
+ 
+     m_inFormat = GetInputFormat(m_iInBitsPerSample);
+     m_outFormat = m_codecCtx->sample_fmt;
+@@ -150,44 +136,48 @@
+ 
+     m_bufferFrame = av_frame_alloc();
+     if (!m_bufferFrame || !m_buffer)
+-      throw EncoderException("Failed to allocate necessary buffers");
++      throw FFMpegException("Failed to allocate necessary buffers");
+ 
+     m_bufferFrame->nb_samples = m_codecCtx->frame_size;
+     m_bufferFrame->format = m_inFormat;
+-    m_bufferFrame->channel_layout = m_codecCtx->channel_layout;
++
++    av_channel_layout_uninit(&m_bufferFrame->ch_layout);
++    av_channel_layout_copy(&m_bufferFrame->ch_layout, &m_codecCtx->ch_layout);
++
+     m_bufferFrame->sample_rate = m_codecCtx->sample_rate;
+ 
+     err = av_frame_get_buffer(m_bufferFrame, 0);
+     if (err < 0)
+-      throw EncoderException("Could not allocate output frame samples (error '{}')",
+-                             FFmpegErrorToString(err));
++      throw FFMpegException("Could not allocate output frame samples (error '{}')",
++                            FFMpegErrorToString(err));
+ 
+     avcodec_fill_audio_frame(m_bufferFrame, m_iInChannels, m_inFormat, m_buffer, m_neededBytes, 0);
+ 
+     if (m_needConversion)
+     {
+-      m_swrCtx = swr_alloc_set_opts(nullptr, m_codecCtx->channel_layout, m_outFormat,
+-                                    m_codecCtx->sample_rate, m_codecCtx->channel_layout, m_inFormat,
++      int ret = swr_alloc_set_opts2(&m_swrCtx, &m_codecCtx->ch_layout, m_outFormat,
++                                    m_codecCtx->sample_rate, &m_codecCtx->ch_layout, m_inFormat,
+                                     m_codecCtx->sample_rate, 0, nullptr);
+-      if (!m_swrCtx || swr_init(m_swrCtx) < 0)
+-        throw EncoderException("Failed to initialize the resampler");
++      if (ret || swr_init(m_swrCtx) < 0)
++        throw FFMpegException("Failed to initialize the resampler");
+ 
+       m_resampledBufferSize =
+           av_samples_get_buffer_size(nullptr, m_iInChannels, m_neededFrames, m_outFormat, 0);
+       m_resampledBuffer = static_cast<uint8_t*>(av_malloc(m_resampledBufferSize));
+       m_resampledFrame = av_frame_alloc();
+       if (!m_resampledBuffer || !m_resampledFrame)
+-        throw EncoderException("Failed to allocate a frame for resampling");
++        throw FFMpegException("Failed to allocate a frame for resampling");
+ 
+       m_resampledFrame->nb_samples = m_neededFrames;
+       m_resampledFrame->format = m_outFormat;
+-      m_resampledFrame->channel_layout = m_codecCtx->channel_layout;
++      av_channel_layout_uninit(&m_resampledFrame->ch_layout);
++      av_channel_layout_copy(&m_resampledFrame->ch_layout, &m_codecCtx->ch_layout);
+       m_resampledFrame->sample_rate = m_codecCtx->sample_rate;
+ 
+       err = av_frame_get_buffer(m_resampledFrame, 0);
+       if (err < 0)
+-        throw EncoderException("Could not allocate output resample frame samples (error '{}')",
+-                               FFmpegErrorToString(err));
++        throw FFMpegException("Could not allocate output resample frame samples (error '{}')",
++                              FFMpegErrorToString(err));
+ 
+       avcodec_fill_audio_frame(m_resampledFrame, m_iInChannels, m_outFormat, m_resampledBuffer,
+                                m_resampledBufferSize, 0);
+@@ -204,7 +194,7 @@
+     /* write the header */
+     err = avformat_write_header(m_formatCtx, nullptr);
+     if (err != 0)
+-      throw EncoderException("Failed to write the header (error '{}')", FFmpegErrorToString(err));
++      throw FFMpegException("Failed to write the header (error '{}')", FFMpegErrorToString(err));
+ 
+     CLog::Log(LOGDEBUG, "CEncoderFFmpeg::{} - Successfully initialized with muxer {} and codec {}",
+               __func__,
+@@ -212,16 +202,19 @@
+                                               : m_formatCtx->oformat->name,
+               codec->long_name ? codec->long_name : codec->name);
+   }
+-  catch (EncoderException& caught)
++  catch (const FFMpegException& caught)
+   {
+     CLog::Log(LOGERROR, "CEncoderFFmpeg::{} - {}", __func__, caught.what());
+ 
+     av_freep(&m_buffer);
++    av_channel_layout_uninit(&m_bufferFrame->ch_layout);
+     av_frame_free(&m_bufferFrame);
+     swr_free(&m_swrCtx);
++    av_channel_layout_uninit(&m_resampledFrame->ch_layout);
+     av_frame_free(&m_resampledFrame);
+     av_freep(&m_resampledBuffer);
+     av_free(m_bcBuffer);
++    av_channel_layout_uninit(&m_codecCtx->ch_layout);
+     avcodec_free_context(&m_codecCtx);
+     if (m_formatCtx)
+     {
+@@ -299,7 +292,7 @@
+       if (swr_convert(m_swrCtx, m_resampledFrame->data, m_neededFrames,
+                       const_cast<const uint8_t**>(m_bufferFrame->extended_data),
+                       m_neededFrames) < 0)
+-        throw EncoderException("Error resampling audio");
++        throw FFMpegException("Error resampling audio");
+ 
+       frame = m_resampledFrame;
+     }
+@@ -316,8 +309,8 @@
+     m_bufferSize = 0;
+     err = avcodec_send_frame(m_codecCtx, frame);
+     if (err < 0)
+-      throw EncoderException("Error sending a frame for encoding (error '{}')", __func__,
+-                             FFmpegErrorToString(err));
++      throw FFMpegException("Error sending a frame for encoding (error '{}')",
++                            FFMpegErrorToString(err));
+ 
+     while (err >= 0)
+     {
+@@ -329,19 +322,18 @@
+       }
+       else if (err < 0)
+       {
+-        throw EncoderException("Error during encoding (error '{}')", __func__,
+-                               FFmpegErrorToString(err));
++        throw FFMpegException("Error during encoding (error '{}')", FFMpegErrorToString(err));
+       }
+ 
+       err = av_write_frame(m_formatCtx, pkt);
+       if (err < 0)
+-        throw EncoderException("Failed to write the frame data (error '{}')", __func__,
+-                               FFmpegErrorToString(err));
++        throw FFMpegException("Failed to write the frame data (error '{}')",
++                              FFMpegErrorToString(err));
+ 
+       av_packet_unref(pkt);
+     }
+   }
+-  catch (EncoderException& caught)
++  catch (const FFMpegException& caught)
+   {
+     CLog::Log(LOGERROR, "CEncoderFFmpeg::{} - {}", __func__, caught.what());
+   }
+@@ -366,8 +358,10 @@
+ 
+     /* Flush if needed */
+     av_freep(&m_buffer);
++    av_channel_layout_uninit(&m_bufferFrame->ch_layout);
+     av_frame_free(&m_bufferFrame);
+     swr_free(&m_swrCtx);
++    av_channel_layout_uninit(&m_resampledFrame->ch_layout);
+     av_frame_free(&m_resampledFrame);
+     av_freep(&m_resampledBuffer);
+     m_needConversion = false;
+@@ -379,6 +373,7 @@
+ 
+     /* cleanup */
+     av_free(m_bcBuffer);
++    av_channel_layout_uninit(&m_codecCtx->ch_layout);
+     avcodec_free_context(&m_codecCtx);
+     av_freep(&m_formatCtx->pb);
+     avformat_free_context(m_formatCtx);
+@@ -400,14 +395,6 @@
+     case 32:
+       return AV_SAMPLE_FMT_S32;
+     default:
+-      throw EncoderException("Invalid input bits per sample");
++      throw FFMpegException("Invalid input bits per sample");
+   }
+-}
+-
+-std::string CEncoderFFmpeg::FFmpegErrorToString(int err)
+-{
+-  std::string text;
+-  text.reserve(AV_ERROR_MAX_STRING_SIZE);
+-  av_strerror(err, text.data(), AV_ERROR_MAX_STRING_SIZE);
+-  return text;
+ }
+diff -urN xbmc/cdrip/EncoderFFmpeg.h.orig xbmc/cdrip/EncoderFFmpeg.h
+--- xbmc/cdrip/EncoderFFmpeg.h.orig	2023-03-11 22:16:38.000000000 +0000
++++ xbmc/cdrip/EncoderFFmpeg.h	2023-04-19 10:01:22.835616000 +0000
+@@ -39,7 +39,6 @@
+   void SetTag(const std::string& tag, const std::string& value);
+   bool WriteFrame();
+   AVSampleFormat GetInputFormat(int inBitsPerSample);
+-  std::string FFmpegErrorToString(int err);
+ 
+   AVFormatContext* m_formatCtx{nullptr};
+   AVCodecContext* m_codecCtx{nullptr};
+diff -urN xbmc/cores/AudioEngine/Encoders/AEEncoderFFmpeg.cpp.orig xbmc/cores/AudioEngine/Encoders/AEEncoderFFmpeg.cpp
+--- xbmc/cores/AudioEngine/Encoders/AEEncoderFFmpeg.cpp.orig	2023-03-11 22:16:38.000000000 +0000
++++ xbmc/cores/AudioEngine/Encoders/AEEncoderFFmpeg.cpp	2023-04-19 10:01:22.848879000 +0000
+@@ -10,14 +10,25 @@
+ #define DTS_ENCODE_BITRATE 1411200
+ 
+ #include "cores/AudioEngine/Encoders/AEEncoderFFmpeg.h"
+-#include "cores/AudioEngine/Utils/AEUtil.h"
++
+ #include "ServiceBroker.h"
+-#include "utils/log.h"
++#include "cores/AudioEngine/Utils/AEUtil.h"
++#include "cores/FFmpeg.h"
+ #include "settings/Settings.h"
+ #include "settings/SettingsComponent.h"
+-#include <string.h>
++#include "utils/log.h"
++
++extern "C"
++{
++#include <libavutil/channel_layout.h>
++}
++
+ #include <cassert>
++#include <string.h>
+ 
++using FFMPEG_HELP_TOOLS::FFMpegErrorToString;
++using FFMPEG_HELP_TOOLS::FFMpegException;
++
+ CAEEncoderFFmpeg::CAEEncoderFFmpeg() : m_CodecCtx(NULL), m_SwrCtx(NULL)
+ {
+ }
+@@ -26,6 +37,7 @@
+ {
+   Reset();
+   swr_free(&m_SwrCtx);
++  av_channel_layout_uninit(&m_CodecCtx->ch_layout);
+   avcodec_free_context(&m_CodecCtx);
+ }
+ 
+@@ -81,7 +93,7 @@
+ 
+   bool ac3 = CServiceBroker::GetSettingsComponent()->GetSettings()->GetBool(CSettings::SETTING_AUDIOOUTPUT_AC3PASSTHROUGH);
+ 
+-  AVCodec *codec = NULL;
++  const AVCodec* codec = nullptr;
+ 
+   /* fallback to ac3 if we support it, we might not have DTS support */
+   if (ac3)
+@@ -102,7 +114,8 @@
+ 
+   m_CodecCtx->bit_rate = m_BitRate;
+   m_CodecCtx->sample_rate = format.m_sampleRate;
+-  m_CodecCtx->channel_layout = AV_CH_LAYOUT_5POINT1_BACK;
++  av_channel_layout_uninit(&m_CodecCtx->ch_layout);
++  av_channel_layout_from_mask(&m_CodecCtx->ch_layout, AV_CH_LAYOUT_5POINT1_BACK);
+ 
+   /* select a suitable data format */
+   if (codec->sample_fmts)
+@@ -179,22 +192,28 @@
+           LOGERROR,
+           "CAEEncoderFFmpeg::Initialize - Unable to find a suitable data format for the codec ({})",
+           m_CodecName);
++      av_channel_layout_uninit(&m_CodecCtx->ch_layout);
+       avcodec_free_context(&m_CodecCtx);
+       return false;
+     }
+   }
+ 
+-  m_CodecCtx->channels = BuildChannelLayout(m_CodecCtx->channel_layout, m_Layout);
++  uint64_t mask = m_CodecCtx->ch_layout.u.mask;
++  av_channel_layout_uninit(&m_CodecCtx->ch_layout);
++  av_channel_layout_from_mask(&m_CodecCtx->ch_layout, mask);
++  m_CodecCtx->ch_layout.nb_channels = BuildChannelLayout(mask, m_Layout);
+ 
+   /* open the codec */
+   if (avcodec_open2(m_CodecCtx, codec, NULL))
+   {
++    av_channel_layout_uninit(&m_CodecCtx->ch_layout);
+     avcodec_free_context(&m_CodecCtx);
+     return false;
+   }
+ 
+   format.m_frames = m_CodecCtx->frame_size;
+-  format.m_frameSize = m_CodecCtx->channels * (CAEUtil::DataFormatToBits(format.m_dataFormat) >> 3);
++  int channels = m_CodecCtx->ch_layout.nb_channels;
++  format.m_frameSize = channels * (CAEUtil::DataFormatToBits(format.m_dataFormat) >> 3);
+   format.m_channelLayout = m_Layout;
+ 
+   m_CurrentFormat = format;
+@@ -204,14 +223,14 @@
+ 
+   if (m_NeedConversion)
+   {
+-    m_SwrCtx = swr_alloc_set_opts(NULL,
+-                      m_CodecCtx->channel_layout, m_CodecCtx->sample_fmt, m_CodecCtx->sample_rate,
+-                      m_CodecCtx->channel_layout, AV_SAMPLE_FMT_FLT, m_CodecCtx->sample_rate,
+-                      0, NULL);
+-    if (!m_SwrCtx || swr_init(m_SwrCtx) < 0)
++    int ret = swr_alloc_set_opts2(&m_SwrCtx, &m_CodecCtx->ch_layout, m_CodecCtx->sample_fmt,
++                                  m_CodecCtx->sample_rate, &m_CodecCtx->ch_layout,
++                                  AV_SAMPLE_FMT_FLT, m_CodecCtx->sample_rate, 0, NULL);
++    if (ret || swr_init(m_SwrCtx) < 0)
+     {
+       CLog::Log(LOGERROR, "CAEEncoderFFmpeg::Initialize - Failed to initialise resampler.");
+       swr_free(&m_SwrCtx);
++      av_channel_layout_uninit(&m_CodecCtx->ch_layout);
+       avcodec_free_context(&m_CodecCtx);
+       return false;
+     }
+@@ -242,62 +261,78 @@
+ 
+ int CAEEncoderFFmpeg::Encode(uint8_t *in, int in_size, uint8_t *out, int out_size)
+ {
+-  int got_output;
+-  AVFrame *frame;
++  int size = 0;
++  int err = AVERROR_UNKNOWN;
++  AVFrame* frame = nullptr;
++  AVPacket* pkt = nullptr;
+ 
+   if (!m_CodecCtx)
+-    return 0;
++    return size;
+ 
+-  /* allocate the input frame
+-   * sadly, we have to alloc/dealloc it everytime since we have no guarantee the
+-   * data argument will be constant over iterated calls and the frame needs to
+-   * setup pointers inside data */
+-  frame = av_frame_alloc();
+-  if (!frame)
+-    return 0;
++  try
++  {
++    /* allocate the input frame and output packet
++     * sadly, we have to alloc/dealloc it everytime since we have no guarantee the
++     * data argument will be constant over iterated calls and the frame needs to
++     * setup pointers inside data */
++    frame = av_frame_alloc();
++    pkt = av_packet_alloc();
++    if (!frame || !pkt)
++      throw FFMpegException(
++          "Failed to allocate \"AVFrame\" or \"AVPacket\" for encoding (error '{}')",
++          strerror(errno));
+ 
+-  frame->nb_samples = m_CodecCtx->frame_size;
+-  frame->format = m_CodecCtx->sample_fmt;
+-  frame->channel_layout = m_CodecCtx->channel_layout;
+-  frame->channels = m_CodecCtx->channels;
++    frame->nb_samples = m_CodecCtx->frame_size;
++    frame->format = m_CodecCtx->sample_fmt;
++    av_channel_layout_uninit(&frame->ch_layout);
++    av_channel_layout_copy(&frame->ch_layout, &m_CodecCtx->ch_layout);
++    int channelNum = m_CodecCtx->ch_layout.nb_channels;
+ 
+-  avcodec_fill_audio_frame(frame, m_CodecCtx->channels, m_CodecCtx->sample_fmt,
+-                    in, in_size, 0);
++    avcodec_fill_audio_frame(frame, channelNum, m_CodecCtx->sample_fmt, in, in_size, 0);
+ 
+-  /* initialize the output packet */
+-  AVPacket* pkt = av_packet_alloc();
+-  if (!pkt)
+-  {
+-    CLog::Log(LOGERROR, "CAEEncoderFFmpeg::{} - av_packet_alloc failed: {}", __FUNCTION__,
+-              strerror(errno));
+-    av_frame_free(&frame);
+-    return 0;
+-  }
++    pkt->size = out_size;
++    pkt->data = out;
+ 
+-  pkt->size = out_size;
+-  pkt->data = out;
++    /* encode it */
++    err = avcodec_send_frame(m_CodecCtx, frame);
++    if (err < 0)
++      throw FFMpegException("Error sending a frame for encoding (error '{}')",
++                            FFMpegErrorToString(err));
+ 
+-  /* encode it */
+-  int ret = avcodec_encode_audio2(m_CodecCtx, pkt, frame, &got_output);
++    while (err >= 0)
++    {
++      err = avcodec_receive_packet(m_CodecCtx, pkt);
++      if (err == AVERROR(EAGAIN) || err == AVERROR_EOF)
++      {
++        av_channel_layout_uninit(&frame->ch_layout);
++        av_frame_free(&frame);
++        av_packet_free(&pkt);
++        return (err == AVERROR(EAGAIN)) ? -1 : 0;
++      }
++      else if (err < 0)
++      {
++        throw FFMpegException("Error during encoding (error '{}')", FFMpegErrorToString(err));
++      }
+ 
+-  int size = pkt->size;
++      av_packet_unref(pkt);
++    }
+ 
++    size = pkt->size;
++  }
++  catch (const FFMpegException& caught)
++  {
++    CLog::Log(LOGERROR, "CAEEncoderFFmpeg::{} - {}", __func__, caught.what());
++  }
++
+   /* free temporary data */
+   av_frame_free(&frame);
+ 
+   /* free the packet */
+   av_packet_free(&pkt);
+ 
+-  if (ret < 0 || !got_output)
+-  {
+-    CLog::Log(LOGERROR, "CAEEncoderFFmpeg::Encode - Encoding failed");
+-    return 0;
+-  }
+-
+   /* return the number of frames used */
+   return size;
+ }
+-
+ 
+ int CAEEncoderFFmpeg::GetData(uint8_t **data)
+ {
+diff -urN xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp.orig xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp
+--- xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp.orig	2023-03-11 22:16:38.000000000 +0000
++++ xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp	2023-04-19 10:01:22.849708000 +0000
+@@ -16,17 +16,16 @@
+ #include "ActiveAESound.h"
+ #include "ActiveAEStream.h"
+ #include "ServiceBroker.h"
++#include "cores/AudioEngine/AEResampleFactory.h"
++#include "cores/AudioEngine/Encoders/AEEncoderFFmpeg.h"
+ #include "cores/AudioEngine/Interfaces/IAudioCallback.h"
+-#include "cores/AudioEngine/Utils/AEUtil.h"
+ #include "cores/AudioEngine/Utils/AEStreamData.h"
+ #include "cores/AudioEngine/Utils/AEStreamInfo.h"
+-#include "cores/AudioEngine/AEResampleFactory.h"
+-#include "cores/AudioEngine/Encoders/AEEncoderFFmpeg.h"
+-
++#include "cores/AudioEngine/Utils/AEUtil.h"
+ #include "settings/Settings.h"
+ #include "settings/SettingsComponent.h"
+-#include "windowing/WinSystem.h"
+ #include "utils/log.h"
++#include "windowing/WinSystem.h"
+ 
+ using namespace std::chrono_literals;
+ 
+@@ -3043,8 +3042,8 @@
+   AVFormatContext *fmt_ctx = nullptr;
+   AVCodecContext *dec_ctx = nullptr;
+   AVIOContext *io_ctx;
+-  AVInputFormat *io_fmt = nullptr;
+-  AVCodec *dec = nullptr;
++  const AVInputFormat* io_fmt = nullptr;
++  const AVCodec* dec = nullptr;
+   SampleConfig config;
+ 
+   // No custom deleter until sound is registered
+@@ -3096,8 +3095,8 @@
+       AVCodecID codecId = fmt_ctx->streams[0]->codecpar->codec_id;
+       dec = avcodec_find_decoder(codecId);
+       config.sample_rate = fmt_ctx->streams[0]->codecpar->sample_rate;
+-      config.channels = fmt_ctx->streams[0]->codecpar->channels;
+-      config.channel_layout = fmt_ctx->streams[0]->codecpar->channel_layout;
++      config.channels = fmt_ctx->streams[0]->codecpar->ch_layout.nb_channels;
++      config.channel_layout = fmt_ctx->streams[0]->codecpar->ch_layout.u.mask;
+     }
+   }
+   if (dec == nullptr)
+@@ -3113,10 +3112,14 @@
+ 
+   dec_ctx = avcodec_alloc_context3(dec);
+   dec_ctx->sample_rate = config.sample_rate;
+-  dec_ctx->channels = config.channels;
++  AVChannelLayout layout = {};
+   if (!config.channel_layout)
+-    config.channel_layout = av_get_default_channel_layout(config.channels);
+-  dec_ctx->channel_layout = config.channel_layout;
++    av_channel_layout_default(&layout, config.channels);
++  else
++    av_channel_layout_from_mask(&layout, config.channel_layout);
++  config.channel_layout = layout.u.mask;
++  av_channel_layout_copy(&dec_ctx->ch_layout, &layout);
++  av_channel_layout_uninit(&layout);
+ 
+   AVPacket* avpkt = av_packet_alloc();
+   if (!avpkt)
+@@ -3183,6 +3186,7 @@
+ 
+   av_packet_free(&avpkt);
+   av_frame_free(&decoded_frame);
++  av_channel_layout_uninit(&dec_ctx->ch_layout);
+   avcodec_free_context(&dec_ctx);
+   avformat_close_input(&fmt_ctx);
+   if (io_ctx)
+diff -urN xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEFilter.cpp.orig xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEFilter.cpp
+--- xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEFilter.cpp.orig	2023-03-11 22:16:38.000000000 +0000
++++ xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEFilter.cpp	2023-04-19 10:01:22.849964000 +0000
+@@ -12,8 +12,8 @@
+ #include <algorithm>
+ 
+ extern "C" {
+-#include <libavfilter/avfilter.h>
+ #include <libavcodec/avcodec.h>
++#include <libavfilter/avfilter.h>
+ #include <libavfilter/buffersink.h>
+ #include <libavfilter/buffersrc.h>
+ #include <libswresample/swresample.h>
+@@ -171,7 +171,10 @@
+   }
+ 
+   if (m_pOutFrame)
++  {
++    av_channel_layout_uninit(&m_pOutFrame->ch_layout);
+     av_frame_free(&m_pOutFrame);
++  }
+ 
+   if (m_pConvertFrame)
+     av_frame_free(&m_pConvertFrame);
+@@ -205,10 +208,9 @@
+     if (!frame)
+       return -1;
+ 
+-    int channels = av_get_channel_layout_nb_channels(m_channelLayout);
+-
+-    frame->channel_layout = m_channelLayout;
+-    frame->channels = channels;
++    av_channel_layout_uninit(&frame->ch_layout);
++    av_channel_layout_from_mask(&frame->ch_layout, m_channelLayout);
++    int channels = frame->ch_layout.nb_channels;
+     frame->sample_rate = m_sampleRate;
+     frame->nb_samples = src_samples;
+     frame->format = m_sampleFormat;
+@@ -224,6 +226,7 @@
+                              src_buffer[0], src_bufsize, 16);
+     if (result < 0)
+     {
++      av_channel_layout_uninit(&frame->ch_layout);
+       av_frame_free(&frame);
+       CLog::Log(LOGERROR, "CActiveAEFilter::ProcessFilter - avcodec_fill_audio_frame failed");
+       m_filterEof = true;
+@@ -231,6 +234,7 @@
+     }
+ 
+     result = av_buffersrc_write_frame(m_pFilterCtxIn, frame);
++    av_channel_layout_uninit(&frame->ch_layout);
+     av_frame_free(&frame);
+     if (result < 0)
+     {
+@@ -284,7 +288,8 @@
+     {
+       av_frame_unref(m_pOutFrame);
+       m_pOutFrame->format = m_sampleFormat;
+-      m_pOutFrame->channel_layout = m_channelLayout;
++      av_channel_layout_uninit(&m_pOutFrame->ch_layout);
++      av_channel_layout_from_mask(&m_pOutFrame->ch_layout, m_channelLayout);
+       m_pOutFrame->sample_rate = m_sampleRate;
+       result = swr_convert_frame(m_pConvertCtx, m_pOutFrame, m_pConvertFrame);
+       av_frame_unref(m_pConvertFrame);
+@@ -302,7 +307,10 @@
+ 
+   if (m_hasData)
+   {
+-    int channels = av_get_channel_layout_nb_channels(m_channelLayout);
++    AVChannelLayout layout = {};
++    av_channel_layout_from_mask(&layout, m_channelLayout);
++    int channels = layout.nb_channels;
++    av_channel_layout_uninit(&layout);
+     int planes = av_sample_fmt_is_planar(m_sampleFormat) ? channels : 1;
+     int samples = std::min(dst_samples, m_pOutFrame->nb_samples - m_sampleOffset);
+     int bytes = samples * av_get_bytes_per_sample(m_sampleFormat) * channels / planes;
+diff -urN xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResampleFFMPEG.cpp.orig xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResampleFFMPEG.cpp
+--- xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResampleFFMPEG.cpp.orig	2023-03-11 22:16:38.000000000 +0000
++++ xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResampleFFMPEG.cpp	2023-04-19 10:01:22.850224000 +0000
+@@ -49,15 +49,30 @@
+     m_doesResample = true;
+ 
+   if (m_dst_chan_layout == 0)
+-    m_dst_chan_layout = av_get_default_channel_layout(m_dst_channels);
++  {
++    AVChannelLayout layout = {};
++    av_channel_layout_default(&layout, m_dst_channels);
++    m_dst_chan_layout = layout.u.mask;
++    av_channel_layout_uninit(&layout);
++  }
+   if (m_src_chan_layout == 0)
+-    m_src_chan_layout = av_get_default_channel_layout(m_src_channels);
++  {
++    AVChannelLayout layout = {};
++    av_channel_layout_default(&layout, m_src_channels);
++    m_src_chan_layout = layout.u.mask;
++    av_channel_layout_uninit(&layout);
++  }
+ 
+-  m_pContext = swr_alloc_set_opts(NULL, m_dst_chan_layout, m_dst_fmt, m_dst_rate,
+-                                                        m_src_chan_layout, m_src_fmt, m_src_rate,
+-                                                        0, NULL);
++  AVChannelLayout dstChLayout = {};
++  AVChannelLayout srcChLayout = {};
+ 
+-  if (!m_pContext)
++  av_channel_layout_from_mask(&dstChLayout, m_dst_chan_layout);
++  av_channel_layout_from_mask(&srcChLayout, m_src_chan_layout);
++
++  int ret = swr_alloc_set_opts2(&m_pContext, &dstChLayout, m_dst_fmt, m_dst_rate, &srcChLayout,
++                                m_src_fmt, m_src_rate, 0, NULL);
++
++  if (ret)
+   {
+     CLog::Log(LOGERROR, "CActiveAEResampleFFMPEG::Init - create context failed");
+     return false;
+@@ -126,10 +141,12 @@
+   else if (upmix && m_src_channels == 2 && m_dst_channels > 2)
+   {
+     memset(m_rematrix, 0, sizeof(m_rematrix));
++    av_channel_layout_uninit(&dstChLayout);
++    av_channel_layout_from_mask(&dstChLayout, m_dst_chan_layout);
+     for (int out=0; out<m_dst_channels; out++)
+     {
+-      uint64_t out_chan = av_channel_layout_extract_channel(m_dst_chan_layout, out);
+-      switch(out_chan)
++      AVChannel outChan = av_channel_layout_channel_from_index(&dstChLayout, out);
++      switch (outChan)
+       {
+         case AV_CH_FRONT_LEFT:
+         case AV_CH_BACK_LEFT:
+@@ -153,6 +170,8 @@
+           break;
+       }
+     }
++
++    av_channel_layout_uninit(&dstChLayout);
+ 
+     if (swr_set_matrix(m_pContext, (const double*)m_rematrix, AE_CH_MAX) < 0)
+     {
+diff -urN xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEStream.cpp.orig xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEStream.cpp
+--- xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEStream.cpp.orig	2023-03-11 22:16:38.000000000 +0000
++++ xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEStream.cpp	2023-04-19 10:01:22.844169000 +0000
+@@ -88,7 +88,7 @@
+   for(unsigned int i=0; i<m_format.m_channelLayout.Count(); i++)
+   {
+     avLast = avCur;
+-    avCur = CAEUtil::GetAVChannel(m_format.m_channelLayout[i]);
++    avCur = CAEUtil::GetAVChannelMask(m_format.m_channelLayout[i]);
+     if(avCur < avLast)
+     {
+       needRemap = true;
+diff -urN xbmc/cores/AudioEngine/Utils/AEUtil.cpp.orig xbmc/cores/AudioEngine/Utils/AEUtil.cpp
+--- xbmc/cores/AudioEngine/Utils/AEUtil.cpp.orig	2023-03-11 22:16:38.000000000 +0000
++++ xbmc/cores/AudioEngine/Utils/AEUtil.cpp	2023-04-19 10:01:22.850463000 +0000
+@@ -19,10 +19,6 @@
+ #include <xmmintrin.h>
+ #endif
+ 
+-extern "C" {
+-#include <libavutil/channel_layout.h>
+-}
+-
+ void AEDelayStatus::SetDelay(double d)
+ {
+   delay = d;
+@@ -550,34 +546,64 @@
+   }
+ }
+ 
+-uint64_t CAEUtil::GetAVChannel(enum AEChannel aechannel)
++uint64_t CAEUtil::GetAVChannelMask(enum AEChannel aechannel)
+ {
++  enum AVChannel ch = GetAVChannel(aechannel);
++  if (ch == AV_CHAN_NONE)
++    return 0;
++  return (1ULL << ch);
++}
++
++enum AVChannel CAEUtil::GetAVChannel(enum AEChannel aechannel)
++{
+   switch (aechannel)
+   {
+-  case AE_CH_FL:   return AV_CH_FRONT_LEFT;
+-  case AE_CH_FR:   return AV_CH_FRONT_RIGHT;
+-  case AE_CH_FC:   return AV_CH_FRONT_CENTER;
+-  case AE_CH_LFE:  return AV_CH_LOW_FREQUENCY;
+-  case AE_CH_BL:   return AV_CH_BACK_LEFT;
+-  case AE_CH_BR:   return AV_CH_BACK_RIGHT;
+-  case AE_CH_FLOC: return AV_CH_FRONT_LEFT_OF_CENTER;
+-  case AE_CH_FROC: return AV_CH_FRONT_RIGHT_OF_CENTER;
+-  case AE_CH_BC:   return AV_CH_BACK_CENTER;
+-  case AE_CH_SL:   return AV_CH_SIDE_LEFT;
+-  case AE_CH_SR:   return AV_CH_SIDE_RIGHT;
+-  case AE_CH_TC:   return AV_CH_TOP_CENTER;
+-  case AE_CH_TFL:  return AV_CH_TOP_FRONT_LEFT;
+-  case AE_CH_TFC:  return AV_CH_TOP_FRONT_CENTER;
+-  case AE_CH_TFR:  return AV_CH_TOP_FRONT_RIGHT;
+-  case AE_CH_TBL:  return AV_CH_TOP_BACK_LEFT;
+-  case AE_CH_TBC:  return AV_CH_TOP_BACK_CENTER;
+-  case AE_CH_TBR:  return AV_CH_TOP_BACK_RIGHT;
+-  default:
+-    return 0;
++    case AE_CH_FL:
++      return AV_CHAN_FRONT_LEFT;
++    case AE_CH_FR:
++      return AV_CHAN_FRONT_RIGHT;
++    case AE_CH_FC:
++      return AV_CHAN_FRONT_CENTER;
++    case AE_CH_LFE:
++      return AV_CHAN_LOW_FREQUENCY;
++    case AE_CH_BL:
++      return AV_CHAN_BACK_LEFT;
++    case AE_CH_BR:
++      return AV_CHAN_BACK_RIGHT;
++    case AE_CH_FLOC:
++      return AV_CHAN_FRONT_LEFT_OF_CENTER;
++    case AE_CH_FROC:
++      return AV_CHAN_FRONT_RIGHT_OF_CENTER;
++    case AE_CH_BC:
++      return AV_CHAN_BACK_CENTER;
++    case AE_CH_SL:
++      return AV_CHAN_SIDE_LEFT;
++    case AE_CH_SR:
++      return AV_CHAN_SIDE_RIGHT;
++    case AE_CH_TC:
++      return AV_CHAN_TOP_CENTER;
++    case AE_CH_TFL:
++      return AV_CHAN_TOP_FRONT_LEFT;
++    case AE_CH_TFC:
++      return AV_CHAN_TOP_FRONT_CENTER;
++    case AE_CH_TFR:
++      return AV_CHAN_TOP_FRONT_RIGHT;
++    case AE_CH_TBL:
*** 1189 LINES SKIPPED ***