diff -pruN 7:5.0.1-3/Changelog 7:5.1-1/Changelog
--- 7:5.0.1-3/Changelog	2022-04-04 14:40:22.000000000 +0000
+++ 7:5.1-1/Changelog	2022-07-22 17:58:38.000000000 +0000
@@ -1,65 +1,30 @@
 Entries are sorted chronologically from oldest to youngest within each release,
 releases are sorted from youngest to oldest.
 
-version 5.0.1:
-- avcodec/exr: Avoid signed overflow in displayWindow
-- avcodec/diracdec: avoid signed integer overflow in global mv
-- avcodec/takdsp: Fix integer overflow in decorrelate_sf()
-- avcodec/apedec: fix a integer overflow in long_filter_high_3800()
-- avdevice/dshow: fix regression
-- avfilter/vf_subtitles: pass storage size to libass
-- avcodec/vp9_superframe_split_bsf: Don't read inexistent data
-- avcodec/vp9_superframe_split_bsf: Discard invalid zero-sized frames
-- avcodec/vp9_superframe_bsf: Check for existence of data before reading it
-- avcodec/vp9_raw_reorder_bsf: Check for existence of data before reading it
-- avformat/imf: fix packet pts, dts and muxing
-- avformat/imf: open resources only when first needed
-- avformat/imf: cosmetics
-- avformat/imf_cpl: do not use filesize when reading XML file
-- avformat/imfdec: Use proper logcontext
-- avformat/imfdec: do not use filesize when reading XML file
-- doc/utils: add missing 22.2 layout entry
-- avcodec/av1: only set the private context pix_fmt field if get_pixel_format() succeeds
-- avformat/aqtitledec: Skip unrepresentable durations
-- avformat/cafdec: Do not store empty keys in read_info_chunk()
-- avformat/mxfdec: Do not clear array in mxf_read_strong_ref_array() before writing
-- avformat/mxfdec: Check for avio_read() failure in mxf_read_strong_ref_array()
-- avformat/mxfdec: Check count in mxf_read_strong_ref_array()
-- avformat/hls: Check target_duration
-- avcodec/pixlet: Avoid signed integer overflow in scaling in filterfn()
-- avformat/matroskadec: Check pre_ns
-- avcodec/sonic: Use unsigned for predictor_k to avoid undefined behavior
-- avcodec/libuavs3d: Check ff_set_dimensions() for failure
-- avcodec/speexdec: Align some comments
-- avcodec/speexdec: Use correct doxygen comments
-- avcodec/mjpegbdec: Set buf_size
-- avformat/matroskadec: Use rounded down duration in get_cue_desc() check
-- avcodec/argo: Check packet size
-- avcodec/g729_parser: Check channels
-- avformat/avidec: Check height
-- avformat/rmdec: Better duplicate tags check
-- avformat/mov: Disallow empty sidx
-- avformat/argo_cvg:: Fix order of operations in error check in argo_cvg_write_trailer()
-- avformat/argo_asf: Fix order of operations in error check in argo_asf_write_trailer()
-- avcodec/movtextdec: add () to CMP() macro to avoid unexpected behavior
-- avformat/matroskadec: Check duration
-- avformat/mov: Corner case encryption error cleanup in mov_read_senc()
-- avcodec/jpeglsdec: Fix if( code style
-- avcodec/jpeglsdec: Check get_ur_golomb_jpegls() for error
-- avcodec/motion_est: fix indention of ff_get_best_fcode()
-- avcodec/motion_est: Fix xy indexing on range violation in ff_get_best_fcode()
-- avformat/hls: Use unsigned for iv computation
-- avcodec/jpeglsdec: Increase range for N in ls_get_code_runterm() by using unsigned
-- avformat/matroskadec: Check desc_bytes
-- avformat/utils: Fix invalid NULL pointer operation in ff_parse_key_value()
-- avformat/matroskadec: Fix infinite loop with bz decompression
-- avformat/utils: keep chapter monotonicity on chapter updates
-- avformat/mov: Check size before subtraction
-- avcodec/cfhd: Avoid signed integer overflow in coeff
-- avcodec/libdav1d: free the Dav1dData packet on dav1d_send_data() failure
-- avcodec/h264_parser: don't alter decoder private data
-- configure: link to libatomic when it's present
-- fate/ffmpeg: add missing samples dependency to fate-shortest
+version 5.1:
+- add ipfs/ipns protocol support
+- dialogue enhance audio filter
+- dropped obsolete XvMC hwaccel
+- pcm-bluray encoder
+- DFPWM audio encoder/decoder and raw muxer/demuxer
+- SITI filter
+- Vizrt Binary Image encoder/decoder
+- avsynctest source filter
+- feedback video filter
+- pixelize video filter
+- colormap video filter
+- colorchart video source filter
+- multiply video filter
+- PGS subtitle frame merge bitstream filter
+- blurdetect filter
+- tiltshelf audio filter
+- QOI image format support
+- ffprobe -o option
+- virtualbass audio filter
+- VDPAU AV1 hwaccel
+- PHM image format support
+- remap_opencl filter
+- added chromakey_cuda filter
 
 
 version 5.0:
diff -pruN 7:5.0.1-3/compat/cuda/cuda_runtime.h 7:5.1-1/compat/cuda/cuda_runtime.h
--- 7:5.0.1-3/compat/cuda/cuda_runtime.h	2022-01-14 18:45:39.000000000 +0000
+++ 7:5.1-1/compat/cuda/cuda_runtime.h	2022-07-22 17:58:38.000000000 +0000
@@ -181,7 +181,9 @@ static inline __device__ double trunc(do
 static inline __device__ float fabsf(float a) { return __builtin_fabsf(a); }
 static inline __device__ float fabs(float a) { return __builtin_fabsf(a); }
 static inline __device__ double fabs(double a) { return __builtin_fabs(a); }
+static inline __device__ float sqrtf(float a) { return __builtin_sqrtf(a); }
 
+static inline __device__ float __saturatef(float a) { return __nvvm_saturate_f(a); }
 static inline __device__ float __sinf(float a) { return __nvvm_sin_approx_f(a); }
 static inline __device__ float __cosf(float a) { return __nvvm_cos_approx_f(a); }
 static inline __device__ float __expf(float a) { return __nvvm_ex2_approx_f(a * (float)__builtin_log2(__builtin_exp(1))); }
diff -pruN 7:5.0.1-3/compat/w32dlfcn.h 7:5.1-1/compat/w32dlfcn.h
--- 7:5.0.1-3/compat/w32dlfcn.h	2022-01-14 18:45:39.000000000 +0000
+++ 7:5.1-1/compat/w32dlfcn.h	2022-07-22 17:58:38.000000000 +0000
@@ -20,11 +20,40 @@
 #define COMPAT_W32DLFCN_H
 
 #ifdef _WIN32
+#include <stdint.h>
+
 #include <windows.h>
+
 #include "config.h"
-#if (_WIN32_WINNT < 0x0602) || HAVE_WINRT
+#include "libavutil/macros.h"
 #include "libavutil/wchar_filename.h"
-#endif
+
+static inline wchar_t *get_module_filename(HMODULE module)
+{
+    wchar_t *path = NULL, *new_path;
+    DWORD path_size = 0, path_len;
+
+    do {
+        path_size = path_size ? FFMIN(2 * path_size, INT16_MAX + 1) : MAX_PATH;
+        new_path = av_realloc_array(path, path_size, sizeof *path);
+        if (!new_path) {
+            av_free(path);
+            return NULL;
+        }
+        path = new_path;
+        // Returns path_size in case of insufficient buffer.
+        // Whether the error is set or not and whether the output
+        // is null-terminated or not depends on the version of Windows.
+        path_len = GetModuleFileNameW(module, path, path_size);
+    } while (path_len && path_size <= INT16_MAX && path_size <= path_len);
+
+    if (!path_len) {
+        av_free(path);
+        return NULL;
+    }
+    return path;
+}
+
 /**
  * Safe function used to open dynamic libs. This attempts to improve program security
  * by removing the current directory from the dll search path. Only dll's found in the
@@ -34,29 +63,53 @@
  */
 static inline HMODULE win32_dlopen(const char *name)
 {
+    wchar_t *name_w;
+    HMODULE module = NULL;
+    if (utf8towchar(name, &name_w))
+        name_w = NULL;
 #if _WIN32_WINNT < 0x0602
-    // Need to check if KB2533623 is available
+    // On Win7 and earlier we check if KB2533623 is available
     if (!GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "SetDefaultDllDirectories")) {
-        HMODULE module = NULL;
-        wchar_t *path = NULL, *name_w = NULL;
-        DWORD pathlen;
-        if (utf8towchar(name, &name_w))
+        wchar_t *path = NULL, *new_path;
+        DWORD pathlen, pathsize, namelen;
+        if (!name_w)
             goto exit;
-        path = (wchar_t *)av_calloc(MAX_PATH, sizeof(wchar_t));
+        namelen = wcslen(name_w);
         // Try local directory first
-        pathlen = GetModuleFileNameW(NULL, path, MAX_PATH);
-        pathlen = wcsrchr(path, '\\') - path;
-        if (pathlen == 0 || pathlen + wcslen(name_w) + 2 > MAX_PATH)
+        path = get_module_filename(NULL);
+        if (!path)
+            goto exit;
+        new_path = wcsrchr(path, '\\');
+        if (!new_path)
             goto exit;
-        path[pathlen] = '\\';
+        pathlen = new_path - path;
+        pathsize = pathlen + namelen + 2;
+        new_path = av_realloc_array(path, pathsize, sizeof *path);
+        if (!new_path)
+            goto exit;
+        path = new_path;
         wcscpy(path + pathlen + 1, name_w);
         module = LoadLibraryExW(path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
         if (module == NULL) {
             // Next try System32 directory
-            pathlen = GetSystemDirectoryW(path, MAX_PATH);
-            if (pathlen == 0 || pathlen + wcslen(name_w) + 2 > MAX_PATH)
+            pathlen = GetSystemDirectoryW(path, pathsize);
+            if (!pathlen)
                 goto exit;
-            path[pathlen] = '\\';
+            // Buffer is not enough in two cases:
+            // 1. system directory + \ + module name
+            // 2. system directory even without the module name.
+            if (pathlen + namelen + 2 > pathsize) {
+                pathsize = pathlen + namelen + 2;
+                new_path = av_realloc_array(path, pathsize, sizeof *path);
+                if (!new_path)
+                    goto exit;
+                path = new_path;
+                // Query again to handle the case #2.
+                pathlen = GetSystemDirectoryW(path, pathsize);
+                if (!pathlen)
+                    goto exit;
+            }
+            path[pathlen] = L'\\';
             wcscpy(path + pathlen + 1, name_w);
             module = LoadLibraryExW(path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
         }
@@ -73,16 +126,19 @@ exit:
 #   define LOAD_LIBRARY_SEARCH_SYSTEM32        0x00000800
 #endif
 #if HAVE_WINRT
-    wchar_t *name_w = NULL;
-    int ret;
-    if (utf8towchar(name, &name_w))
+    if (!name_w)
         return NULL;
-    ret = LoadPackagedLibrary(name_w, 0);
-    av_free(name_w);
-    return ret;
+    module = LoadPackagedLibrary(name_w, 0);
 #else
-    return LoadLibraryExA(name, NULL, LOAD_LIBRARY_SEARCH_APPLICATION_DIR | LOAD_LIBRARY_SEARCH_SYSTEM32);
+#define LOAD_FLAGS (LOAD_LIBRARY_SEARCH_APPLICATION_DIR | LOAD_LIBRARY_SEARCH_SYSTEM32)
+    /* filename may be be in CP_ACP */
+    if (!name_w)
+        return LoadLibraryExA(name, NULL, LOAD_FLAGS);
+    module = LoadLibraryExW(name_w, NULL, LOAD_FLAGS);
+#undef LOAD_FLAGS
 #endif
+    av_free(name_w);
+    return module;
 }
 #define dlopen(name, flags) win32_dlopen(name)
 #define dlclose FreeLibrary
diff -pruN 7:5.0.1-3/configure 7:5.1-1/configure
--- 7:5.0.1-3/configure	2022-04-04 14:40:22.000000000 +0000
+++ 7:5.1-1/configure	2022-07-22 17:58:38.000000000 +0000
@@ -140,7 +140,6 @@ Component options:
   --disable-dwt            disable DWT code
   --disable-error-resilience disable error resilience code
   --disable-lsp            disable LSP code
-  --disable-lzo            disable LZO decoder code
   --disable-mdct           disable MDCT code
   --disable-rdft           disable RDFT code
   --disable-fft            disable FFT code
@@ -216,6 +215,7 @@ External library support:
   --disable-iconv          disable iconv [autodetect]
   --enable-jni             enable JNI support [no]
   --enable-ladspa          enable LADSPA audio filtering [no]
+  --enable-lcms2           enable ICC profile support via LittleCMS 2 [no]
   --enable-libaom          enable AV1 video encoding/decoding via libaom [no]
   --enable-libaribb24      enable ARIB text and caption decoding via libaribb24 [no]
   --enable-libass          enable libass subtitles rendering,
@@ -241,6 +241,7 @@ External library support:
   --enable-libiec61883     enable iec61883 via libiec61883 [no]
   --enable-libilbc         enable iLBC de/encoding via libilbc [no]
   --enable-libjack         enable JACK audio sound server [no]
+  --enable-libjxl          enable JPEG XL de/encoding via libjxl [no]
   --enable-libklvanc       enable Kernel Labs VANC processing [no]
   --enable-libkvazaar      enable HEVC encoding via libkvazaar [no]
   --enable-liblensfun      enable lensfun lens correction [no]
@@ -255,6 +256,7 @@ External library support:
   --enable-libopenvino     enable OpenVINO as a DNN module backend
                            for DNN based filters like dnn_processing [no]
   --enable-libopus         enable Opus de/encoding via libopus [no]
+  --enable-libplacebo      enable libplacebo library [no]
   --enable-libpulse        enable Pulseaudio input via libpulse [no]
   --enable-librabbitmq     enable RabbitMQ library [no]
   --enable-librav1e        enable AV1 encoding via rav1e [no]
@@ -443,6 +445,7 @@ Optimization options (experts only):
   --disable-fma4           disable FMA4 optimizations
   --disable-avx2           disable AVX2 optimizations
   --disable-avx512         disable AVX-512 optimizations
+  --disable-avx512icl      disable AVX-512ICL optimizations
   --disable-aesni          disable AESNI optimizations
   --disable-armv5te        disable armv5te optimizations
   --disable-armv6          disable armv6 optimizations
@@ -1812,6 +1815,7 @@ EXTERNAL_LIBRARY_LIST="
     gnutls
     jni
     ladspa
+    lcms2
     libaom
     libass
     libbluray
@@ -1832,6 +1836,7 @@ EXTERNAL_LIBRARY_LIST="
     libiec61883
     libilbc
     libjack
+    libjxl
     libklvanc
     libkvazaar
     libmodplug
@@ -1899,7 +1904,6 @@ HWACCEL_AUTODETECT_LIBRARY_LIST="
     videotoolbox
     vulkan
     v4l2_m2m
-    xvmc
 "
 
 # catchall list of things that require external libs to link
@@ -1975,7 +1979,6 @@ SUBSYSTEM_LIST="
     fast_unaligned
     fft
     lsp
-    lzo
     mdct
     pixelutils
     network
@@ -2098,6 +2101,7 @@ ARCH_EXT_LIST_X86_SIMD="
     avx
     avx2
     avx512
+    avx512icl
     fma3
     fma4
     mmx
@@ -2267,6 +2271,8 @@ SYSTEM_FUNCS="
     CommandLineToArgvW
     fcntl
     getaddrinfo
+    getauxval
+    getenv
     gethrtime
     getopt
     GetModuleHandle
@@ -2432,6 +2438,7 @@ CONFIG_EXTRA="
     cbs_jpeg
     cbs_mpeg2
     cbs_vp9
+    deflate_wrapper
     dirac_parse
     dnn
     dovi_rpu
@@ -2460,6 +2467,7 @@ CONFIG_EXTRA="
     idctdsp
     iirfilter
     mdct15
+    inflate_wrapper
     intrax8
     iso_media
     ividsp
@@ -2478,6 +2486,7 @@ CONFIG_EXTRA="
     mpegaudioheader
     mpeg4audio
     mpegvideo
+    mpegvideodec
     mpegvideoenc
     mss34dsp
     pixblockdsp
@@ -2665,6 +2674,7 @@ fma3_deps="avx"
 fma4_deps="avx"
 avx2_deps="avx"
 avx512_deps="avx2"
+avx512icl_deps="avx512"
 
 mmx_external_deps="x86asm"
 mmx_inline_deps="inline_asm x86"
@@ -2707,6 +2717,7 @@ cbs_jpeg_select="cbs"
 cbs_mpeg2_select="cbs"
 cbs_vp9_select="cbs"
 dct_select="rdft"
+deflate_wrapper_deps="zlib"
 dirac_parse_select="golomb"
 dovi_rpu_select="golomb"
 dnn_suggest="libtensorflow libopenvino"
@@ -2719,6 +2730,7 @@ faanidct_select="idctdsp"
 h264dsp_select="startcode"
 hevcparse_select="atsc_a53 golomb"
 frame_thread_encoder_deps="encoders threads"
+inflate_wrapper_deps="zlib"
 intrax8_select="blockdsp idctdsp"
 iso_media_select="mpeg4audio"
 mdct_select="fft"
@@ -2727,7 +2739,8 @@ me_cmp_select="fdctdsp idctdsp pixblockd
 mpeg_er_select="error_resilience"
 mpegaudio_select="mpegaudiodsp mpegaudioheader"
 mpegaudiodsp_select="dct"
-mpegvideo_select="blockdsp h264chroma hpeldsp idctdsp me_cmp mpeg_er videodsp"
+mpegvideo_select="blockdsp h264chroma hpeldsp idctdsp videodsp"
+mpegvideodec_select="mpegvideo mpeg_er"
 mpegvideoenc_select="aandcttables me_cmp mpegvideo pixblockdsp qpeldsp"
 vc1dsp_select="h264chroma qpeldsp startcode"
 rdft_select="fft"
@@ -2752,9 +2765,8 @@ amrwb_decoder_select="lsp"
 amv_decoder_select="sp5x_decoder exif"
 amv_encoder_select="jpegtables mpegvideoenc"
 ape_decoder_select="bswapdsp llauddsp"
-apng_decoder_deps="zlib"
-apng_encoder_deps="zlib"
-apng_encoder_select="llvidencdsp"
+apng_decoder_select="inflate_wrapper"
+apng_encoder_select="deflate_wrapper llvidencdsp"
 aptx_decoder_select="audio_frame_queue"
 aptx_encoder_select="audio_frame_queue"
 aptx_hd_decoder_select="audio_frame_queue"
@@ -2778,7 +2790,7 @@ clearvideo_decoder_select="idctdsp"
 cllc_decoder_select="bswapdsp"
 comfortnoise_encoder_select="lpc"
 cook_decoder_select="audiodsp mdct sinewin"
-cscd_decoder_select="lzo"
+cri_decoder_select="mjpeg_decoder"
 cscd_decoder_suggest="zlib"
 dca_decoder_select="mdct"
 dca_encoder_select="mdct"
@@ -2805,9 +2817,9 @@ ffvhuff_encoder_select="huffyuv_encoder"
 fic_decoder_select="golomb"
 flac_decoder_select="flacdsp"
 flac_encoder_select="bswapdsp flacdsp lpc"
-flashsv2_decoder_deps="zlib"
-flashsv2_encoder_deps="zlib"
-flashsv_decoder_deps="zlib"
+flashsv2_decoder_select="inflate_wrapper"
+flashsv2_encoder_select="deflate_wrapper"
+flashsv_decoder_select="inflate_wrapper"
 flashsv_encoder_deps="zlib"
 flv_decoder_select="h263_decoder"
 flv_encoder_select="h263_encoder"
@@ -2816,9 +2828,9 @@ fraps_decoder_select="bswapdsp huffman"
 g2m_decoder_deps="zlib"
 g2m_decoder_select="blockdsp idctdsp jpegtables"
 g729_decoder_select="audiodsp"
-h261_decoder_select="mpegvideo"
+h261_decoder_select="mpegvideodec"
 h261_encoder_select="mpegvideoenc"
-h263_decoder_select="h263_parser h263dsp mpegvideo qpeldsp"
+h263_decoder_select="h263_parser h263dsp mpegvideodec qpeldsp"
 h263_encoder_select="h263dsp mpegvideoenc"
 h263i_decoder_select="h263_decoder"
 h263p_decoder_select="h263_decoder"
@@ -2840,12 +2852,12 @@ indeo3_decoder_select="hpeldsp"
 indeo4_decoder_select="ividsp"
 indeo5_decoder_select="ividsp"
 interplay_video_decoder_select="hpeldsp"
-ipu_decoder_select="mpegvideo"
+ipu_decoder_select="mpegvideodec"
 jpegls_decoder_select="mjpeg_decoder"
 jv_decoder_select="blockdsp"
 lagarith_decoder_select="llviddsp"
 ljpeg_encoder_select="idctdsp jpegtables"
-lscr_decoder_deps="zlib"
+lscr_decoder_select="inflate_wrapper"
 magicyuv_decoder_select="llviddsp"
 magicyuv_encoder_select="llvidencdsp"
 mdec_decoder_select="blockdsp bswapdsp idctdsp mpegvideo"
@@ -2870,38 +2882,36 @@ mp3on4_decoder_select="mpegaudio mpeg4au
 mp3on4float_decoder_select="mpegaudio mpeg4audio"
 mpc7_decoder_select="bswapdsp mpegaudiodsp"
 mpc8_decoder_select="mpegaudiodsp"
-mpegvideo_decoder_select="mpegvideo"
-mpeg1video_decoder_select="mpegvideo"
+mpegvideo_decoder_select="mpegvideodec"
+mpeg1video_decoder_select="mpegvideodec"
 mpeg1video_encoder_select="mpegvideoenc h263dsp"
-mpeg2video_decoder_select="mpegvideo"
+mpeg2video_decoder_select="mpegvideodec"
 mpeg2video_encoder_select="mpegvideoenc h263dsp"
 mpeg4_decoder_select="h263_decoder mpeg4video_parser"
 mpeg4_encoder_select="h263_encoder"
 msa1_decoder_select="mss34dsp"
-mscc_decoder_deps="zlib"
+mscc_decoder_select="inflate_wrapper"
 msmpeg4v1_decoder_select="h263_decoder"
 msmpeg4v2_decoder_select="h263_decoder"
 msmpeg4v2_encoder_select="h263_encoder"
 msmpeg4v3_decoder_select="h263_decoder"
 msmpeg4v3_encoder_select="h263_encoder"
-mss2_decoder_select="mpegvideo qpeldsp vc1_decoder"
+mss2_decoder_select="mpegvideodec qpeldsp vc1_decoder"
 mts2_decoder_select="jpegtables mss34dsp"
 mv30_decoder_select="aandcttables blockdsp"
-mvha_decoder_deps="zlib"
-mvha_decoder_select="llviddsp"
-mwsc_decoder_deps="zlib"
+mvha_decoder_select="inflate_wrapper llviddsp"
+mwsc_decoder_select="inflate_wrapper"
 mxpeg_decoder_select="mjpeg_decoder"
 nellymoser_decoder_select="mdct sinewin"
 nellymoser_encoder_select="audio_frame_queue mdct sinewin"
 notchlc_decoder_select="lzf"
-nuv_decoder_select="idctdsp lzo"
+nuv_decoder_select="idctdsp"
 on2avc_decoder_select="mdct"
 opus_decoder_deps="swresample"
 opus_decoder_select="mdct15"
 opus_encoder_select="audio_frame_queue mdct15"
-png_decoder_deps="zlib"
-png_encoder_deps="zlib"
-png_encoder_select="llvidencdsp"
+png_decoder_select="inflate_wrapper"
+png_encoder_select="deflate_wrapper llvidencdsp"
 prores_decoder_select="blockdsp idctdsp"
 prores_encoder_select="fdctdsp"
 qcelp_decoder_select="lsp"
@@ -2909,7 +2919,7 @@ qdm2_decoder_select="mdct rdft mpegaudio
 ra_144_decoder_select="audiodsp"
 ra_144_encoder_select="audio_frame_queue lpc audiodsp"
 ralf_decoder_select="golomb"
-rasc_decoder_deps="zlib"
+rasc_decoder_select="inflate_wrapper"
 rawvideo_decoder_select="bswapdsp"
 rscc_decoder_deps="zlib"
 rtjpeg_decoder_select="me_cmp"
@@ -2917,8 +2927,8 @@ rv10_decoder_select="h263_decoder"
 rv10_encoder_select="h263_encoder"
 rv20_decoder_select="h263_decoder"
 rv20_encoder_select="h263_encoder"
-rv30_decoder_select="golomb h264pred h264qpel mpegvideo rv34dsp"
-rv40_decoder_select="golomb h264pred h264qpel mpegvideo rv34dsp"
+rv30_decoder_select="golomb h264pred h264qpel mpegvideodec rv34dsp"
+rv40_decoder_select="golomb h264pred h264qpel mpegvideodec rv34dsp"
 screenpresso_decoder_deps="zlib"
 shorten_decoder_select="bswapdsp"
 sipr_decoder_select="lsp"
@@ -2931,7 +2941,7 @@ sonic_ls_encoder_select="golomb rangecod
 sp5x_decoder_select="mjpeg_decoder"
 speedhq_decoder_select="mpegvideo"
 speedhq_encoder_select="mpegvideoenc"
-srgc_decoder_deps="zlib"
+srgc_decoder_select="inflate_wrapper"
 svq1_decoder_select="hpeldsp"
 svq1_encoder_select="hpeldsp me_cmp mpegvideoenc"
 svq3_decoder_select="golomb h264dsp h264parse h264pred hpeldsp tpeldsp videodsp"
@@ -2948,13 +2958,15 @@ truehd_decoder_select="mlp_parser"
 truehd_encoder_select="lpc audio_frame_queue"
 truemotion2_decoder_select="bswapdsp"
 truespeech_decoder_select="bswapdsp"
-tscc_decoder_deps="zlib"
+tscc_decoder_select="inflate_wrapper"
 twinvq_decoder_select="mdct lsp sinewin"
 txd_decoder_select="texturedsp"
 utvideo_decoder_select="bswapdsp llviddsp"
 utvideo_encoder_select="bswapdsp huffman llvidencdsp"
 vble_decoder_select="llviddsp"
-vc1_decoder_select="blockdsp h263_decoder h264qpel intrax8 mpegvideo vc1dsp"
+vbn_decoder_select="texturedsp"
+vbn_encoder_select="texturedspenc"
+vc1_decoder_select="blockdsp h263_decoder h264qpel intrax8 mpegvideodec vc1dsp"
 vc1image_decoder_select="vc1_decoder"
 vorbis_decoder_select="mdct"
 vorbis_encoder_select="audio_frame_queue mdct"
@@ -2967,7 +2979,7 @@ vp6f_decoder_select="vp6_decoder"
 vp7_decoder_select="h264pred videodsp vp8dsp"
 vp8_decoder_select="h264pred videodsp vp8dsp"
 vp9_decoder_select="videodsp vp9_parser vp9_superframe_split_bsf"
-wcmv_decoder_deps="zlib"
+wcmv_decoder_select="inflate_wrapper"
 webp_decoder_select="vp8_decoder exif"
 wmalossless_decoder_select="llauddsp"
 wmapro_decoder_select="mdct sinewin wma_freqs"
@@ -2985,11 +2997,11 @@ wmv3image_decoder_select="wmv3_decoder"
 xma1_decoder_select="wmapro_decoder"
 xma2_decoder_select="wmapro_decoder"
 ylc_decoder_select="bswapdsp"
-zerocodec_decoder_deps="zlib"
-zlib_decoder_deps="zlib"
-zlib_encoder_deps="zlib"
-zmbv_decoder_deps="zlib"
-zmbv_encoder_deps="zlib"
+zerocodec_decoder_select="inflate_wrapper"
+zlib_decoder_select="inflate_wrapper"
+zlib_encoder_select="deflate_wrapper"
+zmbv_decoder_select="inflate_wrapper"
+zmbv_encoder_select="deflate_wrapper"
 
 # hardware accelerators
 crystalhd_deps="libcrystalhd_libcrystalhd_if_h"
@@ -3003,7 +3015,6 @@ vaapi_x11_deps="xlib_x11"
 videotoolbox_hwaccel_deps="videotoolbox pthreads"
 videotoolbox_hwaccel_extralibs="-framework QuartzCore"
 vulkan_deps_any="libdl LoadLibrary"
-xvmc_deps="X11_extensions_XvMClib_h"
 
 av1_d3d11va_hwaccel_deps="d3d11va DXVA_PicParams_AV1"
 av1_d3d11va_hwaccel_select="av1_decoder"
@@ -3015,6 +3026,8 @@ av1_nvdec_hwaccel_deps="nvdec CUVIDAV1PI
 av1_nvdec_hwaccel_select="av1_decoder"
 av1_vaapi_hwaccel_deps="vaapi VADecPictureParameterBufferAV1_bit_depth_idx"
 av1_vaapi_hwaccel_select="av1_decoder"
+av1_vdpau_hwaccel_deps="vdpau VdpPictureInfoAV1"
+av1_vdpau_hwaccel_select="av1_decoder"
 h263_vaapi_hwaccel_deps="vaapi"
 h263_vaapi_hwaccel_select="h263_decoder"
 h263_videotoolbox_hwaccel_deps="videotoolbox"
@@ -3051,16 +3064,12 @@ mjpeg_nvdec_hwaccel_deps="nvdec"
 mjpeg_nvdec_hwaccel_select="mjpeg_decoder"
 mjpeg_vaapi_hwaccel_deps="vaapi"
 mjpeg_vaapi_hwaccel_select="mjpeg_decoder"
-mpeg_xvmc_hwaccel_deps="xvmc"
-mpeg_xvmc_hwaccel_select="mpeg2video_decoder"
 mpeg1_nvdec_hwaccel_deps="nvdec"
 mpeg1_nvdec_hwaccel_select="mpeg1video_decoder"
 mpeg1_vdpau_hwaccel_deps="vdpau"
 mpeg1_vdpau_hwaccel_select="mpeg1video_decoder"
 mpeg1_videotoolbox_hwaccel_deps="videotoolbox"
 mpeg1_videotoolbox_hwaccel_select="mpeg1video_decoder"
-mpeg1_xvmc_hwaccel_deps="xvmc"
-mpeg1_xvmc_hwaccel_select="mpeg1video_decoder"
 mpeg2_d3d11va_hwaccel_deps="d3d11va"
 mpeg2_d3d11va_hwaccel_select="mpeg2video_decoder"
 mpeg2_d3d11va2_hwaccel_deps="d3d11va"
@@ -3075,8 +3084,6 @@ mpeg2_vdpau_hwaccel_deps="vdpau"
 mpeg2_vdpau_hwaccel_select="mpeg2video_decoder"
 mpeg2_videotoolbox_hwaccel_deps="videotoolbox"
 mpeg2_videotoolbox_hwaccel_select="mpeg2video_decoder"
-mpeg2_xvmc_hwaccel_deps="xvmc"
-mpeg2_xvmc_hwaccel_select="mpeg2video_decoder"
 mpeg4_nvdec_hwaccel_deps="nvdec"
 mpeg4_nvdec_hwaccel_select="mpeg4_decoder"
 mpeg4_vaapi_hwaccel_deps="vaapi"
@@ -3126,7 +3133,6 @@ wmv3_vdpau_hwaccel_select="vc1_vdpau_hwa
 
 # hardware-accelerated codecs
 mediafoundation_deps="mftransform_h MFCreateAlignedMemoryBuffer"
-mediafoundation_extralibs="-lmfplat -lmfuuid -lole32 -lstrmiids"
 omx_deps="libdl pthreads"
 omx_rpi_select="omx"
 qsv_deps="libmfx"
@@ -3136,6 +3142,8 @@ qsvvpp_select="qsv"
 vaapi_encode_deps="vaapi"
 v4l2_m2m_deps="linux_videodev2_h sem_timedwait"
 
+chromakey_cuda_filter_deps="ffnvcodec"
+chromakey_cuda_filter_deps_any="cuda_nvcc cuda_llvm"
 hwupload_cuda_filter_deps="ffnvcodec"
 scale_npp_filter_deps="ffnvcodec libnpp"
 scale2ref_npp_filter_deps="ffnvcodec libnpp"
@@ -3250,7 +3258,7 @@ h264_parser_select="atsc_a53 golomb h264
 hevc_parser_select="hevcparse"
 mpegaudio_parser_select="mpegaudioheader"
 mpegvideo_parser_select="mpegvideo"
-mpeg4video_parser_select="h263dsp mpegvideo qpeldsp"
+mpeg4video_parser_select="h263dsp mpegvideodec qpeldsp"
 vc1_parser_select="vc1dsp"
 
 # bitstream_filters
@@ -3292,7 +3300,6 @@ mp2_at_decoder_select="mpegaudioheader"
 mp3_at_decoder_select="mpegaudioheader"
 pcm_alaw_at_decoder_deps="audiotoolbox"
 pcm_mulaw_at_decoder_deps="audiotoolbox"
-qdmc_decoder_select="fft"
 qdmc_at_decoder_deps="audiotoolbox"
 qdm2_at_decoder_deps="audiotoolbox"
 aac_at_encoder_deps="audiotoolbox"
@@ -3322,6 +3329,7 @@ libcodec2_encoder_deps="libcodec2"
 libdav1d_decoder_deps="libdav1d"
 libdav1d_decoder_select="atsc_a53"
 libdavs2_decoder_deps="libdavs2"
+libdavs2_decoder_select="avs2_parser"
 libfdk_aac_decoder_deps="libfdk_aac"
 libfdk_aac_encoder_deps="libfdk_aac"
 libfdk_aac_encoder_select="audio_frame_queue"
@@ -3332,6 +3340,8 @@ libgsm_ms_decoder_deps="libgsm"
 libgsm_ms_encoder_deps="libgsm"
 libilbc_decoder_deps="libilbc"
 libilbc_encoder_deps="libilbc"
+libjxl_decoder_deps="libjxl libjxl_threads"
+libjxl_encoder_deps="libjxl libjxl_threads"
 libkvazaar_encoder_deps="libkvazaar"
 libmodplug_demuxer_deps="libmodplug"
 libmp3lame_encoder_deps="libmp3lame"
@@ -3399,6 +3409,7 @@ asf_stream_muxer_select="asf_muxer"
 av1_demuxer_select="av1_frame_merge_bsf av1_parser"
 avi_demuxer_select="riffdec exif"
 avi_muxer_select="riffenc"
+avif_muxer_select="mov_muxer"
 caf_demuxer_select="iso_media"
 caf_muxer_select="iso_media"
 dash_muxer_select="mp4_muxer"
@@ -3429,13 +3440,13 @@ ivf_muxer_select="av1_metadata_bsf vp9_s
 latm_muxer_select="aac_adtstoasc_bsf mpeg4audio"
 matroska_audio_muxer_select="matroska_muxer"
 matroska_demuxer_select="riffdec"
-matroska_demuxer_suggest="bzlib lzo zlib"
-matroska_muxer_select="mpeg4audio riffenc vp9_superframe_bsf aac_adtstoasc_bsf"
+matroska_demuxer_suggest="bzlib zlib"
+matroska_muxer_select="mpeg4audio riffenc aac_adtstoasc_bsf pgs_frame_merge_bsf vp9_superframe_bsf"
 mlp_demuxer_select="mlp_parser"
 mmf_muxer_select="riffenc"
 mov_demuxer_select="iso_media riffdec"
 mov_demuxer_suggest="zlib"
-mov_muxer_select="iso_media riffenc rtpenc_chain vp9_superframe_bsf aac_adtstoasc_bsf"
+mov_muxer_select="iso_media riffenc rtpenc_chain vp9_superframe_bsf aac_adtstoasc_bsf ac3_parser"
 mp3_demuxer_select="mpegaudio_parser"
 mp3_muxer_select="mpegaudioheader"
 mp4_muxer_select="mov_muxer"
@@ -3582,6 +3593,8 @@ udp_protocol_select="network"
 udplite_protocol_select="network"
 unix_protocol_deps="sys_un_h"
 unix_protocol_select="network"
+ipfs_protocol_select="https_protocol"
+ipns_protocol_select="https_protocol"
 
 # external library protocols
 libamqp_protocol_deps="librabbitmq"
@@ -3602,19 +3615,16 @@ libzmq_protocol_deps="libzmq"
 libzmq_protocol_select="network"
 
 # filters
-afir_filter_deps="avcodec"
-afir_filter_select="rdft"
 ametadata_filter_deps="avformat"
 amovie_filter_deps="avcodec avformat"
 aresample_filter_deps="swresample"
 asr_filter_deps="pocketsphinx"
 ass_filter_deps="libass"
-atempo_filter_deps="avcodec"
-atempo_filter_select="rdft"
 avgblur_opencl_filter_deps="opencl"
 avgblur_vulkan_filter_deps="vulkan spirv_compiler"
 azmq_filter_deps="libzmq"
 blackframe_filter_deps="gpl"
+blend_vulkan_filter_deps="vulkan spirv_compiler"
 bm3d_filter_deps="avcodec"
 bm3d_filter_select="dct"
 boxblur_filter_deps="gpl"
@@ -3646,10 +3656,6 @@ drawtext_filter_suggest="libfontconfig l
 elbg_filter_deps="avcodec"
 eq_filter_deps="gpl"
 erosion_opencl_filter_deps="opencl"
-fftfilt_filter_deps="avcodec"
-fftfilt_filter_select="rdft"
-fftdnoiz_filter_deps="avcodec"
-fftdnoiz_filter_select="fft"
 find_rect_filter_deps="avcodec avformat gpl"
 firequalizer_filter_deps="avcodec"
 firequalizer_filter_select="rdft"
@@ -3665,6 +3671,8 @@ gblur_vulkan_filter_deps="vulkan spirv_c
 hflip_vulkan_filter_deps="vulkan spirv_compiler"
 histeq_filter_deps="gpl"
 hqdn3d_filter_deps="gpl"
+iccdetect_filter_deps="lcms2"
+iccgen_filter_deps="lcms2"
 interlace_filter_deps="gpl"
 kerndeint_filter_deps="gpl"
 ladspa_filter_deps="ladspa libdl"
@@ -3687,6 +3695,7 @@ openclsrc_filter_deps="opencl"
 overlay_opencl_filter_deps="opencl"
 overlay_qsv_filter_deps="libmfx"
 overlay_qsv_filter_select="qsvvpp"
+overlay_vaapi_filter_deps="vaapi VAProcPipelineCaps_blend_flags"
 overlay_vulkan_filter_deps="vulkan spirv_compiler"
 owdenoise_filter_deps="gpl"
 pad_opencl_filter_deps="opencl"
@@ -3699,6 +3708,7 @@ prewitt_opencl_filter_deps="opencl"
 procamp_vaapi_filter_deps="vaapi"
 program_opencl_filter_deps="opencl"
 pullup_filter_deps="gpl"
+remap_opencl_filter_deps="opencl"
 removelogo_filter_deps="avcodec avformat swscale"
 repeatfields_filter_deps="gpl"
 roberts_opencl_filter_deps="opencl"
@@ -3715,8 +3725,6 @@ showcqt_filter_suggest="libfontconfig li
 showspatial_filter_deps="avcodec"
 showspatial_filter_select="fft"
 signature_filter_deps="gpl avcodec avformat"
-sinc_filter_deps="avcodec"
-sinc_filter_select="rdft"
 smartblur_filter_deps="gpl swscale"
 sobel_opencl_filter_deps="opencl"
 sofalizer_filter_deps="libmysofa"
@@ -3728,10 +3736,6 @@ stereo3d_filter_deps="gpl"
 subtitles_filter_deps="avformat avcodec libass"
 super2xsai_filter_deps="gpl"
 pixfmts_super2xsai_test_deps="super2xsai_filter"
-superequalizer_filter_deps="avcodec"
-superequalizer_filter_select="rdft"
-surround_filter_deps="avcodec"
-surround_filter_select="rdft"
 tinterlace_filter_deps="gpl"
 tinterlace_merge_test_deps="tinterlace_filter"
 tinterlace_pad_test_deps="tinterlace_filter"
@@ -3747,7 +3751,7 @@ vaguedenoiser_filter_deps="gpl"
 vflip_vulkan_filter_deps="vulkan spirv_compiler"
 vidstabdetect_filter_deps="libvidstab"
 vidstabtransform_filter_deps="libvidstab"
-libvmaf_filter_deps="libvmaf pthreads"
+libvmaf_filter_deps="libvmaf"
 zmq_filter_deps="libzmq"
 zoompan_filter_deps="swscale"
 zscale_filter_deps="libzimg const_nan"
@@ -4000,14 +4004,14 @@ OUTDEV_LIST=$(find_things_extern muxer A
 INDEV_LIST=$(find_things_extern demuxer AVInputFormat libavdevice/alldevices.c indev)
 MUXER_LIST=$(find_things_extern muxer AVOutputFormat libavformat/allformats.c)
 DEMUXER_LIST=$(find_things_extern demuxer AVInputFormat libavformat/allformats.c)
-ENCODER_LIST=$(find_things_extern encoder AVCodec libavcodec/allcodecs.c)
-DECODER_LIST=$(find_things_extern decoder AVCodec libavcodec/allcodecs.c)
+ENCODER_LIST=$(find_things_extern encoder FFCodec libavcodec/allcodecs.c)
+DECODER_LIST=$(find_things_extern decoder FFCodec libavcodec/allcodecs.c)
 CODEC_LIST="
     $ENCODER_LIST
     $DECODER_LIST
 "
 PARSER_LIST=$(find_things_extern parser AVCodecParser libavcodec/parsers.c)
-BSF_LIST=$(find_things_extern bsf AVBitStreamFilter libavcodec/bitstream_filters.c)
+BSF_LIST=$(find_things_extern bsf FFBitStreamFilter libavcodec/bitstream_filters.c)
 HWACCEL_LIST=$(find_things_extern hwaccel AVHWAccel libavcodec/hwaccels.h)
 PROTOCOL_LIST=$(find_things_extern protocol URLProtocol libavformat/protocols.c)
 
@@ -4420,11 +4424,7 @@ cc_default="${cross_prefix}${cc_default}
 cxx_default="${cross_prefix}${cxx_default}"
 nm_default="${cross_prefix}${nm_default}"
 pkg_config_default="${cross_prefix}${pkg_config_default}"
-if ${cross_prefix}${ranlib_default} 2>&1 | grep -q "\-D "; then
-    ranlib_default="${cross_prefix}${ranlib_default} -D"
-else
-    ranlib_default="${cross_prefix}${ranlib_default}"
-fi
+ranlib_default="${cross_prefix}${ranlib_default}"
 strip_default="${cross_prefix}${strip_default}"
 windres_default="${cross_prefix}${windres_default}"
 
@@ -4457,6 +4457,10 @@ set_default arch cc cxx doxygen pkg_conf
 enabled cross_compile || host_cc_default=$cc
 set_default host_cc
 
+if ${ranlib} 2>&1 | grep -q "\-D "; then
+    ranlib="${ranlib} -D"
+fi
+
 pkg_config_fail_message=""
 if ! $pkg_config --version >/dev/null 2>&1; then
     warn "$pkg_config not found, library detection may fail."
@@ -6146,10 +6150,11 @@ EOF
             elf*) enabled debug && append X86ASMFLAGS $x86asm_debug ;;
         esac
 
-        enabled avx512 && check_x86asm avx512_external "vmovdqa32 [eax]{k1}{z}, zmm0"
-        enabled avx2   && check_x86asm avx2_external   "vextracti128 xmm0, ymm0, 0"
-        enabled xop    && check_x86asm xop_external    "vpmacsdd xmm0, xmm1, xmm2, xmm3"
-        enabled fma4   && check_x86asm fma4_external   "vfmaddps ymm0, ymm1, ymm2, ymm3"
+        enabled avx512    && check_x86asm avx512_external    "vmovdqa32 [eax]{k1}{z}, zmm0"
+        enabled avx512icl && check_x86asm avx512icl_external "vpdpwssds zmm31{k1}{z}, zmm29, zmm28"
+        enabled avx2      && check_x86asm avx2_external      "vextracti128 xmm0, ymm0, 0"
+        enabled xop       && check_x86asm xop_external       "vpmacsdd xmm0, xmm1, xmm2, xmm3"
+        enabled fma4      && check_x86asm fma4_external      "vfmaddps ymm0, ymm1, ymm2, ymm3"
         check_x86asm cpunop          "CPU amdnop"
     fi
 
@@ -6260,6 +6265,7 @@ check_func_headers lzo/lzo1x.h lzo1x_999
 check_func_headers mach/mach_time.h mach_absolute_time
 check_func_headers stdlib.h getenv
 check_func_headers sys/stat.h lstat
+check_func_headers sys/auxv.h getauxval
 
 check_func_headers windows.h GetModuleHandle
 check_func_headers windows.h GetProcessAffinityMask
@@ -6315,7 +6321,6 @@ check_headers unistd.h
 check_headers valgrind/valgrind.h
 check_func_headers VideoToolbox/VTCompressionSession.h VTCompressionSessionPrepareToEncodeFrames -framework VideoToolbox
 check_headers windows.h
-check_headers X11/extensions/XvMClib.h
 check_headers asm/types.h
 
 # it seems there are versions of clang in some distros that try to use the
@@ -6393,6 +6398,7 @@ check_func_headers mfapi.h MFCreateAlign
 
 check_type "vdpau/vdpau.h" "VdpPictureInfoHEVC"
 check_type "vdpau/vdpau.h" "VdpPictureInfoVP9"
+check_type "vdpau/vdpau.h" "VdpPictureInfoAV1"
 
 if [ -z "$nvccflags" ]; then
     nvccflags=$nvccflags_default
@@ -6504,7 +6510,9 @@ for func in $COMPLEX_FUNCS; do
 done
 
 # these are off by default, so fail if requested and not available
-enabled avisynth          && require_headers "avisynth/avisynth_c.h"
+enabled avisynth          && { require_headers "avisynth/avisynth_c.h avisynth/avs/version.h" &&
+                               { test_cpp_condition avisynth/avs/version.h "AVS_MAJOR_VER >= 3 && AVS_MINOR_VER >= 7 && AVS_BUGFIX_VER >= 1 || AVS_MAJOR_VER >= 3 && AVS_MINOR_VER > 7 || AVS_MAJOR_VER > 3" ||
+                                 die "ERROR: AviSynth+ header version must be >= 3.7.1"; } }
 enabled cuda_nvcc         && { check_nvcc cuda_nvcc || die "ERROR: failed checking for nvcc."; }
 enabled chromaprint       && require chromaprint chromaprint.h chromaprint_get_version -lchromaprint
 enabled decklink          && { require_headers DeckLinkAPI.h &&
@@ -6514,6 +6522,7 @@ enabled gmp               && require gmp
 enabled gnutls            && require_pkg_config gnutls gnutls gnutls/gnutls.h gnutls_global_init
 enabled jni               && { [ $target_os = "android" ] && check_headers jni.h && enabled pthreads || die "ERROR: jni not found"; }
 enabled ladspa            && require_headers "ladspa.h dlfcn.h"
+enabled lcms2             && require_pkg_config lcms2 "lcms2 >= 2.13" lcms2.h cmsCreateContext
 enabled libaom            && require_pkg_config libaom "aom >= 1.0.0" aom/aom_codec.h aom_codec_version
 enabled libaribb24        && { check_pkg_config libaribb24 "aribb24 > 1.0.3" "aribb24/aribb24.h" arib_instance_new ||
                                { enabled gpl && require_pkg_config libaribb24 aribb24 "aribb24/aribb24.h" arib_instance_new; } ||
@@ -6553,6 +6562,8 @@ enabled libgsm            && { for gsm_h
                                    check_lib libgsm "${gsm_hdr}" gsm_create -lgsm && break;
                                done || die "ERROR: libgsm not found"; }
 enabled libilbc           && require libilbc ilbc.h WebRtcIlbcfix_InitDecode -lilbc $pthreads_extralibs
+enabled libjxl            && require_pkg_config libjxl "libjxl >= 0.7.0" jxl/decode.h JxlDecoderVersion &&
+                             require_pkg_config libjxl_threads "libjxl_threads >= 0.7.0" jxl/thread_parallel_runner.h JxlThreadParallelRunner
 enabled libklvanc         && require libklvanc libklvanc/vanc.h klvanc_context_create -lklvanc
 enabled libkvazaar        && require_pkg_config libkvazaar "kvazaar >= 0.8.1" kvazaar.h kvz_api_get
 enabled liblensfun        && require_pkg_config liblensfun lensfun lensfun.h lf_db_new
@@ -6562,8 +6573,11 @@ enabled liblensfun        && require_pkg
 # Media SDK or Intel Media Server Studio, these don't come with
 # pkg-config support.  Instead, users should make sure that the build
 # can find the libraries and headers through other means.
-enabled libmfx            && { check_pkg_config libmfx libmfx "mfx/mfxvideo.h" MFXInit ||
-                               { require libmfx "mfx/mfxvideo.h" MFXInit "-llibmfx $advapi32_extralibs" && warn "using libmfx without pkg-config"; } }
+enabled libmfx            && { check_pkg_config libmfx "libmfx >= 1.28" "mfx/mfxvideo.h" MFXInit ||
+                               { require libmfx "mfx/mfxvideo.h mfx/mfxdefs.h" MFXInit "-llibmfx $advapi32_extralibs" &&
+                                 { test_cpp_condition mfx/mfxdefs.h "MFX_VERSION >= 1028" || die "ERROR: libmfx version must be >= 1.28"; }  &&
+                                 warn "using libmfx without pkg-config"; } }
+
 if enabled libmfx; then
    check_cc MFX_CODEC_VP9 "mfx/mfxvp9.h mfx/mfxstructures.h" "MFX_CODEC_VP9"
 fi
@@ -6598,7 +6612,7 @@ enabled libplacebo        && require_pkg
 enabled libpulse          && require_pkg_config libpulse libpulse pulse/pulseaudio.h pa_context_new
 enabled librabbitmq       && require_pkg_config librabbitmq "librabbitmq >= 0.7.1" amqp.h amqp_new_connection
 enabled librav1e          && require_pkg_config librav1e "rav1e >= 0.4.0" rav1e.h rav1e_context_new
-enabled librist           && require_pkg_config librist "librist >= 0.2" librist/librist.h rist_receiver_create
+enabled librist           && require_pkg_config librist "librist >= 0.2.7" librist/librist.h rist_receiver_create
 enabled librsvg           && require_pkg_config librsvg librsvg-2.0 librsvg-2.0/librsvg/rsvg.h rsvg_handle_render_cairo
 enabled librtmp           && require_pkg_config librtmp librtmp librtmp/rtmp.h RTMP_Socket
 enabled librubberband     && require_pkg_config librubberband "rubberband >= 1.8.1" rubberband/rubberband-c.h rubberband_new -lstdc++ && append librubberband_extralibs "-lstdc++"
@@ -6611,7 +6625,7 @@ enabled libsoxr           && require lib
 enabled libssh            && require_pkg_config libssh libssh libssh/sftp.h sftp_init
 enabled libspeex          && require_pkg_config libspeex speex speex/speex.h speex_decoder_init
 enabled libsrt            && require_pkg_config libsrt "srt >= 1.3.0" srt/srt.h srt_socket
-enabled libsvtav1         && require_pkg_config libsvtav1 "SvtAv1Enc >= 0.8.4" EbSvtAv1Enc.h svt_av1_enc_init_handle
+enabled libsvtav1         && require_pkg_config libsvtav1 "SvtAv1Enc >= 0.9.0" EbSvtAv1Enc.h svt_av1_enc_init_handle
 enabled libtensorflow     && require libtensorflow tensorflow/c/c_api.h TF_Version -ltensorflow
 enabled libtesseract      && require_pkg_config libtesseract tesseract tesseract/capi.h TessBaseAPICreate
 enabled libtheora         && require libtheora theora/theoraenc.h th_info_init -ltheoraenc -ltheoradec -logg
@@ -6622,7 +6636,7 @@ enabled libtwolame        && require lib
 enabled libuavs3d         && require_pkg_config libuavs3d "uavs3d >= 1.1.41" uavs3d.h uavs3d_decode
 enabled libv4l2           && require_pkg_config libv4l2 libv4l2 libv4l2.h v4l2_ioctl
 enabled libvidstab        && require_pkg_config libvidstab "vidstab >= 0.98" vid.stab/libvidstab.h vsMotionDetectInit
-enabled libvmaf           && require_pkg_config libvmaf "libvmaf >= 1.5.2" libvmaf.h compute_vmaf
+enabled libvmaf           && require_pkg_config libvmaf "libvmaf >= 2.0.0" libvmaf.h vmaf_init
 enabled libvo_amrwbenc    && require libvo_amrwbenc vo-amrwbenc/enc_if.h E_IF_init -lvo-amrwbenc
 enabled libvorbis         && require_pkg_config libvorbis vorbis vorbis/codec.h vorbis_info_init &&
                              require_pkg_config libvorbisenc vorbisenc vorbis/vorbisenc.h vorbis_encode_init
@@ -6652,10 +6666,10 @@ enabled libvpx            && {
 enabled libwebp           && {
     enabled libwebp_encoder      && require_pkg_config libwebp "libwebp >= 0.2.0" webp/encode.h WebPGetEncoderVersion
     enabled libwebp_anim_encoder && check_pkg_config libwebp_anim_encoder "libwebpmux >= 0.4.0" webp/mux.h WebPAnimEncoderOptionsInit; }
-enabled libx264           && { check_pkg_config libx264 x264 "stdint.h x264.h" x264_encoder_encode ||
-                               { require libx264 "stdint.h x264.h" x264_encoder_encode "-lx264 $pthreads_extralibs $libm_extralibs" &&
-                                 warn "using libx264 without pkg-config"; } } &&
-                             require_cpp_condition libx264 x264.h "X264_BUILD >= 118" &&
+enabled libx264           && check_pkg_config libx264 x264 "stdint.h x264.h" x264_encoder_encode &&
+                             require_cpp_condition libx264 x264.h "X264_BUILD >= 118" && {
+                             [ "$toolchain" != "msvc" ] ||
+                             require_cpp_condition libx264 x264.h "X264_BUILD >= 158"; } &&
                              check_cpp_condition libx262 x264.h "X264_MPEG2"
 enabled libx265           && require_pkg_config libx265 x265 x265.h x265_api_get &&
                              require_cpp_condition libx265 x265.h "X265_BUILD >= 70"
@@ -6739,12 +6753,12 @@ fi
 
 if enabled sdl2; then
     SDL2_CONFIG="${cross_prefix}sdl2-config"
-    test_pkg_config sdl2 "sdl2 >= 2.0.1 sdl2 < 2.1.0" SDL_events.h SDL_PollEvent
+    test_pkg_config sdl2 "sdl2 >= 2.0.1 sdl2 < 3.0.0" SDL_events.h SDL_PollEvent
     if disabled sdl2 && "${SDL2_CONFIG}" --version > /dev/null 2>&1; then
         sdl2_cflags=$("${SDL2_CONFIG}" --cflags)
         sdl2_extralibs=$("${SDL2_CONFIG}" --libs)
         test_cpp_condition SDL.h "(SDL_MAJOR_VERSION<<16 | SDL_MINOR_VERSION<<8 | SDL_PATCHLEVEL) >= 0x020001" $sdl2_cflags &&
-        test_cpp_condition SDL.h "(SDL_MAJOR_VERSION<<16 | SDL_MINOR_VERSION<<8 | SDL_PATCHLEVEL) < 0x020100" $sdl2_cflags &&
+        test_cpp_condition SDL.h "(SDL_MAJOR_VERSION<<16 | SDL_MINOR_VERSION<<8 | SDL_PATCHLEVEL) < 0x030000" $sdl2_cflags &&
         check_func_headers SDL_events.h SDL_PollEvent $sdl2_extralibs $sdl2_cflags &&
             enable sdl2
     fi
@@ -6872,6 +6886,9 @@ test_cpp <<EOF && enable uwp && d3d11va_
 #endif
 EOF
 
+# mediafoundation requires linking directly to mfplat if building for uwp target
+enabled uwp && mediafoundation_extralibs="-lmfplat -lmfuuid -lole32 -lstrmiids" || mediafoundation_extralibs="-lmfuuid -lole32 -lstrmiids"
+
 enabled libdrm &&
     check_pkg_config libdrm_getfb2 libdrm "xf86drmMode.h" drmModeGetFB2
 
@@ -6892,6 +6909,7 @@ if enabled vaapi; then
     check_struct "va/va.h" "VADecPictureParameterBufferAV1" bit_depth_idx
     check_type   "va/va.h va/va_vpp.h" "VAProcFilterParameterBufferHDRToneMapping"
     check_struct "va/va.h va/va_vpp.h" "VAProcPipelineCaps" rotation_flags
+    check_struct "va/va.h va/va_vpp.h" "VAProcPipelineCaps" blend_flags
     check_type "va/va.h va/va_enc_hevc.h" "VAEncPictureParameterBufferHEVC"
     check_type "va/va.h va/va_enc_jpeg.h" "VAEncPictureParameterBufferJPEG"
     check_type "va/va.h va/va_enc_vp8.h"  "VAEncPictureParameterBufferVP8"
@@ -7381,15 +7399,12 @@ done
 enabled zlib && add_cppflags -DZLIB_CONST
 
 # conditional library dependencies, in any order
-enabled afir_filter         && prepend avfilter_deps "avcodec"
 enabled amovie_filter       && prepend avfilter_deps "avformat avcodec"
 enabled aresample_filter    && prepend avfilter_deps "swresample"
-enabled atempo_filter       && prepend avfilter_deps "avcodec"
 enabled bm3d_filter         && prepend avfilter_deps "avcodec"
 enabled cover_rect_filter   && prepend avfilter_deps "avformat avcodec"
 enabled ebur128_filter && enabled swresample && prepend avfilter_deps "swresample"
 enabled elbg_filter         && prepend avfilter_deps "avcodec"
-enabled fftfilt_filter      && prepend avfilter_deps "avcodec"
 enabled find_rect_filter    && prepend avfilter_deps "avformat avcodec"
 enabled firequalizer_filter && prepend avfilter_deps "avcodec"
 enabled mcdeint_filter      && prepend avfilter_deps "avcodec"
@@ -7489,6 +7504,7 @@ if enabled x86; then
     echo "AVX enabled               ${avx-no}"
     echo "AVX2 enabled              ${avx2-no}"
     echo "AVX-512 enabled           ${avx512-no}"
+    echo "AVX-512ICL enabled        ${avx512icl-no}"
     echo "XOP enabled               ${xop-no}"
     echo "FMA3 enabled              ${fma3-no}"
     echo "FMA4 enabled              ${fma4-no}"
@@ -7806,17 +7822,30 @@ print_config ARCH_   "$config_files" $AR
 print_config HAVE_   "$config_files" $HAVE_LIST
 print_config CONFIG_ "$config_files" $CONFIG_LIST       \
                                      $CONFIG_EXTRA      \
-                                     $ALL_COMPONENTS    \
 
 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.
 cp_if_changed $TMPH config.h
 touch ffbuild/.config
 
+# Copy config.asm before printing ALL_COMPONENTS; that's not needed in assembly.
 enabled x86asm && cp_if_changed $TMPASM config.asm
 
+# Reopen a new TMPH for config_components.h.
+cat > $TMPH <<EOF
+/* Automatically generated by configure - do not modify! */
+#ifndef FFMPEG_CONFIG_COMPONENTS_H
+#define FFMPEG_CONFIG_COMPONENTS_H
+EOF
+
+print_config CONFIG_ "$config_files" $ALL_COMPONENTS
+
+echo "#endif /* FFMPEG_CONFIG_COMPONENTS_H */" >> $TMPH
+echo "endif # FFMPEG_CONFIG_MAK" >> ffbuild/config.mak
+
+cp_if_changed $TMPH config_components.h
+
 cat > $TMPH <<EOF
 /* Generated by ffmpeg configure */
 #ifndef AVUTIL_AVCONFIG_H
@@ -7867,9 +7896,9 @@ print_enabled_components(){
 }
 
 print_enabled_components libavfilter/filter_list.c AVFilter filter_list $FILTER_LIST
-print_enabled_components libavcodec/codec_list.c AVCodec codec_list $CODEC_LIST
+print_enabled_components libavcodec/codec_list.c FFCodec codec_list $CODEC_LIST
 print_enabled_components libavcodec/parser_list.c AVCodecParser parser_list $PARSER_LIST
-print_enabled_components libavcodec/bsf_list.c AVBitStreamFilter bitstream_filters $BSF_LIST
+print_enabled_components libavcodec/bsf_list.c FFBitStreamFilter bitstream_filters $BSF_LIST
 print_enabled_components libavformat/demuxer_list.c AVInputFormat demuxer_list $DEMUXER_LIST
 print_enabled_components libavformat/muxer_list.c AVOutputFormat muxer_list $MUXER_LIST
 print_enabled_components libavdevice/indev_list.c AVInputFormat indev_list $INDEV_LIST
diff -pruN 7:5.0.1-3/debian/changelog 7:5.1-1/debian/changelog
--- 7:5.0.1-3/debian/changelog	2022-06-23 09:29:43.000000000 +0000
+++ 7:5.1-1/debian/changelog	2022-07-31 18:07:37.000000000 +0000
@@ -1,3 +1,13 @@
+ffmpeg (7:5.1-1) unstable; urgency=medium
+
+  * New upstream version 5.1
+  * debian/control: Remove libxvmc-dev; decoder mpeg_xvmc was removed
+  * debian/patches: Apply some upstream patches from the release/5.1 branch
+  * debian/ffmpeg-doc.install: Fix installation of documentation
+  * debian/*.symbols: Add new symbols
+
+ -- Sebastian Ramacher <sramacher@debian.org>  Sun, 31 Jul 2022 20:07:37 +0200
+
 ffmpeg (7:5.0.1-3) unstable; urgency=medium
 
   * debian/tests: Update encoders for autopkgtests
diff -pruN 7:5.0.1-3/debian/control 7:5.1-1/debian/control
--- 7:5.0.1-3/debian/control	2022-06-23 08:45:55.000000000 +0000
+++ 7:5.1-1/debian/control	2022-07-30 21:45:55.000000000 +0000
@@ -180,8 +180,6 @@ Build-Depends:
  libxv-dev,
 # --enable-libxvid
  libxvidcore-dev,
-# autodetected: decoder 'mpeg_xvmc'; outdev 'xv'
- libxvmc-dev,
 # --enable-libzimg
  libzimg-dev,
 # --enable-libzmq
diff -pruN 7:5.0.1-3/debian/ffmpeg-doc.install 7:5.1-1/debian/ffmpeg-doc.install
--- 7:5.0.1-3/debian/ffmpeg-doc.install	2022-06-23 08:45:55.000000000 +0000
+++ 7:5.1-1/debian/ffmpeg-doc.install	2022-07-31 18:07:03.000000000 +0000
@@ -1,6 +1,6 @@
-debian/standard/doc/doxy/html/*		usr/share/doc/ffmpeg/api
-usr/share/doc/ffmpeg/*.html		usr/share/doc/ffmpeg/manual
-debian/standard/doc/style.min.css	usr/share/doc/ffmpeg/manual
-doc/APIchanges				usr/share/doc/ffmpeg/developer-info
-doc/*.txt				usr/share/doc/ffmpeg/developer-info
+debian/standard/doc/doxy/html/* usr/share/doc/ffmpeg/api
+usr/share/doc/ffmpeg/*.html usr/share/doc/ffmpeg/manual
+usr/share/doc/ffmpeg/*.css usr/share/doc/ffmpeg/manual
+doc/APIchanges usr/share/doc/ffmpeg/developer-info
+doc/*.txt usr/share/doc/ffmpeg/developer-info
 usr/share/man/man3
diff -pruN 7:5.0.1-3/debian/libavcodec59.symbols 7:5.1-1/debian/libavcodec59.symbols
--- 7:5.0.1-3/debian/libavcodec59.symbols	2022-06-23 08:45:55.000000000 +0000
+++ 7:5.1-1/debian/libavcodec59.symbols	2022-07-31 18:07:03.000000000 +0000
@@ -1,7 +1,7 @@
 # SymbolsHelper-Confirmed: 7:5.0 amd64
 libavcodec.so.59 libavcodec59 #MINVER#
 * Build-Depends-Package: libavcodec-dev
- LIBAVCODEC_59@LIBAVCODEC_59 7:5.0
+ LIBAVCODEC_59@LIBAVCODEC_59 7:5.1
  (optional|regex)^avpriv_ 0
  av_ac3_parse_header@LIBAVCODEC_59 7:5.0
  av_adts_header_parse@LIBAVCODEC_59 7:5.0
diff -pruN 7:5.0.1-3/debian/libavdevice59.symbols 7:5.1-1/debian/libavdevice59.symbols
--- 7:5.0.1-3/debian/libavdevice59.symbols	2022-06-23 08:45:55.000000000 +0000
+++ 7:5.1-1/debian/libavdevice59.symbols	2022-07-31 18:07:03.000000000 +0000
@@ -1,7 +1,7 @@
 # SymbolsHelper-Confirmed: 7:5.0 amd64
 libavdevice.so.59 libavdevice59 #MINVER#
 * Build-Depends-Package: libavdevice-dev
- LIBAVDEVICE_59@LIBAVDEVICE_59 7:5.0
+ LIBAVDEVICE_59@LIBAVDEVICE_59 7:5.1
  av_device_capabilities@LIBAVDEVICE_59 7:5.0
  av_device_ffversion@LIBAVDEVICE_59 7:5.0
  av_input_audio_device_next@LIBAVDEVICE_59 7:5.0
diff -pruN 7:5.0.1-3/debian/libavfilter8.symbols 7:5.1-1/debian/libavfilter8.symbols
--- 7:5.0.1-3/debian/libavfilter8.symbols	2022-06-23 08:45:55.000000000 +0000
+++ 7:5.1-1/debian/libavfilter8.symbols	2022-07-31 18:07:09.000000000 +0000
@@ -1,8 +1,9 @@
 # SymbolsHelper-Confirmed: 7:5.0 amd64
 libavfilter.so.8 libavfilter8 #MINVER#
 * Build-Depends-Package: libavfilter-dev
- LIBAVFILTER_8@LIBAVFILTER_8 7:5.0
+ LIBAVFILTER_8@LIBAVFILTER_8 7:5.1
  av_abuffersink_params_alloc@LIBAVFILTER_8 7:5.0
+ av_buffersink_get_ch_layout@LIBAVFILTER_8 7:5.1
  av_buffersink_get_channel_layout@LIBAVFILTER_8 7:5.0
  av_buffersink_get_channels@LIBAVFILTER_8 7:5.0
  av_buffersink_get_format@LIBAVFILTER_8 7:5.0
diff -pruN 7:5.0.1-3/debian/libavformat59.symbols 7:5.1-1/debian/libavformat59.symbols
--- 7:5.0.1-3/debian/libavformat59.symbols	2022-06-23 08:45:55.000000000 +0000
+++ 7:5.1-1/debian/libavformat59.symbols	2022-07-31 18:07:09.000000000 +0000
@@ -2,7 +2,7 @@
 libavformat.so.59 libavformat59 #MINVER#
 * Build-Depends-Package: libavformat-dev
  (optional|regex)^avpriv_ 0
- LIBAVFORMAT_59@LIBAVFORMAT_59 7:5.0
+ LIBAVFORMAT_59@LIBAVFORMAT_59 7:5.1
  av_add_index_entry@LIBAVFORMAT_59 7:5.0
  av_append_packet@LIBAVFORMAT_59 7:5.0
  av_codec_get_id@LIBAVFORMAT_59 7:5.0
@@ -135,6 +135,7 @@ libavformat.so.59 libavformat59 #MINVER#
  avio_seek_time@LIBAVFORMAT_59 7:5.0
  avio_size@LIBAVFORMAT_59 7:5.0
  avio_skip@LIBAVFORMAT_59 7:5.0
+ avio_vprintf@LIBAVFORMAT_59 7:5.1
  avio_w8@LIBAVFORMAT_59 7:5.0
  avio_wb16@LIBAVFORMAT_59 7:5.0
  avio_wb24@LIBAVFORMAT_59 7:5.0
diff -pruN 7:5.0.1-3/debian/libavutil57.symbols 7:5.1-1/debian/libavutil57.symbols
--- 7:5.0.1-3/debian/libavutil57.symbols	2022-06-23 08:45:55.000000000 +0000
+++ 7:5.1-1/debian/libavutil57.symbols	2022-07-31 18:07:09.000000000 +0000
@@ -1,7 +1,7 @@
 # SymbolsHelper-Confirmed: 7:5.0 amd64
 libavutil.so.57 libavutil57 #MINVER#
 * Build-Depends-Package: libavutil-dev
- LIBAVUTIL_57@LIBAVUTIL_57 7:5.0
+ LIBAVUTIL_57@LIBAVUTIL_57 7:5.1
  (optional|regex)^avpriv_ 0
  av_add_i@LIBAVUTIL_57 7:5.0
  av_add_q@LIBAVUTIL_57 7:5.0
@@ -80,7 +80,27 @@ libavutil.so.57 libavutil57 #MINVER#
  av_cast5_crypt@LIBAVUTIL_57 7:5.0
  av_cast5_init@LIBAVUTIL_57 7:5.0
  av_cast5_size@LIBAVUTIL_57 7:5.0
+ av_channel_description@LIBAVUTIL_57 7:5.1
+ av_channel_description_bprint@LIBAVUTIL_57 7:5.1
+ av_channel_from_string@LIBAVUTIL_57 7:5.1
+ av_channel_layout_channel_from_index@LIBAVUTIL_57 7:5.1
+ av_channel_layout_channel_from_string@LIBAVUTIL_57 7:5.1
+ av_channel_layout_check@LIBAVUTIL_57 7:5.1
+ av_channel_layout_compare@LIBAVUTIL_57 7:5.1
+ av_channel_layout_copy@LIBAVUTIL_57 7:5.1
+ av_channel_layout_default@LIBAVUTIL_57 7:5.1
+ av_channel_layout_describe@LIBAVUTIL_57 7:5.1
+ av_channel_layout_describe_bprint@LIBAVUTIL_57 7:5.1
  av_channel_layout_extract_channel@LIBAVUTIL_57 7:5.0
+ av_channel_layout_from_mask@LIBAVUTIL_57 7:5.1
+ av_channel_layout_from_string@LIBAVUTIL_57 7:5.1
+ av_channel_layout_index_from_channel@LIBAVUTIL_57 7:5.1
+ av_channel_layout_index_from_string@LIBAVUTIL_57 7:5.1
+ av_channel_layout_standard@LIBAVUTIL_57 7:5.1
+ av_channel_layout_subset@LIBAVUTIL_57 7:5.1
+ av_channel_layout_uninit@LIBAVUTIL_57 7:5.1
+ av_channel_name@LIBAVUTIL_57 7:5.1
+ av_channel_name_bprint@LIBAVUTIL_57 7:5.1
  av_chroma_location_from_name@LIBAVUTIL_57 7:5.0
  av_chroma_location_name@LIBAVUTIL_57 7:5.0
  av_cmp_i@LIBAVUTIL_57 7:5.0
@@ -102,6 +122,9 @@ libavutil.so.57 libavutil57 #MINVER#
  av_crc@LIBAVUTIL_57 7:5.0
  av_crc_get_table@LIBAVUTIL_57 7:5.0
  av_crc_init@LIBAVUTIL_57 7:5.0
+ av_csp_luma_coeffs_from_avcsp@LIBAVUTIL_57 7:5.1
+ av_csp_primaries_desc_from_id@LIBAVUTIL_57 7:5.1
+ av_csp_primaries_id_from_desc@LIBAVUTIL_57 7:5.1
  av_d2q@LIBAVUTIL_57 7:5.0
  av_d2str@LIBAVUTIL_57 7:5.0
  av_default_get_category@LIBAVUTIL_57 7:5.0
@@ -131,6 +154,8 @@ libavutil.so.57 libavutil57 #MINVER#
  av_downmix_info_update_side_data@LIBAVUTIL_57 7:5.0
  av_dynamic_hdr_plus_alloc@LIBAVUTIL_57 7:5.0
  av_dynamic_hdr_plus_create_side_data@LIBAVUTIL_57 7:5.0
+ av_dynamic_hdr_vivid_alloc@LIBAVUTIL_57 7:5.1
+ av_dynamic_hdr_vivid_create_side_data@LIBAVUTIL_57 7:5.1
  av_dynarray2_add@LIBAVUTIL_57 7:5.0
  av_dynarray_add@LIBAVUTIL_57 7:5.0
  av_dynarray_add_nofree@LIBAVUTIL_57 7:5.0
@@ -153,20 +178,35 @@ libavutil.so.57 libavutil57 #MINVER#
  av_fast_malloc@LIBAVUTIL_57 7:5.0
  av_fast_mallocz@LIBAVUTIL_57 7:5.0
  av_fast_realloc@LIBAVUTIL_57 7:5.0
+ av_fifo_alloc2@LIBAVUTIL_57 7:5.1
  av_fifo_alloc@LIBAVUTIL_57 7:5.0
  av_fifo_alloc_array@LIBAVUTIL_57 7:5.0
+ av_fifo_auto_grow_limit@LIBAVUTIL_57 7:5.1
+ av_fifo_can_read@LIBAVUTIL_57 7:5.1
+ av_fifo_can_write@LIBAVUTIL_57 7:5.1
+ av_fifo_drain2@LIBAVUTIL_57 7:5.1
  av_fifo_drain@LIBAVUTIL_57 7:5.0
+ av_fifo_elem_size@LIBAVUTIL_57 7:5.1
  av_fifo_free@LIBAVUTIL_57 7:5.0
+ av_fifo_freep2@LIBAVUTIL_57 7:5.1
  av_fifo_freep@LIBAVUTIL_57 7:5.0
  av_fifo_generic_peek@LIBAVUTIL_57 7:5.0
  av_fifo_generic_peek_at@LIBAVUTIL_57 7:5.0
  av_fifo_generic_read@LIBAVUTIL_57 7:5.0
  av_fifo_generic_write@LIBAVUTIL_57 7:5.0
+ av_fifo_grow2@LIBAVUTIL_57 7:5.1
  av_fifo_grow@LIBAVUTIL_57 7:5.0
+ av_fifo_peek@LIBAVUTIL_57 7:5.1
+ av_fifo_peek_to_cb@LIBAVUTIL_57 7:5.1
+ av_fifo_read@LIBAVUTIL_57 7:5.1
+ av_fifo_read_to_cb@LIBAVUTIL_57 7:5.1
  av_fifo_realloc2@LIBAVUTIL_57 7:5.0
+ av_fifo_reset2@LIBAVUTIL_57 7:5.1
  av_fifo_reset@LIBAVUTIL_57 7:5.0
  av_fifo_size@LIBAVUTIL_57 7:5.0
  av_fifo_space@LIBAVUTIL_57 7:5.0
+ av_fifo_write@LIBAVUTIL_57 7:5.1
+ av_fifo_write_from_cb@LIBAVUTIL_57 7:5.1
  av_file_map@LIBAVUTIL_57 7:5.0
  av_file_unmap@LIBAVUTIL_57 7:5.0
  av_film_grain_params_alloc@LIBAVUTIL_57 7:5.0
@@ -345,6 +385,7 @@ libavutil.so.57 libavutil57 #MINVER#
  av_opt_freep_ranges@LIBAVUTIL_57 7:5.0
  av_opt_get@LIBAVUTIL_57 7:5.0
  av_opt_get_channel_layout@LIBAVUTIL_57 7:5.0
+ av_opt_get_chlayout@LIBAVUTIL_57 7:5.1
  av_opt_get_dict_val@LIBAVUTIL_57 7:5.0
  av_opt_get_double@LIBAVUTIL_57 7:5.0
  av_opt_get_image_size@LIBAVUTIL_57 7:5.0
@@ -364,6 +405,7 @@ libavutil.so.57 libavutil57 #MINVER#
  av_opt_set@LIBAVUTIL_57 7:5.0
  av_opt_set_bin@LIBAVUTIL_57 7:5.0
  av_opt_set_channel_layout@LIBAVUTIL_57 7:5.0
+ av_opt_set_chlayout@LIBAVUTIL_57 7:5.1
  av_opt_set_defaults2@LIBAVUTIL_57 7:5.0
  av_opt_set_defaults@LIBAVUTIL_57 7:5.0
  av_opt_set_dict2@LIBAVUTIL_57 7:5.0
@@ -501,6 +543,10 @@ libavutil.so.57 libavutil57 #MINVER#
  av_usleep@LIBAVUTIL_57 7:5.0
  av_utf8_decode@LIBAVUTIL_57 7:5.0
  av_util_ffversion@LIBAVUTIL_57 7:5.0
+ av_uuid_parse@LIBAVUTIL_57 7:5.1
+ av_uuid_parse_range@LIBAVUTIL_57 7:5.1
+ av_uuid_unparse@LIBAVUTIL_57 7:5.1
+ av_uuid_urn_parse@LIBAVUTIL_57 7:5.1
  av_vbprintf@LIBAVUTIL_57 7:5.0
  av_version_info@LIBAVUTIL_57 7:5.0
  av_video_enc_params_alloc@LIBAVUTIL_57 7:5.0
diff -pruN 7:5.0.1-3/debian/libpostproc56.symbols 7:5.1-1/debian/libpostproc56.symbols
--- 7:5.0.1-3/debian/libpostproc56.symbols	2022-06-23 08:45:55.000000000 +0000
+++ 7:5.1-1/debian/libpostproc56.symbols	2022-07-31 18:07:03.000000000 +0000
@@ -1,7 +1,7 @@
 # SymbolsHelper-Confirmed: 7:5.0 amd64
 libpostproc.so.56 libpostproc56 #MINVER#
 * Build-Depends-Package: libpostproc-dev
- LIBPOSTPROC_56@LIBPOSTPROC_56 7:5.0
+ LIBPOSTPROC_56@LIBPOSTPROC_56 7:5.1
  postproc_configuration@LIBPOSTPROC_56 7:5.0
  postproc_ffversion@LIBPOSTPROC_56 7:5.0
  postproc_license@LIBPOSTPROC_56 7:5.0
diff -pruN 7:5.0.1-3/debian/libswresample4.symbols 7:5.1-1/debian/libswresample4.symbols
--- 7:5.0.1-3/debian/libswresample4.symbols	2022-06-23 08:45:55.000000000 +0000
+++ 7:5.1-1/debian/libswresample4.symbols	2022-07-31 18:07:09.000000000 +0000
@@ -1,9 +1,11 @@
 # SymbolsHelper-Confirmed: 7:5.0 amd64
 libswresample.so.4 libswresample4 #MINVER#
 * Build-Depends-Package: libswresample-dev
- LIBSWRESAMPLE_4@LIBSWRESAMPLE_4 7:5.0
+ LIBSWRESAMPLE_4@LIBSWRESAMPLE_4 7:5.1
  swr_alloc@LIBSWRESAMPLE_4 7:5.0
+ swr_alloc_set_opts2@LIBSWRESAMPLE_4 7:5.1
  swr_alloc_set_opts@LIBSWRESAMPLE_4 7:5.0
+ swr_build_matrix2@LIBSWRESAMPLE_4 7:5.1
  swr_build_matrix@LIBSWRESAMPLE_4 7:5.0
  swr_close@LIBSWRESAMPLE_4 7:5.0
  swr_config_frame@LIBSWRESAMPLE_4 7:5.0
diff -pruN 7:5.0.1-3/debian/libswscale6.symbols 7:5.1-1/debian/libswscale6.symbols
--- 7:5.0.1-3/debian/libswscale6.symbols	2022-06-23 08:45:55.000000000 +0000
+++ 7:5.1-1/debian/libswscale6.symbols	2022-07-31 18:07:03.000000000 +0000
@@ -1,7 +1,7 @@
 # SymbolsHelper-Confirmed: 7:5.0 amd64
 libswscale.so.6 libswscale6 #MINVER#
 * Build-Depends-Package: libswscale-dev
- LIBSWSCALE_6@LIBSWSCALE_6 7:5.0
+ LIBSWSCALE_6@LIBSWSCALE_6 7:5.1
  sws_allocVec@LIBSWSCALE_6 7:5.0
  sws_alloc_context@LIBSWSCALE_6 7:5.0
  sws_alloc_set_opts@LIBSWSCALE_6 7:5.0
diff -pruN 7:5.0.1-3/debian/patches/0002-configure-properly-require-libx264-if-enabled.patch 7:5.1-1/debian/patches/0002-configure-properly-require-libx264-if-enabled.patch
--- 7:5.0.1-3/debian/patches/0002-configure-properly-require-libx264-if-enabled.patch	1970-01-01 00:00:00.000000000 +0000
+++ 7:5.1-1/debian/patches/0002-configure-properly-require-libx264-if-enabled.patch	2022-07-31 17:14:59.000000000 +0000
@@ -0,0 +1,25 @@
+From: Marvin Scholz <epirat07@gmail.com>
+Date: Sun, 24 Jul 2022 12:11:49 +0200
+Subject: configure: properly require libx264 if enabled
+
+When libx264 can not be found even though it is enabled, it should error
+out properly instead of silently disabling it.
+
+(cherry picked from commit 564d7946de56155d1c42165a8b561fcf5028cbbc)
+---
+ configure | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/configure b/configure
+index 9d6457d..6e012e4 100755
+--- a/configure
++++ b/configure
+@@ -6666,7 +6666,7 @@ enabled libvpx            && {
+ enabled libwebp           && {
+     enabled libwebp_encoder      && require_pkg_config libwebp "libwebp >= 0.2.0" webp/encode.h WebPGetEncoderVersion
+     enabled libwebp_anim_encoder && check_pkg_config libwebp_anim_encoder "libwebpmux >= 0.4.0" webp/mux.h WebPAnimEncoderOptionsInit; }
+-enabled libx264           && check_pkg_config libx264 x264 "stdint.h x264.h" x264_encoder_encode &&
++enabled libx264           && require_pkg_config libx264 x264 "stdint.h x264.h" x264_encoder_encode &&
+                              require_cpp_condition libx264 x264.h "X264_BUILD >= 118" && {
+                              [ "$toolchain" != "msvc" ] ||
+                              require_cpp_condition libx264 x264.h "X264_BUILD >= 158"; } &&
diff -pruN 7:5.0.1-3/debian/patches/0003-avcodec-alac-don-t-fail-if-channels-aren-t-set-durin.patch 7:5.1-1/debian/patches/0003-avcodec-alac-don-t-fail-if-channels-aren-t-set-durin.patch
--- 7:5.0.1-3/debian/patches/0003-avcodec-alac-don-t-fail-if-channels-aren-t-set-durin.patch	1970-01-01 00:00:00.000000000 +0000
+++ 7:5.1-1/debian/patches/0003-avcodec-alac-don-t-fail-if-channels-aren-t-set-durin.patch	2022-07-31 17:14:59.000000000 +0000
@@ -0,0 +1,38 @@
+From: James Almer <jamrial@gmail.com>
+Date: Fri, 29 Jul 2022 18:05:51 -0300
+Subject: avcodec/alac: don't fail if channels aren't set during init() when
+ extradata is valid
+
+The decoder is meant to use it as a fallback if the value in extradata is
+invalid.
+
+Regression since d199099be.
+
+Signed-off-by: James Almer <jamrial@gmail.com>
+---
+ libavcodec/alac.c | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/libavcodec/alac.c b/libavcodec/alac.c
+index 9aaf706..4aab82d 100644
+--- a/libavcodec/alac.c
++++ b/libavcodec/alac.c
+@@ -574,13 +574,15 @@ static av_cold int alac_decode_init(AVCodecContext * avctx)
+     avctx->bits_per_raw_sample = alac->sample_size;
+     avctx->sample_rate         = alac->sample_rate;
+ 
+-    if (alac->channels < 1 || alac->channels > ALAC_MAX_CHANNELS) {
++    if (alac->channels < 1) {
+         av_log(avctx, AV_LOG_WARNING, "Invalid channel count\n");
++        if (avctx->ch_layout.nb_channels < 1)
++            return AVERROR(EINVAL);
+         alac->channels = avctx->ch_layout.nb_channels;
+     }
+-    if (avctx->ch_layout.nb_channels > ALAC_MAX_CHANNELS || avctx->ch_layout.nb_channels <= 0 ) {
++    if (alac->channels > ALAC_MAX_CHANNELS) {
+         avpriv_report_missing_feature(avctx, "Channel count %d",
+-                                      avctx->ch_layout.nb_channels);
++                                      alac->channels);
+         return AVERROR_PATCHWELCOME;
+     }
+     av_channel_layout_uninit(&avctx->ch_layout);
diff -pruN 7:5.0.1-3/debian/patches/0004-fate-imf-Rename-IMF-fate-target.patch 7:5.1-1/debian/patches/0004-fate-imf-Rename-IMF-fate-target.patch
--- 7:5.0.1-3/debian/patches/0004-fate-imf-Rename-IMF-fate-target.patch	1970-01-01 00:00:00.000000000 +0000
+++ 7:5.1-1/debian/patches/0004-fate-imf-Rename-IMF-fate-target.patch	2022-07-31 17:14:59.000000000 +0000
@@ -0,0 +1,26 @@
+From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
+Date: Sun, 24 Jul 2022 21:34:58 +0200
+Subject: fate/imf: Rename IMF fate-target
+
+It conflicts with the name of the test using the testtool
+in libavformat.mak.
+
+Fixes ticket #9841.
+
+Reviewed-by: Pierre-Anthony Lemieux <pal@sandflow.com>
+Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
+(cherry picked from commit 3b923116e5a348945281b8d827074ac8f897464d)
+---
+ tests/fate/imf.mak | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tests/fate/imf.mak b/tests/fate/imf.mak
+index 70a3efd..feb54d1 100644
+--- a/tests/fate/imf.mak
++++ b/tests/fate/imf.mak
+@@ -3,4 +3,4 @@ fate-imf-cpl-with-repeat: CMD = framecrc -f imf -i $(TARGET_SAMPLES)/imf/countdo
+ 
+ FATE_SAMPLES_FFMPEG-$(CONFIG_IMF_DEMUXER) += $(FATE_IMF)
+ 
+-fate-imf: $(FATE_IMF)
++fate-imfdec: $(FATE_IMF)
diff -pruN 7:5.0.1-3/debian/patches/series 7:5.1-1/debian/patches/series
--- 7:5.0.1-3/debian/patches/series	2022-06-23 08:45:55.000000000 +0000
+++ 7:5.1-1/debian/patches/series	2022-07-31 17:14:59.000000000 +0000
@@ -1 +1,4 @@
 0001-avcodec-arm-sbcenc-avoid-callee-preserved-vfp-regist.patch
+0002-configure-properly-require-libx264-if-enabled.patch
+0003-avcodec-alac-don-t-fail-if-channels-aren-t-set-durin.patch
+0004-fate-imf-Rename-IMF-fate-target.patch
diff -pruN 7:5.0.1-3/doc/APIchanges 7:5.1-1/doc/APIchanges
--- 7:5.0.1-3/doc/APIchanges	2022-01-14 18:45:39.000000000 +0000
+++ 7:5.1-1/doc/APIchanges	2022-07-22 17:58:38.000000000 +0000
@@ -14,6 +14,92 @@ libavutil:     2021-04-27
 
 API changes, most recent first:
 
+-------- 8< --------- FFmpeg 5.1 was cut here -------- 8< ---------
+
+2022-06-12 - 7cae3d8b76 - lavf 59.25.100 - avio.h
+  Add avio_vprintf(), similar to avio_printf() but allow to use it
+  from within a function taking a variable argument list as input.
+
+2022-06-12 - ff59ecc4de - lavu 57.27.100 - uuid.h
+  Add UUID handling functions.
+  Add av_uuid_parse(), av_uuid_urn_parse(), av_uuid_parse_range(),
+  av_uuid_parse_range(), av_uuid_equal(), av_uuid_copy(), and av_uuid_nil().
+
+2022-06-01 - d42b410e05 - lavu 57.26.100 - csp.h
+  Add public API for colorspace structs.
+  Add av_csp_luma_coeffs_from_avcsp(), av_csp_primaries_desc_from_id(),
+  and av_csp_primaries_id_from_desc().
+
+2022-05-23 - 4cdc14aa95 - lavu 57.25.100 - avutil.h
+  Deprecate av_fopen_utf8() without replacement.
+
+2022-03-16 - f3a0e2ee2b - all libraries - version_major.h
+  Add lib<name>/version_major.h as new installed headers, which only
+  contain the major version number (and corresponding API deprecation
+  defines).
+
+2022-03-15 - cdba98bb80 - swr 4.5.100 - swresample.h
+  Add swr_alloc_set_opts2() and swr_build_matrix2().
+  Deprecate swr_alloc_set_opts() and swr_build_matrix().
+
+2022-03-15 - cdba98bb80 - lavfi 8.28.100 - avfilter.h buffersink.h buffersrc.h
+  Update AVFilterLink for the new channel layout API: add ch_layout,
+  deprecate channel_layout.
+
+  Update the buffersink filter sink for the new channel layout API:
+  add av_buffersink_get_ch_layout() and the ch_layouts option,
+  deprecate av_buffersink_get_channel_layout() and the channel_layouts option.
+
+  Update AVBufferSrcParameters for the new channel layout API:
+  add ch_layout, deprecate channel_layout.
+
+2022-03-15 - cdba98bb80 - lavf 59.19.100 - avformat.h
+  Add AV_DISPOSITION_NON_DIEGETIC.
+
+2022-03-15 - cdba98bb80 - lavc 59.24.100 - avcodec.h codec_par.h
+  Update AVCodecParameters for the new channel layout API: add ch_layout,
+  deprecate channels/channel_layout.
+
+  Update AVCodecContext for the new channel layout API: add ch_layout,
+  deprecate channels/channel_layout.
+
+  Update AVCodec for the new channel layout API: add ch_layouts,
+  deprecate channel_layouts.
+
+2022-03-15 - cdba98bb80 - lavu 57.24.100 - channel_layout.h frame.h opt.h
+  Add new channel layout API based on the AVChannelLayout struct.
+  Add support for Ambisonic audio.
+  Deprecate previous channel layout API based on uint64 bitmasks.
+
+  Add AV_OPT_TYPE_CHLAYOUT option type, deprecate AV_OPT_TYPE_CHANNEL_LAYOUT.
+  Update AVFrame for the new channel layout API: add ch_layout, deprecate
+  channels/channel_layout.
+
+2022-03-10 - f629ea2e18 - lavu 57.23.100 - cpu.h
+  Add AV_CPU_FLAG_AVX512ICL.
+
+2022-02-07 - a10f1aec1f - lavu 57.21.100 - fifo.h
+  Deprecate AVFifoBuffer and the API around it, namely av_fifo_alloc(),
+  av_fifo_alloc_array(), av_fifo_free(), av_fifo_freep(), av_fifo_reset(),
+  av_fifo_size(), av_fifo_space(), av_fifo_generic_peek_at(),
+  av_fifo_generic_peek(), av_fifo_generic_read(), av_fifo_generic_write(),
+  av_fifo_realloc2(), av_fifo_grow(), av_fifo_drain() and av_fifo_peek2().
+  Users should switch to the AVFifo-API.
+
+2022-02-07 - 7329b22c05 - lavu 57.20.100 - fifo.h
+  Add a new FIFO API, which allows setting a FIFO element size.
+  This API operates on these elements rather than on bytes.
+  Add av_fifo_alloc2(), av_fifo_elem_size(), av_fifo_can_read(),
+  av_fifo_can_write(), av_fifo_grow2(), av_fifo_drain2(), av_fifo_write(),
+  av_fifo_write_from_cb(), av_fifo_read(), av_fifo_read_to_cb(),
+  av_fifo_peek(), av_fifo_peek_to_cb(), av_fifo_drain2(), av_fifo_reset2(),
+  av_fifo_freep2(), av_fifo_auto_grow_limit().
+
+2022-01-26 - af94ab7c7c0 - lavu 57.19.100 - tx.h
+  Add AV_TX_FLOAT_RDFT, AV_TX_DOUBLE_RDFT and AV_TX_INT32_RDFT.
+
+-------- 8< --------- FFmpeg 5.0 was cut here -------- 8< ---------
+
 2022-01-04 - 78dc21b123e - lavu 57.16.100 - frame.h
   Add AV_FRAME_DATA_DOVI_METADATA.
 
@@ -1603,7 +1689,7 @@ API changes, most recent first:
 2014-04-15 - ef818d8 - lavf 55.37.101 - avformat.h
   Add av_format_inject_global_side_data()
 
-2014-04-12 - 4f698be - lavu 52.76.100 - log.h
+2014-04-12 - 4f698be8f - lavu 52.76.100 - log.h
   Add av_log_get_flags()
 
 2014-04-11 - 6db42a2b - lavd 55.12.100 - avdevice.h
diff -pruN 7:5.0.1-3/doc/bitstream_filters.texi 7:5.1-1/doc/bitstream_filters.texi
--- 7:5.0.1-3/doc/bitstream_filters.texi	2022-01-14 18:45:39.000000000 +0000
+++ 7:5.1-1/doc/bitstream_filters.texi	2022-07-22 17:58:38.000000000 +0000
@@ -132,6 +132,36 @@ the header stored in extradata to the ke
 ffmpeg -i INPUT -map 0 -flags:v +global_header -c:v libx264 -bsf:v dump_extra out.ts
 @end example
 
+@section dv_error_marker
+
+Blocks in DV which are marked as damaged are replaced by blocks of the specified color.
+
+@table @option
+@item color
+The color to replace damaged blocks by
+@item sta
+A 16 bit mask which specifies which of the 16 possible error status values are
+to be replaced by colored blocks. 0xFFFE is the default which replaces all non 0
+error status values.
+@table @samp
+@item ok
+No error, no concealment
+@item err
+Error, No concealment
+@item res
+Reserved
+@item notok
+Error or concealment
+@item notres
+Not reserved
+@item Aa, Ba, Ca, Ab, Bb, Cb, A, B, C, a, b, erri, erru
+The specific error status code
+@end table
+see page 44-46 or section 5.5 of
+@url{http://web.archive.org/web/20060927044735/http://www.smpte.org/smpte_store/standards/pdf/s314m.pdf}
+
+@end table
+
 @section eac3_core
 
 Extract the core from a E-AC-3 stream, dropping extra channels.
@@ -217,12 +247,16 @@ Modify metadata embedded in an H.264 str
 Insert or remove AUD NAL units in all access units of the stream.
 
 @table @samp
+@item pass
 @item insert
 @item remove
 @end table
 
+Default is pass.
+
 @item sample_aspect_ratio
 Set the sample aspect ratio of the stream in the VUI parameters.
+See H.264 table E-1.
 
 @item overscan_appropriate_flag
 Set whether the stream is suitable for display using overscan
@@ -281,6 +315,37 @@ insert the string ``hello'' associated w
 @item delete_filler
 Deletes both filler NAL units and filler SEI messages.
 
+@item display_orientation
+Insert, extract or remove Display orientation SEI messages.
+See H.264 section D.1.27 and D.2.27 for syntax and semantics.
+
+@table @samp
+@item pass
+@item insert
+@item remove
+@item extract
+@end table
+
+Default is pass.
+
+Insert mode works in conjunction with @code{rotate} and @code{flip} options.
+Any pre-existing Display orientation messages will be removed in insert or remove mode.
+Extract mode attaches the display matrix to the packet as side data.
+
+@item rotate
+Set rotation in display orientation SEI (anticlockwise angle in degrees).
+Range is -360 to +360. Default is NaN.
+
+@item flip
+Set flip in display orientation SEI.
+
+@table @samp
+@item horizontal
+@item vertical
+@end table
+
+Default is unset.
+
 @item level
 Set the level in the SPS.  Refer to H.264 section A.3 and tables A-1
 to A-5.
@@ -630,6 +695,14 @@ for NTSC frame rate using the @option{fr
 ffmpeg -f lavfi -i sine=r=48000:d=1 -c pcm_s16le -bsf pcm_rechunk=r=30000/1001 -f framecrc -
 @end example
 
+@section pgs_frame_merge
+
+Merge a sequence of PGS Subtitle segments ending with an "end of display set"
+segment into a single packet.
+
+This is required by some containers that support PGS subtitles
+(muxer @code{matroska}).
+
 @section prores_metadata
 
 Modify color property metadata embedded in prores stream.
@@ -736,6 +809,10 @@ It accepts the following parameters:
 @item pts
 @item dts
 Set expressions for PTS, DTS or both.
+@item duration
+Set expression for duration.
+@item time_base
+Set output time base.
 @end table
 
 The expressions are evaluated through the eval API and can contain the following
@@ -759,6 +836,9 @@ The demux timestamp in input.
 @item PTS
 The presentation timestamp in input.
 
+@item DURATION
+The duration in input.
+
 @item STARTDTS
 The DTS of the first packet.
 
@@ -771,15 +851,33 @@ The previous input DTS.
 @item PREV_INPTS
 The previous input PTS.
 
+@item PREV_INDURATION
+The previous input duration.
+
 @item PREV_OUTDTS
 The previous output DTS.
 
 @item PREV_OUTPTS
 The previous output PTS.
 
+@item PREV_OUTDURATION
+The previous output duration.
+
+@item NEXT_DTS
+The next input DTS.
+
+@item NEXT_PTS
+The next input PTS.
+
+@item NEXT_DURATION
+The next input duration.
+
 @item TB
 The timebase of stream packet belongs.
 
+@item TB_OUT
+The output timebase.
+
 @item SR
 The sample rate of stream packet belongs.
 
diff -pruN 7:5.0.1-3/doc/decoders.texi 7:5.1-1/doc/decoders.texi
--- 7:5.0.1-3/doc/decoders.texi	2022-01-14 18:45:39.000000000 +0000
+++ 7:5.1-1/doc/decoders.texi	2022-07-22 17:58:38.000000000 +0000
@@ -126,6 +126,63 @@ Set amount of frame threads to use durin
 
 @end table
 
+@section QSV Decoders
+
+The family of Intel QuickSync Video decoders (VC1, MPEG-2, H.264, HEVC,
+JPEG/MJPEG, VP8, VP9, AV1).
+
+@subsection Common Options
+
+The following options are supported by all qsv decoders.
+
+@table @option
+
+@item @var{async_depth}
+Internal parallelization depth, the higher the value the higher the latency.
+
+@item @var{gpu_copy}
+A GPU-accelerated copy between video and system memory
+@table @samp
+@item default
+@item on
+@item off
+@end table
+
+@end table
+
+@subsection HEVC Options
+Extra options for hevc_qsv.
+
+@table @option
+
+@item @var{load_plugin}
+A user plugin to load in an internal session
+@table @samp
+@item none
+@item hevc_sw
+@item hevc_hw
+@end table
+
+@item @var{load_plugins}
+A :-separate list of hexadecimal plugin UIDs to load in an internal session
+
+@end table
+
+@section v210
+
+Uncompressed 4:2:2 10-bit decoder.
+
+@subsection Options
+
+@table @option
+
+@item custom_stride
+Set the line size of the v210 data in bytes. The default value is 0
+(autodetect). You can use the special -1 value for a strideless v210 as seen in
+BOXX files.
+
+@end table
+
 @c man end VIDEO DECODERS
 
 @chapter Audio Decoders
diff -pruN 7:5.0.1-3/doc/demuxers.texi 7:5.1-1/doc/demuxers.texi
--- 7:5.0.1-3/doc/demuxers.texi	2022-01-14 18:45:39.000000000 +0000
+++ 7:5.1-1/doc/demuxers.texi	2022-07-22 17:58:38.000000000 +0000
@@ -274,6 +274,17 @@ which streams to actually receive.
 Each stream mirrors the @code{id} and @code{bandwidth} properties from the
 @code{<Representation>} as metadata keys named "id" and "variant_bitrate" respectively.
 
+@subsection Options
+
+This demuxer accepts the following option:
+
+@table @option
+
+@item cenc_decryption_key
+16-byte key, in hex, to decrypt files encrypted using ISO Common Encryption (CENC/AES-128 CTR; ISO/IEC 23001-7).
+
+@end table
+
 @section imf
 
 Interoperable Master Format demuxer.
@@ -362,6 +373,9 @@ It accepts the following options:
 @item live_start_index
 segment index to start live streams at (negative values are from the end).
 
+@item prefer_x_start
+prefer to use #EXT-X-START if it's in playlist instead of live_start_index.
+
 @item allowed_extensions
 ',' separated list of file extensions that hls is allowed to access.
 
@@ -775,6 +789,10 @@ disabled). Default value is -1.
 @item merge_pmt_versions
 Re-use existing streams when a PMT's version is updated and elementary
 streams move to different PIDs. Default value is 0.
+
+@item max_packet_size
+Set maximum size, in bytes, of packet emitted by the demuxer. Payloads above this size
+are split across multiple packets. Range is 1 to INT_MAX/2. Default is 204800 bytes.
 @end table
 
 @section mpjpeg
diff -pruN 7:5.0.1-3/doc/Doxyfile 7:5.1-1/doc/Doxyfile
--- 7:5.0.1-3/doc/Doxyfile	2022-04-04 14:40:22.000000000 +0000
+++ 7:5.1-1/doc/Doxyfile	2022-07-22 17:58:38.000000000 +0000
@@ -38,7 +38,7 @@ PROJECT_NAME           = FFmpeg
 # could be handy for archiving the generated documentation or if some version
 # control system is used.
 
-PROJECT_NUMBER         = 5.0.1
+PROJECT_NUMBER         = 5.1
 
 # Using the PROJECT_BRIEF tag one can provide an optional one line description
 # for a project that appears at the top of each page and should give viewer a
diff -pruN 7:5.0.1-3/doc/encoders.texi 7:5.1-1/doc/encoders.texi
--- 7:5.0.1-3/doc/encoders.texi	2022-01-14 18:45:39.000000000 +0000
+++ 7:5.1-1/doc/encoders.texi	2022-07-22 17:58:38.000000000 +0000
@@ -1271,6 +1271,55 @@ follows.
 
 A64 / Commodore 64 multicolor charset encoder. @code{a64_multi5} is extended with 5th color (colram).
 
+@section Cinepak
+
+Cinepak aka CVID encoder.
+Compatible with Windows 3.1 and vintage MacOS.
+
+@subsection Options
+
+@table @option
+@item g @var{integer}
+Keyframe interval.
+A keyframe is inserted at least every @code{-g} frames, sometimes sooner.
+
+@item q:v @var{integer}
+Quality factor. Lower is better. Higher gives lower bitrate.
+The following table lists bitrates when encoding akiyo_cif.y4m for various values of @code{-q:v} with @code{-g 100}:
+
+@table @option
+@item @code{-q:v 1} 1918 kb/s
+@item @code{-q:v 2} 1735 kb/s
+@item @code{-q:v 4} 1500 kb/s
+@item @code{-q:v 10} 1041 kb/s
+@item @code{-q:v 20} 826 kb/s
+@item @code{-q:v 40} 553 kb/s
+@item @code{-q:v 100} 394 kb/s
+@item @code{-q:v 200} 312 kb/s
+@item @code{-q:v 400} 266 kb/s
+@item @code{-q:v 1000} 237 kb/s
+@end table
+
+@item max_extra_cb_iterations @var{integer}
+Max extra codebook recalculation passes, more is better and slower.
+
+@item skip_empty_cb @var{boolean}
+Avoid wasting bytes, ignore vintage MacOS decoder.
+
+@item max_strips @var{integer}
+@itemx min_strips @var{integer}
+The minimum and maximum number of strips to use.
+Wider range sometimes improves quality.
+More strips is generally better quality but costs more bits.
+Fewer strips tend to yield more keyframes.
+Vintage compatible is 1..3.
+
+@item strip_number_adaptivity @var{integer}
+How much number of strips is allowed to change between frames.
+Higher is better but slower.
+
+@end table
+
 @section GIF
 
 GIF image/animation encoder.
@@ -1775,28 +1824,15 @@ This is the default.
 @item high
 @end table
 
-@item rc
-Set the rate control mode to use.
-
-Possible modes:
-@table @option
-@item cqp
-Constant quantizer: use fixed values of qindex (dependent on the frame type)
-throughout the stream.  This mode is the default.
-
-@item vbr
-Variable bitrate: use a target bitrate for the whole stream.
-
-@item cvbr
-Constrained variable bitrate: use a target bitrate for each GOP.
-@end table
-
 @item qmax
 Set the maximum quantizer to use when using a bitrate mode.
 
 @item qmin
 Set the minimum quantizer to use when using a bitrate mode.
 
+@item crf
+Constant rate factor value used in crf rate control mode (0-63).
+
 @item qp
 Set the quantizer used in cqp rate control mode (0-63).
 
@@ -1807,8 +1843,8 @@ Enable scene change detection.
 Set number of frames to look ahead (0-120).
 
 @item preset
-Set the quality-speed tradeoff, in the range 0 to 8.  Higher values are
-faster but lower quality.  Defaults to 8 (highest speed).
+Set the quality-speed tradeoff, in the range 0 to 13.  Higher values are
+faster but lower quality.
 
 @item tile_rows
 Set log2 of the number of rows of tiles to use (0-6).
@@ -1816,6 +1852,45 @@ Set log2 of the number of rows of tiles
 @item tile_columns
 Set log2 of the number of columns of tiles to use (0-4).
 
+@item svtav1-params
+Set SVT-AV1 options using a list of @var{key}=@var{value} pairs separated
+by ":". See the SVT-AV1 encoder user guide for a list of accepted parameters.
+
+@end table
+
+@section libjxl
+
+libjxl JPEG XL encoder wrapper.
+
+Requires the presence of the libjxl headers and library during
+configuration. You need to explicitly configure the build with
+@code{--enable-libjxl}.
+
+@subsection Options
+
+The libjxl wrapper supports the following options:
+
+@table @option
+
+@item distance
+Set the target Butteraugli distance. This is a quality setting: lower
+distance yields higher quality, with distance=1.0 roughly comparable to
+libjpeg Quality 90 for photographic content. Setting distance=0.0 yields
+true lossless encoding. Valid values range between 0.0 and 15.0, and sane
+values rarely exceed 5.0. Setting distance=0.1 usually attains
+transparency for most input. The default is 1.0.
+
+@item effort
+Set the encoding effort used. Higher effort values produce more consistent
+quality and usually produces a better quality/bpp curve, at the cost of
+more CPU time required. Valid values range from 1 to 9, and the default is 7.
+
+@item modular
+Force the encoder to use Modular mode instead of choosing automatically. The
+default is to use VarDCT for lossy encoding and Modular for lossless. VarDCT
+is generally superior to Modular for lossy encoding but does not support
+lossless encoding.
+
 @end table
 
 @section libkvazaar
@@ -2005,8 +2080,11 @@ kilobits/s.
 @item keyint_min (@emph{kf-min-dist})
 
 @item qmin (@emph{min-q})
+Minimum (Best Quality) Quantizer.
 
 @item qmax (@emph{max-q})
+Maximum (Worst Quality) Quantizer.
+Can be changed per-frame.
 
 @item bufsize (@emph{buf-sz}, @emph{buf-optimal-sz})
 Set ratecontrol buffer size (in bits). Note @command{vpxenc}'s options are
@@ -2270,11 +2348,10 @@ and compression tools used, and varies t
 maps to the @var{method} option in libwebp. The valid range is 0 to 6.
 Default is 4.
 
-@item -qscale @var{float}
-For lossy encoding, this controls image quality, 0 to 100. For lossless
-encoding, this controls the effort and time spent at compressing more. The
-default value is 75. Note that for usage via libavcodec, this option is called
-@var{global_quality} and must be multiplied by @var{FF_QP2LAMBDA}.
+@item -quality @var{float}
+For lossy encoding, this controls image quality. For lossless encoding, this
+controls the effort and time spent in compression.
+Range is 0 to 100. Default is 75.
 
 @item -preset @var{type}
 Configuration preset. This does some automatic settings based on the general
@@ -3123,12 +3200,13 @@ Setting a higher @option{bits_per_mb} li
 For the fastest encoding speed set the @option{qscale} parameter (4 is the
 recommended value) and do not set a size constraint.
 
-@section QSV encoders
+@section QSV Encoders
 
-The family of Intel QuickSync Video encoders (MPEG-2, H.264, HEVC, JPEG/MJPEG and VP9)
+The family of Intel QuickSync Video encoders (MPEG-2, H.264, HEVC, JPEG/MJPEG
+and VP9)
 
+@subsection Ratecontrol Method
 The ratecontrol method is selected as follows:
-
 @itemize @bullet
 @item
 When @option{global_quality} is specified, a quality-based mode is used.
@@ -3176,6 +3254,7 @@ Note that depending on your system, a di
 may be selected by the encoder. Set the verbosity level to @var{verbose} or
 higher to see the actual settings used by the QSV runtime.
 
+@subsection Global Options -> MSDK Options
 Additional libavcodec global options are mapped to MSDK options as follows:
 
 @itemize
@@ -3212,6 +3291,389 @@ encoder use CAVLC instead of CABAC.
 
 @end itemize
 
+@subsection Common Options
+Following options are used by all qsv encoders.
+
+@table @option
+@item @var{async_depth}
+Specifies how many asynchronous operations an application performs
+before the application explicitly synchronizes the result. If zero,
+the value is not specified.
+
+@item @var{avbr_accuracy}
+Accuracy of the AVBR ratecontrol (unit of tenth of percent).
+
+@item @var{avbr_convergence}
+Convergence of the AVBR ratecontrol (unit of 100 frames)
+
+The parameters @var{avbr_accuracy} and @var{avbr_convergence} are for the
+average variable bitrate control (AVBR) algorithm.
+The algorithm focuses on overall encoding quality while meeting the specified
+bitrate, @var{target_bitrate}, within the accuracy range @var{avbr_accuracy},
+after a @var{avbr_Convergence} period. This method does not follow HRD and the
+instant bitrate is not capped or padded.
+
+@item @var{preset}
+This option itemizes a range of choices from veryfast (best speed) to veryslow
+(best quality).
+@table @samp
+@item veryfast
+@item faster
+@item fast
+@item medium
+@item slow
+@item slower
+@item veryslow
+@end table
+
+@item @var{forced_idr}
+Forcing I frames as IDR frames.
+
+@item @var{low_power}
+For encoders set this flag to ON to reduce power consumption and GPU usage.
+@end table
+
+@subsection Runtime Options
+Following options can be used durning qsv encoding.
+
+@table @option
+@item @var{qsv_config_qp}
+Supported in h264_qsv and hevc_qsv.
+This option can be set in per-frame metadata. QP parameter can be dynamically
+changed when encoding in CQP mode.
+@end table
+
+@subsection H264 options
+These options are used by h264_qsv
+
+@table @option
+@item @var{extbrc}
+Extended bitrate control.
+
+@item @var{recovery_point_sei}
+Set this flag to insert the recovery point SEI message at the beginning of every
+intra refresh cycle.
+
+@item @var{rdo}
+Enable rate distortion optimization.
+
+@item @var{max_frame_size}
+Maximum encoded frame size in bytes.
+
+@item @var{max_frame_size_i}
+Maximum encoded frame size for I frames in bytes. If this value is set as larger
+than zero, then for I frames the value set by max_frame_size is ignored.
+
+@item @var{max_frame_size_p}
+Maximum encoded frame size for P frames in bytes. If this value is set as larger
+than zero, then for P frames the value set by max_frame_size is ignored.
+
+@item @var{max_slice_size}
+Maximum encoded slice size in bytes.
+
+@item @var{bitrate_limit}
+Toggle bitrate limitations.
+Modifies bitrate to be in the range imposed by the QSV encoder. Setting this
+flag off may lead to violation of HRD conformance. Mind that specifying bitrate
+below the QSV encoder range might significantly affect quality. If on this
+option takes effect in non CQP modes: if bitrate is not in the range imposed
+by the QSV encoder, it will be changed to be in the range.
+
+@item @var{mbbrc}
+Setting this flag enables macroblock level bitrate control that generally
+improves subjective visual quality. Enabling this flag may have negative impact
+on performance and objective visual quality metric.
+
+@item @var{low_delay_brc}
+Setting this flag turns on or off LowDelayBRC feautre in qsv plugin, which provides
+more accurate bitrate control to minimize the variance of bitstream size frame
+by frame. Value: -1-default 0-off 1-on
+
+@item @var{adaptive_i}
+This flag controls insertion of I frames by the QSV encoder. Turn ON this flag
+to allow changing of frame type from P and B to I.
+
+@item @var{adaptive_b}
+This flag controls changing of frame type from B to P.
+
+@item @var{p_strategy}
+Enable P-pyramid: 0-default 1-simple 2-pyramid(bf need to be set to 0).
+
+@item @var{b_strategy}
+This option controls usage of B frames as reference.
+
+@item @var{dblk_idc}
+This option disable deblocking. It has value in range 0~2.
+
+@item @var{cavlc}
+If set, CAVLC is used; if unset, CABAC is used for encoding.
+
+@item @var{vcm}
+Video conferencing mode, please see ratecontrol method.
+
+@item @var{idr_interval}
+Distance (in I-frames) between IDR frames.
+
+@item @var{pic_timing_sei}
+Insert picture timing SEI with pic_struct_syntax element.
+
+@item @var{single_sei_nal_unit}
+Put all the SEI messages into one NALU.
+
+@item @var{max_dec_frame_buffering}
+Maximum number of frames buffered in the DPB.
+
+@item @var{look_ahead}
+Use VBR algorithm with look ahead.
+
+@item @var{look_ahead_depth}
+Depth of look ahead in number frames.
+
+@item @var{look_ahead_downsampling}
+Downscaling factor for the frames saved for the lookahead analysis.
+@table @samp
+@item unknown
+@item auto
+@item off
+@item 2x
+@item 4x
+@end table
+
+@item @var{int_ref_type}
+Specifies intra refresh type. The major goal of intra refresh is improvement of
+error resilience without significant impact on encoded bitstream size caused by
+I frames. The SDK encoder achieves this by encoding part of each frame in
+refresh cycle using intra MBs. @var{none} means no refresh. @var{vertical} means
+vertical refresh, by column of MBs. To enable intra refresh, B frame should be
+set to 0.
+
+@item @var{int_ref_cycle_size}
+Specifies number of pictures within refresh cycle starting from 2. 0 and 1 are
+invalid values.
+
+@item @var{int_ref_qp_delta}
+Specifies QP difference for inserted intra MBs. This is signed value in
+[-51, 51] range if target encoding bit-depth for luma samples is 8 and this
+range is [-63, 63] for 10 bit-depth or [-75, 75] for 12 bit-depth respectively.
+
+@item @var{int_ref_cycle_dist}
+Distance between the beginnings of the intra-refresh cycles in frames.
+
+@item @var{profile}
+@table @samp
+@item unknown
+@item baseline
+@item main
+@item high
+@end table
+
+@item @var{a53cc}
+Use A53 Closed Captions (if available).
+
+@item @var{aud}
+Insert the Access Unit Delimiter NAL.
+
+@item @var{mfmode}
+Multi-Frame Mode.
+@table @samp
+@item off
+@item auto
+@end table
+
+@item @var{repeat_pps}
+Repeat pps for every frame.
+
+@item @var{max_qp_i}
+Maximum video quantizer scale for I frame.
+
+@item @var{min_qp_i}
+Minimum video quantizer scale for I frame.
+
+@item @var{max_qp_p}
+Maximum video quantizer scale for P frame.
+
+@item @var{min_qp_p}
+Minimum video quantizer scale for P frame.
+
+@item @var{max_qp_b}
+Maximum video quantizer scale for B frame.
+
+@item @var{min_qp_b}
+Minimum video quantizer scale for B frame.
+@end table
+
+@subsection HEVC Options
+These options are used by hevc_qsv
+
+@table @option
+@item @var{extbrc}
+Extended bitrate control.
+
+@item @var{recovery_point_sei}
+Set this flag to insert the recovery point SEI message at the beginning of every
+intra refresh cycle.
+
+@item @var{rdo}
+Enable rate distortion optimization.
+
+@item @var{max_frame_size}
+Maximum encoded frame size in bytes.
+
+@item @var{max_frame_size_i}
+Maximum encoded frame size for I frames in bytes. If this value is set as larger
+than zero, then for I frames the value set by max_frame_size is ignored.
+
+@item @var{max_frame_size_p}
+Maximum encoded frame size for P frames in bytes. If this value is set as larger
+than zero, then for P frames the value set by max_frame_size is ignored.
+
+@item @var{max_slice_size}
+Maximum encoded slice size in bytes.
+
+@item @var{mbbrc}
+Setting this flag enables macroblock level bitrate control that generally
+improves subjective visual quality. Enabling this flag may have negative impact
+on performance and objective visual quality metric.
+
+@item @var{low_delay_brc}
+Setting this flag turns on or off LowDelayBRC feautre in qsv plugin, which provides
+more accurate bitrate control to minimize the variance of bitstream size frame
+by frame. Value: -1-default 0-off 1-on
+
+@item @var{p_strategy}
+Enable P-pyramid: 0-default 1-simple 2-pyramid(bf need to be set to 0).
+
+@item @var{b_strategy}
+This option controls usage of B frames as reference.
+
+@item @var{dblk_idc}
+This option disable deblocking. It has value in range 0~2.
+
+@item @var{idr_interval}
+Distance (in I-frames) between IDR frames.
+@table @samp
+@item begin_only
+Output an IDR-frame only at the beginning of the stream.
+@end table
+
+@item @var{load_plugin}
+A user plugin to load in an internal session.
+@table @samp
+@item none
+@item hevc_sw
+@item hevc_hw
+@end table
+
+@item @var{load_plugins}
+A :-separate list of hexadecimal plugin UIDs to load in
+an internal session.
+
+@item @var{look_ahead_depth}
+Depth of look ahead in number frames, available when extbrc option is enabled.
+
+@item @var{profile}
+Set the encoding profile (scc requires libmfx >= 1.32).
+
+@table @samp
+@item unknown
+@item main
+@item main10
+@item mainsp
+@item rext
+@item scc
+@end table
+
+@item @var{gpb}
+1: GPB (generalized P/B frame)
+
+0: regular P frame.
+
+@item @var{tile_cols}
+Number of columns for tiled encoding.
+
+@item @var{tile_rows}
+Number of rows for tiled encoding.
+
+@item @var{aud}
+Insert the Access Unit Delimiter NAL.
+
+@item @var{pic_timing_sei}
+Insert picture timing SEI with pic_struct_syntax element.
+
+@item @var{transform_skip}
+Turn this option ON to enable transformskip. It is supported on platform equal
+or newer than ICL.
+
+@item @var{int_ref_type}
+Specifies intra refresh type. The major goal of intra refresh is improvement of
+error resilience without significant impact on encoded bitstream size caused by
+I frames. The SDK encoder achieves this by encoding part of each frame in
+refresh cycle using intra MBs. @var{none} means no refresh. @var{vertical} means
+vertical refresh, by column of MBs. To enable intra refresh, B frame should be
+set to 0.
+
+@item @var{int_ref_cycle_size}
+Specifies number of pictures within refresh cycle starting from 2. 0 and 1 are
+invalid values.
+
+@item @var{int_ref_qp_delta}
+Specifies QP difference for inserted intra MBs. This is signed value in
+[-51, 51] range if target encoding bit-depth for luma samples is 8 and this
+range is [-63, 63] for 10 bit-depth or [-75, 75] for 12 bit-depth respectively.
+
+@item @var{int_ref_cycle_dist}
+Distance between the beginnings of the intra-refresh cycles in frames.
+
+@item @var{max_qp_i}
+Maximum video quantizer scale for I frame.
+
+@item @var{min_qp_i}
+Minimum video quantizer scale for I frame.
+
+@item @var{max_qp_p}
+Maximum video quantizer scale for P frame.
+
+@item @var{min_qp_p}
+Minimum video quantizer scale for P frame.
+
+@item @var{max_qp_b}
+Maximum video quantizer scale for B frame.
+
+@item @var{min_qp_b}
+Minimum video quantizer scale for B frame.
+@end table
+
+@subsection MPEG2 Options
+These options are used by mpeg2_qsv
+@table @option
+@item @var{profile}
+@table @samp
+@item unknown
+@item simple
+@item main
+@item high
+@end table
+@end table
+
+@subsection VP9 Options
+These options are used by vp9_qsv
+@table @option
+@item @var{profile}
+@table @samp
+@item unknown
+@item profile0
+@item profile1
+@item profile2
+@item profile3
+@end table
+
+@item @var{tile_cols}
+Number of columns for tiled encoding (requires libmfx >= 1.29).
+
+@item @var{tile_rows}
+Number of rows for tiled encoding (requires libmfx  >= 1.29).
+@end table
+
 @section snow
 
 @subsection Options
@@ -3292,6 +3754,17 @@ will refer only to P- or I-frames.  When
 of B-frames will be present, frames in each layer only referring to frames in
 higher layers.
 
+@item async_depth
+Maximum processing parallelism. Increase this to improve single channel
+performance. This option doesn't work if driver doesn't implement vaSyncBuffer
+function. Please make sure there are enough hw_frames allocated if a large
+number of async_depth is used.
+
+@item max_frame_size
+Set the allowed max size in bytes for each frame. If the frame size exceeds
+the limitation, encoder will adjust the QP value to control the frame size.
+Invalid in CQP rate control mode.
+
 @item rc_mode
 Set the rate control mode to use.  A given driver may only support a subset of
 modes.
@@ -3435,6 +3908,22 @@ required to produce a stream usable with
 
 @end table
 
+@section vbn
+
+Vizrt Binary Image encoder.
+
+This format is used by the broadcast vendor Vizrt for quick texture streaming.
+Advanced features of the format such as LZW compression of texture data or
+generation of mipmaps are not supported.
+
+@subsection Options
+
+@table @option
+@item format @var{string}
+Sets the texture compression used by the VBN file. Can be @var{dxt1},
+@var{dxt5} or @var{raw}. Default is @var{dxt5}.
+@end table
+
 @section vc2
 
 SMPTE VC-2 (previously BBC Dirac Pro). This codec was primarily aimed at
diff -pruN 7:5.0.1-3/doc/examples/decode_audio.c 7:5.1-1/doc/examples/decode_audio.c
--- 7:5.0.1-3/doc/examples/decode_audio.c	2021-10-21 17:06:35.000000000 +0000
+++ 7:5.1-1/doc/examples/decode_audio.c	2022-07-22 17:58:38.000000000 +0000
@@ -97,7 +97,7 @@ static void decode(AVCodecContext *dec_c
             exit(1);
         }
         for (i = 0; i < frame->nb_samples; i++)
-            for (ch = 0; ch < dec_ctx->channels; ch++)
+            for (ch = 0; ch < dec_ctx->ch_layout.nb_channels; ch++)
                 fwrite(frame->data[ch] + data_size*i, 1, data_size, outfile);
     }
 }
@@ -215,7 +215,7 @@ int main(int argc, char **argv)
         sfmt = av_get_packed_sample_fmt(sfmt);
     }
 
-    n_channels = c->channels;
+    n_channels = c->ch_layout.nb_channels;
     if ((ret = get_format_from_sample_fmt(&fmt, sfmt)) < 0)
         goto end;
 
diff -pruN 7:5.0.1-3/doc/examples/decode_video.c 7:5.1-1/doc/examples/decode_video.c
--- 7:5.0.1-3/doc/examples/decode_video.c	2021-10-24 20:47:07.000000000 +0000
+++ 7:5.1-1/doc/examples/decode_video.c	2022-07-22 17:58:38.000000000 +0000
@@ -92,6 +92,7 @@ int main(int argc, char **argv)
     uint8_t *data;
     size_t   data_size;
     int ret;
+    int eof;
     AVPacket *pkt;
 
     if (argc <= 2) {
@@ -150,15 +151,16 @@ int main(int argc, char **argv)
         exit(1);
     }
 
-    while (!feof(f)) {
+    do {
         /* read raw data from the input file */
         data_size = fread(inbuf, 1, INBUF_SIZE, f);
-        if (!data_size)
+        if (ferror(f))
             break;
+        eof = !data_size;
 
         /* use the parser to split the data into frames */
         data = inbuf;
-        while (data_size > 0) {
+        while (data_size > 0 || eof) {
             ret = av_parser_parse2(parser, c, &pkt->data, &pkt->size,
                                    data, data_size, AV_NOPTS_VALUE, AV_NOPTS_VALUE, 0);
             if (ret < 0) {
@@ -170,8 +172,10 @@ int main(int argc, char **argv)
 
             if (pkt->size)
                 decode(c, frame, pkt, outfilename);
+            else if (eof)
+                break;
         }
-    }
+    } while (!eof);
 
     /* flush the decoder */
     decode(c, frame, NULL, outfilename);
diff -pruN 7:5.0.1-3/doc/examples/demuxing_decoding.c 7:5.1-1/doc/examples/demuxing_decoding.c
--- 7:5.0.1-3/doc/examples/demuxing_decoding.c	2022-01-14 18:45:39.000000000 +0000
+++ 7:5.1-1/doc/examples/demuxing_decoding.c	2022-07-22 17:58:38.000000000 +0000
@@ -345,7 +345,7 @@ int main (int argc, char **argv)
 
     if (audio_stream) {
         enum AVSampleFormat sfmt = audio_dec_ctx->sample_fmt;
-        int n_channels = audio_dec_ctx->channels;
+        int n_channels = audio_dec_ctx->ch_layout.nb_channels;
         const char *fmt;
 
         if (av_sample_fmt_is_planar(sfmt)) {
diff -pruN 7:5.0.1-3/doc/examples/encode_audio.c 7:5.1-1/doc/examples/encode_audio.c
--- 7:5.0.1-3/doc/examples/encode_audio.c	2021-10-21 17:06:35.000000000 +0000
+++ 7:5.1-1/doc/examples/encode_audio.c	2022-07-22 17:58:38.000000000 +0000
@@ -70,26 +70,25 @@ static int select_sample_rate(const AVCo
 }
 
 /* select layout with the highest channel count */
-static int select_channel_layout(const AVCodec *codec)
+static int select_channel_layout(const AVCodec *codec, AVChannelLayout *dst)
 {
-    const uint64_t *p;
-    uint64_t best_ch_layout = 0;
+    const AVChannelLayout *p, *best_ch_layout;
     int best_nb_channels   = 0;
 
-    if (!codec->channel_layouts)
-        return AV_CH_LAYOUT_STEREO;
+    if (!codec->ch_layouts)
+        return av_channel_layout_copy(dst, &(AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO);
 
-    p = codec->channel_layouts;
-    while (*p) {
-        int nb_channels = av_get_channel_layout_nb_channels(*p);
+    p = codec->ch_layouts;
+    while (p->nb_channels) {
+        int nb_channels = p->nb_channels;
 
         if (nb_channels > best_nb_channels) {
-            best_ch_layout    = *p;
+            best_ch_layout   = p;
             best_nb_channels = nb_channels;
         }
         p++;
     }
-    return best_ch_layout;
+    return av_channel_layout_copy(dst, best_ch_layout);
 }
 
 static void encode(AVCodecContext *ctx, AVFrame *frame, AVPacket *pkt,
@@ -164,8 +163,9 @@ int main(int argc, char **argv)
 
     /* select other audio parameters supported by the encoder */
     c->sample_rate    = select_sample_rate(codec);
-    c->channel_layout = select_channel_layout(codec);
-    c->channels       = av_get_channel_layout_nb_channels(c->channel_layout);
+    ret = select_channel_layout(codec, &c->ch_layout);
+    if (ret < 0)
+        exit(1);
 
     /* open it */
     if (avcodec_open2(c, codec, NULL) < 0) {
@@ -195,7 +195,9 @@ int main(int argc, char **argv)
 
     frame->nb_samples     = c->frame_size;
     frame->format         = c->sample_fmt;
-    frame->channel_layout = c->channel_layout;
+    ret = av_channel_layout_copy(&frame->ch_layout, &c->ch_layout);
+    if (ret < 0)
+        exit(1);
 
     /* allocate the data buffers */
     ret = av_frame_get_buffer(frame, 0);
@@ -218,7 +220,7 @@ int main(int argc, char **argv)
         for (j = 0; j < c->frame_size; j++) {
             samples[2*j] = (int)(sin(t) * 10000);
 
-            for (k = 1; k < c->channels; k++)
+            for (k = 1; k < c->ch_layout.nb_channels; k++)
                 samples[2*j + k] = samples[2*j];
             t += tincr;
         }
diff -pruN 7:5.0.1-3/doc/examples/filter_audio.c 7:5.1-1/doc/examples/filter_audio.c
--- 7:5.0.1-3/doc/examples/filter_audio.c	2021-10-21 17:06:35.000000000 +0000
+++ 7:5.1-1/doc/examples/filter_audio.c	2022-07-22 17:58:38.000000000 +0000
@@ -55,7 +55,7 @@
 
 #define INPUT_SAMPLERATE     48000
 #define INPUT_FORMAT         AV_SAMPLE_FMT_FLTP
-#define INPUT_CHANNEL_LAYOUT AV_CH_LAYOUT_5POINT0
+#define INPUT_CHANNEL_LAYOUT (AVChannelLayout)AV_CHANNEL_LAYOUT_5POINT0
 
 #define VOLUME_VAL 0.90
 
@@ -100,7 +100,7 @@ static int init_filter_graph(AVFilterGra
     }
 
     /* Set the filter options through the AVOptions API. */
-    av_get_channel_layout_string(ch_layout, sizeof(ch_layout), 0, INPUT_CHANNEL_LAYOUT);
+    av_channel_layout_describe(&INPUT_CHANNEL_LAYOUT, ch_layout, sizeof(ch_layout));
     av_opt_set    (abuffer_ctx, "channel_layout", ch_layout,                            AV_OPT_SEARCH_CHILDREN);
     av_opt_set    (abuffer_ctx, "sample_fmt",     av_get_sample_fmt_name(INPUT_FORMAT), AV_OPT_SEARCH_CHILDREN);
     av_opt_set_q  (abuffer_ctx, "time_base",      (AVRational){ 1, INPUT_SAMPLERATE },  AV_OPT_SEARCH_CHILDREN);
@@ -154,9 +154,8 @@ static int init_filter_graph(AVFilterGra
     /* A third way of passing the options is in a string of the form
      * key1=value1:key2=value2.... */
     snprintf(options_str, sizeof(options_str),
-             "sample_fmts=%s:sample_rates=%d:channel_layouts=0x%"PRIx64,
-             av_get_sample_fmt_name(AV_SAMPLE_FMT_S16), 44100,
-             (uint64_t)AV_CH_LAYOUT_STEREO);
+             "sample_fmts=%s:sample_rates=%d:channel_layouts=stereo",
+             av_get_sample_fmt_name(AV_SAMPLE_FMT_S16), 44100);
     err = avfilter_init_str(aformat_ctx, options_str);
     if (err < 0) {
         av_log(NULL, AV_LOG_ERROR, "Could not initialize the aformat filter.\n");
@@ -215,7 +214,7 @@ static int init_filter_graph(AVFilterGra
 static int process_output(struct AVMD5 *md5, AVFrame *frame)
 {
     int planar     = av_sample_fmt_is_planar(frame->format);
-    int channels   = av_get_channel_layout_nb_channels(frame->channel_layout);
+    int channels   = frame->ch_layout.nb_channels;
     int planes     = planar ? channels : 1;
     int bps        = av_get_bytes_per_sample(frame->format);
     int plane_size = bps * frame->nb_samples * (planar ? 1 : channels);
@@ -248,7 +247,7 @@ static int get_input(AVFrame *frame, int
     /* Set up the frame properties and allocate the buffer for the data. */
     frame->sample_rate    = INPUT_SAMPLERATE;
     frame->format         = INPUT_FORMAT;
-    frame->channel_layout = INPUT_CHANNEL_LAYOUT;
+    av_channel_layout_copy(&frame->ch_layout, &INPUT_CHANNEL_LAYOUT);
     frame->nb_samples     = FRAME_SIZE;
     frame->pts            = frame_num * FRAME_SIZE;
 
diff -pruN 7:5.0.1-3/doc/examples/filtering_audio.c 7:5.1-1/doc/examples/filtering_audio.c
--- 7:5.0.1-3/doc/examples/filtering_audio.c	2022-01-14 18:45:39.000000000 +0000
+++ 7:5.1-1/doc/examples/filtering_audio.c	2022-07-22 17:58:38.000000000 +0000
@@ -94,7 +94,6 @@ static int init_filters(const char *filt
     AVFilterInOut *outputs = avfilter_inout_alloc();
     AVFilterInOut *inputs  = avfilter_inout_alloc();
     static const enum AVSampleFormat out_sample_fmts[] = { AV_SAMPLE_FMT_S16, -1 };
-    static const int64_t out_channel_layouts[] = { AV_CH_LAYOUT_MONO, -1 };
     static const int out_sample_rates[] = { 8000, -1 };
     const AVFilterLink *outlink;
     AVRational time_base = fmt_ctx->streams[audio_stream_index]->time_base;
@@ -106,12 +105,13 @@ static int init_filters(const char *filt
     }
 
     /* buffer audio source: the decoded frames from the decoder will be inserted here. */
-    if (!dec_ctx->channel_layout)
-        dec_ctx->channel_layout = av_get_default_channel_layout(dec_ctx->channels);
-    snprintf(args, sizeof(args),
-            "time_base=%d/%d:sample_rate=%d:sample_fmt=%s:channel_layout=0x%"PRIx64,
+    if (dec_ctx->ch_layout.order == AV_CHANNEL_ORDER_UNSPEC)
+        av_channel_layout_default(&dec_ctx->ch_layout, dec_ctx->ch_layout.nb_channels);
+    ret = snprintf(args, sizeof(args),
+            "time_base=%d/%d:sample_rate=%d:sample_fmt=%s:channel_layout=",
              time_base.num, time_base.den, dec_ctx->sample_rate,
-             av_get_sample_fmt_name(dec_ctx->sample_fmt), dec_ctx->channel_layout);
+             av_get_sample_fmt_name(dec_ctx->sample_fmt));
+    av_channel_layout_describe(&dec_ctx->ch_layout, args + ret, sizeof(args) - ret);
     ret = avfilter_graph_create_filter(&buffersrc_ctx, abuffersrc, "in",
                                        args, NULL, filter_graph);
     if (ret < 0) {
@@ -134,7 +134,7 @@ static int init_filters(const char *filt
         goto end;
     }
 
-    ret = av_opt_set_int_list(buffersink_ctx, "channel_layouts", out_channel_layouts, -1,
+    ret = av_opt_set(buffersink_ctx, "ch_layouts", "mono",
                               AV_OPT_SEARCH_CHILDREN);
     if (ret < 0) {
         av_log(NULL, AV_LOG_ERROR, "Cannot set output channel layout\n");
@@ -185,7 +185,7 @@ static int init_filters(const char *filt
     /* Print summary of the sink buffer
      * Note: args buffer is reused to store channel layout string */
     outlink = buffersink_ctx->inputs[0];
-    av_get_channel_layout_string(args, sizeof(args), -1, outlink->channel_layout);
+    av_channel_layout_describe(&outlink->ch_layout, args, sizeof(args));
     av_log(NULL, AV_LOG_INFO, "Output: srate:%dHz fmt:%s chlayout:%s\n",
            (int)outlink->sample_rate,
            (char *)av_x_if_null(av_get_sample_fmt_name(outlink->format), "?"),
@@ -200,7 +200,7 @@ end:
 
 static void print_frame(const AVFrame *frame)
 {
-    const int n = frame->nb_samples * av_get_channel_layout_nb_channels(frame->channel_layout);
+    const int n = frame->nb_samples * frame->ch_layout.nb_channels;
     const uint16_t *p     = (uint16_t*)frame->data[0];
     const uint16_t *p_end = p + n;
 
diff -pruN 7:5.0.1-3/doc/examples/muxing.c 7:5.1-1/doc/examples/muxing.c
--- 7:5.0.1-3/doc/examples/muxing.c	2022-01-14 18:45:39.000000000 +0000
+++ 7:5.1-1/doc/examples/muxing.c	2022-07-22 17:58:38.000000000 +0000
@@ -170,16 +170,7 @@ static void add_stream(OutputStream *ost
                     c->sample_rate = 44100;
             }
         }
-        c->channels        = av_get_channel_layout_nb_channels(c->channel_layout);
-        c->channel_layout = AV_CH_LAYOUT_STEREO;
-        if ((*codec)->channel_layouts) {
-            c->channel_layout = (*codec)->channel_layouts[0];
-            for (i = 0; (*codec)->channel_layouts[i]; i++) {
-                if ((*codec)->channel_layouts[i] == AV_CH_LAYOUT_STEREO)
-                    c->channel_layout = AV_CH_LAYOUT_STEREO;
-            }
-        }
-        c->channels        = av_get_channel_layout_nb_channels(c->channel_layout);
+        av_channel_layout_copy(&c->ch_layout, &(AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO);
         ost->st->time_base = (AVRational){ 1, c->sample_rate };
         break;
 
@@ -224,7 +215,7 @@ static void add_stream(OutputStream *ost
 /* audio output */
 
 static AVFrame *alloc_audio_frame(enum AVSampleFormat sample_fmt,
-                                  uint64_t channel_layout,
+                                  const AVChannelLayout *channel_layout,
                                   int sample_rate, int nb_samples)
 {
     AVFrame *frame = av_frame_alloc();
@@ -236,7 +227,7 @@ static AVFrame *alloc_audio_frame(enum A
     }
 
     frame->format = sample_fmt;
-    frame->channel_layout = channel_layout;
+    av_channel_layout_copy(&frame->ch_layout, channel_layout);
     frame->sample_rate = sample_rate;
     frame->nb_samples = nb_samples;
 
@@ -281,9 +272,9 @@ static void open_audio(AVFormatContext *
     else
         nb_samples = c->frame_size;
 
-    ost->frame     = alloc_audio_frame(c->sample_fmt, c->channel_layout,
+    ost->frame     = alloc_audio_frame(c->sample_fmt, &c->ch_layout,
                                        c->sample_rate, nb_samples);
-    ost->tmp_frame = alloc_audio_frame(AV_SAMPLE_FMT_S16, c->channel_layout,
+    ost->tmp_frame = alloc_audio_frame(AV_SAMPLE_FMT_S16, &c->ch_layout,
                                        c->sample_rate, nb_samples);
 
     /* copy the stream parameters to the muxer */
@@ -301,10 +292,10 @@ static void open_audio(AVFormatContext *
     }
 
     /* set options */
-    av_opt_set_int       (ost->swr_ctx, "in_channel_count",   c->channels,       0);
+    av_opt_set_chlayout  (ost->swr_ctx, "in_chlayout",       &c->ch_layout,      0);
     av_opt_set_int       (ost->swr_ctx, "in_sample_rate",     c->sample_rate,    0);
     av_opt_set_sample_fmt(ost->swr_ctx, "in_sample_fmt",      AV_SAMPLE_FMT_S16, 0);
-    av_opt_set_int       (ost->swr_ctx, "out_channel_count",  c->channels,       0);
+    av_opt_set_chlayout  (ost->swr_ctx, "out_chlayout",      &c->ch_layout,      0);
     av_opt_set_int       (ost->swr_ctx, "out_sample_rate",    c->sample_rate,    0);
     av_opt_set_sample_fmt(ost->swr_ctx, "out_sample_fmt",     c->sample_fmt,     0);
 
@@ -330,7 +321,7 @@ static AVFrame *get_audio_frame(OutputSt
 
     for (j = 0; j <frame->nb_samples; j++) {
         v = (int)(sin(ost->t) * 10000);
-        for (i = 0; i < ost->enc->channels; i++)
+        for (i = 0; i < ost->enc->ch_layout.nb_channels; i++)
             *q++ = v;
         ost->t     += ost->tincr;
         ost->tincr += ost->tincr2;
@@ -638,10 +629,6 @@ int main(int argc, char **argv)
         }
     }
 
-    /* Write the trailer, if any. The trailer must be written before you
-     * close the CodecContexts open when you wrote the header; otherwise
-     * av_write_trailer() may try to use memory that was freed on
-     * av_codec_close(). */
     av_write_trailer(oc);
 
     /* Close each codec. */
diff -pruN 7:5.0.1-3/doc/examples/resampling_audio.c 7:5.1-1/doc/examples/resampling_audio.c
--- 7:5.0.1-3/doc/examples/resampling_audio.c	2020-04-27 21:48:15.000000000 +0000
+++ 7:5.1-1/doc/examples/resampling_audio.c	2022-07-22 17:58:38.000000000 +0000
@@ -80,7 +80,7 @@ static void fill_samples(double *dst, in
 
 int main(int argc, char **argv)
 {
-    int64_t src_ch_layout = AV_CH_LAYOUT_STEREO, dst_ch_layout = AV_CH_LAYOUT_SURROUND;
+    AVChannelLayout src_ch_layout = AV_CHANNEL_LAYOUT_STEREO, dst_ch_layout = AV_CHANNEL_LAYOUT_SURROUND;
     int src_rate = 48000, dst_rate = 44100;
     uint8_t **src_data = NULL, **dst_data = NULL;
     int src_nb_channels = 0, dst_nb_channels = 0;
@@ -92,6 +92,7 @@ int main(int argc, char **argv)
     int dst_bufsize;
     const char *fmt;
     struct SwrContext *swr_ctx;
+    char buf[64];
     double t;
     int ret;
 
@@ -120,11 +121,11 @@ int main(int argc, char **argv)
     }
 
     /* set options */
-    av_opt_set_int(swr_ctx, "in_channel_layout",    src_ch_layout, 0);
+    av_opt_set_chlayout(swr_ctx, "in_chlayout",    &src_ch_layout, 0);
     av_opt_set_int(swr_ctx, "in_sample_rate",       src_rate, 0);
     av_opt_set_sample_fmt(swr_ctx, "in_sample_fmt", src_sample_fmt, 0);
 
-    av_opt_set_int(swr_ctx, "out_channel_layout",    dst_ch_layout, 0);
+    av_opt_set_chlayout(swr_ctx, "out_chlayout",    &dst_ch_layout, 0);
     av_opt_set_int(swr_ctx, "out_sample_rate",       dst_rate, 0);
     av_opt_set_sample_fmt(swr_ctx, "out_sample_fmt", dst_sample_fmt, 0);
 
@@ -136,7 +137,7 @@ int main(int argc, char **argv)
 
     /* allocate source and destination samples buffers */
 
-    src_nb_channels = av_get_channel_layout_nb_channels(src_ch_layout);
+    src_nb_channels = src_ch_layout.nb_channels;
     ret = av_samples_alloc_array_and_samples(&src_data, &src_linesize, src_nb_channels,
                                              src_nb_samples, src_sample_fmt, 0);
     if (ret < 0) {
@@ -151,7 +152,7 @@ int main(int argc, char **argv)
         av_rescale_rnd(src_nb_samples, dst_rate, src_rate, AV_ROUND_UP);
 
     /* buffer is going to be directly written to a rawaudio file, no alignment */
-    dst_nb_channels = av_get_channel_layout_nb_channels(dst_ch_layout);
+    dst_nb_channels = dst_ch_layout.nb_channels;
     ret = av_samples_alloc_array_and_samples(&dst_data, &dst_linesize, dst_nb_channels,
                                              dst_nb_samples, dst_sample_fmt, 0);
     if (ret < 0) {
@@ -194,9 +195,10 @@ int main(int argc, char **argv)
 
     if ((ret = get_format_from_sample_fmt(&fmt, dst_sample_fmt)) < 0)
         goto end;
+    av_channel_layout_describe(&dst_ch_layout, buf, sizeof(buf));
     fprintf(stderr, "Resampling succeeded. Play the output file with the command:\n"
-            "ffplay -f %s -channel_layout %"PRId64" -channels %d -ar %d %s\n",
-            fmt, dst_ch_layout, dst_nb_channels, dst_rate, dst_filename);
+            "ffplay -f %s -channel_layout %s -channels %d -ar %d %s\n",
+            fmt, buf, dst_nb_channels, dst_rate, dst_filename);
 
 end:
     fclose(dst_file);
diff -pruN 7:5.0.1-3/doc/examples/transcode_aac.c 7:5.1-1/doc/examples/transcode_aac.c
--- 7:5.0.1-3/doc/examples/transcode_aac.c	2022-01-14 18:45:39.000000000 +0000
+++ 7:5.1-1/doc/examples/transcode_aac.c	2022-07-22 17:58:38.000000000 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2018 Andreas Unterweger
+ * Copyright (c) 2013-2022 Andreas Unterweger
  *
  * This file is part of FFmpeg.
  *
@@ -62,6 +62,7 @@ static int open_input_file(const char *f
 {
     AVCodecContext *avctx;
     const AVCodec *input_codec;
+    const AVStream *stream;
     int error;
 
     /* Open the input file to read from it. */
@@ -89,8 +90,10 @@ static int open_input_file(const char *f
         return AVERROR_EXIT;
     }
 
+    stream = (*input_format_context)->streams[0];
+
     /* Find a decoder for the audio stream. */
-    if (!(input_codec = avcodec_find_decoder((*input_format_context)->streams[0]->codecpar->codec_id))) {
+    if (!(input_codec = avcodec_find_decoder(stream->codecpar->codec_id))) {
         fprintf(stderr, "Could not find input codec\n");
         avformat_close_input(input_format_context);
         return AVERROR_EXIT;
@@ -105,7 +108,7 @@ static int open_input_file(const char *f
     }
 
     /* Initialize the stream parameters with demuxer information. */
-    error = avcodec_parameters_to_context(avctx, (*input_format_context)->streams[0]->codecpar);
+    error = avcodec_parameters_to_context(avctx, stream->codecpar);
     if (error < 0) {
         avformat_close_input(input_format_context);
         avcodec_free_context(&avctx);
@@ -121,6 +124,9 @@ static int open_input_file(const char *f
         return error;
     }
 
+    /* Set the packet timebase for the decoder. */
+    avctx->pkt_timebase = stream->time_base;
+
     /* Save the decoder context for easier access later. */
     *input_codec_context = avctx;
 
@@ -200,15 +206,11 @@ static int open_output_file(const char *
 
     /* Set the basic encoder parameters.
      * The input file's sample rate is used to avoid a sample rate conversion. */
-    avctx->channels       = OUTPUT_CHANNELS;
-    avctx->channel_layout = av_get_default_channel_layout(OUTPUT_CHANNELS);
+    av_channel_layout_default(&avctx->ch_layout, OUTPUT_CHANNELS);
     avctx->sample_rate    = input_codec_context->sample_rate;
     avctx->sample_fmt     = output_codec->sample_fmts[0];
     avctx->bit_rate       = OUTPUT_BIT_RATE;
 
-    /* Allow the use of the experimental AAC encoder. */
-    avctx->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL;
-
     /* Set the sample rate for the container. */
     stream->time_base.den = input_codec_context->sample_rate;
     stream->time_base.num = 1;
@@ -290,21 +292,18 @@ static int init_resampler(AVCodecContext
         /*
          * Create a resampler context for the conversion.
          * Set the conversion parameters.
-         * Default channel layouts based on the number of channels
-         * are assumed for simplicity (they are sometimes not detected
-         * properly by the demuxer and/or decoder).
          */
-        *resample_context = swr_alloc_set_opts(NULL,
-                                              av_get_default_channel_layout(output_codec_context->channels),
+        error = swr_alloc_set_opts2(resample_context,
+                                             &output_codec_context->ch_layout,
                                               output_codec_context->sample_fmt,
                                               output_codec_context->sample_rate,
-                                              av_get_default_channel_layout(input_codec_context->channels),
+                                             &input_codec_context->ch_layout,
                                               input_codec_context->sample_fmt,
                                               input_codec_context->sample_rate,
                                               0, NULL);
-        if (!*resample_context) {
+        if (error < 0) {
             fprintf(stderr, "Could not allocate resample context\n");
-            return AVERROR(ENOMEM);
+            return error;
         }
         /*
         * Perform a sanity check so that the number of converted samples is
@@ -332,7 +331,7 @@ static int init_fifo(AVAudioFifo **fifo,
 {
     /* Create the FIFO buffer based on the specified output sample format. */
     if (!(*fifo = av_audio_fifo_alloc(output_codec_context->sample_fmt,
-                                      output_codec_context->channels, 1))) {
+                                      output_codec_context->ch_layout.nb_channels, 1))) {
         fprintf(stderr, "Could not allocate FIFO\n");
         return AVERROR(ENOMEM);
     }
@@ -381,6 +380,8 @@ static int decode_audio_frame(AVFrame *f
     if (error < 0)
         return error;
 
+    *data_present = 0;
+    *finished = 0;
     /* Read one audio frame from the input file into a temporary packet. */
     if ((error = av_read_frame(input_format_context, input_packet)) < 0) {
         /* If we are at the end of the file, flush the decoder below. */
@@ -450,7 +451,7 @@ static int init_converted_samples(uint8_
      * Each pointer will later point to the audio samples of the corresponding
      * channels (although it may be NULL for interleaved formats).
      */
-    if (!(*converted_input_samples = calloc(output_codec_context->channels,
+    if (!(*converted_input_samples = calloc(output_codec_context->ch_layout.nb_channels,
                                             sizeof(**converted_input_samples)))) {
         fprintf(stderr, "Could not allocate converted input sample pointers\n");
         return AVERROR(ENOMEM);
@@ -459,7 +460,7 @@ static int init_converted_samples(uint8_
     /* Allocate memory for the samples of all channels in one consecutive
      * block for convenience. */
     if ((error = av_samples_alloc(*converted_input_samples, NULL,
-                                  output_codec_context->channels,
+                                  output_codec_context->ch_layout.nb_channels,
                                   frame_size,
                                   output_codec_context->sample_fmt, 0)) < 0) {
         fprintf(stderr,
@@ -559,7 +560,7 @@ static int read_decode_convert_and_store
     AVFrame *input_frame = NULL;
     /* Temporary storage for the converted input samples. */
     uint8_t **converted_input_samples = NULL;
-    int data_present = 0;
+    int data_present;
     int ret = AVERROR_EXIT;
 
     /* Initialize temporary storage for one input frame. */
@@ -633,7 +634,7 @@ static int init_output_frame(AVFrame **f
      * Default channel layouts based on the number of channels
      * are assumed for simplicity. */
     (*frame)->nb_samples     = frame_size;
-    (*frame)->channel_layout = output_codec_context->channel_layout;
+    av_channel_layout_copy(&(*frame)->ch_layout, &output_codec_context->ch_layout);
     (*frame)->format         = output_codec_context->sample_fmt;
     (*frame)->sample_rate    = output_codec_context->sample_rate;
 
@@ -680,17 +681,16 @@ static int encode_audio_frame(AVFrame *f
         pts += frame->nb_samples;
     }
 
+    *data_present = 0;
     /* Send the audio frame stored in the temporary packet to the encoder.
      * The output audio stream encoder is used to do this. */
     error = avcodec_send_frame(output_codec_context, frame);
-    /* The encoder signals that it has nothing more to encode. */
-    if (error == AVERROR_EOF) {
-        error = 0;
-        goto cleanup;
-    } else if (error < 0) {
-        fprintf(stderr, "Could not send packet for encoding (error '%s')\n",
-                av_err2str(error));
-        goto cleanup;
+    /* Check for errors, but proceed with fetching encoded samples if the
+     *  encoder signals that it has nothing more to encode. */
+    if (error < 0 && error != AVERROR_EOF) {
+      fprintf(stderr, "Could not send packet for encoding (error '%s')\n",
+              av_err2str(error));
+      goto cleanup;
     }
 
     /* Receive one encoded frame from the encoder. */
@@ -861,7 +861,6 @@ int main(int argc, char **argv)
             int data_written;
             /* Flush the encoder as it may have delayed frames. */
             do {
-                data_written = 0;
                 if (encode_audio_frame(NULL, output_format_context,
                                        output_codec_context, &data_written))
                     goto cleanup;
diff -pruN 7:5.0.1-3/doc/examples/transcoding.c 7:5.1-1/doc/examples/transcoding.c
--- 7:5.0.1-3/doc/examples/transcoding.c	2022-01-14 18:45:39.000000000 +0000
+++ 7:5.1-1/doc/examples/transcoding.c	2022-07-22 17:58:38.000000000 +0000
@@ -175,8 +175,9 @@ static int open_output_file(const char *
                 enc_ctx->time_base = av_inv_q(dec_ctx->framerate);
             } else {
                 enc_ctx->sample_rate = dec_ctx->sample_rate;
-                enc_ctx->channel_layout = dec_ctx->channel_layout;
-                enc_ctx->channels = av_get_channel_layout_nb_channels(enc_ctx->channel_layout);
+                ret = av_channel_layout_copy(&enc_ctx->ch_layout, &dec_ctx->ch_layout);
+                if (ret < 0)
+                    return ret;
                 /* take first format from list of supported formats */
                 enc_ctx->sample_fmt = encoder->sample_fmts[0];
                 enc_ctx->time_base = (AVRational){1, enc_ctx->sample_rate};
@@ -289,6 +290,7 @@ static int init_filter(FilteringContext*
             goto end;
         }
     } else if (dec_ctx->codec_type == AVMEDIA_TYPE_AUDIO) {
+        char buf[64];
         buffersrc = avfilter_get_by_name("abuffer");
         buffersink = avfilter_get_by_name("abuffersink");
         if (!buffersrc || !buffersink) {
@@ -297,14 +299,14 @@ static int init_filter(FilteringContext*
             goto end;
         }
 
-        if (!dec_ctx->channel_layout)
-            dec_ctx->channel_layout =
-                av_get_default_channel_layout(dec_ctx->channels);
+        if (dec_ctx->ch_layout.order == AV_CHANNEL_ORDER_UNSPEC)
+            av_channel_layout_default(&dec_ctx->ch_layout, dec_ctx->ch_layout.nb_channels);
+        av_channel_layout_describe(&dec_ctx->ch_layout, buf, sizeof(buf));
         snprintf(args, sizeof(args),
-                "time_base=%d/%d:sample_rate=%d:sample_fmt=%s:channel_layout=0x%"PRIx64,
+                "time_base=%d/%d:sample_rate=%d:sample_fmt=%s:channel_layout=%s",
                 dec_ctx->time_base.num, dec_ctx->time_base.den, dec_ctx->sample_rate,
                 av_get_sample_fmt_name(dec_ctx->sample_fmt),
-                dec_ctx->channel_layout);
+                buf);
         ret = avfilter_graph_create_filter(&buffersrc_ctx, buffersrc, "in",
                 args, NULL, filter_graph);
         if (ret < 0) {
@@ -327,9 +329,9 @@ static int init_filter(FilteringContext*
             goto end;
         }
 
-        ret = av_opt_set_bin(buffersink_ctx, "channel_layouts",
-                (uint8_t*)&enc_ctx->channel_layout,
-                sizeof(enc_ctx->channel_layout), AV_OPT_SEARCH_CHILDREN);
+        av_channel_layout_describe(&enc_ctx->ch_layout, buf, sizeof(buf));
+        ret = av_opt_set(buffersink_ctx, "ch_layouts",
+                         buf, AV_OPT_SEARCH_CHILDREN);
         if (ret < 0) {
             av_log(NULL, AV_LOG_ERROR, "Cannot set output channel layout\n");
             goto end;
diff -pruN 7:5.0.1-3/doc/fate.texi 7:5.1-1/doc/fate.texi
--- 7:5.0.1-3/doc/fate.texi	2021-10-21 17:06:35.000000000 +0000
+++ 7:5.1-1/doc/fate.texi	2022-07-22 17:58:38.000000000 +0000
@@ -79,6 +79,21 @@ Do not put a '~' character in the sample
 directory. Because of shell nuances, this will cause FATE to fail.
 @end float
 
+To get the complete list of tests, run the command:
+@example
+make fate-list
+@end example
+
+You can specify a subset of tests to run by specifying the
+corresponding elements from the list with the @code{fate-} prefix,
+e.g. as in:
+@example
+make fate-ffprobe_compact fate-ffprobe_xml
+@end example
+
+This makes it easier to run a few tests in case of failure without
+running the complete test suite.
+
 To use a custom wrapper to run the test, pass @option{--target-exec} to
 @command{configure} or set the @var{TARGET_EXEC} Make variable.
 
diff -pruN 7:5.0.1-3/doc/ffmpeg.texi 7:5.1-1/doc/ffmpeg.texi
--- 7:5.0.1-3/doc/ffmpeg.texi	2022-01-14 18:45:39.000000000 +0000
+++ 7:5.1-1/doc/ffmpeg.texi	2022-07-22 17:58:38.000000000 +0000
@@ -518,6 +518,21 @@ see @ref{time duration syntax,,the Time
 Like the @code{-ss} option but relative to the "end of file". That is negative
 values are earlier in the file, 0 is at EOF.
 
+@item -isync @var{input_index} (@emph{input})
+Assign an input as a sync source.
+
+This will take the difference between the start times of the target and reference inputs and
+offset the timestamps of the target file by that difference. The source timestamps of the two
+inputs should derive from the same clock source for expected results. If @code{copyts} is set
+then @code{start_at_zero} must also be set. If either of the inputs has no starting timestamp
+then no sync adjustment is made.
+
+Acceptable values are those that refer to a valid ffmpeg input index. If the sync reference is
+the target index itself or @var{-1}, then no adjustment is made to target timestamps. A sync
+reference may not itself be synced to any other input.
+
+Default value is @var{-1}.
+
 @item -itsoffset @var{offset} (@emph{input})
 Set the input time offset.
 
@@ -624,21 +639,21 @@ The parameters set for each target are a
 @var{pal}:
 -f vcd -muxrate 1411200 -muxpreload 0.44 -packetsize 2324
 -s 352x288 -r 25
--codec:v mpeg1video -g 15 -b:v 1150k -maxrate:v 1150v -minrate:v 1150k -bufsize:v 327680
+-codec:v mpeg1video -g 15 -b:v 1150k -maxrate:v 1150k -minrate:v 1150k -bufsize:v 327680
 -ar 44100 -ac 2
 -codec:a mp2 -b:a 224k
 
 @var{ntsc}:
 -f vcd -muxrate 1411200 -muxpreload 0.44 -packetsize 2324
 -s 352x240 -r 30000/1001
--codec:v mpeg1video -g 18 -b:v 1150k -maxrate:v 1150v -minrate:v 1150k -bufsize:v 327680
+-codec:v mpeg1video -g 18 -b:v 1150k -maxrate:v 1150k -minrate:v 1150k -bufsize:v 327680
 -ar 44100 -ac 2
 -codec:a mp2 -b:a 224k
 
 @var{film}:
 -f vcd -muxrate 1411200 -muxpreload 0.44 -packetsize 2324
 -s 352x240 -r 24000/1001
--codec:v mpeg1video -g 18 -b:v 1150k -maxrate:v 1150v -minrate:v 1150k -bufsize:v 327680
+-codec:v mpeg1video -g 18 -b:v 1150k -maxrate:v 1150k -minrate:v 1150k -bufsize:v 327680
 -ar 44100 -ac 2
 -codec:a mp2 -b:a 224k
 @end example
@@ -1618,12 +1633,14 @@ it may cause packet loss.
 It is useful for when flow speed of output packets is important, such as live streaming.
 @item -re (@emph{input})
 Read input at native frame rate. This is equivalent to setting @code{-readrate 1}.
-@item -vsync @var{parameter}
-Video sync method.
+@item -vsync @var{parameter} (@emph{global})
+@itemx -fps_mode[:@var{stream_specifier}] @var{parameter} (@emph{output,per-stream})
+Set video sync method / framerate mode. vsync is applied to all output video streams
+but can be overridden for a stream by setting fps_mode. vsync is deprecated and will be
+removed in the future.
 
-For compatibility reasons some of the values can be specified as numbers (shown
-in parentheses in the following table). This is deprecated and will stop working
-in the future.
+For compatibility reasons some of the values for vsync can be specified as numbers (shown
+in parentheses in the following table).
 
 @table @option
 @item passthrough (0)
@@ -1747,7 +1764,7 @@ Default value is 0.
 @item -bitexact (@emph{input/output})
 Enable bitexact mode for (de)muxer and (de/en)coder
 @item -shortest (@emph{output})
-Finish encoding when the shortest input stream ends.
+Finish encoding when the shortest output stream ends.
 @item -dts_delta_threshold
 Timestamp discontinuity delta threshold.
 @item -dts_error_threshold @var{seconds}
@@ -1887,7 +1904,7 @@ This option sets the maximum number of q
 file or device. With low latency / high rate live streams, packets may be
 discarded if they are not read in a timely manner; setting this value can
 force ffmpeg to use a separate input thread and read packets as soon as they
-arrive. By default ffmpeg only do this if multiple inputs are specified.
+arrive. By default ffmpeg only does this if multiple inputs are specified.
 
 @item -sdp_file @var{file} (@emph{global})
 Print sdp information for an output stream to @var{file}.
diff -pruN 7:5.0.1-3/doc/ffplay.texi 7:5.1-1/doc/ffplay.texi
--- 7:5.0.1-3/doc/ffplay.texi	2021-10-24 20:47:07.000000000 +0000
+++ 7:5.1-1/doc/ffplay.texi	2022-07-22 17:58:38.000000000 +0000
@@ -34,10 +34,6 @@ various FFmpeg APIs.
 Force displayed width.
 @item -y @var{height}
 Force displayed height.
-@item -s @var{size}
-Set frame size (WxH or abbreviation), needed for videos which do
-not contain a header with the frame size like raw YUV.  This option
-has been deprecated in favor of private options, try -video_size.
 @item -fs
 Start in fullscreen mode.
 @item -an
@@ -126,10 +122,6 @@ Read @var{input_url}.
 
 @section Advanced options
 @table @option
-@item -pix_fmt @var{format}
-Set pixel format.
-This option has been deprecated in favor of private options, try -pixel_format.
-
 @item -stats
 Print several playback statistics, in particular show the stream
 duration, the codec parameters, the current position in the stream and
@@ -222,8 +214,6 @@ Pause.
 Toggle mute.
 
 @item 9, 0
-Decrease and increase volume respectively.
-
 @item /, *
 Decrease and increase volume respectively.
 
diff -pruN 7:5.0.1-3/doc/ffprobe.texi 7:5.1-1/doc/ffprobe.texi
--- 7:5.0.1-3/doc/ffprobe.texi	2022-01-14 18:45:39.000000000 +0000
+++ 7:5.1-1/doc/ffprobe.texi	2022-07-22 17:58:38.000000000 +0000
@@ -12,7 +12,7 @@
 
 @chapter Synopsis
 
-ffprobe [@var{options}] [@file{input_url}]
+ffprobe [@var{options}] @file{input_url}
 
 @chapter Description
 @c man begin DESCRIPTION
@@ -28,6 +28,9 @@ If a url is specified in input, ffprobe
 probe the url content. If the url cannot be opened or recognized as
 a multimedia file, a positive exit code is returned.
 
+If no output is specified as output with @option{o} ffprobe will write
+to stdout.
+
 ffprobe may be employed both as a standalone application or in
 combination with a textual filter, which may perform more
 sophisticated processing, e.g. statistical processing or plotting.
@@ -348,6 +351,10 @@ on the specific build.
 @item -i @var{input_url}
 Read @var{input_url}.
 
+@item -o @var{output_url}
+Write output to @var{output_url}. If not specified, the output is sent
+to stdout.
+
 @end table
 @c man end
 
diff -pruN 7:5.0.1-3/doc/filters.texi 7:5.1-1/doc/filters.texi
--- 7:5.0.1-3/doc/filters.texi	2022-01-14 18:45:39.000000000 +0000
+++ 7:5.1-1/doc/filters.texi	2022-07-22 17:58:38.000000000 +0000
@@ -557,6 +557,22 @@ Set input gain level. Allowed range is f
 
 @item gains
 Set output gain for each band. Default value is 1 for all bands.
+
+@item precision
+Set which precision to use when processing samples.
+
+@table @option
+@item auto
+Auto pick internal sample format depending on other filters.
+
+@item float
+Always use single-floating point precision sample format.
+
+@item double
+Always use double-floating point precision sample format.
+@end table
+
+Default value is @code{auto}.
 @end table
 
 @subsection Examples
@@ -913,6 +929,16 @@ Cut frequencies above detection threshol
 Boost frequencies bellow detection threshold.
 @end table
 Default mode is @samp{cut}.
+
+@item tftype
+Set the type of target filter, can be one of the following:
+
+@table @samp
+@item bell
+@item lowshelf
+@item highshelf
+@end table
+Default type is @samp{bell}.
 @end table
 
 @subsection Commands
@@ -1282,90 +1308,151 @@ Denoise audio samples with FFT.
 A description of the accepted parameters follows.
 
 @table @option
-@item nr
+@item noise_reduction, nr
 Set the noise reduction in dB, allowed range is 0.01 to 97.
 Default value is 12 dB.
 
-@item nf
+@item noise_floor, nf
 Set the noise floor in dB, allowed range is -80 to -20.
 Default value is -50 dB.
 
-@item nt
+@item noise_type, nt
 Set the noise type.
 
 It accepts the following values:
 @table @option
-@item w
+@item white, w
 Select white noise.
 
-@item v
+@item vinyl, v
 Select vinyl noise.
 
-@item s
+@item shellac, s
 Select shellac noise.
 
-@item c
+@item custom, c
 Select custom noise, defined in @code{bn} option.
 
 Default value is white noise.
 @end table
 
-@item bn
-Set custom band noise for every one of 15 bands.
+@item band_noise, bn
+Set custom band noise profile for every one of 15 bands.
 Bands are separated by ' ' or '|'.
 
-@item rf
+@item residual_floor, rf
 Set the residual floor in dB, allowed range is -80 to -20.
 Default value is -38 dB.
 
-@item tn
-Enable noise tracking. By default is disabled.
+@item track_noise, tn
+Enable noise floor tracking. By default is disabled.
 With this enabled, noise floor is automatically adjusted.
 
-@item tr
+@item track_residual, tr
 Enable residual tracking. By default is disabled.
 
-@item om
+@item output_mode, om
 Set the output mode.
 
 It accepts the following values:
 @table @option
-@item i
+@item input, i
 Pass input unchanged.
 
-@item o
+@item output, o
 Pass noise filtered out.
 
-@item n
+@item noise, n
 Pass only noise.
 
-Default value is @var{o}.
-@end table
+Default value is @var{output}.
 @end table
 
-@subsection Commands
+@item adaptivity, ad
+Set the adaptivity factor, used how fast to adapt gains adjustments per
+each frequency bin. Value @var{0} enables instant adaptation, while higher values
+react much slower.
+Allowed range is from @var{0} to @var{1}. Default value is @var{0.5}.
+
+@item floor_offset, fo
+Set the noise floor offset factor. This option is used to adjust offset applied to measured
+noise floor. It is only effective when noise floor tracking is enabled.
+Allowed range is from @var{-2.0} to @var{2.0}. Default value is @var{1.0}.
 
-This filter supports the following commands:
+@item noise_link, nl
+Set the noise link used for multichannel audio.
+
+It accepts the following values:
 @table @option
+@item none
+Use unchanged channel's noise floor.
+
+@item min
+Use measured min noise floor of all channels.
+
+@item max
+Use measured max noise floor of all channels.
+
+@item average
+Use measured average noise floor of all channels.
+
+Default value is @var{min}.
+@end table
+
+@item band_multiplier, bm
+Set the band multiplier factor, used how much to spread bands across frequency bins.
+Allowed range is from @var{0.2} to @var{5}. Default value is @var{1.25}.
+
 @item sample_noise, sn
-Start or stop measuring noise profile.
-Syntax for the command is : "start" or "stop" string.
-After measuring noise profile is stopped it will be
-automatically applied in filtering.
+Toggle capturing and measurement of noise profile from input audio.
 
-@item noise_reduction, nr
-Change noise reduction. Argument is single float number.
-Syntax for the command is : "@var{noise_reduction}"
+It accepts the following values:
+@table @option
+@item start, begin
+Start sample noise capture.
 
-@item noise_floor, nf
-Change noise floor. Argument is single float number.
-Syntax for the command is : "@var{noise_floor}"
+@item stop, end
+Stop sample noise capture and measure new noise band profile.
 
-@item output_mode, om
-Change output mode operation.
-Syntax for the command is : "i", "o" or "n" string.
+Default value is @code{none}.
+@end table
+
+@item gain_smooth, gs
+Set gain smooth spatial radius, used to smooth gains applied to each frequency bin.
+Useful to reduce random music noise artefacts.
+Higher values increases smoothing of gains.
+Allowed range is from @code{0} to @code{50}.
+Default value is @code{0}.
 @end table
 
+@subsection Commands
+
+This filter supports the some above mentioned options as @ref{commands}.
+
+@subsection Examples
+
+@itemize
+@item
+Reduce white noise by 10dB, and use previously measured noise floor of -40dB:
+@example
+afftdn=nr=10:nf=-40
+@end example
+
+@item
+Reduce white noise by 10dB, also set initial noise floor to -80dB and enable automatic
+tracking of noise floor so noise floor will gradually change during processing:
+@example
+afftdn=nr=10:nf=-80:tn=1
+@end example
+
+@item
+Reduce noise by 20dB, using noise floor of -40dB and using commands to take noise profile
+of first 0.4 seconds of input audio:
+@example
+asendcmd=0.0 afftdn sn start,asendcmd=0.4 afftdn sn stop,afftdn=nr=20:nf=-40
+@end example
+@end itemize
+
 @section afftfilt
 Apply arbitrary expressions to samples in frequency domain.
 
@@ -1568,6 +1655,22 @@ Allowed range is from @var{1} to @var{32
 Set IR stream which will be used for convolution, starting from @var{0}, should always be
 lower than supplied value by @code{nbirs} option. Default is @var{0}.
 This option can be changed at runtime via @ref{commands}.
+
+@item precision
+Set which precision to use when processing samples.
+
+@table @option
+@item auto
+Auto pick internal sample format depending on other filters.
+
+@item float
+Always use single-floating point precision sample format.
+
+@item double
+Always use double-floating point precision sample format.
+@end table
+
+Default value is auto.
 @end table
 
 @subsection Examples
@@ -1924,6 +2027,11 @@ in release time while 1 produces higher
 @item level
 Auto level output signal. Default is enabled.
 This normalizes audio back to 0dB if enabled.
+
+@item latency
+Compensate the delay introduced by using the lookahead buffer set with attack
+parameter. Also flush the valid audio data in the lookahead buffer when the
+stream hits EOF.
 @end table
 
 Depending on picked setting it is recommended to upsample input 2x or 4x times
@@ -1979,9 +2087,11 @@ Set transform type of IIR filter.
 @table @option
 @item di
 @item dii
+@item tdi
 @item tdii
 @item latt
 @item svf
+@item zdf
 @end table
 
 @item precision, r
@@ -2266,7 +2376,7 @@ The filter accepts the following options
 
 @table @option
 @item strength, s
-Set denoising strength. Allowed range is from 0.00001 to 10. Default value is 0.00001.
+Set denoising strength. Allowed range is from 0.00001 to 10000. Default value is 0.00001.
 
 @item patch, p
 Set patch radius duration. Allowed range is from 1 to 100 milliseconds.
@@ -2294,7 +2404,7 @@ Default value is @var{o}.
 @end table
 
 @item smooth, m
-Set smooth factor. Default value is @var{11}. Allowed range is from @var{1} to @var{15}.
+Set smooth factor. Default value is @var{11}. Allowed range is from @var{1} to @var{1000}.
 @end table
 
 @subsection Commands
@@ -2508,7 +2618,7 @@ Output only difference samples, useful t
 By default is disabled.
 
 @item adaptive
-Set strenght of adaptive distortion applied. Default value is 0.5.
+Set strength of adaptive distortion applied. Default value is 0.5.
 Allowed range is from 0 to 1.
 
 @item iterations
@@ -3053,15 +3163,18 @@ The filter accepts the following options
 @table @option
 @item dry
 Set dry gain, how much of original signal is kept. Allowed range is from 0 to 1.
-Default value is 0.7.
+Default value is 1.0.
 
 @item wet
 Set wet gain, how much of filtered signal is kept. Allowed range is from 0 to 1.
-Default value is 0.7.
+Default value is 1.0.
+
+@item boost
+Set max boost factor. Allowed range is from 1 to 12. Default value is 2.
 
 @item decay
 Set delay line decay gain value. Allowed range is from 0 to 1.
-Default value is 0.7.
+Default value is 0.0.
 
 @item feedback
 Set delay line feedback gain value. Allowed range is from 0 to 1.
@@ -3078,6 +3191,9 @@ Default value is 0.5.
 @item delay
 Set delay. Allowed range is from 1 to 100.
 Default value is 20.
+
+@item channels
+Set the channels to process. Default value is all available.
 @end table
 
 @subsection Commands
@@ -3408,9 +3524,11 @@ Set transform type of IIR filter.
 @table @option
 @item di
 @item dii
+@item tdi
 @item tdii
 @item latt
 @item svf
+@item zdf
 @end table
 
 @item precision, r
@@ -3427,6 +3545,13 @@ Always use float 32-bit.
 @item f64
 Always use float 64-bit.
 @end table
+
+@item block_size, b
+Set block size used for reverse IIR processing. If this value is set to high enough
+value (higher than impulse response length truncated when reaches near zero values) filtering
+will become linear phase otherwise if not big enough it will just produce nasty artifacts.
+
+Note that filter delay will be exactly this many samples when set to non-zero value.
 @end table
 
 @subsection Commands
@@ -3496,9 +3621,11 @@ Set transform type of IIR filter.
 @table @option
 @item di
 @item dii
+@item tdi
 @item tdii
 @item latt
 @item svf
+@item zdf
 @end table
 
 @item precision, r
@@ -3515,6 +3642,13 @@ Always use float 32-bit.
 @item f64
 Always use float 64-bit.
 @end table
+
+@item block_size, b
+Set block size used for reverse IIR processing. If this value is set to high enough
+value (higher than impulse response length truncated when reaches near zero values) filtering
+will become linear phase otherwise if not big enough it will just produce nasty artifacts.
+
+Note that filter delay will be exactly this many samples when set to non-zero value.
 @end table
 
 @subsection Commands
@@ -3594,9 +3728,11 @@ Set transform type of IIR filter.
 @table @option
 @item di
 @item dii
+@item tdi
 @item tdii
 @item latt
 @item svf
+@item zdf
 @end table
 
 @item precision, r
@@ -3613,6 +3749,13 @@ Always use float 32-bit.
 @item f64
 Always use float 64-bit.
 @end table
+
+@item block_size, b
+Set block size used for reverse IIR processing. If this value is set to high enough
+value (higher than impulse response length truncated when reaches near zero values) filtering
+will become linear phase otherwise if not big enough it will just produce nasty artifacts.
+
+Note that filter delay will be exactly this many samples when set to non-zero value.
 @end table
 
 @subsection Commands
@@ -3677,9 +3820,11 @@ Set transform type of IIR filter.
 @table @option
 @item di
 @item dii
+@item tdi
 @item tdii
 @item latt
 @item svf
+@item zdf
 @end table
 
 @item precision, r
@@ -3696,6 +3841,13 @@ Always use float 32-bit.
 @item f64
 Always use float 64-bit.
 @end table
+
+@item block_size, b
+Set block size used for reverse IIR processing. If this value is set to high enough
+value (higher than impulse response length truncated when reaches near zero values) filtering
+will become linear phase otherwise if not big enough it will just produce nasty artifacts.
+
+Note that filter delay will be exactly this many samples when set to non-zero value.
 @end table
 
 @section bs2b
@@ -4066,6 +4218,10 @@ Set temperature in degrees Celsius. This
 Default is 20.
 @end table
 
+@subsection Commands
+
+This filter supports the all above options as @ref{commands}.
+
 @section crossfeed
 Apply headphone crossfeed filter.
 
@@ -4097,6 +4253,13 @@ Set input gain. Default is 0.9.
 
 @item level_out
 Set output gain. Default is 1.
+
+@item block_size
+Set block size used for reverse IIR processing. If this value is set to high enough
+value (higher than impulse response length truncated when reaches near zero values) filtering
+will become linear phase otherwise if not big enough it will just produce nasty artifacts.
+
+Note that filter delay will be exactly this many samples when set to non-zero value.
 @end table
 
 @subsection Commands
@@ -4178,6 +4341,34 @@ Default value is @var{o}.
 
 @end table
 
+@section dialoguenhance
+Enhance dialogue in stereo audio.
+
+This filter accepts stereo input and produce surround (3.0) channels output.
+The newly produced front center channel have enhanced speech dialogue originally
+available in both stereo channels.
+This filter outputs front left and front right channels same as available in stereo input.
+
+The filter accepts the following options:
+
+@table @option
+@item original
+Set the original center factor to keep in front center channel output.
+Allowed range is from 0 to 1. Default value is 1.
+
+@item enhance
+Set the dialogue enhance factor to put in front center channel output.
+Allowed range is from 0 to 3. Default value is 1.
+
+@item voice
+Set the voice detection factor.
+Allowed range is from 2 to 32. Default value is 2.
+@end table
+
+@subsection Commands
+
+This filter supports the all above options as @ref{commands}.
+
 @section drmeter
 Measure audio dynamic range.
 
@@ -4357,6 +4548,16 @@ If input frame volume is above this valu
 Otherwise frame may not be normalized at all. The default value is set
 to 0, which means all input frames will be normalized.
 This option is mostly useful if digital noise is not wanted to be amplified.
+
+@item channels, h
+Specify which channels to filter, by default all available channels are filtered.
+
+@item overlap, o
+Specify overlap for frames. If set to 0 (default) no frame overlapping is done.
+Using >0 and <1 values will make less conservative gain adjustments, like
+when framelen option is set to smaller value, if framelen option value is
+compensated for non-zero overlap then gain adjustments will be smoother across time
+compared to zero overlap case.
 @end table
 
 @subsection Commands
@@ -4428,9 +4629,11 @@ Set transform type of IIR filter.
 @table @option
 @item di
 @item dii
+@item tdi
 @item tdii
 @item latt
 @item svf
+@item zdf
 @end table
 
 @item precision, r
@@ -4447,6 +4650,13 @@ Always use float 32-bit.
 @item f64
 Always use float 64-bit.
 @end table
+
+@item block_size, b
+Set block size used for reverse IIR processing. If this value is set to high enough
+value (higher than impulse response length truncated when reaches near zero values) filtering
+will become linear phase otherwise if not big enough it will just produce nasty artifacts.
+
+Note that filter delay will be exactly this many samples when set to non-zero value.
 @end table
 
 @subsection Examples
@@ -4930,9 +5140,11 @@ Set transform type of IIR filter.
 @table @option
 @item di
 @item dii
+@item tdi
 @item tdii
 @item latt
 @item svf
+@item zdf
 @end table
 
 @item precision, r
@@ -4949,6 +5161,13 @@ Always use float 32-bit.
 @item f64
 Always use float 64-bit.
 @end table
+
+@item block_size, b
+Set block size used for reverse IIR processing. If this value is set to high enough
+value (higher than impulse response length truncated when reaches near zero values) filtering
+will become linear phase otherwise if not big enough it will just produce nasty artifacts.
+
+Note that filter delay will be exactly this many samples when set to non-zero value.
 @end table
 
 @subsection Commands
@@ -5183,7 +5402,7 @@ Range is -70.0 - -5.0. Default value is
 
 @item LRA, lra
 Set loudness range target.
-Range is 1.0 - 20.0. Default value is 7.0.
+Range is 1.0 - 50.0. Default value is 7.0.
 
 @item TP, tp
 Set maximum true peak.
@@ -5281,9 +5500,11 @@ Set transform type of IIR filter.
 @table @option
 @item di
 @item dii
+@item tdi
 @item tdii
 @item latt
 @item svf
+@item zdf
 @end table
 
 @item precision, r
@@ -5300,6 +5521,13 @@ Always use float 32-bit.
 @item f64
 Always use float 64-bit.
 @end table
+
+@item block_size, b
+Set block size used for reverse IIR processing. If this value is set to high enough
+value (higher than impulse response length truncated when reaches near zero values) filtering
+will become linear phase otherwise if not big enough it will just produce nasty artifacts.
+
+Note that filter delay will be exactly this many samples when set to non-zero value.
 @end table
 
 @subsection Examples
@@ -5391,6 +5619,10 @@ lv2=p=http\\\\://www.openavproductions.c
 @end example
 @end itemize
 
+@subsection Commands
+
+This filter supports all options that are exported by plugin as commands.
+
 @section mcompand
 Multiband Compress or expand the audio's dynamic range.
 
@@ -6404,15 +6636,23 @@ Set LFE output volume. By default, this
 
 @item allx
 Set spread usage of stereo image across X axis for all channels.
+Allowed range is from @var{-1} to @var{15}.
+By default this value is negative @var{-1}, and thus unused.
 
 @item ally
 Set spread usage of stereo image across Y axis for all channels.
+Allowed range is from @var{-1} to @var{15}.
+By default this value is negative @var{-1}, and thus unused.
 
 @item fcx, flx, frx, blx, brx, slx, srx, bcx
 Set spread usage of stereo image across X axis for each channel.
+Allowed range is from @var{0.06} to @var{15}.
+By default this value is @var{0.5}.
 
 @item fcy, fly, fry, bly, bry, sly, sry, bcy
 Set spread usage of stereo image across Y axis for each channel.
+Allowed range is from @var{0.06} to @var{15}.
+By default this value is @var{0.5}.
 
 @item win_size
 Set window size. Allowed range is from @var{1024} to @var{65536}. Default size is @var{4096}.
@@ -6450,6 +6690,97 @@ Set window overlap. If set to 1, the rec
 window function will be picked. Default is @code{0.5}.
 @end table
 
+@section tiltshelf
+
+Boost or cut the lower frequencies and cut or boost higher frequencies
+of the audio using a two-pole shelving filter with a response similar to
+that of a standard hi-fi's tone-controls.
+This is also known as shelving equalisation (EQ).
+
+The filter accepts the following options:
+
+@table @option
+@item gain, g
+Give the gain at 0 Hz. Its useful range is about -20
+(for a large cut) to +20 (for a large boost).
+Beware of clipping when using a positive gain.
+
+@item frequency, f
+Set the filter's central frequency and so can be used
+to extend or reduce the frequency range to be boosted or cut.
+The default value is @code{3000} Hz.
+
+@item width_type, t
+Set method to specify band-width of filter.
+@table @option
+@item h
+Hz
+@item q
+Q-Factor
+@item o
+octave
+@item s
+slope
+@item k
+kHz
+@end table
+
+@item width, w
+Determine how steep is the filter's shelf transition.
+
+@item poles, p
+Set number of poles. Default is 2.
+
+@item mix, m
+How much to use filtered signal in output. Default is 1.
+Range is between 0 and 1.
+
+@item channels, c
+Specify which channels to filter, by default all available are filtered.
+
+@item normalize, n
+Normalize biquad coefficients, by default is disabled.
+Enabling it will normalize magnitude response at DC to 0dB.
+
+@item transform, a
+Set transform type of IIR filter.
+@table @option
+@item di
+@item dii
+@item tdi
+@item tdii
+@item latt
+@item svf
+@item zdf
+@end table
+
+@item precision, r
+Set precison of filtering.
+@table @option
+@item auto
+Pick automatic sample format depending on surround filters.
+@item s16
+Always use signed 16-bit.
+@item s32
+Always use signed 32-bit.
+@item f32
+Always use float 32-bit.
+@item f64
+Always use float 64-bit.
+@end table
+
+@item block_size, b
+Set block size used for reverse IIR processing. If this value is set to high enough
+value (higher than impulse response length truncated when reaches near zero values) filtering
+will become linear phase otherwise if not big enough it will just produce nasty artifacts.
+
+Note that filter delay will be exactly this many samples when set to non-zero value.
+@end table
+
+@subsection Commands
+
+This filter supports some options as @ref{commands}.
+
 @section treble, highshelf
 
 Boost or cut treble (upper) frequencies of the audio using a two-pole
@@ -6506,9 +6837,11 @@ Set transform type of IIR filter.
 @table @option
 @item di
 @item dii
+@item tdi
 @item tdii
 @item latt
 @item svf
+@item zdf
 @end table
 
 @item precision, r
@@ -6525,6 +6858,13 @@ Always use float 32-bit.
 @item f64
 Always use float 64-bit.
 @end table
+
+@item block_size, b
+Set block size used for reverse IIR processing. If this value is set to high enough
+value (higher than impulse response length truncated when reaches near zero values) filtering
+will become linear phase otherwise if not big enough it will just produce nasty artifacts.
+
+Note that filter delay will be exactly this many samples when set to non-zero value.
 @end table
 
 @subsection Commands
@@ -6587,6 +6927,26 @@ Depth of modulation as a percentage. Ran
 Default value is 0.5.
 @end table
 
+@section virtualbass
+
+Apply audio Virtual Bass filter.
+
+This filter accepts stereo input and produce stereo with LFE (2.1) channels output.
+The newly produced LFE channel have enhanced virtual bass originally obtained from both stereo channels.
+This filter outputs front left and front right channels unchanged as available in stereo input.
+
+The filter accepts the following options:
+
+@table @option
+@item cutoff
+Set the virtual bass cutoff frequency. Default value is 250 Hz.
+Allowed range is from 100 to 500 Hz.
+
+@item strength
+Set the virtual bass strength. Allowed range is from 0.5 to 3.
+Default value is 3.
+@end table
+
 @section volume
 
 Adjust the input audio volume.
@@ -6743,8 +7103,9 @@ volume='if(lt(t,10),1,max(1-(t-10)/5,0))
 
 Detect the volume of the input video.
 
-The filter has no parameters. The input is not modified. Statistics about
-the volume will be printed in the log when the input stream end is reached.
+The filter has no parameters. It supports only 16-bit signed integer samples,
+so the input will be converted when needed. Statistics about the volume will
+be printed in the log when the input stream end is reached.
 
 In particular it will show the mean volume (root mean square), maximum
 volume (on a per-sample basis), and the beginning of a histogram of the
@@ -7881,35 +8242,116 @@ tblend=all_mode=grainextract
 @subsection Commands
 This filter supports same @ref{commands} as options.
 
-@section bm3d
+@anchor{blockdetect}
+@section blockdetect
 
-Denoise frames using Block-Matching 3D algorithm.
+Determines blockiness of frames without altering the input frames.
 
-The filter accepts the following options.
+Based on Remco Muijs and Ihor Kirenko: "A no-reference blocking artifact measure for adaptive video processing." 2005 13th European signal processing conference.
+
+The filter accepts the following options:
 
 @table @option
-@item sigma
-Set denoising strength. Default value is 1.
-Allowed range is from 0 to 999.9.
-The denoising algorithm is very sensitive to sigma, so adjust it
-according to the source.
+@item period_min
+@item period_max
+Set minimum and maximum values for determining pixel grids (periods).
+Default values are [3,24].
 
-@item block
-Set local patch size. This sets dimensions in 2D.
+@item planes
+Set planes to filter. Default is first only.
+@end table
 
-@item bstep
-Set sliding step for processing blocks. Default value is 4.
-Allowed range is from 1 to 64.
-Smaller values allows processing more reference blocks and is slower.
+@subsection Examples
 
-@item group
-Set maximal number of similar blocks for 3rd dimension. Default value is 1.
-When set to 1, no block matching is done. Larger values allows more blocks
-in single group.
-Allowed range is from 1 to 256.
+@itemize
+@item
+Determine blockiness for the first plane and search for periods within [8,32]:
+@example
+blockdetect=period_min=8:period_max=32:planes=1
+@end example
+@end itemize
 
-@item range
-Set radius for search block matching. Default is 9.
+@anchor{blurdetect}
+@section blurdetect
+
+Determines blurriness of frames without altering the input frames.
+
+Based on Marziliano, Pina, et al. "A no-reference perceptual blur metric."
+Allows for a block-based abbreviation.
+
+The filter accepts the following options:
+
+@table @option
+@item low
+@item high
+Set low and high threshold values used by the Canny thresholding
+algorithm.
+
+The high threshold selects the "strong" edge pixels, which are then
+connected through 8-connectivity with the "weak" edge pixels selected
+by the low threshold.
+
+@var{low} and @var{high} threshold values must be chosen in the range
+[0,1], and @var{low} should be lesser or equal to @var{high}.
+
+Default value for @var{low} is @code{20/255}, and default value for @var{high}
+is @code{50/255}.
+
+@item radius
+Define the radius to search around an edge pixel for local maxima.
+
+@item block_pct
+Determine blurriness only for the most significant blocks, given in percentage.
+
+@item block_width
+Determine blurriness for blocks of width @var{block_width}. If set to any value smaller 1, no blocks are used and the whole image is processed as one no matter of @var{block_height}.
+
+@item block_height
+Determine blurriness for blocks of height @var{block_height}. If set to any value smaller 1, no blocks are used and the whole image is processed as one no matter of @var{block_width}.
+
+@item planes
+Set planes to filter. Default is first only.
+@end table
+
+@subsection Examples
+
+@itemize
+@item
+Determine blur for 80% of most significant 32x32 blocks:
+@example
+blurdetect=block_width=32:block_height=32:block_pct=80
+@end example
+@end itemize
+
+@section bm3d
+
+Denoise frames using Block-Matching 3D algorithm.
+
+The filter accepts the following options.
+
+@table @option
+@item sigma
+Set denoising strength. Default value is 1.
+Allowed range is from 0 to 999.9.
+The denoising algorithm is very sensitive to sigma, so adjust it
+according to the source.
+
+@item block
+Set local patch size. This sets dimensions in 2D.
+
+@item bstep
+Set sliding step for processing blocks. Default value is 4.
+Allowed range is from 1 to 64.
+Smaller values allows processing more reference blocks and is slower.
+
+@item group
+Set maximal number of similar blocks for 3rd dimension. Default value is 1.
+When set to 1, no block matching is done. Larger values allows more blocks
+in single group.
+Allowed range is from 1 to 256.
+
+@item range
+Set radius for search block matching. Default is 9.
 Allowed range is from 1 to INT32_MAX.
 
 @item mstep
@@ -8157,6 +8599,7 @@ The command accepts the same syntax of t
 If the specified expression is not valid, it is kept at its current
 value.
 
+@anchor{chromakey}
 @section chromakey
 YUV colorspace color/chroma keying.
 
@@ -8209,6 +8652,48 @@ ffmpeg -f lavfi -i color=c=black:s=1280x
 @end example
 @end itemize
 
+@section chromakey_cuda
+CUDA accelerated YUV colorspace color/chroma keying.
+
+This filter works like normal chromakey filter but operates on CUDA frames.
+for more details and parameters see @ref{chromakey}.
+
+@subsection Examples
+
+@itemize
+@item
+Make all the green pixels in the input video transparent and use it as an overlay for another video:
+
+@example
+./ffmpeg \
+    -hwaccel cuda -hwaccel_output_format cuda -i input_green.mp4  \
+    -hwaccel cuda -hwaccel_output_format cuda -i base_video.mp4 \
+    -init_hw_device cuda \
+    -filter_complex \
+    " \
+        [0:v]chromakey_cuda=0x25302D:0.1:0.12:1[overlay_video]; \
+        [1:v]scale_cuda=format=yuv420p[base]; \
+        [base][overlay_video]overlay_cuda" \
+    -an -sn -c:v h264_nvenc -cq 20 output.mp4
+@end example
+
+@item
+Process two software sources, explicitly uploading the frames:
+
+@example
+./ffmpeg -init_hw_device cuda=cuda -filter_hw_device cuda \
+    -f lavfi -i color=size=800x600:color=white,format=yuv420p \
+    -f lavfi -i yuvtestsrc=size=200x200,format=yuv420p \
+    -filter_complex \
+    " \
+        [0]hwupload[under]; \
+        [1]hwupload,chromakey_cuda=green:0.1:0.12[over]; \
+        [under][over]overlay_cuda" \
+    -c:v hevc_nvenc -cq 18 -preset slow output.mp4
+@end example
+
+@end itemize
+
 @section chromanr
 Reduce chrominance noise.
 
@@ -8350,6 +8835,9 @@ Show white point on CIE diagram, by defa
 
 @item gamma
 Set input gamma. Used only with XYZ input color space.
+
+@item fill
+Fill with CIE colors. By default is enabled.
 @end table
 
 @section codecview
@@ -8832,6 +9320,41 @@ colorlevels=romin=0.5:gomin=0.5:bomin=0.
 
 This filter supports the all above options as @ref{commands}.
 
+@section colormap
+Apply custom color maps to video stream.
+
+This filter needs three input video streams.
+First stream is video stream that is going to be filtered out.
+Second and third video stream specify color patches for source
+color to target color mapping.
+
+The filter accepts the following options:
+
+@table @option
+@item patch_size
+Set the source and target video stream patch size in pixels.
+
+@item nb_patches
+Set the max number of used patches from source and target video stream.
+Default value is number of patches available in additional video streams.
+Max allowed number of patches is @code{64}.
+
+@item type
+Set the adjustments used for target colors. Can be @code{relative} or @code{absolute}.
+Defaults is @code{absolute}.
+
+@item kernel
+Set the kernel used to measure color differences between mapped colors.
+
+The accepted values are:
+@table @samp
+@item euclidean
+@item weuclidean
+@end table
+
+Default is @code{euclidean}.
+@end table
+
 @section colormatrix
 
 Convert color matrix.
@@ -11227,8 +11750,10 @@ text data in detection bboxes of side da
 if you are not sure about the text source.
 
 @item reload
-If set to 1, the @var{textfile} will be reloaded before each frame.
-Be sure to update it atomically, or it may be read partially, or even fail.
+The @var{textfile} will be reloaded at specified frame interval.
+Be sure to update @var{textfile} atomically, or it may be read partially,
+or even fail.
+Range is 0 to INT_MAX. Default is 0.
 
 @item x
 @item y
@@ -11378,10 +11903,14 @@ It can be used to add padding with zeros
 @item gmtime
 The time at which the filter is running, expressed in UTC.
 It can accept an argument: a strftime() format string.
+The format string is extended to support the variable @var{%[1-6]N}
+which prints fractions of the second with optionally specified number of digits.
 
 @item localtime
 The time at which the filter is running, expressed in the local time zone.
 It can accept an argument: a strftime() format string.
+The format string is extended to support the variable @var{%[1-6]N}
+which prints fractions of the second with optionally specified number of digits.
 
 @item metadata
 Frame metadata. Takes one or two arguments.
@@ -11890,8 +12419,8 @@ Specify the search radius for best edge
 Allowed range is from 0 to 15.
 
 @item ecost
-Specify the edge cost for edge matching. Default value is 0.03125.
-Allowed range is from 0 to 1.
+Specify the edge cost for edge matching. Default value is 1.0.
+Allowed range is from 0 to 9.
 
 @item mcost
 Specify the middle cost for edge matching. Default value is 0.5.
@@ -12066,6 +12595,44 @@ fade=t=in:st=5.5:d=0.5
 
 @end itemize
 
+@section feedback
+Apply feedback video filter.
+
+This filter pass cropped input frames to 2nd output.
+From there it can be filtered with other video filters.
+After filter receives frame from 2nd input, that frame
+is combined on top of original frame from 1st input and passed
+to 1st output.
+
+The typical usage is filter only part of frame.
+
+The filter accepts the following options:
+@table @option
+@item x
+@item y
+Set the top left crop position.
+
+@item w
+@item h
+Set the crop size.
+@end table
+
+@subsection Examples
+
+@itemize
+@item
+Blur only top left rectangular part of video frame size 100x100 with gblur filter.
+@example
+[in][blurin]feedback=x=0:y=0:w=100:h=100[out][blurout];[blurout]gblur=8[blurin]
+@end example
+
+@item
+Draw black box on top left part of video frame of size 100x100 with drawbox filter.
+@example
+[in][blurin]feedback=x=0:y=0:w=100:h=100[out][blurout];[blurout]drawbox=x=0:y=0:w=100:h=100:t=100[blurin]
+@end example
+@end itemize
+
 @section fftdnoiz
 Denoise frames using 3D FFT (frequency domain filtering).
 
@@ -12082,13 +12649,14 @@ Set amount of denoising. By default all
 Default value is 1. Allowed range is from 0 to 1.
 
 @item block
-Set size of block, Default is 4, can be 3, 4, 5 or 6.
-Actual size of block in pixels is 2 to power of @var{block}, so by default
-block size in pixels is 2^4 which is 16.
+Set size of block in pixels, Default is 32, can be 8 to 256.
 
 @item overlap
 Set block overlap. Default is 0.5. Allowed range is from 0.2 to 0.8.
 
+@item method
+Set denoising method. Default is @code{wiener}, can also be @code{hard}.
+
 @item prev
 Set number of previous frames to use for denoising. By default is set to 0.
 
@@ -12227,7 +12795,9 @@ case of @code{b} it will use only bottom
 If line starts with @code{#} or @code{;} that line is skipped.
 
 @item mode
-Can be item @code{absolute} or @code{relative}. Default is @code{absolute}.
+Can be item @code{absolute} or @code{relative} or @code{pattern}. Default is @code{absolute}.
+The @code{pattern} mode is same as @code{relative} mode, except at last entry of file if there
+are more frames to process than @code{hint} file is seek back to start.
 @end table
 
 Example of first several lines of @code{hint} file for @code{relative} mode:
@@ -13379,12 +13949,21 @@ Display number of frames taken from filt
 @item frame_count_out
 Display number of frames given out from filter.
 
+@item frame_count_delta
+Display delta number of frames between above two values.
+
 @item pts
 Display current filtered frame pts.
 
+@item pts_delta
+Display pts delta between current and previous frame.
+
 @item time
 Display current filtered frame time.
 
+@item time_delta
+Display time delta between current and previous frame.
+
 @item timebase
 Display time base for filter link.
 
@@ -13405,6 +13984,9 @@ Display number of samples taken from fil
 
 @item sample_count_out
 Display number of samples given out from filter.
+
+@item sample_count_delta
+Display delta number of samples between above two values.
 @end table
 
 @item rate, r
@@ -13529,6 +14111,10 @@ The Hald CLUT input can be a simple pict
 The filter accepts the following options:
 
 @table @option
+@item clut
+Set which CLUT video frames will be processed from second input stream,
+can be @var{first} or @var{all}. Default is @var{all}.
+
 @item shortest
 Force termination when the shortest input terminates. Default is @code{0}.
 @item repeatlast
@@ -14175,6 +14761,41 @@ By default value is 0.
 
 The @code{hysteresis} filter also supports the @ref{framesync} options.
 
+@section iccdetect
+
+Detect the colorspace  from an embedded ICC profile (if present), and update
+the frame's tags accordingly.
+
+This filter accepts the following options:
+
+@table @option
+@item force
+If true, the frame's existing colorspace tags will always be overridden by
+values detected from an ICC profile. Otherwise, they will only be assigned if
+they contain @code{unknown}. Enabled by default.
+@end table
+
+@section iccgen
+
+Generate ICC profiles and attach them to frames.
+
+This filter accepts the following options:
+
+@table @option
+@item color_primaries
+@item color_trc
+Configure the colorspace that the ICC profile will be generated for. The
+default value of @code{auto} infers the value from the input frame's metadata,
+defaulting to BT.709/sRGB as appropriate.
+
+See the @ref{setparams} filter for a list of possible values, but note that
+@code{unknown} are not valid values for this filter.
+
+@item force
+If true, an ICC profile will be generated even if it would overwrite an
+already existing ICC profile. Disabled by default.
+@end table
+
 @section identity
 
 Obtain the identity score between two input videos.
@@ -14550,6 +15171,13 @@ filter choosing the best match with the
 output the chosen camera and lens models (logged with level "info"). You must
 provide the make, camera model, and lens model as they are required.
 
+To obtain a list of available makes and models, leave out one or both of @code{make} and
+@code{model} options. The filter will send the full list to the log with level @code{INFO}.
+The first column is the make and the second column is the model.
+To obtain a list of available lenses, set any values for make and model and leave out the
+@code{lens_model} option. The filter will send the full list of lenses in the log with level
+@code{INFO}. The ffmpeg tool will exit after the list is printed.
+
 The filter accepts the following options:
 
 @table @option
@@ -14564,6 +15192,10 @@ required.
 The model of the lens (for example, "Canon EF-S 18-55mm f/3.5-5.6 IS STM"). This
 option is required.
 
+@item db_path
+The full path to the lens database folder. If not set, the filter will attempt to
+load the database from the install path when the library was built. Default is unset.
+
 @item mode
 The type of correction to apply. The following values are valid options:
 
@@ -14618,116 +15250,612 @@ unmapped areas in the output.
 The target geometry of the output image/video. The following values are valid
 options:
 
-@table @samp
-@item rectilinear (default)
-@item fisheye
-@item panoramic
-@item equirectangular
-@item fisheye_orthographic
-@item fisheye_stereographic
-@item fisheye_equisolid
-@item fisheye_thoby
+@table @samp
+@item rectilinear (default)
+@item fisheye
+@item panoramic
+@item equirectangular
+@item fisheye_orthographic
+@item fisheye_stereographic
+@item fisheye_equisolid
+@item fisheye_thoby
+@end table
+@item reverse
+Apply the reverse of image correction (instead of correcting distortion, apply
+it).
+
+@item interpolation
+The type of interpolation used when correcting distortion. The following values
+are valid options:
+
+@table @samp
+@item nearest
+@item linear (default)
+@item lanczos
+@end table
+@end table
+
+@subsection Examples
+
+@itemize
+@item
+Apply lens correction with make "Canon", camera model "Canon EOS 100D", and lens
+model "Canon EF-S 18-55mm f/3.5-5.6 IS STM" with focal length of "18" and
+aperture of "8.0".
+
+@example
+ffmpeg -i input.mov -vf lensfun=make=Canon:model="Canon EOS 100D":lens_model="Canon EF-S 18-55mm f/3.5-5.6 IS STM":focal_length=18:aperture=8 -c:v h264 -b:v 8000k output.mov
+@end example
+
+@item
+Apply the same as before, but only for the first 5 seconds of video.
+
+@example
+ffmpeg -i input.mov -vf lensfun=make=Canon:model="Canon EOS 100D":lens_model="Canon EF-S 18-55mm f/3.5-5.6 IS STM":focal_length=18:aperture=8:enable='lte(t\,5)' -c:v h264 -b:v 8000k output.mov
+@end example
+
+@end itemize
+
+@section libplacebo
+
+Flexible GPU-accelerated processing filter based on libplacebo
+(@url{https://code.videolan.org/videolan/libplacebo}). Note that this filter
+currently only accepts Vulkan input frames.
+
+@subsection Options
+
+The options for this filter are divided into the following sections:
+
+@subsubsection Output mode
+These options control the overall output mode. By default, libplacebo will try
+to preserve the source colorimetry and size as best as it can, but it will
+apply any embedded film grain, dolby vision metadata or anamorphic SAR present
+in source frames.
+@table @option
+@item w
+@item h
+Set the output video dimension expression. Default value is the input dimension.
+
+Allows for the same expressions as the @ref{scale} filter.
+
+@item format
+Set the output format override. If unset (the default), frames will be output
+in the same format as the respective input frames. Otherwise, format conversion
+will be performed.
+
+@item force_original_aspect_ratio
+@item force_divisible_by
+Work the same as the identical @ref{scale} filter options.
+
+@item normalize_sar
+If enabled (the default), output frames will always have a pixel aspect ratio
+of 1:1. If disabled, any aspect ratio mismatches, including those from e.g.
+anamorphic video sources, are forwarded to the output pixel aspect ratio.
+
+@item pad_crop_ratio
+Specifies a ratio (between @code{0.0} and @code{1.0}) between padding and
+cropping when the input aspect ratio does not match the output aspect ratio and
+@option{normalize_sar} is in effect. The default of @code{0.0} always pads the
+content with black borders, while a value of @code{1.0} always crops off parts
+of the content. Intermediate values are possible, leading to a mix of the two
+approaches.
+
+@item colorspace
+@item color_primaries
+@item color_trc
+@item range
+Configure the colorspace that output frames will be delivered in. The default
+value of @code{auto} outputs frames in the same format as the input frames,
+leading to no change. For any other value, conversion will be performed.
+
+See the @ref{setparams} filter for a list of possible values.
+
+@item apply_filmgrain
+Apply film grain (e.g. AV1 or H.274) if present in source frames, and strip
+it from the output. Enabled by default.
+
+@item apply_dolbyvision
+Apply Dolby Vision RPU metadata if present in source frames, and strip it from
+the output. Enabled by default. Note that Dolby Vision will always output
+BT.2020+PQ, overriding the usual input frame metadata. These will also be
+picked as the values of @code{auto} for the respective frame output options.
+@end table
+
+@subsubsection Scaling
+The options in this section control how libplacebo performs upscaling and (if
+necessary) downscaling. Note that libplacebo will always internally operate on
+4:4:4 content, so any sub-sampled chroma formats such as @code{yuv420p} will
+necessarily be upsampled and downsampled as part of the rendering process. That
+means scaling might be in effect even if the source and destination resolution
+are the same.
+@table @option
+@item upscaler
+@item downscaler
+Configure the filter kernel used for upscaling and downscaling. The respective
+defaults are @code{spline36} and @code{mitchell}. For a full list of possible
+values, pass @code{help} to these options. The most important values are:
+@table @samp
+
+@item none
+Forces the use of built-in GPU texture sampling (typically bilinear). Extremely
+fast but poor quality, especially when downscaling.
+
+@item bilinear
+Bilinear interpolation. Can generally be done for free on GPUs, except when
+doing so would lead to aliasing. Fast and low quality.
+
+@item nearest
+Nearest-neighbour interpolation. Sharp but highly aliasing.
+
+@item oversample
+Algorithm that looks visually similar to nearest-neighbour interpolation but
+tries to preserve pixel aspect ratio. Good for pixel art, since it results in
+minimal distortion of the artistic appearance.
+
+@item lanczos
+Standard sinc-sinc interpolation kernel.
+
+@item spline36
+Cubic spline approximation of lanczos. No difference in performance, but has
+very slightly less ringing.
+
+@item ewa_lanczos
+Elliptically weighted average version of lanczos, based on a jinc-sinc kernel.
+This is also popularly referred to as just "Jinc scaling". Slow but very high
+quality.
+
+@item gaussian
+Gaussian kernel. Has certain ideal mathematical properties, but subjectively
+very blurry.
+
+@item mitchell
+Cubic BC spline with parameters recommended by Mitchell and Netravali. Very
+little ringing.
+@end table
+
+@item lut_entries
+Configures the size of scaler LUTs, ranging from @code{1} to @code{256}. The
+default of @code{0} will pick libplacebo's internal default, typically
+@code{64}.
+
+@item antiringing
+Enables anti-ringing (for non-EWA filters). The value (between @code{0.0} and
+@code{1.0}) configures the strength of the anti-ringing algorithm. May increase
+aliasing if set too high. Disabled by default.
+
+@item sigmoid
+Enable sigmoidal compression during upscaling. Reduces ringing slightly.
+Enabled by default.
+@end table
+
+@subsubsection Debanding
+Libplacebo comes with a built-in debanding filter that is good at counteracting
+many common sources of banding and blocking. Turning this on is highly
+recommended whenever quality is desired.
+@table @option
+@item deband
+Enable (fast) debanding algorithm. Disabled by default.
+
+@item deband_iterations
+Number of deband iterations of the debanding algorithm. Each iteration is
+performed with progressively increased radius (and diminished threshold).
+Recommended values are in the range @code{1} to @code{4}. Defaults to @code{1}.
+
+@item deband_threshold
+Debanding filter strength. Higher numbers lead to more aggressive debanding.
+Defaults to @code{4.0}.
+
+@item deband_radius
+Debanding filter radius. A higher radius is better for slow gradients, while
+a lower radius is better for steep gradients. Defaults to @code{16.0}.
+
+@item deband_grain
+Amount of extra output grain to add. Helps hide imperfections. Defaults to
+@code{6.0}.
+@end table
+
+@subsubsection Color adjustment
+A collection of subjective color controls. Not very rigorous, so the exact
+effect will vary somewhat depending on the input primaries and colorspace.
+@table @option
+@item brightness
+Brightness boost, between @code{-1.0} and @code{1.0}. Defaults to @code{0.0}.
+
+@item contrast
+Contrast gain, between @code{0.0} and @code{16.0}. Defaults to @code{1.0}.
+
+@item saturation
+Saturation gain, between @code{0.0} and @code{16.0}. Defaults to @code{1.0}.
+
+@item hue
+Hue shift in radians, between @code{-3.14} and @code{3.14}. Defaults to
+@code{0.0}. This will rotate the UV subvector, defaulting to BT.709
+coefficients for RGB inputs.
+
+@item gamma
+Gamma adjustment, between @code{0.0} and @code{16.0}. Defaults to @code{1.0}.
+
+@item cones
+Cone model to use for color blindness simulation. Accepts any combination of
+@code{l}, @code{m} and @code{s}. Here are some examples:
+@table @samp
+@item m
+Deuteranomaly / deuteranopia (affecting 3%-4% of the population)
+@item l
+Protanomaly / protanopia (affecting 1%-2% of the population)
+@item l+m
+Monochromacy (very rare)
+@item l+m+s
+Achromatopsy (complete loss of daytime vision, extremely rare)
+@end table
+
+@item cone-strength
+Gain factor for the cones specified by @code{cones}, between @code{0.0} and
+@code{10.0}. A value of @code{1.0} results in no change to color vision. A
+value of @code{0.0} (the default) simulates complete loss of those cones. Values
+above @code{1.0} result in exaggerating the differences between cones, which
+may help compensate for reduced color vision.
+@end table
+
+@subsubsection Peak detection
+To help deal with sources that only have static HDR10 metadata (or no tagging
+whatsoever), libplacebo uses its own internal frame analysis compute shader to
+analyze source frames and adapt the tone mapping function in realtime. If this
+is too slow, or if exactly reproducible frame-perfect results are needed, it's
+recommended to turn this feature off.
+@table @option
+@item peak_detect
+Enable HDR peak detection. Ignores static MaxCLL/MaxFALL values in favor of
+dynamic detection from the input. Note that the detected values do not get
+written back to the output frames, they merely guide the internal tone mapping
+process. Enabled by default.
+
+@item smoothing_period
+Peak detection smoothing period, between @code{0.0} and @code{1000.0}. Higher
+values result in peak detection becoming less responsive to changes in the
+input. Defaults to @code{100.0}.
+
+@item minimum_peak
+Lower bound on the detected peak (relative to SDR white), between @code{0.0}
+and @code{100.0}. Defaults to @code{1.0}.
+
+@item scene_threshold_low
+@item scene_threshold_high
+Lower and upper thresholds for scene change detection. Expressed in a
+logarithmic scale between @code{0.0} and @code{100.0}. Default to @code{5.5}
+and @code{10.0}, respectively. Setting either to a negative value disables
+this functionality.
+
+@item overshoot
+Peak smoothing overshoot margin, between @code{0.0} and @code{1.0}. Provides a
+safety margin to prevent clipping as a result of peak smoothing. Defaults to
+@code{0.05}, corresponding to a margin of 5%.
+@end table
+
+@subsubsection Tone mapping
+The options in this section control how libplacebo performs tone-mapping and
+gamut-mapping when dealing with mismatches between wide-gamut or HDR content.
+In general, libplacebo relies on accurate source tagging and mastering display
+gamut information to produce the best results.
+@table @option
+@item intent
+Rendering intent to use when adapting between different primary color gamuts
+(after tone-mapping).
+@table @samp
+@item perceptual
+Perceptual gamut mapping. Currently equivalent to relative colorimetric.
+@item relative
+Relative colorimetric. This is the default.
+@item absolute
+Absolute colorimetric.
+@item saturation
+Saturation mapping. Forcibly stretches the source gamut to the target gamut.
+@end table
+
+@item gamut_mode
+How to handle out-of-gamut colors that can occur as a result of colorimetric
+gamut mapping.
+@table @samp
+@item clip
+Do nothing, simply clip out-of-range colors to the RGB volume. This is the
+default.
+@item warn
+Highlight out-of-gamut pixels (by coloring them pink).
+@item darken
+Linearly reduces content brightness to preserves saturated details, followed by
+clipping the remaining out-of-gamut colors. As the name implies, this makes
+everything darker, but provides a good balance between preserving details and
+colors.
+@item desaturate
+Hard-desaturates out-of-gamut colors towards white, while preserving the
+luminance. Has a tendency to shift colors.
+@end table
+
+@item tonemapping
+Tone-mapping algorithm to use. Available values are:
+@table @samp
+@item auto
+Automatic selection based on internal heuristics. This is the default.
+@item clip
+Performs no tone-mapping, just clips out-of-range colors. Retains perfect color
+accuracy for in-range colors but completely destroys out-of-range information.
+Does not perform any black point adaptation. Not configurable.
+@item bt.2390
+EETF from the ITU-R Report BT.2390, a hermite spline roll-off with linear
+segment. The knee point offset is configurable. Note that this parameter
+defaults to @code{1.0}, rather than the value of @code{0.5} from the ITU-R
+spec.
+@item bt.2446a
+EETF from ITU-R Report BT.2446, method A. Designed for well-mastered HDR
+sources. Can be used for both forward and inverse tone mapping. Not
+configurable.
+@item spline
+Simple spline consisting of two polynomials, joined by a single pivot point.
+The parameter gives the pivot point (in PQ space), defaulting to @code{0.30}.
+Can be used for both forward and inverse tone mapping.
+@item reinhard
+Simple non-linear, global tone mapping algorithm. The parameter specifies the
+local contrast coefficient at the display peak. Essentially, a parameter of
+@code{0.5} implies that the reference white will be about half as bright as
+when clipping. Defaults to @code{0.5}, which results in the simplest
+formulation of this function.
+@item mobius
+Generalization of the reinhard tone mapping algorithm to support an additional
+linear slope near black. The tone mapping parameter indicates the trade-off
+between the linear section and the non-linear section. Essentially, for a given
+parameter @var{x}, every color value below @var{x} will be mapped linearly,
+while higher values get non-linearly tone-mapped. Values near @code{1.0} make
+this curve behave like @code{clip}, while values near @code{0.0} make this
+curve behave like @code{reinhard}. The default value is @code{0.3}, which
+provides a good balance between colorimetric accuracy and preserving
+out-of-gamut details.
+@item hable
+Piece-wise, filmic tone-mapping algorithm developed by John Hable for use in
+Uncharted 2, inspired by a similar tone-mapping algorithm used by Kodak.
+Popularized by its use in video games with HDR rendering. Preserves both dark
+and bright details very well, but comes with the drawback of changing the
+average brightness quite significantly. This is sort of similar to
+@code{reinhard} with parameter @code{0.24}.
+@item gamma
+Fits a gamma (power) function to transfer between the source and target color
+spaces, effectively resulting in a perceptual hard-knee joining two roughly
+linear sections. This preserves details at all scales fairly accurately, but
+can result in an image with a muted or dull appearance. The parameter is used
+as the cutoff point, defaulting to @code{0.5}.
+@item linear
+Linearly stretches the input range to the output range, in PQ space. This will
+preserve all details accurately, but results in a significantly different
+average brightness. Can be used for inverse tone-mapping in addition to regular
+tone-mapping. The parameter can be used as an additional linear gain
+coefficient (defaulting to @code{1.0}).
+@end table
+
+@item tonemapping_param
+For tunable tone mapping functions, this parameter can be used to fine-tune the
+curve behavior. Refer to the documentation of @code{tonemapping}. The default
+value of @code{0.0} is replaced by the curve's preferred default setting.
+
+@item tonemapping_mode
+This option determines how the tone mapping function specified by
+@code{tonemapping} is applied to the colors in a scene. Possible values are:
+@table @samp
+@item auto
+Automatic selection based on internal heuristics. This is the default.
+@item rgb
+Apply the function per-channel in the RGB colorspace.
+Per-channel tone-mapping in RGB. Guarantees no clipping and heavily desaturates
+the output, but distorts the colors quite significantly. Very similar to the
+"Hollywood" look and feel.
+@item max
+Tone-mapping is performed on the brightest component found in the signal. Good
+at preserving details in highlights, but has a tendency to crush blacks.
+@item hybrid
+Tone-map per-channel for highlights and linearly (luma-based) for
+midtones/shadows, based on a fixed gamma @code{2.4} coefficient curve.
+@item luma
+Tone-map linearly on the luma component (CIE Y), and adjust (desaturate) the
+chromaticities to compensate using a simple constant factor. This is
+essentially the mode used in ITU-R BT.2446 method A.
+@end table
+
+@item inverse_tonemapping
+If enabled, this filter will also attempt stretching SDR signals to fill HDR
+output color volumes. Disabled by default.
+
+@item tonemapping_crosstalk
+Extra tone-mapping crosstalk factor, between @code{0.0} and @code{0.3}. This
+can help reduce issues tone-mapping certain bright spectral colors. Defaults to
+@code{0.04}.
+
+@item tonemapping_lut_size
+Size of the tone-mapping LUT, between @code{2} and @code{1024}. Defaults to
+@code{256}. Note that this figure is squared when combined with
+@code{peak_detect}.
+@end table
+
+@subsubsection Dithering
+By default, libplacebo will dither whenever necessary, which includes rendering
+to any integer format below 16-bit precision. It's recommended to always leave
+this on, since not doing so may result in visible banding in the output, even
+if the @code{debanding} filter is enabled. If maximum performance is needed,
+use @code{ordered_fixed} instead of disabling dithering.
+@table @option
+@item dithering
+Dithering method to use. Accepts the following values:
+@table @samp
+@item none
+Disables dithering completely. May result in visible banding.
+@item blue
+Dither with pseudo-blue noise. This is the default.
+@item ordered
+Tunable ordered dither pattern.
+@item ordered_fixed
+Faster ordered dither with a fixed size of @code{6}. Texture-less.
+@item white
+Dither with white noise. Texture-less.
+@end table
+
+@item dither_lut_size
+Dither LUT size, as log base2 between @code{1} and @code{8}. Defaults to
+@code{6}, corresponding to a LUT size of @code{64x64}.
+
+@item dither_temporal
+Enables temporal dithering. Disabled by default.
 @end table
-@item reverse
-Apply the reverse of image correction (instead of correcting distortion, apply
-it).
 
-@item interpolation
-The type of interpolation used when correcting distortion. The following values
-are valid options:
+@subsubsection Custom shaders
+libplacebo supports a number of custom shaders based on the mpv .hook GLSL
+syntax. A collection of such shaders can be found here:
+@url{https://github.com/mpv-player/mpv/wiki/User-Scripts#user-shaders}
 
-@table @samp
-@item nearest
-@item linear (default)
-@item lanczos
+A full description of the mpv shader format is beyond the scope of this
+section, but a summary can be found here:
+@url{https://mpv.io/manual/master/#options-glsl-shader}
+@table @option
+@item custom_shader_path
+Specifies a path to a custom shader file to load at runtime.
+
+@item custom_shader_bin
+Specifies a complete custom shader as a raw string.
 @end table
+
+@subsubsection Debugging / performance
+All of the options in this section default off. They may be of assistance when
+attempting to squeeze the maximum performance at the cost of quality.
+@table @option
+@item skip_aa
+Disable anti-aliasing when downscaling.
+
+@item polar_cutoff
+Truncate polar (EWA) scaler kernels below this absolute magnitude, between
+@code{0.0} and @code{1.0}.
+
+@item disable_linear
+Disable linear light scaling.
+
+@item disable_builtin
+Disable built-in GPU sampling (forces LUT).
+
+@item force_icc_lut
+Force the use of a full ICC 3DLUT for gamut mapping.
+
+@item disable_fbos
+Forcibly disable FBOs, resulting in loss of almost all functionality, but
+offering the maximum possible speed.
 @end table
 
-@subsection Examples
+@subsection Commands
+This filter supports almost all of the above options as @ref{commands}.
 
+@subsection Examples
 @itemize
 @item
-Apply lens correction with make "Canon", camera model "Canon EOS 100D", and lens
-model "Canon EF-S 18-55mm f/3.5-5.6 IS STM" with focal length of "18" and
-aperture of "8.0".
+Complete example for how to initialize the Vulkan device, upload frames to the
+GPU, perform filter conversion to yuv420p, and download frames back to the CPU
+for output. Note that in specific cases you can get around the need to perform
+format conversion by specifying the correct @code{format} filter option
+corresponding to the input frames.
+@example
+ffmpeg -i $INPUT -init_hw_device vulkan -vf hwupload,libplacebo=format=yuv420p,hwdownload,format=yuv420p $OUTPUT
+@end example
 
+@item
+Tone-map input to standard gamut BT.709 output:
 @example
-ffmpeg -i input.mov -vf lensfun=make=Canon:model="Canon EOS 100D":lens_model="Canon EF-S 18-55mm f/3.5-5.6 IS STM":focal_length=18:aperture=8 -c:v h264 -b:v 8000k output.mov
+libplacebo=colorspace=bt709:color_primaries=bt709:color_trc=bt709:range=tv
 @end example
 
 @item
-Apply the same as before, but only for the first 5 seconds of video.
+Rescale input to fit into standard 1080p, with high quality scaling:
+@example
+libplacebo=w=1920:h=1080:force_original_aspect_ratio=decrease:normalize_sar=true:upscaler=ewa_lanczos:downscaler=ewa_lanczos
+@end example
 
+@item
+Convert input to standard sRGB JPEG:
 @example
-ffmpeg -i input.mov -vf lensfun=make=Canon:model="Canon EOS 100D":lens_model="Canon EF-S 18-55mm f/3.5-5.6 IS STM":focal_length=18:aperture=8:enable='lte(t\,5)' -c:v h264 -b:v 8000k output.mov
+libplacebo=format=yuv420p:colorspace=bt470bg:color_primaries=bt709:color_trc=iec61966-2-1:range=pc
+@end example
+
+@item
+Use higher quality debanding settings:
+@example
+libplacebo=deband=true:deband_iterations=3:deband_radius=8:deband_threshold=6
+@end example
+
+@item
+Run this filter on the CPU, on systems with Mesa installed (and with the most
+expensive options disabled):
+@example
+ffmpeg ... -init_hw_device vulkan:llvmpipe ... -vf libplacebo=upscaler=none:downscaler=none:peak_detect=false
 @end example
 
+@item
+Suppress CPU-based AV1/H.274 film grain application in the decoder, in favor of
+doing it with this filter. Note that this is only a gain if the frames are
+either already on the GPU, or if you're using libplacebo for other purposes,
+since otherwise the VRAM roundtrip will more than offset any expected speedup.
+@example
+ffmpeg -export_side_data +film_grain ... -vf libplacebo=apply_filmgrain=true
+@end example
 @end itemize
 
 @section libvmaf
 
-Obtain the VMAF (Video Multi-Method Assessment Fusion)
-score between two input videos.
+Calulate the VMAF (Video Multi-Method Assessment Fusion) score for a
+reference/distorted pair of input videos.
 
-The first input is the encoded video, and the second input is the reference video.
+The first input is the distorted video, and the second input is the reference video.
 
 The obtained VMAF score is printed through the logging system.
 
 It requires Netflix's vmaf library (libvmaf) as a pre-requisite.
 After installing the library it can be enabled using:
 @code{./configure --enable-libvmaf}.
-If no model path is specified it uses the default model: @code{vmaf_v0.6.1.pkl}.
 
 The filter has following options:
 
 @table @option
-@item model_path
-Set the model path which is to be used for SVM.
-Default value: @code{"/usr/local/share/model/vmaf_v0.6.1.pkl"}
-
-@item log_path
-Set the file path to be used to store logs.
+@item model
+A `|` delimited list of vmaf models. Each model can be configured with a number of parameters.
+Default value: @code{"version=vmaf_v0.6.1"}
 
-@item log_fmt
-Set the format of the log file (csv, json or xml).
+@item model_path
+Deprecated, use model='path=...'.
 
 @item enable_transform
-This option can enable/disable the @code{score_transform} applied to the final predicted VMAF score,
-if you have specified score_transform option in the input parameter file passed to @code{run_vmaf_training.py}
-Default value: @code{false}
+Deprecated, use model='enable_transform=true'.
 
 @item phone_model
-Invokes the phone model which will generate VMAF scores higher than in the
-regular model, which is more suitable for laptop, TV, etc. viewing conditions.
-Default value: @code{false}
+Deprecated, use model='enable_transform=true'.
+
+@item enable_conf_interval
+Deprecated, use model='enable_conf_interval=true'.
+
+@item feature
+A `|` delimited list of features. Each feature can be configured with a number of parameters.
 
 @item psnr
-Enables computing psnr along with vmaf.
-Default value: @code{false}
+Deprecated, use feature='name=psnr'.
 
 @item ssim
-Enables computing ssim along with vmaf.
-Default value: @code{false}
+Deprecated, use feature='name=ssim'.
 
 @item ms_ssim
-Enables computing ms_ssim along with vmaf.
-Default value: @code{false}
+Deprecated, use feature='name=ms_ssim'.
+
+@item log_path
+Set the file path to be used to store log files.
 
-@item pool
-Set the pool method to be used for computing vmaf.
-Options are @code{min}, @code{harmonic_mean} or @code{mean} (default).
+@item log_fmt
+Set the format of the log file (xml, json, csv, or sub).
 
 @item n_threads
-Set number of threads to be used when computing vmaf.
-Default value: @code{0}, which makes use of all available logical processors.
+Set number of threads to be used when initializing libvmaf.
+Default value: @code{0}, no threads.
 
 @item n_subsample
-Set interval for frame subsampling used when computing vmaf.
-Default value: @code{1}
-
-@item enable_conf_interval
-Enables confidence interval.
-Default value: @code{false}
+Set frame subsampling interval to be used.
 @end table
 
 This filter also supports the @ref{framesync} options.
@@ -14735,23 +15863,31 @@ This filter also supports the @ref{frame
 @subsection Examples
 @itemize
 @item
-On the below examples the input file @file{main.mpg} being processed is
-compared with the reference file @file{ref.mpg}.
+In the examples below, a distorted video @file{distorted.mpg} is
+compared with a reference file @file{reference.mpg}.
+
+@item
+Basic usage:
+@example
+ffmpeg -i distorted.mpg -i reference.mpg -lavfi libvmaf=log_path=output.xml -f null -
+@end example
 
+@item
+Example with multiple models:
 @example
-ffmpeg -i main.mpg -i ref.mpg -lavfi libvmaf -f null -
+ffmpeg -i distorted.mpg -i reference.mpg -lavfi libvmaf='model=version=vmaf_v0.6.1\\:name=vmaf|version=vmaf_v0.6.1neg\\:name=vmaf_neg' -f null -
 @end example
 
 @item
-Example with options:
+Example with multiple addtional features:
 @example
-ffmpeg -i main.mpg -i ref.mpg -lavfi libvmaf="psnr=1:log_fmt=json" -f null -
+ffmpeg -i distorted.mpg -i reference.mpg -lavfi libvmaf='feature=name=psnr|name=ciede' -f null -
 @end example
 
 @item
 Example with options and different containers:
 @example
-ffmpeg -i main.mpg -i ref.mkv -lavfi "[0:v]settb=AVTB,setpts=PTS-STARTPTS[main];[1:v]settb=AVTB,setpts=PTS-STARTPTS[ref];[main][ref]libvmaf=psnr=1:log_fmt=json" -f null -
+ffmpeg -i distorted.mpg -i reference.mkv -lavfi "[0:v]settb=AVTB,setpts=PTS-STARTPTS[main];[1:v]settb=AVTB,setpts=PTS-STARTPTS[ref];[main][ref]libvmaf=log_fmt=json:log_path=output.json" -f null -
 @end example
 @end itemize
 
@@ -15043,7 +16179,7 @@ expression
 
 @end table
 
-All expressions default to "val".
+All expressions default to "clipval".
 
 @subsection Commands
 
@@ -15439,6 +16575,18 @@ plane, 'Cc' describes the mapping for th
 
 @item format
 Set output pixel format. Default is @code{yuva444p}.
+
+@item map0s
+@item map1s
+@item map2s
+@item map3s
+Set input to output stream mapping for output Nth plane. Default is @code{0}.
+
+@item map0p
+@item map1p
+@item map2p
+@item map3p
+Set input to output plane mapping for output Nth plane. Default is @code{0}.
 @end table
 
 @subsection Examples
@@ -15643,6 +16791,9 @@ Specify scale, if it is set it will be m
 of each weight multiplied with pixel values to give final destination
 pixel value. By default @var{scale} is auto scaled to sum of weights.
 
+@item planes
+Set which planes to filter. Default is all. Allowed range is from 0 to 15.
+
 @item duration
 Specify how end of stream is determined.
 @table @samp
@@ -15663,6 +16814,7 @@ This filter supports the following comma
 @table @option
 @item weights
 @item scale
+@item planes
 Syntax is same as option with same name.
 @end table
 
@@ -15793,6 +16945,29 @@ with the reference file @file{ref.mpg}.
 ffmpeg -i main.mpg -i ref.mpg -lavfi msad -f null -
 @end example
 
+@section multiply
+Multiply first video stream pixels values with second video stream pixels values.
+
+The filter accepts the following options:
+
+@table @option
+@item scale
+Set the scale applied to second video stream. By default is @code{1}.
+Allowed range is from @code{0} to @code{9}.
+
+@item offset
+Set the offset applied to second video stream. By default is @code{0.5}.
+Allowed range is from @code{-1} to @code{1}.
+
+@item planes
+Specify planes from input video stream that will be processed.
+By default all planes are processed.
+@end table
+
+@subsection Commands
+
+This filter supports same @ref{commands} as options.
+
 @section negate
 
 Negate (invert) the input video.
@@ -17165,6 +18340,35 @@ format=monow, pixdesctest
 
 can be used to test the monowhite pixel format descriptor definition.
 
+@section pixelize
+Apply pixelization to video stream.
+
+The filter accepts the following options:
+@table @option
+@item width, w
+@item height, h
+Set block dimensions that will be used for pixelization.
+Default value is @code{16}.
+
+@item mode, m
+Set the mode of pixelization used.
+
+Possible values are:
+@table @samp
+@item avg
+@item min
+@item max
+@end table
+Default value is @code{avg}.
+
+@item planes, p
+Set what planes to filter. Default is to filter all planes.
+@end table
+
+@subsection Commands
+
+This filter supports all options as @ref{commands}.
+
 @section pixscope
 
 Display sample values of color channels. Mainly useful for checking color
@@ -19875,6 +21079,29 @@ ffmpeg -i input1.mkv -i input2.mkv -filt
 
 @end itemize
 
+@anchor{siti}
+@section siti
+
+Calculate Spatial Info (SI) and Temporal Info (TI) scores for a video, as defined
+in ITU-T P.910: Subjective video quality assessment methods for multimedia
+applications. Available PDF at @url{https://www.itu.int/rec/T-REC-P.910-199909-S/en }.
+
+It accepts the following option:
+
+@table @option
+@item print_summary
+If set to 1, Summary statistics will be printed to the console. Default 0.
+@end table
+
+@subsection Examples
+@itemize
+@item
+To calculate SI/TI metrics and print summary:
+@example
+ffmpeg -i input.mp4 -vf siti=print_summary=1 -f null -
+@end example
+@end itemize
+
 @anchor{smartblur}
 @section smartblur
 
@@ -20734,9 +21961,8 @@ The filter accepts the following options
 @table @option
 
 @item layout
-Set the grid size (i.e. the number of lines and columns). For the syntax of
-this option, check the
-@ref{video size syntax,,"Video size" section in the ffmpeg-utils manual,ffmpeg-utils}.
+Set the grid size in the form @code{COLUMNSxROWS}. Range is upto UINT_MAX cells.
+Default is @code{6x5}.
 
 @item nb_frames
 Set the maximum number of frames to render in the given area. It must be less
@@ -20744,12 +21970,12 @@ than or equal to @var{w}x@var{h}. The de
 the area will be used.
 
 @item margin
-Set the outer border margin in pixels.
+Set the outer border margin in pixels. Range is 0 to 1024. Default is @code{0}.
 
 @item padding
 Set the inner border thickness (i.e. the number of pixels between frames). For
 more advanced padding options (such as having different values for the edges),
-refer to the pad video filter.
+refer to the pad video filter. Range is 0 to 1024. Default is @code{0}.
 
 @item color
 Specify the color of the unused area. For the syntax of this option, check the
@@ -20758,12 +21984,12 @@ The default value of @var{color} is "bla
 
 @item overlap
 Set the number of frames to overlap when tiling several successive frames together.
-The value must be between @code{0} and @var{nb_frames - 1}.
+The value must be between @code{0} and @var{nb_frames - 1}. Default is @code{0}.
 
 @item init_padding
 Set the number of frames to initially be empty before displaying first output frame.
 This controls how soon will one get first output frame.
-The value must be between @code{0} and @var{nb_frames - 1}.
+The value must be between @code{0} and @var{nb_frames - 1}. Default is @code{0}.
 @end table
 
 @subsection Examples
@@ -21090,6 +22316,9 @@ unset weights.
 Specify scale, if it is set it will be multiplied with sum
 of each weight multiplied with pixel values to give final destination
 pixel value. By default @var{scale} is auto scaled to sum of weights.
+
+@item planes
+Set which planes to filter. Default is all. Allowed range is from 0 to 15.
 @end table
 
 @subsection Examples
@@ -21120,6 +22349,7 @@ This filter supports the following comma
 @table @option
 @item weights
 @item scale
+@item planes
 Syntax is same as option with same name.
 @end table
 
@@ -21526,6 +22756,23 @@ sharpen it, a value of zero will disable
 
 Default value is 0.0.
 
+@item alpha_msize_x, ax
+Set the alpha matrix horizontal size. It must be an odd integer
+between 3 and 23. The default value is 5.
+
+@item alpha_msize_y, ay
+Set the alpha matrix vertical size. It must be an odd integer
+between 3 and 23. The default value is 5.
+
+@item alpha_amount, aa
+Set the alpha effect strength. It must be a floating point number, reasonable
+values lay between -1.5 and 1.5.
+
+Negative values will blur the input video, while positive values will
+sharpen it, a value of zero will disable the effect.
+
+Default value is 0.0.
+
 @end table
 
 All parameters are optional and default to the equivalent of the
@@ -23061,6 +24308,8 @@ Set one of available transition effects:
 @item squeezeh
 @item squeezev
 @item zoomin
+@item fadefast
+@item fadeslow
 @end table
 Default transition effect is fade.
 
@@ -23177,8 +24426,26 @@ the output video frame will be filled. S
 other if their position doesn't leave enough space for the full frame of
 adjoining videos.
 
-For 2 inputs, a default layout of @code{0_0|w0_0} is set. In all other cases,
-a layout must be set by the user.
+For 2 inputs, a default layout of @code{0_0|w0_0} (equivalent to
+@code{grid=2x1}) is set. In all other cases, a layout or a grid must be set by
+the user. Either @code{grid} or @code{layout} can be specified at a time.
+Specifying both will result in an error.
+
+@item grid
+Specify a fixed size grid of inputs.
+This option is used to create a fixed size grid of the input streams. Set the
+grid size in the form @code{COLUMNSxROWS}. There must be @code{ROWS * COLUMNS}
+input streams and they will be arranged as a grid with @code{ROWS} rows and
+@code{COLUMNS} columns. When using this option, each input stream within a row
+must have the same height and all the rows must have the same width.
+
+If @code{grid} is set, then @code{inputs} option is ignored and is implicitly
+set to @code{ROWS * COLUMNS}.
+
+For 2 inputs, a default grid of @code{2x1} (equivalent to
+@code{layout=0_0|w0_0}) is set. In all other cases, a layout or a grid must be
+set by the user. Either @code{grid} or @code{layout} can be specified at a time.
+Specifying both will result in an error.
 
 @item shortest
 If set to 1, force the output to terminate when the shortest input
@@ -24479,6 +25746,30 @@ __kernel void blend_images(__write_only
 
 @end itemize
 
+@section remap_opencl
+
+Remap pixels using 2nd: Xmap and 3rd: Ymap input video stream.
+
+Destination pixel at position (X, Y) will be picked from source (x, y) position
+where x = Xmap(X, Y) and y = Ymap(X, Y). If mapping values are out of range, zero
+value for pixel will be used for destination pixel.
+
+Xmap and Ymap input video streams must be of same dimensions. Output video stream
+will have Xmap/Ymap video stream dimensions.
+Xmap and Ymap input video streams are 32bit float pixel format, single channel.
+
+@table @option
+@item interp
+Specify interpolation used for remapping of pixels.
+Allowed values are @code{near} and @code{linear}.
+Default value is @code{linear}.
+
+@item fill
+Specify the color of the unmapped pixels. For the syntax of this option,
+check the @ref{color syntax,,"Color" section in the ffmpeg-utils
+manual,ffmpeg-utils}. Default color is @code{black}.
+@end table
+
 @section roberts_opencl
 Apply the Roberts cross operator (@url{https://en.wikipedia.org/wiki/Roberts_cross}) to input video stream.
 
@@ -24798,6 +26089,57 @@ To enable compilation of these filters y
 
 To use vaapi filters, you need to setup the vaapi device correctly. For more information, please read @url{https://trac.ffmpeg.org/wiki/Hardware/VAAPI}
 
+@section overlay_vaapi
+
+Overlay one video on the top of another.
+
+It takes two inputs and has one output. The first input is the "main" video on which the second input is overlaid.
+This filter requires same memory layout for all the inputs. So, format conversion may be needed.
+
+The filter accepts the following options:
+
+@table @option
+
+@item x
+Set the x coordinate of the overlaid video on the main video.
+Default value is @code{0}.
+
+@item y
+Set the y coordinate of the overlaid video on the main video.
+Default value is @code{0}.
+
+@item w
+Set the width of the overlaid video on the main video.
+Default value is the width of input overlay video.
+
+@item h
+Set the height of the overlaid video on the main video.
+Default value is the height of input overlay video.
+
+@item alpha
+Set blocking detection thresholds. Allowed range is 0.0 to 1.0, it
+requires an input video with alpha channel.
+Default value is @code{0.0}.
+
+@end table
+
+@subsection Examples
+
+@itemize
+@item
+Overlay an image LOGO at the top-left corner of the INPUT video. Both inputs for this filter are yuv420p format.
+@example
+-i INPUT -i LOGO -filter_complex "[0:v]hwupload[a], [1:v]format=yuv420p, hwupload[b], [a][b]overlay_vaapi" OUTPUT
+@end example
+@item
+Overlay an image LOGO at the offset (200, 100) from the top-left corner of the INPUT video.
+The inputs have same memory layout for color channels, the overlay has additional alpha plane, like INPUT is yuv420p, and the LOGO is yuva420p.
+@example
+-i INPUT -i LOGO -filter_complex "[0:v]hwupload[a], [1:v]format=yuva420p, hwupload[b], [a][b]overlay_vaapi=x=200:y=100:w=400:h=300:alpha=1.0, hwdownload, format=nv12" OUTPUT
+@end example
+
+@end itemize
+
 @section tonemap_vaapi
 
 Perform HDR(High Dynamic Range) to SDR(Standard Dynamic Range) conversion with tone-mapping.
@@ -25128,6 +26470,9 @@ supposed to be generated forever.
 
 @item speed
 Set speed of gradients rotation.
+
+@item type, t
+Set type of gradients, can be @code{linear} or @code{radial} or @code{circular} or @code{spiral}.
 @end table
 
 
@@ -25427,6 +26772,7 @@ ffplay -f lavfi life=s=300x200:mold=10:r
 @anchor{allrgb}
 @anchor{allyuv}
 @anchor{color}
+@anchor{colorchart}
 @anchor{colorspectrum}
 @anchor{haldclutsrc}
 @anchor{nullsrc}
@@ -25438,7 +26784,7 @@ ffplay -f lavfi life=s=300x200:mold=10:r
 @anchor{testsrc}
 @anchor{testsrc2}
 @anchor{yuvtestsrc}
-@section allrgb, allyuv, color, colorspectrum, haldclutsrc, nullsrc, pal75bars, pal100bars, rgbtestsrc, smptebars, smptehdbars, testsrc, testsrc2, yuvtestsrc
+@section allrgb, allyuv, color, colorchart, colorspectrum, haldclutsrc, nullsrc, pal75bars, pal100bars, rgbtestsrc, smptebars, smptehdbars, testsrc, testsrc2, yuvtestsrc
 
 The @code{allrgb} source returns frames of size 4096x4096 of all rgb colors.
 
@@ -25446,6 +26792,8 @@ The @code{allyuv} source returns frames
 
 The @code{color} source provides an uniformly colored input.
 
+The @code{colorchart} source provides a colors checker chart.
+
 The @code{colorspectrum} source provides a color spectrum input.
 
 The @code{haldclutsrc} source provides an identity Hald CLUT. See also
@@ -25549,6 +26897,22 @@ Set the type of the color spectrum, only
 @item white
 @item all
 @end table
+
+@item patch_size
+Set patch size of single color patch, only available in the
+@code{colorchart} source. Default is @code{64x64}.
+
+@item preset
+Set colorchecker colors preset, only available in the
+@code{colorchart} source.
+
+Available values are:
+@table @samp
+@item reference
+@item skintones
+@end table
+
+Default value is @code{reference}.
 @end table
 
 @subsection Examples
@@ -25738,6 +27102,9 @@ Default value is @code{1024x256}.
 Specify list of colors separated by space or by '|' which will be used to
 draw channels. Unrecognized or missing colors will be replaced
 by white color.
+
+@item mode, m
+Set output mode. Can be @code{bars} or @code{trace}. Default is @code{bars}.
 @end table
 
 @section adrawgraph
@@ -25825,6 +27192,18 @@ replace old rows with new ones.
 scroll from top to bottom.
 @end table
 Default is @code{replace}.
+
+@item hmode
+Set histogram mode.
+
+It accepts the following values:
+@table @samp
+@item abs
+Use absolute values of samples.
+@item sign
+Use untouched values of samples.
+@end table
+Default is @code{abs}.
 @end table
 
 @section aphasemeter
@@ -26534,6 +27913,10 @@ A processing speed faster than what is p
 be achieved.
 @end table
 
+@subsection Commands
+
+Both filters supports the all above options as @ref{commands}.
+
 @section segment, asegment
 
 Split single input stream into multiple streams.
@@ -26882,6 +28265,12 @@ The end time in seconds of the current c
 
 @item TI
 The interpolated time of the current command interval, TI = (T - TS) / (TE - TS).
+
+@item W
+The video frame width.
+
+@item H
+The video frame height.
 @end table
 
 @end table
@@ -27464,6 +28853,9 @@ Specify size of video. For the syntax of
 @ref{video size syntax,,"Video size" section in the ffmpeg-utils manual,ffmpeg-utils}.
 Default is @code{1024x512}.
 
+@item rate, r
+Set video rate. Default is @code{25}.
+
 @item mode
 Set display mode.
 This set how each frequency bin will be represented.
@@ -27580,6 +28972,9 @@ It accepts the following values:
 @item delay
 @end table
 Default is @code{magnitude}.
+
+@item channels
+Set channels to use when processing audio. By default all are processed.
 @end table
 
 @section showspatial
@@ -27829,6 +29224,9 @@ Allowed range is from 10 to 200.
 @item limit
 Set upper limit of input audio samples volume in dBFS. Default is 0 dBFS.
 Allowed range is from -100 to 100.
+
+@item opacity
+Set opacity strength when using pixel format output with alpha component.
 @end table
 
 The usage is very similar to the showwaves filter; see the examples in that
@@ -28010,6 +29408,9 @@ Allowed range is from 10 to 200.
 @item limit
 Set upper limit of input audio samples volume in dBFS. Default is 0 dBFS.
 Allowed range is from -100 to 100.
+
+@item opacity
+Set opacity strength when using pixel format output with alpha component.
 @end table
 
 @subsection Examples
@@ -28504,6 +29905,43 @@ Below is a description of the currently
 This is the same as @ref{movie} source, except it selects an audio
 stream by default.
 
+@section avsynctest
+Generate an Audio/Video Sync Test.
+
+Generated stream periodically shows flash video frame and emits beep in audio.
+Useful to inspect A/V sync issues.
+
+It accepts the following options:
+
+@table @option
+@item size, s
+Set output video size. Default value is @code{hd720}.
+
+@item framerate, fr
+Set output video frame rate. Default value is @code{30}.
+
+@item samplerate, sr
+Set output audio sample rate. Default value is @code{44100}.
+
+@item amplitude, a
+Set output audio beep amplitude. Default value is @code{0.7}.
+
+@item period, p
+Set output audio beep period in seconds. Default value is @code{3}.
+
+@item delay, dl
+Set output video flash delay in number of frames. Default value is @code{0}.
+
+@item cycle, c
+Enable cycling of video delays, by default is disabled.
+
+@item duration, d
+Set stream output duration. By default duration is unlimited.
+
+@item fg, bg, ag
+Set foreground/background/additional color.
+@end table
+
 @anchor{movie}
 @section movie
 
diff -pruN 7:5.0.1-3/doc/general_contents.texi 7:5.1-1/doc/general_contents.texi
--- 7:5.0.1-3/doc/general_contents.texi	2022-01-14 18:45:39.000000000 +0000
+++ 7:5.1-1/doc/general_contents.texi	2022-07-22 17:58:38.000000000 +0000
@@ -171,6 +171,13 @@ Go to @url{https://github.com/TimothyGu/
 installing the library. Then pass @code{--enable-libilbc} to configure to
 enable it.
 
+@section libjxl
+
+JPEG XL is an image format intended to fully replace legacy JPEG for an extended
+period of life. See @url{https://jpegxl.info/} for more information, and see
+@url{https://github.com/libjxl/libjxl} for the library source. You can pass
+@code{--enable-libjxl} to configure in order enable the libjxl wrapper.
+
 @section libvpx
 
 FFmpeg can make use of the libvpx library for VP8/VP9 decoding and encoding.
@@ -578,6 +585,7 @@ library:
 @item raw aptX                  @tab X @tab X
 @item raw aptX HD               @tab X @tab X
 @item raw Chinese AVS video     @tab X @tab X
+@item raw DFPWM                 @tab X @tab X
 @item raw Dirac                 @tab X @tab X
 @item raw DNxHD                 @tab X @tab X
 @item raw DTS                   @tab X @tab X
@@ -767,6 +775,8 @@ following image formats are supported:
     @tab PGM with U and V components in YUV 4:2:0
 @item PGX          @tab   @tab X
     @tab PGX file decoder
+@item PHM          @tab X @tab X
+    @tab Portable HalfFloatMap image
 @item PIC          @tab @tab X
     @tab Pictor/PC Paint
 @item PNG          @tab X @tab X
@@ -777,6 +787,8 @@ following image formats are supported:
     @tab Photoshop
 @item PTX          @tab   @tab X
     @tab V.Flash PTX format
+@item QOI          @tab X @tab X
+    @tab Quite OK Image format
 @item SGI          @tab X @tab X
     @tab SGI RGB image format
 @item Sun Rasterfile  @tab X @tab X
@@ -785,6 +797,8 @@ following image formats are supported:
     @tab YUV, JPEG and some extension is not supported yet.
 @item Truevision Targa  @tab X @tab X
     @tab Targa (.TGA) image format
+@item VBN  @tab X @tab X
+    @tab Vizrt Binary Image format
 @item WebP         @tab E @tab X
     @tab WebP image format, encoding supported through external library libwebp
 @item XBM  @tab X @tab X
@@ -1194,6 +1208,7 @@ following image formats are supported:
 @item CRI HCA                @tab     @tab X
 @item Delphine Software International CIN audio  @tab     @tab  X
     @tab Codec used in Delphine Software International games.
+@item DFPWM                  @tab  X  @tab  X
 @item Digital Speech Standard - Standard Play mode (DSS SP) @tab     @tab  X
 @item Discworld II BMV Audio @tab     @tab  X
 @item COOK                   @tab     @tab  X
diff -pruN 7:5.0.1-3/doc/indevs.texi 7:5.1-1/doc/indevs.texi
--- 7:5.0.1-3/doc/indevs.texi	2022-01-14 18:45:39.000000000 +0000
+++ 7:5.1-1/doc/indevs.texi	2022-07-22 17:58:38.000000000 +0000
@@ -1289,11 +1289,11 @@ Specify the samplerate in Hz, by default
 Specify the channels in use, by default 2 (stereo) is set.
 
 @item frame_size
-Specify the number of bytes per frame, by default it is set to 1024.
+This option does nothing and is deprecated.
 
 @item fragment_size
-Specify the minimal buffering fragment in PulseAudio, it will affect the
-audio latency. By default it is unset.
+Specify the size in bytes of the minimal buffering fragment in PulseAudio, it
+will affect the audio latency. By default it is set to 50 ms amount of data.
 
 @item wallclock
 Set the initial PTS using the current time. Default is 1.
diff -pruN 7:5.0.1-3/doc/Makefile 7:5.1-1/doc/Makefile
--- 7:5.0.1-3/doc/Makefile	2022-01-14 18:45:39.000000000 +0000
+++ 7:5.1-1/doc/Makefile	2022-07-22 17:58:38.000000000 +0000
@@ -27,6 +27,9 @@ HTMLPAGES   = $(AVPROGS-yes:%=doc/%.html
               doc/mailing-list-faq.html                                 \
               doc/nut.html                                              \
               doc/platform.html                                         \
+              $(SRC_PATH)/doc/bootstrap.min.css                         \
+              $(SRC_PATH)/doc/style.min.css                             \
+              $(SRC_PATH)/doc/default.css                               \
 
 TXTPAGES    = doc/fate.txt                                              \
 
diff -pruN 7:5.0.1-3/doc/muxers.texi 7:5.1-1/doc/muxers.texi
--- 7:5.0.1-3/doc/muxers.texi	2022-01-14 18:45:39.000000000 +0000
+++ 7:5.1-1/doc/muxers.texi	2022-07-22 17:58:38.000000000 +0000
@@ -1060,6 +1060,8 @@ and remove the @code{#EXT-X-ENDLIST} fro
 @item round_durations
 Round the duration info in the playlist file segment info to integer
 values, instead of using floating point.
+If there are no other features requiring higher HLS versions be used,
+then this will allow ffmpeg to output a HLS version 2 m3u8.
 
 @item discont_start
 Add the @code{#EXT-X-DISCONTINUITY} tag to the playlist, before the
@@ -1567,6 +1569,15 @@ A safe size for most use cases should be
 
 Note that cues are only written if the output is seekable and this option will
 have no effect if it is not.
+
+@item cues_to_front
+If set, the muxer will write the index at the beginning of the file
+by shifting the main data if necessary. This can be combined with
+reserve_index_space in which case the data is only shifted if
+the initially reserved space turns out to be insufficient.
+
+This option is ignored if the output is unseekable.
+
 @item default_mode
 This option controls how the FlagDefault of the output tracks will be set.
 It influences which tracks players should play by default. The default mode
@@ -1722,6 +1733,14 @@ B-frames. Additionally, eases conformanc
 guidelines.
 
 This option is implicitly set when writing ismv (Smooth Streaming) files.
+
+@item -write_btrt @var{bool}
+Force or disable writing bitrate box inside stsd box of a track.
+The box contains decoding buffer size (in bytes), maximum bitrate and
+average bitrate for the track. The box will be skipped if none of these values
+can be computed.
+Default is @code{-1} or @code{auto}, which will write the box only in MP4 mode.
+
 @item -write_prft
 Write producer time reference box (PRFT) with a specified time source for the
 NTP field in the PRFT box. Set value as @samp{wallclock} to specify timesource
@@ -1733,10 +1752,18 @@ where PTS values are set as as wallclock
 encoding use case with decklink capture source where @option{video_pts} and
 @option{audio_pts} are set to @samp{abs_wallclock}.
 
+@item -empty_hdlr_name @var{bool}
+Enable to skip writing the name inside a @code{hdlr} box.
+Default is @code{false}.
+
 @item -movie_timescale @var{scale}
 Set the timescale written in the movie header box (@code{mvhd}).
 Range is 1 to INT_MAX. Default is 1000.
 
+@item -video_track_timescale @var{scale}
+Set the timescale used for video tracks. Range is 0 to INT_MAX.
+If set to @code{0}, the timescale is automatically set based on
+the native stream time base. Default is 0.
 @end table
 
 @subsection Example
diff -pruN 7:5.0.1-3/doc/protocols.texi 7:5.1-1/doc/protocols.texi
--- 7:5.0.1-3/doc/protocols.texi	2022-01-14 18:45:39.000000000 +0000
+++ 7:5.1-1/doc/protocols.texi	2022-07-22 17:58:38.000000000 +0000
@@ -614,6 +614,38 @@ Establish a TLS (HTTPS) connection to Ic
 icecast://[@var{username}[:@var{password}]@@]@var{server}:@var{port}/@var{mountpoint}
 @end example
 
+@section ipfs
+
+InterPlanetary File System (IPFS) protocol support. One can access files stored
+on the IPFS network through so-called gateways. These are http(s) endpoints.
+This protocol wraps the IPFS native protocols (ipfs:// and ipns://) to be sent
+to such a gateway. Users can (and should) host their own node which means this
+protocol will use one's local gateway to access files on the IPFS network.
+
+If a user doesn't have a node of their own then the public gateway @code{https://dweb.link}
+is used by default.
+
+This protocol accepts the following options:
+
+@table @option
+
+@item gateway
+Defines the gateway to use. When not set, the protocol will first try
+locating the local gateway by looking at @code{$IPFS_GATEWAY}, @code{$IPFS_PATH}
+and @code{$HOME/.ipfs/}, in that order. If that fails @code{https://dweb.link} will be used.
+
+@end table
+
+One can use this protocol in 2 ways. Using IPFS:
+@example
+ffplay ipfs://QmbGtJg23skhvFmu9mJiePVByhfzu5rwo74MEkVDYAmF5T
+@end example
+
+Or the IPNS protocol (IPNS is mutable IPFS):
+@example
+ffplay ipns://QmbGtJg23skhvFmu9mJiePVByhfzu5rwo74MEkVDYAmF5T
+@end example
+
 @section mmst
 
 MMS (Microsoft Media Server) protocol over TCP.
@@ -745,6 +777,14 @@ Set internal RIST buffer size in millise
 Default value is 0 which means the librist default (1 sec). Maximum value is 30
 seconds.
 
+@item fifo_size
+Size of the librist receiver output fifo in number of packets. This must be a
+power of 2.
+Defaults to 8192 (vs the librist default of 1024).
+
+@item overrun_nonfatal=@var{1|0}
+Survive in case of librist fifo buffer overrun. Default value is 0.
+
 @item pkt_size
 Set maximum packet size for sending data. 1316 by default.
 
@@ -2025,5 +2065,4 @@ decoding errors.
 
 @end table
 
-
 @c man end PROTOCOLS
diff -pruN 7:5.0.1-3/doc/utils.texi 7:5.1-1/doc/utils.texi
--- 7:5.0.1-3/doc/utils.texi	2022-04-04 14:40:22.000000000 +0000
+++ 7:5.1-1/doc/utils.texi	2022-07-22 17:58:38.000000000 +0000
@@ -723,20 +723,28 @@ DL+DR
 FL+FR+FC+LFE+BL+BR+FLC+FRC+BC+SL+SR+TC+TFL+TFC+TFR+TBL+TBC+TBR+LFE2+TSL+TSR+BFC+BFL+BFR
 @end table
 
-A custom channel layout can be specified as a sequence of terms, separated by
-'+' or '|'. Each term can be:
+A custom channel layout can be specified as a sequence of terms, separated by '+'.
+Each term can be:
 @itemize
 @item
-the name of a standard channel layout (e.g. @samp{mono},
-@samp{stereo}, @samp{4.0}, @samp{quad}, @samp{5.0}, etc.)
+the name of a single channel (e.g. @samp{FL}, @samp{FR}, @samp{FC}, @samp{LFE}, etc.),
+each optionally containing a custom name after a '@@', (e.g. @samp{FL@@Left},
+@samp{FR@@Right}, @samp{FC@@Center}, @samp{LFE@@Low_Frequency}, etc.)
+@end itemize
 
+A standard channel layout can be specified by the following:
+@itemize
 @item
 the name of a single channel (e.g. @samp{FL}, @samp{FR}, @samp{FC}, @samp{LFE}, etc.)
 
 @item
+the name of a standard channel layout (e.g. @samp{mono},
+@samp{stereo}, @samp{4.0}, @samp{quad}, @samp{5.0}, etc.)
+
+@item
 a number of channels, in decimal, followed by 'c', yielding the default channel
 layout for that number of channels (see the function
-@code{av_get_default_channel_layout}). Note that not all channel counts have a
+@code{av_channel_layout_default}). Note that not all channel counts have a
 default layout.
 
 @item
@@ -753,7 +761,7 @@ Before libavutil version 53 the trailing
 channels was optional, but now it is required, while a channel layout mask can
 also be specified as a decimal number (if and only if not followed by "c" or "C").
 
-See also the function @code{av_get_channel_layout} defined in
+See also the function @code{av_channel_layout_from_string} defined in
 @file{libavutil/channel_layout.h}.
 @c man end SYNTAX
 
diff -pruN 7:5.0.1-3/ffbuild/common.mak 7:5.1-1/ffbuild/common.mak
--- 7:5.0.1-3/ffbuild/common.mak	2022-01-14 18:45:39.000000000 +0000
+++ 7:5.1-1/ffbuild/common.mak	2022-07-22 17:58:38.000000000 +0000
@@ -29,7 +29,8 @@ $(foreach VAR,$(SILENT),$(eval override
 $(eval INSTALL = @$(call ECHO,INSTALL,$$(^:$(SRC_DIR)/%=%)); $(INSTALL))
 endif
 
-ALLFFLIBS = avcodec avdevice avfilter avformat avutil postproc swscale swresample
+# Prepend to a recursively expanded variable without making it simply expanded.
+PREPEND = $(eval $(1) = $(patsubst %,$$(%), $(2)) $(value $(1)))
 
 # NASM requires -I path terminated with /
 IFLAGS     := -I. -I$(SRC_LINK)/
@@ -39,7 +40,9 @@ CCFLAGS     = $(CPPFLAGS) $(CFLAGS)
 OBJCFLAGS  += $(EOBJCFLAGS)
 OBJCCFLAGS  = $(CPPFLAGS) $(CFLAGS) $(OBJCFLAGS)
 ASFLAGS    := $(CPPFLAGS) $(ASFLAGS)
-CXXFLAGS   := $(CPPFLAGS) $(CFLAGS) $(CXXFLAGS)
+# Use PREPEND here so that later (target-dependent) additions to CPPFLAGS
+# end up in CXXFLAGS.
+$(call PREPEND,CXXFLAGS, CPPFLAGS CFLAGS)
 X86ASMFLAGS += $(IFLAGS:%=%/) -I$(<D)/ -Pconfig.asm
 
 HOSTCCFLAGS = $(IFLAGS) $(HOSTCPPFLAGS) $(HOSTCFLAGS)
diff -pruN 7:5.0.1-3/ffbuild/library.mak 7:5.1-1/ffbuild/library.mak
--- 7:5.0.1-3/ffbuild/library.mak	2022-01-14 18:45:39.000000000 +0000
+++ 7:5.1-1/ffbuild/library.mak	2022-07-22 17:58:38.000000000 +0000
@@ -52,8 +52,8 @@ $(LIBOBJS): CPPFLAGS += -DBUILDING_$(NAM
 $(TESTPROGS) $(TOOLS): %$(EXESUF): %.o
 	$$(LD) $(LDFLAGS) $(LDEXEFLAGS) $$(LD_O) $$(filter %.o,$$^) $$(THISLIB) $(FFEXTRALIBS) $$(EXTRALIBS-$$(*F)) $$(ELIBS)
 
-$(SUBDIR)lib$(NAME).version: $(SUBDIR)version.h | $(SUBDIR)
-	$$(M) $$(SRC_PATH)/ffbuild/libversion.sh $(NAME) $$< > $$@
+$(SUBDIR)lib$(NAME).version: $(SUBDIR)version.h $(SUBDIR)version_major.h | $(SUBDIR)
+	$$(M) $$(SRC_PATH)/ffbuild/libversion.sh $(NAME) $$^ > $$@
 
 $(SUBDIR)lib$(FULLNAME).pc: $(SUBDIR)version.h ffbuild/config.sh | $(SUBDIR)
 	$$(M) $$(SRC_PATH)/ffbuild/pkgconfig_generate.sh $(NAME) "$(DESC)"
diff -pruN 7:5.0.1-3/ffbuild/libversion.sh 7:5.1-1/ffbuild/libversion.sh
--- 7:5.0.1-3/ffbuild/libversion.sh	2021-10-21 17:06:35.000000000 +0000
+++ 7:5.1-1/ffbuild/libversion.sh	2022-07-22 17:58:38.000000000 +0000
@@ -5,8 +5,12 @@ toupper(){
 name=lib$1
 ucname=$(toupper ${name})
 file=$2
+file2=$3
 
 eval $(awk "/#define ${ucname}_VERSION_M/ { print \$2 \"=\" \$3 }" "$file")
+if [ -f "$file2" ]; then
+  eval $(awk "/#define ${ucname}_VERSION_M/ { print \$2 \"=\" \$3 }" "$file2")
+fi
 eval ${ucname}_VERSION=\$${ucname}_VERSION_MAJOR.\$${ucname}_VERSION_MINOR.\$${ucname}_VERSION_MICRO
 eval echo "${name}_VERSION=\$${ucname}_VERSION"
 eval echo "${name}_VERSION_MAJOR=\$${ucname}_VERSION_MAJOR"
diff -pruN 7:5.0.1-3/fftools/cmdutils.c 7:5.1-1/fftools/cmdutils.c
--- 7:5.0.1-3/fftools/cmdutils.c	2022-01-14 18:45:39.000000000 +0000
+++ 7:5.1-1/fftools/cmdutils.c	2022-07-22 17:58:38.000000000 +0000
@@ -32,54 +32,35 @@
 #include "config.h"
 #include "compat/va_copy.h"
 #include "libavformat/avformat.h"
-#include "libavfilter/avfilter.h"
-#include "libavdevice/avdevice.h"
 #include "libswscale/swscale.h"
+#include "libswscale/version.h"
 #include "libswresample/swresample.h"
-#include "libpostproc/postprocess.h"
-#include "libavutil/attributes.h"
 #include "libavutil/avassert.h"
 #include "libavutil/avstring.h"
-#include "libavutil/bprint.h"
 #include "libavutil/channel_layout.h"
 #include "libavutil/display.h"
+#include "libavutil/getenv_utf8.h"
 #include "libavutil/mathematics.h"
 #include "libavutil/imgutils.h"
 #include "libavutil/libm.h"
 #include "libavutil/parseutils.h"
-#include "libavutil/pixdesc.h"
 #include "libavutil/eval.h"
 #include "libavutil/dict.h"
 #include "libavutil/opt.h"
-#include "libavutil/cpu.h"
-#include "libavutil/ffversion.h"
-#include "libavutil/version.h"
-#include "libavcodec/bsf.h"
 #include "cmdutils.h"
-#if HAVE_SYS_RESOURCE_H
-#include <sys/time.h>
-#include <sys/resource.h>
-#endif
+#include "fopen_utf8.h"
+#include "opt_common.h"
 #ifdef _WIN32
 #include <windows.h>
+#include "compat/w32dlfcn.h"
 #endif
 
-static int init_report(const char *env);
-
 AVDictionary *sws_dict;
 AVDictionary *swr_opts;
 AVDictionary *format_opts, *codec_opts;
 
-static FILE *report_file;
-static int report_file_level = AV_LOG_DEBUG;
 int hide_banner = 0;
 
-enum show_muxdemuxers {
-    SHOW_DEFAULT,
-    SHOW_DEMUXERS,
-    SHOW_MUXERS,
-};
-
 void uninit_opts(void)
 {
     av_dict_free(&swr_opts);
@@ -93,22 +74,6 @@ void log_callback_help(void *ptr, int le
     vfprintf(stdout, fmt, vl);
 }
 
-static void log_callback_report(void *ptr, int level, const char *fmt, va_list vl)
-{
-    va_list vl2;
-    char line[1024];
-    static int print_prefix = 1;
-
-    va_copy(vl2, vl);
-    av_log_default_callback(ptr, level, fmt, vl);
-    av_log_format_line(ptr, level, fmt, vl2, line, sizeof(line), &print_prefix);
-    va_end(vl2);
-    if (report_file_level >= level) {
-        fputs(line, report_file);
-        fflush(report_file);
-    }
-}
-
 void init_dynload(void)
 {
 #if HAVE_SETDLLDIRECTORY && defined(_WIN32)
@@ -341,6 +306,12 @@ static int write_option(void *optctx, co
 int parse_option(void *optctx, const char *opt, const char *arg,
                  const OptionDef *options)
 {
+    static const OptionDef opt_avoptions = {
+        .name       = "AVOption passthrough",
+        .flags      = HAS_ARG,
+        .u.func_arg = opt_default,
+    };
+
     const OptionDef *po;
     int ret;
 
@@ -354,7 +325,7 @@ int parse_option(void *optctx, const cha
         arg = "1";
 
     if (!po->name)
-        po = find_option(options, "default");
+        po = &opt_avoptions;
     if (!po->name) {
         av_log(NULL, AV_LOG_ERROR, "Unrecognized option '%s'\n", opt);
         return AVERROR(EINVAL);
@@ -461,7 +432,7 @@ int locate_option(int argc, char **argv,
     return 0;
 }
 
-static void dump_argument(const char *a)
+static void dump_argument(FILE *report_file, const char *a)
 {
     const unsigned char *p;
 
@@ -497,7 +468,7 @@ static void check_options(const OptionDe
 void parse_loglevel(int argc, char **argv, const OptionDef *options)
 {
     int idx = locate_option(argc, argv, options, "loglevel");
-    const char *env;
+    char *env;
 
     check_options(options);
 
@@ -506,18 +477,21 @@ void parse_loglevel(int argc, char **arg
     if (idx && argv[idx + 1])
         opt_loglevel(NULL, "loglevel", argv[idx + 1]);
     idx = locate_option(argc, argv, options, "report");
-    if ((env = getenv("FFREPORT")) || idx) {
-        init_report(env);
+    env = getenv_utf8("FFREPORT");
+    if (env || idx) {
+        FILE *report_file = NULL;
+        init_report(env, &report_file);
         if (report_file) {
             int i;
             fprintf(report_file, "Command line:\n");
             for (i = 0; i < argc; i++) {
-                dump_argument(argv[i]);
+                dump_argument(report_file, argv[i]);
                 fputc(i < argc - 1 ? ' ' : '\n', report_file);
             }
             fflush(report_file);
         }
     }
+    freeenv_utf8(env);
     idx = locate_option(argc, argv, options, "hide_banner");
     if (idx)
         hide_banner = 1;
@@ -571,20 +545,12 @@ int opt_default(void *optctx, const char
 #if CONFIG_SWSCALE
     if (!consumed && (o = opt_find(&sc, opt, NULL, 0,
                          AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ))) {
-        struct SwsContext *sws = sws_alloc_context();
-        int ret = av_opt_set(sws, opt, arg, 0);
-        sws_freeContext(sws);
         if (!strcmp(opt, "srcw") || !strcmp(opt, "srch") ||
             !strcmp(opt, "dstw") || !strcmp(opt, "dsth") ||
             !strcmp(opt, "src_format") || !strcmp(opt, "dst_format")) {
             av_log(NULL, AV_LOG_ERROR, "Directly using swscale dimensions/format options is not supported, please use the -s or -pix_fmt options\n");
             return AVERROR(EINVAL);
         }
-        if (ret < 0) {
-            av_log(NULL, AV_LOG_ERROR, "Error setting option %s.\n", opt);
-            return ret;
-        }
-
         av_dict_set(&sws_dict, opt, arg, FLAGS);
 
         consumed = 1;
@@ -598,13 +564,6 @@ int opt_default(void *optctx, const char
 #if CONFIG_SWRESAMPLE
     if (!consumed && (o=opt_find(&swr_class, opt, NULL, 0,
                                     AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ))) {
-        struct SwrContext *swr = swr_alloc();
-        int ret = av_opt_set(swr, opt, arg, 0);
-        swr_free(&swr);
-        if (ret < 0) {
-            av_log(NULL, AV_LOG_ERROR, "Error setting option %s.\n", opt);
-            return ret;
-        }
         av_dict_set(&swr_opts, opt, arg, FLAGS);
         consumed = 1;
     }
@@ -831,259 +790,6 @@ do {
     return 0;
 }
 
-int opt_cpuflags(void *optctx, const char *opt, const char *arg)
-{
-    int ret;
-    unsigned flags = av_get_cpu_flags();
-
-    if ((ret = av_parse_cpu_caps(&flags, arg)) < 0)
-        return ret;
-
-    av_force_cpu_flags(flags);
-    return 0;
-}
-
-int opt_cpucount(void *optctx, const char *opt, const char *arg)
-{
-    int ret;
-    int count;
-
-    static const AVOption opts[] = {
-        {"count", NULL, 0, AV_OPT_TYPE_INT, { .i64 = -1}, -1, INT_MAX},
-        {NULL},
-    };
-    static const AVClass class = {
-        .class_name = "cpucount",
-        .item_name  = av_default_item_name,
-        .option     = opts,
-        .version    = LIBAVUTIL_VERSION_INT,
-    };
-    const AVClass *pclass = &class;
-
-    ret = av_opt_eval_int(&pclass, opts, arg, &count);
-
-    if (!ret) {
-        av_cpu_force_count(count);
-    }
-
-    return ret;
-}
-
-int opt_loglevel(void *optctx, const char *opt, const char *arg)
-{
-    const struct { const char *name; int level; } log_levels[] = {
-        { "quiet"  , AV_LOG_QUIET   },
-        { "panic"  , AV_LOG_PANIC   },
-        { "fatal"  , AV_LOG_FATAL   },
-        { "error"  , AV_LOG_ERROR   },
-        { "warning", AV_LOG_WARNING },
-        { "info"   , AV_LOG_INFO    },
-        { "verbose", AV_LOG_VERBOSE },
-        { "debug"  , AV_LOG_DEBUG   },
-        { "trace"  , AV_LOG_TRACE   },
-    };
-    const char *token;
-    char *tail;
-    int flags = av_log_get_flags();
-    int level = av_log_get_level();
-    int cmd, i = 0;
-
-    av_assert0(arg);
-    while (*arg) {
-        token = arg;
-        if (*token == '+' || *token == '-') {
-            cmd = *token++;
-        } else {
-            cmd = 0;
-        }
-        if (!i && !cmd) {
-            flags = 0;  /* missing relative prefix, build absolute value */
-        }
-        if (av_strstart(token, "repeat", &arg)) {
-            if (cmd == '-') {
-                flags |= AV_LOG_SKIP_REPEATED;
-            } else {
-                flags &= ~AV_LOG_SKIP_REPEATED;
-            }
-        } else if (av_strstart(token, "level", &arg)) {
-            if (cmd == '-') {
-                flags &= ~AV_LOG_PRINT_LEVEL;
-            } else {
-                flags |= AV_LOG_PRINT_LEVEL;
-            }
-        } else {
-            break;
-        }
-        i++;
-    }
-    if (!*arg) {
-        goto end;
-    } else if (*arg == '+') {
-        arg++;
-    } else if (!i) {
-        flags = av_log_get_flags();  /* level value without prefix, reset flags */
-    }
-
-    for (i = 0; i < FF_ARRAY_ELEMS(log_levels); i++) {
-        if (!strcmp(log_levels[i].name, arg)) {
-            level = log_levels[i].level;
-            goto end;
-        }
-    }
-
-    level = strtol(arg, &tail, 10);
-    if (*tail) {
-        av_log(NULL, AV_LOG_FATAL, "Invalid loglevel \"%s\". "
-               "Possible levels are numbers or:\n", arg);
-        for (i = 0; i < FF_ARRAY_ELEMS(log_levels); i++)
-            av_log(NULL, AV_LOG_FATAL, "\"%s\"\n", log_levels[i].name);
-        exit_program(1);
-    }
-
-end:
-    av_log_set_flags(flags);
-    av_log_set_level(level);
-    return 0;
-}
-
-static void expand_filename_template(AVBPrint *bp, const char *template,
-                                     struct tm *tm)
-{
-    int c;
-
-    while ((c = *(template++))) {
-        if (c == '%') {
-            if (!(c = *(template++)))
-                break;
-            switch (c) {
-            case 'p':
-                av_bprintf(bp, "%s", program_name);
-                break;
-            case 't':
-                av_bprintf(bp, "%04d%02d%02d-%02d%02d%02d",
-                           tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
-                           tm->tm_hour, tm->tm_min, tm->tm_sec);
-                break;
-            case '%':
-                av_bprint_chars(bp, c, 1);
-                break;
-            }
-        } else {
-            av_bprint_chars(bp, c, 1);
-        }
-    }
-}
-
-static int init_report(const char *env)
-{
-    char *filename_template = NULL;
-    char *key, *val;
-    int ret, count = 0;
-    int prog_loglevel, envlevel = 0;
-    time_t now;
-    struct tm *tm;
-    AVBPrint filename;
-
-    if (report_file) /* already opened */
-        return 0;
-    time(&now);
-    tm = localtime(&now);
-
-    while (env && *env) {
-        if ((ret = av_opt_get_key_value(&env, "=", ":", 0, &key, &val)) < 0) {
-            if (count)
-                av_log(NULL, AV_LOG_ERROR,
-                       "Failed to parse FFREPORT environment variable: %s\n",
-                       av_err2str(ret));
-            break;
-        }
-        if (*env)
-            env++;
-        count++;
-        if (!strcmp(key, "file")) {
-            av_free(filename_template);
-            filename_template = val;
-            val = NULL;
-        } else if (!strcmp(key, "level")) {
-            char *tail;
-            report_file_level = strtol(val, &tail, 10);
-            if (*tail) {
-                av_log(NULL, AV_LOG_FATAL, "Invalid report file level\n");
-                exit_program(1);
-            }
-            envlevel = 1;
-        } else {
-            av_log(NULL, AV_LOG_ERROR, "Unknown key '%s' in FFREPORT\n", key);
-        }
-        av_free(val);
-        av_free(key);
-    }
-
-    av_bprint_init(&filename, 0, AV_BPRINT_SIZE_AUTOMATIC);
-    expand_filename_template(&filename,
-                             av_x_if_null(filename_template, "%p-%t.log"), tm);
-    av_free(filename_template);
-    if (!av_bprint_is_complete(&filename)) {
-        av_log(NULL, AV_LOG_ERROR, "Out of memory building report file name\n");
-        return AVERROR(ENOMEM);
-    }
-
-    prog_loglevel = av_log_get_level();
-    if (!envlevel)
-        report_file_level = FFMAX(report_file_level, prog_loglevel);
-
-    report_file = fopen(filename.str, "w");
-    if (!report_file) {
-        int ret = AVERROR(errno);
-        av_log(NULL, AV_LOG_ERROR, "Failed to open report \"%s\": %s\n",
-               filename.str, strerror(errno));
-        return ret;
-    }
-    av_log_set_callback(log_callback_report);
-    av_log(NULL, AV_LOG_INFO,
-           "%s started on %04d-%02d-%02d at %02d:%02d:%02d\n"
-           "Report written to \"%s\"\n"
-           "Log level: %d\n",
-           program_name,
-           tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
-           tm->tm_hour, tm->tm_min, tm->tm_sec,
-           filename.str, report_file_level);
-    av_bprint_finalize(&filename, NULL);
-    return 0;
-}
-
-int opt_report(void *optctx, const char *opt, const char *arg)
-{
-    return init_report(NULL);
-}
-
-int opt_max_alloc(void *optctx, const char *opt, const char *arg)
-{
-    char *tail;
-    size_t max;
-
-    max = strtol(arg, &tail, 10);
-    if (*tail) {
-        av_log(NULL, AV_LOG_FATAL, "Invalid max_alloc \"%s\".\n", arg);
-        exit_program(1);
-    }
-    av_max_alloc(max);
-    return 0;
-}
-
-int opt_timelimit(void *optctx, const char *opt, const char *arg)
-{
-#if HAVE_SETRLIMIT
-    int lim = parse_number_or_die(opt, arg, OPT_INT64, 0, INT_MAX);
-    struct rlimit rl = { lim, lim + 1 };
-    if (setrlimit(RLIMIT_CPU, &rl))
-        perror("setrlimit");
-#else
-    av_log(NULL, AV_LOG_WARNING, "-%s not implemented on this OS\n", opt);
-#endif
-    return 0;
-}
-
 void print_error(const char *filename, int err)
 {
     char errbuf[128];
@@ -1094,960 +800,6 @@ void print_error(const char *filename, i
     av_log(NULL, AV_LOG_ERROR, "%s: %s\n", filename, errbuf_ptr);
 }
 
-static int warned_cfg = 0;
-
-#define INDENT        1
-#define SHOW_VERSION  2
-#define SHOW_CONFIG   4
-#define SHOW_COPYRIGHT 8
-
-#define PRINT_LIB_INFO(libname, LIBNAME, flags, level)                  \
-    if (CONFIG_##LIBNAME) {                                             \
-        const char *indent = flags & INDENT? "  " : "";                 \
-        if (flags & SHOW_VERSION) {                                     \
-            unsigned int version = libname##_version();                 \
-            av_log(NULL, level,                                         \
-                   "%slib%-11s %2d.%3d.%3d / %2d.%3d.%3d\n",            \
-                   indent, #libname,                                    \
-                   LIB##LIBNAME##_VERSION_MAJOR,                        \
-                   LIB##LIBNAME##_VERSION_MINOR,                        \
-                   LIB##LIBNAME##_VERSION_MICRO,                        \
-                   AV_VERSION_MAJOR(version), AV_VERSION_MINOR(version),\
-                   AV_VERSION_MICRO(version));                          \
-        }                                                               \
-        if (flags & SHOW_CONFIG) {                                      \
-            const char *cfg = libname##_configuration();                \
-            if (strcmp(FFMPEG_CONFIGURATION, cfg)) {                    \
-                if (!warned_cfg) {                                      \
-                    av_log(NULL, level,                                 \
-                            "%sWARNING: library configuration mismatch\n", \
-                            indent);                                    \
-                    warned_cfg = 1;                                     \
-                }                                                       \
-                av_log(NULL, level, "%s%-11s configuration: %s\n",      \
-                        indent, #libname, cfg);                         \
-            }                                                           \
-        }                                                               \
-    }                                                                   \
-
-static void print_all_libs_info(int flags, int level)
-{
-    PRINT_LIB_INFO(avutil,     AVUTIL,     flags, level);
-    PRINT_LIB_INFO(avcodec,    AVCODEC,    flags, level);
-    PRINT_LIB_INFO(avformat,   AVFORMAT,   flags, level);
-    PRINT_LIB_INFO(avdevice,   AVDEVICE,   flags, level);
-    PRINT_LIB_INFO(avfilter,   AVFILTER,   flags, level);
-    PRINT_LIB_INFO(swscale,    SWSCALE,    flags, level);
-    PRINT_LIB_INFO(swresample, SWRESAMPLE, flags, level);
-    PRINT_LIB_INFO(postproc,   POSTPROC,   flags, level);
-}
-
-static void print_program_info(int flags, int level)
-{
-    const char *indent = flags & INDENT? "  " : "";
-
-    av_log(NULL, level, "%s version " FFMPEG_VERSION, program_name);
-    if (flags & SHOW_COPYRIGHT)
-        av_log(NULL, level, " Copyright (c) %d-%d the FFmpeg developers",
-               program_birth_year, CONFIG_THIS_YEAR);
-    av_log(NULL, level, "\n");
-    av_log(NULL, level, "%sbuilt with %s\n", indent, CC_IDENT);
-
-    av_log(NULL, level, "%sconfiguration: " FFMPEG_CONFIGURATION "\n", indent);
-}
-
-static void print_buildconf(int flags, int level)
-{
-    const char *indent = flags & INDENT ? "  " : "";
-    char str[] = { FFMPEG_CONFIGURATION };
-    char *conflist, *remove_tilde, *splitconf;
-
-    // Change all the ' --' strings to '~--' so that
-    // they can be identified as tokens.
-    while ((conflist = strstr(str, " --")) != NULL) {
-        conflist[0] = '~';
-    }
-
-    // Compensate for the weirdness this would cause
-    // when passing 'pkg-config --static'.
-    while ((remove_tilde = strstr(str, "pkg-config~")) != NULL) {
-        remove_tilde[sizeof("pkg-config~") - 2] = ' ';
-    }
-
-    splitconf = strtok(str, "~");
-    av_log(NULL, level, "\n%sconfiguration:\n", indent);
-    while (splitconf != NULL) {
-        av_log(NULL, level, "%s%s%s\n", indent, indent, splitconf);
-        splitconf = strtok(NULL, "~");
-    }
-}
-
-void show_banner(int argc, char **argv, const OptionDef *options)
-{
-    int idx = locate_option(argc, argv, options, "version");
-    if (hide_banner || idx)
-        return;
-
-    print_program_info (INDENT|SHOW_COPYRIGHT, AV_LOG_INFO);
-    print_all_libs_info(INDENT|SHOW_CONFIG,  AV_LOG_INFO);
-    print_all_libs_info(INDENT|SHOW_VERSION, AV_LOG_INFO);
-}
-
-int show_version(void *optctx, const char *opt, const char *arg)
-{
-    av_log_set_callback(log_callback_help);
-    print_program_info (SHOW_COPYRIGHT, AV_LOG_INFO);
-    print_all_libs_info(SHOW_VERSION, AV_LOG_INFO);
-
-    return 0;
-}
-
-int show_buildconf(void *optctx, const char *opt, const char *arg)
-{
-    av_log_set_callback(log_callback_help);
-    print_buildconf      (INDENT|0, AV_LOG_INFO);
-
-    return 0;
-}
-
-int show_license(void *optctx, const char *opt, const char *arg)
-{
-#if CONFIG_NONFREE
-    printf(
-    "This version of %s has nonfree parts compiled in.\n"
-    "Therefore it is not legally redistributable.\n",
-    program_name );
-#elif CONFIG_GPLV3
-    printf(
-    "%s is free software; you can redistribute it and/or modify\n"
-    "it under the terms of the GNU General Public License as published by\n"
-    "the Free Software Foundation; either version 3 of the License, or\n"
-    "(at your option) any later version.\n"
-    "\n"
-    "%s is distributed in the hope that it will be useful,\n"
-    "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
-    "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
-    "GNU General Public License for more details.\n"
-    "\n"
-    "You should have received a copy of the GNU General Public License\n"
-    "along with %s.  If not, see <http://www.gnu.org/licenses/>.\n",
-    program_name, program_name, program_name );
-#elif CONFIG_GPL
-    printf(
-    "%s is free software; you can redistribute it and/or modify\n"
-    "it under the terms of the GNU General Public License as published by\n"
-    "the Free Software Foundation; either version 2 of the License, or\n"
-    "(at your option) any later version.\n"
-    "\n"
-    "%s is distributed in the hope that it will be useful,\n"
-    "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
-    "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
-    "GNU General Public License for more details.\n"
-    "\n"
-    "You should have received a copy of the GNU General Public License\n"
-    "along with %s; if not, write to the Free Software\n"
-    "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n",
-    program_name, program_name, program_name );
-#elif CONFIG_LGPLV3
-    printf(
-    "%s is free software; you can redistribute it and/or modify\n"
-    "it under the terms of the GNU Lesser General Public License as published by\n"
-    "the Free Software Foundation; either version 3 of the License, or\n"
-    "(at your option) any later version.\n"
-    "\n"
-    "%s is distributed in the hope that it will be useful,\n"
-    "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
-    "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
-    "GNU Lesser General Public License for more details.\n"
-    "\n"
-    "You should have received a copy of the GNU Lesser General Public License\n"
-    "along with %s.  If not, see <http://www.gnu.org/licenses/>.\n",
-    program_name, program_name, program_name );
-#else
-    printf(
-    "%s is free software; you can redistribute it and/or\n"
-    "modify it under the terms of the GNU Lesser General Public\n"
-    "License as published by the Free Software Foundation; either\n"
-    "version 2.1 of the License, or (at your option) any later version.\n"
-    "\n"
-    "%s is distributed in the hope that it will be useful,\n"
-    "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
-    "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n"
-    "Lesser General Public License for more details.\n"
-    "\n"
-    "You should have received a copy of the GNU Lesser General Public\n"
-    "License along with %s; if not, write to the Free Software\n"
-    "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n",
-    program_name, program_name, program_name );
-#endif
-
-    return 0;
-}
-
-static int is_device(const AVClass *avclass)
-{
-    if (!avclass)
-        return 0;
-    return AV_IS_INPUT_DEVICE(avclass->category) || AV_IS_OUTPUT_DEVICE(avclass->category);
-}
-
-static int show_formats_devices(void *optctx, const char *opt, const char *arg, int device_only, int muxdemuxers)
-{
-    void *ifmt_opaque = NULL;
-    const AVInputFormat *ifmt  = NULL;
-    void *ofmt_opaque = NULL;
-    const AVOutputFormat *ofmt = NULL;
-    const char *last_name;
-    int is_dev;
-
-    printf("%s\n"
-           " D. = Demuxing supported\n"
-           " .E = Muxing supported\n"
-           " --\n", device_only ? "Devices:" : "File formats:");
-    last_name = "000";
-    for (;;) {
-        int decode = 0;
-        int encode = 0;
-        const char *name      = NULL;
-        const char *long_name = NULL;
-
-        if (muxdemuxers !=SHOW_DEMUXERS) {
-            ofmt_opaque = NULL;
-            while ((ofmt = av_muxer_iterate(&ofmt_opaque))) {
-                is_dev = is_device(ofmt->priv_class);
-                if (!is_dev && device_only)
-                    continue;
-                if ((!name || strcmp(ofmt->name, name) < 0) &&
-                    strcmp(ofmt->name, last_name) > 0) {
-                    name      = ofmt->name;
-                    long_name = ofmt->long_name;
-                    encode    = 1;
-                }
-            }
-        }
-        if (muxdemuxers != SHOW_MUXERS) {
-            ifmt_opaque = NULL;
-            while ((ifmt = av_demuxer_iterate(&ifmt_opaque))) {
-                is_dev = is_device(ifmt->priv_class);
-                if (!is_dev && device_only)
-                    continue;
-                if ((!name || strcmp(ifmt->name, name) < 0) &&
-                    strcmp(ifmt->name, last_name) > 0) {
-                    name      = ifmt->name;
-                    long_name = ifmt->long_name;
-                    encode    = 0;
-                }
-                if (name && strcmp(ifmt->name, name) == 0)
-                    decode = 1;
-            }
-        }
-        if (!name)
-            break;
-        last_name = name;
-
-        printf(" %c%c %-15s %s\n",
-               decode ? 'D' : ' ',
-               encode ? 'E' : ' ',
-               name,
-            long_name ? long_name:" ");
-    }
-    return 0;
-}
-
-int show_formats(void *optctx, const char *opt, const char *arg)
-{
-    return show_formats_devices(optctx, opt, arg, 0, SHOW_DEFAULT);
-}
-
-int show_muxers(void *optctx, const char *opt, const char *arg)
-{
-    return show_formats_devices(optctx, opt, arg, 0, SHOW_MUXERS);
-}
-
-int show_demuxers(void *optctx, const char *opt, const char *arg)
-{
-    return show_formats_devices(optctx, opt, arg, 0, SHOW_DEMUXERS);
-}
-
-int show_devices(void *optctx, const char *opt, const char *arg)
-{
-    return show_formats_devices(optctx, opt, arg, 1, SHOW_DEFAULT);
-}
-
-#define PRINT_CODEC_SUPPORTED(codec, field, type, list_name, term, get_name) \
-    if (codec->field) {                                                      \
-        const type *p = codec->field;                                        \
-                                                                             \
-        printf("    Supported " list_name ":");                              \
-        while (*p != term) {                                                 \
-            get_name(*p);                                                    \
-            printf(" %s", name);                                             \
-            p++;                                                             \
-        }                                                                    \
-        printf("\n");                                                        \
-    }                                                                        \
-
-static void print_codec(const AVCodec *c)
-{
-    int encoder = av_codec_is_encoder(c);
-
-    printf("%s %s [%s]:\n", encoder ? "Encoder" : "Decoder", c->name,
-           c->long_name ? c->long_name : "");
-
-    printf("    General capabilities: ");
-    if (c->capabilities & AV_CODEC_CAP_DRAW_HORIZ_BAND)
-        printf("horizband ");
-    if (c->capabilities & AV_CODEC_CAP_DR1)
-        printf("dr1 ");
-    if (c->capabilities & AV_CODEC_CAP_DELAY)
-        printf("delay ");
-    if (c->capabilities & AV_CODEC_CAP_SMALL_LAST_FRAME)
-        printf("small ");
-    if (c->capabilities & AV_CODEC_CAP_SUBFRAMES)
-        printf("subframes ");
-    if (c->capabilities & AV_CODEC_CAP_EXPERIMENTAL)
-        printf("exp ");
-    if (c->capabilities & AV_CODEC_CAP_CHANNEL_CONF)
-        printf("chconf ");
-    if (c->capabilities & AV_CODEC_CAP_PARAM_CHANGE)
-        printf("paramchange ");
-    if (c->capabilities & AV_CODEC_CAP_VARIABLE_FRAME_SIZE)
-        printf("variable ");
-    if (c->capabilities & (AV_CODEC_CAP_FRAME_THREADS |
-                           AV_CODEC_CAP_SLICE_THREADS |
-                           AV_CODEC_CAP_OTHER_THREADS))
-        printf("threads ");
-    if (c->capabilities & AV_CODEC_CAP_AVOID_PROBING)
-        printf("avoidprobe ");
-    if (c->capabilities & AV_CODEC_CAP_HARDWARE)
-        printf("hardware ");
-    if (c->capabilities & AV_CODEC_CAP_HYBRID)
-        printf("hybrid ");
-    if (!c->capabilities)
-        printf("none");
-    printf("\n");
-
-    if (c->type == AVMEDIA_TYPE_VIDEO ||
-        c->type == AVMEDIA_TYPE_AUDIO) {
-        printf("    Threading capabilities: ");
-        switch (c->capabilities & (AV_CODEC_CAP_FRAME_THREADS |
-                                   AV_CODEC_CAP_SLICE_THREADS |
-                                   AV_CODEC_CAP_OTHER_THREADS)) {
-        case AV_CODEC_CAP_FRAME_THREADS |
-             AV_CODEC_CAP_SLICE_THREADS: printf("frame and slice"); break;
-        case AV_CODEC_CAP_FRAME_THREADS: printf("frame");           break;
-        case AV_CODEC_CAP_SLICE_THREADS: printf("slice");           break;
-        case AV_CODEC_CAP_OTHER_THREADS: printf("other");           break;
-        default:                         printf("none");            break;
-        }
-        printf("\n");
-    }
-
-    if (avcodec_get_hw_config(c, 0)) {
-        printf("    Supported hardware devices: ");
-        for (int i = 0;; i++) {
-            const AVCodecHWConfig *config = avcodec_get_hw_config(c, i);
-            if (!config)
-                break;
-            printf("%s ", av_hwdevice_get_type_name(config->device_type));
-        }
-        printf("\n");
-    }
-
-    if (c->supported_framerates) {
-        const AVRational *fps = c->supported_framerates;
-
-        printf("    Supported framerates:");
-        while (fps->num) {
-            printf(" %d/%d", fps->num, fps->den);
-            fps++;
-        }
-        printf("\n");
-    }
-    PRINT_CODEC_SUPPORTED(c, pix_fmts, enum AVPixelFormat, "pixel formats",
-                          AV_PIX_FMT_NONE, GET_PIX_FMT_NAME);
-    PRINT_CODEC_SUPPORTED(c, supported_samplerates, int, "sample rates", 0,
-                          GET_SAMPLE_RATE_NAME);
-    PRINT_CODEC_SUPPORTED(c, sample_fmts, enum AVSampleFormat, "sample formats",
-                          AV_SAMPLE_FMT_NONE, GET_SAMPLE_FMT_NAME);
-    PRINT_CODEC_SUPPORTED(c, channel_layouts, uint64_t, "channel layouts",
-                          0, GET_CH_LAYOUT_DESC);
-
-    if (c->priv_class) {
-        show_help_children(c->priv_class,
-                           AV_OPT_FLAG_ENCODING_PARAM |
-                           AV_OPT_FLAG_DECODING_PARAM);
-    }
-}
-
-static char get_media_type_char(enum AVMediaType type)
-{
-    switch (type) {
-        case AVMEDIA_TYPE_VIDEO:    return 'V';
-        case AVMEDIA_TYPE_AUDIO:    return 'A';
-        case AVMEDIA_TYPE_DATA:     return 'D';
-        case AVMEDIA_TYPE_SUBTITLE: return 'S';
-        case AVMEDIA_TYPE_ATTACHMENT:return 'T';
-        default:                    return '?';
-    }
-}
-
-static const AVCodec *next_codec_for_id(enum AVCodecID id, void **iter,
-                                        int encoder)
-{
-    const AVCodec *c;
-    while ((c = av_codec_iterate(iter))) {
-        if (c->id == id &&
-            (encoder ? av_codec_is_encoder(c) : av_codec_is_decoder(c)))
-            return c;
-    }
-    return NULL;
-}
-
-static int compare_codec_desc(const void *a, const void *b)
-{
-    const AVCodecDescriptor * const *da = a;
-    const AVCodecDescriptor * const *db = b;
-
-    return (*da)->type != (*db)->type ? FFDIFFSIGN((*da)->type, (*db)->type) :
-           strcmp((*da)->name, (*db)->name);
-}
-
-static unsigned get_codecs_sorted(const AVCodecDescriptor ***rcodecs)
-{
-    const AVCodecDescriptor *desc = NULL;
-    const AVCodecDescriptor **codecs;
-    unsigned nb_codecs = 0, i = 0;
-
-    while ((desc = avcodec_descriptor_next(desc)))
-        nb_codecs++;
-    if (!(codecs = av_calloc(nb_codecs, sizeof(*codecs)))) {
-        av_log(NULL, AV_LOG_ERROR, "Out of memory\n");
-        exit_program(1);
-    }
-    desc = NULL;
-    while ((desc = avcodec_descriptor_next(desc)))
-        codecs[i++] = desc;
-    av_assert0(i == nb_codecs);
-    qsort(codecs, nb_codecs, sizeof(*codecs), compare_codec_desc);
-    *rcodecs = codecs;
-    return nb_codecs;
-}
-
-static void print_codecs_for_id(enum AVCodecID id, int encoder)
-{
-    void *iter = NULL;
-    const AVCodec *codec;
-
-    printf(" (%s: ", encoder ? "encoders" : "decoders");
-
-    while ((codec = next_codec_for_id(id, &iter, encoder)))
-        printf("%s ", codec->name);
-
-    printf(")");
-}
-
-int show_codecs(void *optctx, const char *opt, const char *arg)
-{
-    const AVCodecDescriptor **codecs;
-    unsigned i, nb_codecs = get_codecs_sorted(&codecs);
-
-    printf("Codecs:\n"
-           " D..... = Decoding supported\n"
-           " .E.... = Encoding supported\n"
-           " ..V... = Video codec\n"
-           " ..A... = Audio codec\n"
-           " ..S... = Subtitle codec\n"
-           " ...I.. = Intra frame-only codec\n"
-           " ....L. = Lossy compression\n"
-           " .....S = Lossless compression\n"
-           " -------\n");
-    for (i = 0; i < nb_codecs; i++) {
-        const AVCodecDescriptor *desc = codecs[i];
-        const AVCodec *codec;
-        void *iter = NULL;
-
-        if (strstr(desc->name, "_deprecated"))
-            continue;
-
-        printf(" ");
-        printf(avcodec_find_decoder(desc->id) ? "D" : ".");
-        printf(avcodec_find_encoder(desc->id) ? "E" : ".");
-
-        printf("%c", get_media_type_char(desc->type));
-        printf((desc->props & AV_CODEC_PROP_INTRA_ONLY) ? "I" : ".");
-        printf((desc->props & AV_CODEC_PROP_LOSSY)      ? "L" : ".");
-        printf((desc->props & AV_CODEC_PROP_LOSSLESS)   ? "S" : ".");
-
-        printf(" %-20s %s", desc->name, desc->long_name ? desc->long_name : "");
-
-        /* print decoders/encoders when there's more than one or their
-         * names are different from codec name */
-        while ((codec = next_codec_for_id(desc->id, &iter, 0))) {
-            if (strcmp(codec->name, desc->name)) {
-                print_codecs_for_id(desc->id, 0);
-                break;
-            }
-        }
-        iter = NULL;
-        while ((codec = next_codec_for_id(desc->id, &iter, 1))) {
-            if (strcmp(codec->name, desc->name)) {
-                print_codecs_for_id(desc->id, 1);
-                break;
-            }
-        }
-
-        printf("\n");
-    }
-    av_free(codecs);
-    return 0;
-}
-
-static void print_codecs(int encoder)
-{
-    const AVCodecDescriptor **codecs;
-    unsigned i, nb_codecs = get_codecs_sorted(&codecs);
-
-    printf("%s:\n"
-           " V..... = Video\n"
-           " A..... = Audio\n"
-           " S..... = Subtitle\n"
-           " .F.... = Frame-level multithreading\n"
-           " ..S... = Slice-level multithreading\n"
-           " ...X.. = Codec is experimental\n"
-           " ....B. = Supports draw_horiz_band\n"
-           " .....D = Supports direct rendering method 1\n"
-           " ------\n",
-           encoder ? "Encoders" : "Decoders");
-    for (i = 0; i < nb_codecs; i++) {
-        const AVCodecDescriptor *desc = codecs[i];
-        const AVCodec *codec;
-        void *iter = NULL;
-
-        while ((codec = next_codec_for_id(desc->id, &iter, encoder))) {
-            printf(" %c", get_media_type_char(desc->type));
-            printf((codec->capabilities & AV_CODEC_CAP_FRAME_THREADS) ? "F" : ".");
-            printf((codec->capabilities & AV_CODEC_CAP_SLICE_THREADS) ? "S" : ".");
-            printf((codec->capabilities & AV_CODEC_CAP_EXPERIMENTAL)  ? "X" : ".");
-            printf((codec->capabilities & AV_CODEC_CAP_DRAW_HORIZ_BAND)?"B" : ".");
-            printf((codec->capabilities & AV_CODEC_CAP_DR1)           ? "D" : ".");
-
-            printf(" %-20s %s", codec->name, codec->long_name ? codec->long_name : "");
-            if (strcmp(codec->name, desc->name))
-                printf(" (codec %s)", desc->name);
-
-            printf("\n");
-        }
-    }
-    av_free(codecs);
-}
-
-int show_decoders(void *optctx, const char *opt, const char *arg)
-{
-    print_codecs(0);
-    return 0;
-}
-
-int show_encoders(void *optctx, const char *opt, const char *arg)
-{
-    print_codecs(1);
-    return 0;
-}
-
-int show_bsfs(void *optctx, const char *opt, const char *arg)
-{
-    const AVBitStreamFilter *bsf = NULL;
-    void *opaque = NULL;
-
-    printf("Bitstream filters:\n");
-    while ((bsf = av_bsf_iterate(&opaque)))
-        printf("%s\n", bsf->name);
-    printf("\n");
-    return 0;
-}
-
-int show_protocols(void *optctx, const char *opt, const char *arg)
-{
-    void *opaque = NULL;
-    const char *name;
-
-    printf("Supported file protocols:\n"
-           "Input:\n");
-    while ((name = avio_enum_protocols(&opaque, 0)))
-        printf("  %s\n", name);
-    printf("Output:\n");
-    while ((name = avio_enum_protocols(&opaque, 1)))
-        printf("  %s\n", name);
-    return 0;
-}
-
-int show_filters(void *optctx, const char *opt, const char *arg)
-{
-#if CONFIG_AVFILTER
-    const AVFilter *filter = NULL;
-    char descr[64], *descr_cur;
-    void *opaque = NULL;
-    int i, j;
-    const AVFilterPad *pad;
-
-    printf("Filters:\n"
-           "  T.. = Timeline support\n"
-           "  .S. = Slice threading\n"
-           "  ..C = Command support\n"
-           "  A = Audio input/output\n"
-           "  V = Video input/output\n"
-           "  N = Dynamic number and/or type of input/output\n"
-           "  | = Source or sink filter\n");
-    while ((filter = av_filter_iterate(&opaque))) {
-        descr_cur = descr;
-        for (i = 0; i < 2; i++) {
-            unsigned nb_pads;
-            if (i) {
-                *(descr_cur++) = '-';
-                *(descr_cur++) = '>';
-            }
-            pad = i ? filter->outputs : filter->inputs;
-            nb_pads = avfilter_filter_pad_count(filter, i);
-            for (j = 0; j < nb_pads; j++) {
-                if (descr_cur >= descr + sizeof(descr) - 4)
-                    break;
-                *(descr_cur++) = get_media_type_char(avfilter_pad_get_type(pad, j));
-            }
-            if (!j)
-                *(descr_cur++) = ((!i && (filter->flags & AVFILTER_FLAG_DYNAMIC_INPUTS)) ||
-                                  ( i && (filter->flags & AVFILTER_FLAG_DYNAMIC_OUTPUTS))) ? 'N' : '|';
-        }
-        *descr_cur = 0;
-        printf(" %c%c%c %-17s %-10s %s\n",
-               filter->flags & AVFILTER_FLAG_SUPPORT_TIMELINE ? 'T' : '.',
-               filter->flags & AVFILTER_FLAG_SLICE_THREADS    ? 'S' : '.',
-               filter->process_command                        ? 'C' : '.',
-               filter->name, descr, filter->description);
-    }
-#else
-    printf("No filters available: libavfilter disabled\n");
-#endif
-    return 0;
-}
-
-int show_colors(void *optctx, const char *opt, const char *arg)
-{
-    const char *name;
-    const uint8_t *rgb;
-    int i;
-
-    printf("%-32s #RRGGBB\n", "name");
-
-    for (i = 0; name = av_get_known_color_name(i, &rgb); i++)
-        printf("%-32s #%02x%02x%02x\n", name, rgb[0], rgb[1], rgb[2]);
-
-    return 0;
-}
-
-int show_pix_fmts(void *optctx, const char *opt, const char *arg)
-{
-    const AVPixFmtDescriptor *pix_desc = NULL;
-
-    printf("Pixel formats:\n"
-           "I.... = Supported Input  format for conversion\n"
-           ".O... = Supported Output format for conversion\n"
-           "..H.. = Hardware accelerated format\n"
-           "...P. = Paletted format\n"
-           "....B = Bitstream format\n"
-           "FLAGS NAME            NB_COMPONENTS BITS_PER_PIXEL BIT_DEPTHS\n"
-           "-----\n");
-
-#if !CONFIG_SWSCALE
-#   define sws_isSupportedInput(x)  0
-#   define sws_isSupportedOutput(x) 0
-#endif
-
-    while ((pix_desc = av_pix_fmt_desc_next(pix_desc))) {
-        enum AVPixelFormat av_unused pix_fmt = av_pix_fmt_desc_get_id(pix_desc);
-        printf("%c%c%c%c%c %-16s       %d            %3d      %d",
-               sws_isSupportedInput (pix_fmt)              ? 'I' : '.',
-               sws_isSupportedOutput(pix_fmt)              ? 'O' : '.',
-               pix_desc->flags & AV_PIX_FMT_FLAG_HWACCEL   ? 'H' : '.',
-               pix_desc->flags & AV_PIX_FMT_FLAG_PAL       ? 'P' : '.',
-               pix_desc->flags & AV_PIX_FMT_FLAG_BITSTREAM ? 'B' : '.',
-               pix_desc->name,
-               pix_desc->nb_components,
-               av_get_bits_per_pixel(pix_desc),
-               pix_desc->comp[0].depth);
-
-        for (unsigned i = 1; i < pix_desc->nb_components; i++)
-            printf("-%d", pix_desc->comp[i].depth);
-        printf("\n");
-    }
-    return 0;
-}
-
-int show_layouts(void *optctx, const char *opt, const char *arg)
-{
-    int i = 0;
-    uint64_t layout, j;
-    const char *name, *descr;
-
-    printf("Individual channels:\n"
-           "NAME           DESCRIPTION\n");
-    for (i = 0; i < 63; i++) {
-        name = av_get_channel_name((uint64_t)1 << i);
-        if (!name)
-            continue;
-        descr = av_get_channel_description((uint64_t)1 << i);
-        printf("%-14s %s\n", name, descr);
-    }
-    printf("\nStandard channel layouts:\n"
-           "NAME           DECOMPOSITION\n");
-    for (i = 0; !av_get_standard_channel_layout(i, &layout, &name); i++) {
-        if (name) {
-            printf("%-14s ", name);
-            for (j = 1; j; j <<= 1)
-                if ((layout & j))
-                    printf("%s%s", (layout & (j - 1)) ? "+" : "", av_get_channel_name(j));
-            printf("\n");
-        }
-    }
-    return 0;
-}
-
-int show_sample_fmts(void *optctx, const char *opt, const char *arg)
-{
-    int i;
-    char fmt_str[128];
-    for (i = -1; i < AV_SAMPLE_FMT_NB; i++)
-        printf("%s\n", av_get_sample_fmt_string(fmt_str, sizeof(fmt_str), i));
-    return 0;
-}
-
-int show_dispositions(void *optctx, const char *opt, const char *arg)
-{
-    for (int i = 0; i < 32; i++) {
-        const char *str = av_disposition_to_string(1U << i);
-        if (str)
-            printf("%s\n", str);
-    }
-    return 0;
-}
-
-static void show_help_codec(const char *name, int encoder)
-{
-    const AVCodecDescriptor *desc;
-    const AVCodec *codec;
-
-    if (!name) {
-        av_log(NULL, AV_LOG_ERROR, "No codec name specified.\n");
-        return;
-    }
-
-    codec = encoder ? avcodec_find_encoder_by_name(name) :
-                      avcodec_find_decoder_by_name(name);
-
-    if (codec)
-        print_codec(codec);
-    else if ((desc = avcodec_descriptor_get_by_name(name))) {
-        void *iter = NULL;
-        int printed = 0;
-
-        while ((codec = next_codec_for_id(desc->id, &iter, encoder))) {
-            printed = 1;
-            print_codec(codec);
-        }
-
-        if (!printed) {
-            av_log(NULL, AV_LOG_ERROR, "Codec '%s' is known to FFmpeg, "
-                   "but no %s for it are available. FFmpeg might need to be "
-                   "recompiled with additional external libraries.\n",
-                   name, encoder ? "encoders" : "decoders");
-        }
-    } else {
-        av_log(NULL, AV_LOG_ERROR, "Codec '%s' is not recognized by FFmpeg.\n",
-               name);
-    }
-}
-
-static void show_help_demuxer(const char *name)
-{
-    const AVInputFormat *fmt = av_find_input_format(name);
-
-    if (!fmt) {
-        av_log(NULL, AV_LOG_ERROR, "Unknown format '%s'.\n", name);
-        return;
-    }
-
-    printf("Demuxer %s [%s]:\n", fmt->name, fmt->long_name);
-
-    if (fmt->extensions)
-        printf("    Common extensions: %s.\n", fmt->extensions);
-
-    if (fmt->priv_class)
-        show_help_children(fmt->priv_class, AV_OPT_FLAG_DECODING_PARAM);
-}
-
-static void show_help_protocol(const char *name)
-{
-    const AVClass *proto_class;
-
-    if (!name) {
-        av_log(NULL, AV_LOG_ERROR, "No protocol name specified.\n");
-        return;
-    }
-
-    proto_class = avio_protocol_get_class(name);
-    if (!proto_class) {
-        av_log(NULL, AV_LOG_ERROR, "Unknown protocol '%s'.\n", name);
-        return;
-    }
-
-    show_help_children(proto_class, AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_ENCODING_PARAM);
-}
-
-static void show_help_muxer(const char *name)
-{
-    const AVCodecDescriptor *desc;
-    const AVOutputFormat *fmt = av_guess_format(name, NULL, NULL);
-
-    if (!fmt) {
-        av_log(NULL, AV_LOG_ERROR, "Unknown format '%s'.\n", name);
-        return;
-    }
-
-    printf("Muxer %s [%s]:\n", fmt->name, fmt->long_name);
-
-    if (fmt->extensions)
-        printf("    Common extensions: %s.\n", fmt->extensions);
-    if (fmt->mime_type)
-        printf("    Mime type: %s.\n", fmt->mime_type);
-    if (fmt->video_codec != AV_CODEC_ID_NONE &&
-        (desc = avcodec_descriptor_get(fmt->video_codec))) {
-        printf("    Default video codec: %s.\n", desc->name);
-    }
-    if (fmt->audio_codec != AV_CODEC_ID_NONE &&
-        (desc = avcodec_descriptor_get(fmt->audio_codec))) {
-        printf("    Default audio codec: %s.\n", desc->name);
-    }
-    if (fmt->subtitle_codec != AV_CODEC_ID_NONE &&
-        (desc = avcodec_descriptor_get(fmt->subtitle_codec))) {
-        printf("    Default subtitle codec: %s.\n", desc->name);
-    }
-
-    if (fmt->priv_class)
-        show_help_children(fmt->priv_class, AV_OPT_FLAG_ENCODING_PARAM);
-}
-
-#if CONFIG_AVFILTER
-static void show_help_filter(const char *name)
-{
-#if CONFIG_AVFILTER
-    const AVFilter *f = avfilter_get_by_name(name);
-    int i, count;
-
-    if (!name) {
-        av_log(NULL, AV_LOG_ERROR, "No filter name specified.\n");
-        return;
-    } else if (!f) {
-        av_log(NULL, AV_LOG_ERROR, "Unknown filter '%s'.\n", name);
-        return;
-    }
-
-    printf("Filter %s\n", f->name);
-    if (f->description)
-        printf("  %s\n", f->description);
-
-    if (f->flags & AVFILTER_FLAG_SLICE_THREADS)
-        printf("    slice threading supported\n");
-
-    printf("    Inputs:\n");
-    count = avfilter_filter_pad_count(f, 0);
-    for (i = 0; i < count; i++) {
-        printf("       #%d: %s (%s)\n", i, avfilter_pad_get_name(f->inputs, i),
-               media_type_string(avfilter_pad_get_type(f->inputs, i)));
-    }
-    if (f->flags & AVFILTER_FLAG_DYNAMIC_INPUTS)
-        printf("        dynamic (depending on the options)\n");
-    else if (!count)
-        printf("        none (source filter)\n");
-
-    printf("    Outputs:\n");
-    count = avfilter_filter_pad_count(f, 1);
-    for (i = 0; i < count; i++) {
-        printf("       #%d: %s (%s)\n", i, avfilter_pad_get_name(f->outputs, i),
-               media_type_string(avfilter_pad_get_type(f->outputs, i)));
-    }
-    if (f->flags & AVFILTER_FLAG_DYNAMIC_OUTPUTS)
-        printf("        dynamic (depending on the options)\n");
-    else if (!count)
-        printf("        none (sink filter)\n");
-
-    if (f->priv_class)
-        show_help_children(f->priv_class, AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_FILTERING_PARAM |
-                                          AV_OPT_FLAG_AUDIO_PARAM);
-    if (f->flags & AVFILTER_FLAG_SUPPORT_TIMELINE)
-        printf("This filter has support for timeline through the 'enable' option.\n");
-#else
-    av_log(NULL, AV_LOG_ERROR, "Build without libavfilter; "
-           "can not to satisfy request\n");
-#endif
-}
-#endif
-
-static void show_help_bsf(const char *name)
-{
-    const AVBitStreamFilter *bsf = av_bsf_get_by_name(name);
-
-    if (!name) {
-        av_log(NULL, AV_LOG_ERROR, "No bitstream filter name specified.\n");
-        return;
-    } else if (!bsf) {
-        av_log(NULL, AV_LOG_ERROR, "Unknown bit stream filter '%s'.\n", name);
-        return;
-    }
-
-    printf("Bit stream filter %s\n", bsf->name);
-    PRINT_CODEC_SUPPORTED(bsf, codec_ids, enum AVCodecID, "codecs",
-                          AV_CODEC_ID_NONE, GET_CODEC_NAME);
-    if (bsf->priv_class)
-        show_help_children(bsf->priv_class, AV_OPT_FLAG_BSF_PARAM);
-}
-
-int show_help(void *optctx, const char *opt, const char *arg)
-{
-    char *topic, *par;
-    av_log_set_callback(log_callback_help);
-
-    topic = av_strdup(arg ? arg : "");
-    if (!topic)
-        return AVERROR(ENOMEM);
-    par = strchr(topic, '=');
-    if (par)
-        *par++ = 0;
-
-    if (!*topic) {
-        show_help_default(topic, par);
-    } else if (!strcmp(topic, "decoder")) {
-        show_help_codec(par, 0);
-    } else if (!strcmp(topic, "encoder")) {
-        show_help_codec(par, 1);
-    } else if (!strcmp(topic, "demuxer")) {
-        show_help_demuxer(par);
-    } else if (!strcmp(topic, "muxer")) {
-        show_help_muxer(par);
-    } else if (!strcmp(topic, "protocol")) {
-        show_help_protocol(par);
-#if CONFIG_AVFILTER
-    } else if (!strcmp(topic, "filter")) {
-        show_help_filter(par);
-#endif
-    } else if (!strcmp(topic, "bsf")) {
-        show_help_bsf(par);
-    } else {
-        show_help_default(topic, par);
-    }
-
-    av_freep(&topic);
-    return 0;
-}
-
 int read_yesno(void)
 {
     int c = getchar();
@@ -2065,28 +817,45 @@ FILE *get_preset_file(char *filename, si
 {
     FILE *f = NULL;
     int i;
-    const char *base[3] = { getenv("FFMPEG_DATADIR"),
-                            getenv("HOME"),
+#if HAVE_GETMODULEHANDLE && defined(_WIN32)
+    char *datadir = NULL;
+#endif
+    char *env_home = getenv_utf8("HOME");
+    char *env_ffmpeg_datadir = getenv_utf8("FFMPEG_DATADIR");
+    const char *base[3] = { env_ffmpeg_datadir,
+                            env_home,   /* index=1(HOME) is special: search in a .ffmpeg subfolder */
                             FFMPEG_DATADIR, };
 
     if (is_path) {
         av_strlcpy(filename, preset_name, filename_size);
-        f = fopen(filename, "r");
+        f = fopen_utf8(filename, "r");
     } else {
 #if HAVE_GETMODULEHANDLE && defined(_WIN32)
-        char datadir[MAX_PATH], *ls;
+        wchar_t *datadir_w = get_module_filename(NULL);
         base[2] = NULL;
 
-        if (GetModuleFileNameA(GetModuleHandleA(NULL), datadir, sizeof(datadir) - 1))
+        if (wchartoutf8(datadir_w, &datadir))
+            datadir = NULL;
+        av_free(datadir_w);
+
+        if (datadir)
         {
-            for (ls = datadir; ls < datadir + strlen(datadir); ls++)
+            char *ls;
+            for (ls = datadir; *ls; ls++)
                 if (*ls == '\\') *ls = '/';
 
             if (ls = strrchr(datadir, '/'))
             {
-                *ls = 0;
-                strncat(datadir, "/ffpresets",  sizeof(datadir) - 1 - strlen(datadir));
-                base[2] = datadir;
+                ptrdiff_t datadir_len = ls - datadir;
+                size_t desired_size = datadir_len + strlen("/ffpresets") + 1;
+                char *new_datadir = av_realloc_array(
+                    datadir, desired_size, sizeof *datadir);
+                if (new_datadir) {
+                    datadir = new_datadir;
+                    datadir[datadir_len] = 0;
+                    strncat(datadir, "/ffpresets",  desired_size - 1 - datadir_len);
+                    base[2] = datadir;
+                }
             }
         }
 #endif
@@ -2095,17 +864,22 @@ FILE *get_preset_file(char *filename, si
                 continue;
             snprintf(filename, filename_size, "%s%s/%s.ffpreset", base[i],
                      i != 1 ? "" : "/.ffmpeg", preset_name);
-            f = fopen(filename, "r");
+            f = fopen_utf8(filename, "r");
             if (!f && codec_name) {
                 snprintf(filename, filename_size,
                          "%s%s/%s-%s.ffpreset",
                          base[i], i != 1 ? "" : "/.ffmpeg", codec_name,
                          preset_name);
-                f = fopen(filename, "r");
+                f = fopen_utf8(filename, "r");
             }
         }
     }
 
+#if HAVE_GETMODULEHANDLE && defined(_WIN32)
+    av_free(datadir);
+#endif
+    freeenv_utf8(env_ffmpeg_datadir);
+    freeenv_utf8(env_home);
     return f;
 }
 
@@ -2242,164 +1016,3 @@ double get_rotation(int32_t *displaymatr
 
     return theta;
 }
-
-#if CONFIG_AVDEVICE
-static void print_device_list(const AVDeviceInfoList *device_list)
-{
-    // print devices
-    for (int i = 0; i < device_list->nb_devices; i++) {
-        const AVDeviceInfo *device = device_list->devices[i];
-        printf("%c %s [%s] (", device_list->default_device == i ? '*' : ' ',
-            device->device_name, device->device_description);
-        if (device->nb_media_types > 0) {
-            for (int j = 0; j < device->nb_media_types; ++j) {
-                const char* media_type = av_get_media_type_string(device->media_types[j]);
-                if (j > 0)
-                    printf(", ");
-                printf("%s", media_type ? media_type : "unknown");
-            }
-        } else {
-            printf("none");
-        }
-        printf(")\n");
-    }
-}
-static int print_device_sources(const AVInputFormat *fmt, AVDictionary *opts)
-{
-    int ret;
-    AVDeviceInfoList *device_list = NULL;
-
-    if (!fmt || !fmt->priv_class  || !AV_IS_INPUT_DEVICE(fmt->priv_class->category))
-        return AVERROR(EINVAL);
-
-    printf("Auto-detected sources for %s:\n", fmt->name);
-    if ((ret = avdevice_list_input_sources(fmt, NULL, opts, &device_list)) < 0) {
-        printf("Cannot list sources: %s\n", av_err2str(ret));
-        goto fail;
-    }
-
-    print_device_list(device_list);
-
-  fail:
-    avdevice_free_list_devices(&device_list);
-    return ret;
-}
-
-static int print_device_sinks(const AVOutputFormat *fmt, AVDictionary *opts)
-{
-    int ret;
-    AVDeviceInfoList *device_list = NULL;
-
-    if (!fmt || !fmt->priv_class  || !AV_IS_OUTPUT_DEVICE(fmt->priv_class->category))
-        return AVERROR(EINVAL);
-
-    printf("Auto-detected sinks for %s:\n", fmt->name);
-    if ((ret = avdevice_list_output_sinks(fmt, NULL, opts, &device_list)) < 0) {
-        printf("Cannot list sinks: %s\n", av_err2str(ret));
-        goto fail;
-    }
-
-    print_device_list(device_list);
-
-  fail:
-    avdevice_free_list_devices(&device_list);
-    return ret;
-}
-
-static int show_sinks_sources_parse_arg(const char *arg, char **dev, AVDictionary **opts)
-{
-    int ret;
-    if (arg) {
-        char *opts_str = NULL;
-        av_assert0(dev && opts);
-        *dev = av_strdup(arg);
-        if (!*dev)
-            return AVERROR(ENOMEM);
-        if ((opts_str = strchr(*dev, ','))) {
-            *(opts_str++) = '\0';
-            if (opts_str[0] && ((ret = av_dict_parse_string(opts, opts_str, "=", ":", 0)) < 0)) {
-                av_freep(dev);
-                return ret;
-            }
-        }
-    } else
-        printf("\nDevice name is not provided.\n"
-                "You can pass devicename[,opt1=val1[,opt2=val2...]] as an argument.\n\n");
-    return 0;
-}
-
-int show_sources(void *optctx, const char *opt, const char *arg)
-{
-    const AVInputFormat *fmt = NULL;
-    char *dev = NULL;
-    AVDictionary *opts = NULL;
-    int ret = 0;
-    int error_level = av_log_get_level();
-
-    av_log_set_level(AV_LOG_WARNING);
-
-    if ((ret = show_sinks_sources_parse_arg(arg, &dev, &opts)) < 0)
-        goto fail;
-
-    do {
-        fmt = av_input_audio_device_next(fmt);
-        if (fmt) {
-            if (!strcmp(fmt->name, "lavfi"))
-                continue; //it's pointless to probe lavfi
-            if (dev && !av_match_name(dev, fmt->name))
-                continue;
-            print_device_sources(fmt, opts);
-        }
-    } while (fmt);
-    do {
-        fmt = av_input_video_device_next(fmt);
-        if (fmt) {
-            if (dev && !av_match_name(dev, fmt->name))
-                continue;
-            print_device_sources(fmt, opts);
-        }
-    } while (fmt);
-  fail:
-    av_dict_free(&opts);
-    av_free(dev);
-    av_log_set_level(error_level);
-    return ret;
-}
-
-int show_sinks(void *optctx, const char *opt, const char *arg)
-{
-    const AVOutputFormat *fmt = NULL;
-    char *dev = NULL;
-    AVDictionary *opts = NULL;
-    int ret = 0;
-    int error_level = av_log_get_level();
-
-    av_log_set_level(AV_LOG_WARNING);
-
-    if ((ret = show_sinks_sources_parse_arg(arg, &dev, &opts)) < 0)
-        goto fail;
-
-    do {
-        fmt = av_output_audio_device_next(fmt);
-        if (fmt) {
-            if (dev && !av_match_name(dev, fmt->name))
-                continue;
-            print_device_sinks(fmt, opts);
-        }
-    } while (fmt);
-    do {
-        fmt = av_output_video_device_next(fmt);
-        if (fmt) {
-            if (dev && !av_match_name(dev, fmt->name))
-                continue;
-            print_device_sinks(fmt, opts);
-        }
-    } while (fmt);
-  fail:
-    av_dict_free(&opts);
-    av_free(dev);
-    av_log_set_level(error_level);
-    return ret;
-}
-
-#endif
diff -pruN 7:5.0.1-3/fftools/cmdutils.h 7:5.1-1/fftools/cmdutils.h
--- 7:5.0.1-3/fftools/cmdutils.h	2022-01-14 18:45:39.000000000 +0000
+++ 7:5.1-1/fftools/cmdutils.h	2022-07-22 17:58:38.000000000 +0000
@@ -44,8 +44,6 @@ extern const char program_name[];
  */
 extern const int program_birth_year;
 
-extern AVCodecContext *avcodec_opts[AVMEDIA_TYPE_NB];
-extern AVFormatContext *avformat_opts;
 extern AVDictionary *sws_dict;
 extern AVDictionary *swr_opts;
 extern AVDictionary *format_opts, *codec_opts;
@@ -67,11 +65,6 @@ void exit_program(int ret) av_noreturn;
 void init_dynload(void);
 
 /**
- * Initialize the cmdutils option system, in particular
- * allocate the *_opts contexts.
- */
-void init_opts(void);
-/**
  * Uninitialize the cmdutils option system, in particular
  * free the *_opts contexts and their contents.
  */
@@ -84,33 +77,12 @@ void uninit_opts(void);
 void log_callback_help(void* ptr, int level, const char* fmt, va_list vl);
 
 /**
- * Override the cpuflags.
- */
-int opt_cpuflags(void *optctx, const char *opt, const char *arg);
-
-/**
- * Override the cpucount.
- */
-int opt_cpucount(void *optctx, const char *opt, const char *arg);
-
-/**
  * Fallback for options that are not explicitly handled, these will be
  * parsed through AVOptions.
  */
 int opt_default(void *optctx, const char *opt, const char *arg);
 
 /**
- * Set the libav* libraries log level.
- */
-int opt_loglevel(void *optctx, const char *opt, const char *arg);
-
-int opt_report(void *optctx, const char *opt, const char *arg);
-
-int opt_max_alloc(void *optctx, const char *opt, const char *arg);
-
-int opt_codec_debug(void *optctx, const char *opt, const char *arg);
-
-/**
  * Limit the execution time.
  */
 int opt_timelimit(void *optctx, const char *opt, const char *arg);
@@ -206,49 +178,6 @@ typedef struct OptionDef {
 void show_help_options(const OptionDef *options, const char *msg, int req_flags,
                        int rej_flags, int alt_flags);
 
-#if CONFIG_AVDEVICE
-#define CMDUTILS_COMMON_OPTIONS_AVDEVICE                                                                                \
-    { "sources"    , OPT_EXIT | HAS_ARG, { .func_arg = show_sources },                                                  \
-      "list sources of the input device", "device" },                                                                   \
-    { "sinks"      , OPT_EXIT | HAS_ARG, { .func_arg = show_sinks },                                                    \
-      "list sinks of the output device", "device" },                                                                    \
-
-#else
-#define CMDUTILS_COMMON_OPTIONS_AVDEVICE
-#endif
-
-#define CMDUTILS_COMMON_OPTIONS                                                                                         \
-    { "L",           OPT_EXIT,             { .func_arg = show_license },     "show license" },                          \
-    { "h",           OPT_EXIT,             { .func_arg = show_help },        "show help", "topic" },                    \
-    { "?",           OPT_EXIT,             { .func_arg = show_help },        "show help", "topic" },                    \
-    { "help",        OPT_EXIT,             { .func_arg = show_help },        "show help", "topic" },                    \
-    { "-help",       OPT_EXIT,             { .func_arg = show_help },        "show help", "topic" },                    \
-    { "version",     OPT_EXIT,             { .func_arg = show_version },     "show version" },                          \
-    { "buildconf",   OPT_EXIT,             { .func_arg = show_buildconf },   "show build configuration" },              \
-    { "formats",     OPT_EXIT,             { .func_arg = show_formats },     "show available formats" },                \
-    { "muxers",      OPT_EXIT,             { .func_arg = show_muxers },      "show available muxers" },                 \
-    { "demuxers",    OPT_EXIT,             { .func_arg = show_demuxers },    "show available demuxers" },               \
-    { "devices",     OPT_EXIT,             { .func_arg = show_devices },     "show available devices" },                \
-    { "codecs",      OPT_EXIT,             { .func_arg = show_codecs },      "show available codecs" },                 \
-    { "decoders",    OPT_EXIT,             { .func_arg = show_decoders },    "show available decoders" },               \
-    { "encoders",    OPT_EXIT,             { .func_arg = show_encoders },    "show available encoders" },               \
-    { "bsfs",        OPT_EXIT,             { .func_arg = show_bsfs },        "show available bit stream filters" },     \
-    { "protocols",   OPT_EXIT,             { .func_arg = show_protocols },   "show available protocols" },              \
-    { "filters",     OPT_EXIT,             { .func_arg = show_filters },     "show available filters" },                \
-    { "pix_fmts",    OPT_EXIT,             { .func_arg = show_pix_fmts },    "show available pixel formats" },          \
-    { "layouts",     OPT_EXIT,             { .func_arg = show_layouts },     "show standard channel layouts" },         \
-    { "sample_fmts", OPT_EXIT,             { .func_arg = show_sample_fmts }, "show available audio sample formats" },   \
-    { "dispositions", OPT_EXIT,            { .func_arg = show_dispositions}, "show available stream dispositions" },    \
-    { "colors",      OPT_EXIT,             { .func_arg = show_colors },      "show available color names" },            \
-    { "loglevel",    HAS_ARG,              { .func_arg = opt_loglevel },     "set logging level", "loglevel" },         \
-    { "v",           HAS_ARG,              { .func_arg = opt_loglevel },     "set logging level", "loglevel" },         \
-    { "report",      0,                    { .func_arg = opt_report },       "generate a report" },                     \
-    { "max_alloc",   HAS_ARG,              { .func_arg = opt_max_alloc },    "set maximum size of a single allocated block", "bytes" }, \
-    { "cpuflags",    HAS_ARG | OPT_EXPERT, { .func_arg = opt_cpuflags },     "force specific cpu flags", "flags" },     \
-    { "cpucount",    HAS_ARG | OPT_EXPERT, { .func_arg = opt_cpucount },     "force specific cpu count", "count" },     \
-    { "hide_banner", OPT_BOOL | OPT_EXPERT, {&hide_banner},     "do not show program banner", "hide_banner" },          \
-    CMDUTILS_COMMON_OPTIONS_AVDEVICE                                                                                    \
-
 /**
  * Show help for all options with given flags in class and all its
  * children.
@@ -262,11 +191,6 @@ void show_help_children(const AVClass *c
 void show_help_default(const char *opt, const char *arg);
 
 /**
- * Generic -h handler common to all fftools.
- */
-int show_help(void *optctx, const char *opt, const char *arg);
-
-/**
  * Parse the command line arguments.
  *
  * @param optctx an opaque options context
@@ -455,141 +379,6 @@ void print_error(const char *filename, i
 void show_banner(int argc, char **argv, const OptionDef *options);
 
 /**
- * Print the version of the program to stdout. The version message
- * depends on the current versions of the repository and of the libav*
- * libraries.
- * This option processing function does not utilize the arguments.
- */
-int show_version(void *optctx, const char *opt, const char *arg);
-
-/**
- * Print the build configuration of the program to stdout. The contents
- * depend on the definition of FFMPEG_CONFIGURATION.
- * This option processing function does not utilize the arguments.
- */
-int show_buildconf(void *optctx, const char *opt, const char *arg);
-
-/**
- * Print the license of the program to stdout. The license depends on
- * the license of the libraries compiled into the program.
- * This option processing function does not utilize the arguments.
- */
-int show_license(void *optctx, const char *opt, const char *arg);
-
-/**
- * Print a listing containing all the formats supported by the
- * program (including devices).
- * This option processing function does not utilize the arguments.
- */
-int show_formats(void *optctx, const char *opt, const char *arg);
-
-/**
- * Print a listing containing all the muxers supported by the
- * program (including devices).
- * This option processing function does not utilize the arguments.
- */
-int show_muxers(void *optctx, const char *opt, const char *arg);
-
-/**
- * Print a listing containing all the demuxer supported by the
- * program (including devices).
- * This option processing function does not utilize the arguments.
- */
-int show_demuxers(void *optctx, const char *opt, const char *arg);
-
-/**
- * Print a listing containing all the devices supported by the
- * program.
- * This option processing function does not utilize the arguments.
- */
-int show_devices(void *optctx, const char *opt, const char *arg);
-
-#if CONFIG_AVDEVICE
-/**
- * Print a listing containing autodetected sinks of the output device.
- * Device name with options may be passed as an argument to limit results.
- */
-int show_sinks(void *optctx, const char *opt, const char *arg);
-
-/**
- * Print a listing containing autodetected sources of the input device.
- * Device name with options may be passed as an argument to limit results.
- */
-int show_sources(void *optctx, const char *opt, const char *arg);
-#endif
-
-/**
- * Print a listing containing all the codecs supported by the
- * program.
- * This option processing function does not utilize the arguments.
- */
-int show_codecs(void *optctx, const char *opt, const char *arg);
-
-/**
- * Print a listing containing all the decoders supported by the
- * program.
- */
-int show_decoders(void *optctx, const char *opt, const char *arg);
-
-/**
- * Print a listing containing all the encoders supported by the
- * program.
- */
-int show_encoders(void *optctx, const char *opt, const char *arg);
-
-/**
- * Print a listing containing all the filters supported by the
- * program.
- * This option processing function does not utilize the arguments.
- */
-int show_filters(void *optctx, const char *opt, const char *arg);
-
-/**
- * Print a listing containing all the bit stream filters supported by the
- * program.
- * This option processing function does not utilize the arguments.
- */
-int show_bsfs(void *optctx, const char *opt, const char *arg);
-
-/**
- * Print a listing containing all the protocols supported by the
- * program.
- * This option processing function does not utilize the arguments.
- */
-int show_protocols(void *optctx, const char *opt, const char *arg);
-
-/**
- * Print a listing containing all the pixel formats supported by the
- * program.
- * This option processing function does not utilize the arguments.
- */
-int show_pix_fmts(void *optctx, const char *opt, const char *arg);
-
-/**
- * Print a listing containing all the standard channel layouts supported by
- * the program.
- * This option processing function does not utilize the arguments.
- */
-int show_layouts(void *optctx, const char *opt, const char *arg);
-
-/**
- * Print a listing containing all the sample formats supported by the
- * program.
- */
-int show_sample_fmts(void *optctx, const char *opt, const char *arg);
-
-/**
- * Print a listing containing all supported stream dispositions.
- */
-int show_dispositions(void *optctx, const char *opt, const char *arg);
-
-/**
- * Print a listing containing all the color names and values recognized
- * by the program.
- */
-int show_colors(void *optctx, const char *opt, const char *arg);
-
-/**
  * Return a positive value if a line read from standard input
  * starts with [yY], otherwise return 0.
  */
@@ -642,8 +431,6 @@ void *grow_array(void *array, int elem_s
  */
 void *allocate_array_elem(void *array, size_t elem_size, int *nb_elems);
 
-#define media_type_string av_get_media_type_string
-
 #define GROW_ARRAY(array, nb_elems)\
     array = grow_array(array, sizeof(*array), &nb_elems, nb_elems + 1)
 
@@ -663,14 +450,6 @@ void *allocate_array_elem(void *array, s
     char name[16];\
     snprintf(name, sizeof(name), "%d", rate);
 
-#define GET_CH_LAYOUT_NAME(ch_layout)\
-    char name[16];\
-    snprintf(name, sizeof(name), "0x%"PRIx64, ch_layout);
-
-#define GET_CH_LAYOUT_DESC(ch_layout)\
-    char name[128];\
-    av_get_channel_layout_string(name, sizeof(name), 0, ch_layout);
-
 double get_rotation(int32_t *displaymatrix);
 
 #endif /* FFTOOLS_CMDUTILS_H */
diff -pruN 7:5.0.1-3/fftools/ffmpeg.c 7:5.1-1/fftools/ffmpeg.c
--- 7:5.0.1-3/fftools/ffmpeg.c	2022-01-14 18:45:39.000000000 +0000
+++ 7:5.1-1/fftools/ffmpeg.c	2022-07-22 17:58:38.000000000 +0000
@@ -64,6 +64,7 @@
 #include "libavutil/thread.h"
 #include "libavutil/threadmessage.h"
 #include "libavcodec/mathops.h"
+#include "libavcodec/version.h"
 #include "libavformat/os_support.h"
 
 # include "libavfilter/avfilter.h"
@@ -126,19 +127,17 @@ typedef struct BenchmarkTimeStamps {
     int64_t sys_usec;
 } BenchmarkTimeStamps;
 
-static void do_video_stats(OutputStream *ost, int frame_size);
 static BenchmarkTimeStamps get_benchmark_time_stamps(void);
 static int64_t getmaxrss(void);
 static int ifilter_has_all_input_formats(FilterGraph *fg);
 
-static int run_as_daemon  = 0;
-static int nb_frames_dup = 0;
-static unsigned dup_warning = 1000;
-static int nb_frames_drop = 0;
+static int64_t nb_frames_dup = 0;
+static uint64_t dup_warning = 1000;
+static int64_t nb_frames_drop = 0;
 static int64_t decode_error_stat[2];
-static unsigned nb_output_dumped = 0;
+unsigned nb_output_dumped = 0;
 
-static int want_sdp = 1;
+int want_sdp = 1;
 
 static BenchmarkTimeStamps current_time;
 AVIOContext *progress_avio = NULL;
@@ -344,7 +343,7 @@ static volatile int received_sigterm = 0
 static volatile int received_nb_signals = 0;
 static atomic_int transcode_init_done = ATOMIC_VAR_INIT(0);
 static volatile int ffmpeg_exited = 0;
-static int main_return_code = 0;
+int main_return_code = 0;
 static int64_t copy_ts_first_pts = AV_NOPTS_VALUE;
 
 static void
@@ -419,7 +418,7 @@ void term_init(void)
 #endif
 
 #if HAVE_TERMIOS_H
-    if (!run_as_daemon && stdin_interaction) {
+    if (stdin_interaction) {
         struct termios tty;
         if (tcgetattr (0, &tty) == 0) {
             oldtty = tty;
@@ -528,22 +527,18 @@ static void ffmpeg_cleanup(int ret)
             InputFilter *ifilter = fg->inputs[j];
             struct InputStream *ist = ifilter->ist;
 
-            while (av_fifo_size(ifilter->frame_queue)) {
+            if (ifilter->frame_queue) {
                 AVFrame *frame;
-                av_fifo_generic_read(ifilter->frame_queue, &frame,
-                                     sizeof(frame), NULL);
-                av_frame_free(&frame);
+                while (av_fifo_read(ifilter->frame_queue, &frame, 1) >= 0)
+                    av_frame_free(&frame);
+                av_fifo_freep2(&ifilter->frame_queue);
             }
-            av_fifo_freep(&ifilter->frame_queue);
             av_freep(&ifilter->displaymatrix);
             if (ist->sub2video.sub_queue) {
-                while (av_fifo_size(ist->sub2video.sub_queue)) {
-                    AVSubtitle sub;
-                    av_fifo_generic_read(ist->sub2video.sub_queue,
-                                         &sub, sizeof(sub), NULL);
+                AVSubtitle sub;
+                while (av_fifo_read(ist->sub2video.sub_queue, &sub, 1) >= 0)
                     avsubtitle_free(&sub);
-                }
-                av_fifo_freep(&ist->sub2video.sub_queue);
+                av_fifo_freep2(&ist->sub2video.sub_queue);
             }
             av_buffer_unref(&ifilter->hw_frames_ctx);
             av_freep(&ifilter->name);
@@ -555,6 +550,7 @@ static void ffmpeg_cleanup(int ret)
 
             avfilter_inout_free(&ofilter->out_tmp);
             av_freep(&ofilter->name);
+            av_channel_layout_uninit(&ofilter->ch_layout);
             av_freep(&fg->outputs[j]);
         }
         av_freep(&fg->outputs);
@@ -567,19 +563,9 @@ static void ffmpeg_cleanup(int ret)
     av_freep(&subtitle_out);
 
     /* close files */
-    for (i = 0; i < nb_output_files; i++) {
-        OutputFile *of = output_files[i];
-        AVFormatContext *s;
-        if (!of)
-            continue;
-        s = of->ctx;
-        if (s && s->oformat && !(s->oformat->flags & AVFMT_NOFILE))
-            avio_closep(&s->pb);
-        avformat_free_context(s);
-        av_dict_free(&of->opts);
+    for (i = 0; i < nb_output_files; i++)
+        of_close(&output_files[i]);
 
-        av_freep(&output_files[i]);
-    }
     for (i = 0; i < nb_output_streams; i++) {
         OutputStream *ost = output_streams[i];
 
@@ -608,12 +594,10 @@ static void ffmpeg_cleanup(int ret)
         avcodec_parameters_free(&ost->ref_par);
 
         if (ost->muxing_queue) {
-            while (av_fifo_size(ost->muxing_queue)) {
-                AVPacket *pkt;
-                av_fifo_generic_read(ost->muxing_queue, &pkt, sizeof(pkt), NULL);
+            AVPacket *pkt;
+            while (av_fifo_read(ost->muxing_queue, &pkt, 1) >= 0)
                 av_packet_free(&pkt);
-            }
-            av_fifo_freep(&ost->muxing_queue);
+            av_fifo_freep2(&ost->muxing_queue);
         }
 
         av_freep(&output_streams[i]);
@@ -715,159 +699,6 @@ static void update_benchmark(const char
     }
 }
 
-static void close_all_output_streams(OutputStream *ost, OSTFinished this_stream, OSTFinished others)
-{
-    int i;
-    for (i = 0; i < nb_output_streams; i++) {
-        OutputStream *ost2 = output_streams[i];
-        ost2->finished |= ost == ost2 ? this_stream : others;
-    }
-}
-
-static void write_packet(OutputFile *of, AVPacket *pkt, OutputStream *ost, int unqueue)
-{
-    AVFormatContext *s = of->ctx;
-    AVStream *st = ost->st;
-    int ret;
-
-    /*
-     * Audio encoders may split the packets --  #frames in != #packets out.
-     * But there is no reordering, so we can limit the number of output packets
-     * by simply dropping them here.
-     * Counting encoded video frames needs to be done separately because of
-     * reordering, see do_video_out().
-     * Do not count the packet when unqueued because it has been counted when queued.
-     */
-    if (!(st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && ost->encoding_needed) && !unqueue) {
-        if (ost->frame_number >= ost->max_frames) {
-            av_packet_unref(pkt);
-            return;
-        }
-        ost->frame_number++;
-    }
-
-    if (!of->header_written) {
-        AVPacket *tmp_pkt;
-        /* the muxer is not initialized yet, buffer the packet */
-        if (!av_fifo_space(ost->muxing_queue)) {
-            size_t cur_size = av_fifo_size(ost->muxing_queue);
-            unsigned int are_we_over_size =
-                (ost->muxing_queue_data_size + pkt->size) > ost->muxing_queue_data_threshold;
-            size_t limit    = are_we_over_size ? ost->max_muxing_queue_size : INT_MAX;
-            size_t new_size = FFMIN(2 * cur_size, limit);
-
-            if (new_size <= cur_size) {
-                av_log(NULL, AV_LOG_ERROR,
-                       "Too many packets buffered for output stream %d:%d.\n",
-                       ost->file_index, ost->st->index);
-                exit_program(1);
-            }
-            ret = av_fifo_realloc2(ost->muxing_queue, new_size);
-            if (ret < 0)
-                exit_program(1);
-        }
-        ret = av_packet_make_refcounted(pkt);
-        if (ret < 0)
-            exit_program(1);
-        tmp_pkt = av_packet_alloc();
-        if (!tmp_pkt)
-            exit_program(1);
-        av_packet_move_ref(tmp_pkt, pkt);
-        ost->muxing_queue_data_size += tmp_pkt->size;
-        av_fifo_generic_write(ost->muxing_queue, &tmp_pkt, sizeof(tmp_pkt), NULL);
-        return;
-    }
-
-    if ((st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && video_sync_method == VSYNC_DROP) ||
-        (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && audio_sync_method < 0))
-        pkt->pts = pkt->dts = AV_NOPTS_VALUE;
-
-    if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
-        int i;
-        uint8_t *sd = av_packet_get_side_data(pkt, AV_PKT_DATA_QUALITY_STATS,
-                                              NULL);
-        ost->quality = sd ? AV_RL32(sd) : -1;
-        ost->pict_type = sd ? sd[4] : AV_PICTURE_TYPE_NONE;
-
-        for (i = 0; i<FF_ARRAY_ELEMS(ost->error); i++) {
-            if (sd && i < sd[5])
-                ost->error[i] = AV_RL64(sd + 8 + 8*i);
-            else
-                ost->error[i] = -1;
-        }
-
-        if (ost->frame_rate.num && ost->is_cfr) {
-            if (pkt->duration > 0)
-                av_log(NULL, AV_LOG_WARNING, "Overriding packet duration by frame rate, this should not happen\n");
-            pkt->duration = av_rescale_q(1, av_inv_q(ost->frame_rate),
-                                         ost->mux_timebase);
-        }
-    }
-
-    av_packet_rescale_ts(pkt, ost->mux_timebase, ost->st->time_base);
-
-    if (!(s->oformat->flags & AVFMT_NOTIMESTAMPS)) {
-        if (pkt->dts != AV_NOPTS_VALUE &&
-            pkt->pts != AV_NOPTS_VALUE &&
-            pkt->dts > pkt->pts) {
-            av_log(s, AV_LOG_WARNING, "Invalid DTS: %"PRId64" PTS: %"PRId64" in output stream %d:%d, replacing by guess\n",
-                   pkt->dts, pkt->pts,
-                   ost->file_index, ost->st->index);
-            pkt->pts =
-            pkt->dts = pkt->pts + pkt->dts + ost->last_mux_dts + 1
-                     - FFMIN3(pkt->pts, pkt->dts, ost->last_mux_dts + 1)
-                     - FFMAX3(pkt->pts, pkt->dts, ost->last_mux_dts + 1);
-        }
-        if ((st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO || st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO || st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) &&
-            pkt->dts != AV_NOPTS_VALUE &&
-            !(st->codecpar->codec_id == AV_CODEC_ID_VP9 && ost->stream_copy) &&
-            ost->last_mux_dts != AV_NOPTS_VALUE) {
-            int64_t max = ost->last_mux_dts + !(s->oformat->flags & AVFMT_TS_NONSTRICT);
-            if (pkt->dts < max) {
-                int loglevel = max - pkt->dts > 2 || st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO ? AV_LOG_WARNING : AV_LOG_DEBUG;
-                if (exit_on_error)
-                    loglevel = AV_LOG_ERROR;
-                av_log(s, loglevel, "Non-monotonous DTS in output stream "
-                       "%d:%d; previous: %"PRId64", current: %"PRId64"; ",
-                       ost->file_index, ost->st->index, ost->last_mux_dts, pkt->dts);
-                if (exit_on_error) {
-                    av_log(NULL, AV_LOG_FATAL, "aborting.\n");
-                    exit_program(1);
-                }
-                av_log(s, loglevel, "changing to %"PRId64". This may result "
-                       "in incorrect timestamps in the output file.\n",
-                       max);
-                if (pkt->pts >= pkt->dts)
-                    pkt->pts = FFMAX(pkt->pts, max);
-                pkt->dts = max;
-            }
-        }
-    }
-    ost->last_mux_dts = pkt->dts;
-
-    ost->data_size += pkt->size;
-    ost->packets_written++;
-
-    pkt->stream_index = ost->index;
-
-    if (debug_ts) {
-        av_log(NULL, AV_LOG_INFO, "muxer <- type:%s "
-                "pkt_pts:%s pkt_pts_time:%s pkt_dts:%s pkt_dts_time:%s size:%d\n",
-                av_get_media_type_string(ost->enc_ctx->codec_type),
-                av_ts2str(pkt->pts), av_ts2timestr(pkt->pts, &ost->st->time_base),
-                av_ts2str(pkt->dts), av_ts2timestr(pkt->dts, &ost->st->time_base),
-                pkt->size
-              );
-    }
-
-    ret = av_interleaved_write_frame(s, pkt);
-    if (ret < 0) {
-        print_error("av_interleaved_write_frame()", ret);
-        main_return_code = 1;
-        close_all_output_streams(ost, MUXER_FINISHED | ENCODER_FINISHED, ENCODER_FINISHED);
-    }
-}
-
 static void close_output_stream(OutputStream *ost)
 {
     OutputFile *of = output_files[ost->file_index];
@@ -902,11 +733,11 @@ static void output_packet(OutputFile *of
         if (ret < 0)
             goto finish;
         while ((ret = av_bsf_receive_packet(ost->bsf_ctx, pkt)) >= 0)
-            write_packet(of, pkt, ost, 0);
+            of_write_packet(of, pkt, ost, 0);
         if (ret == AVERROR(EAGAIN))
             ret = 0;
     } else if (!eof)
-        write_packet(of, pkt, ost, 0);
+        of_write_packet(of, pkt, ost, 0);
 
 finish:
     if (ret < 0 && ret != AVERROR_EOF) {
@@ -998,61 +829,166 @@ static int init_output_stream_wrapper(Ou
     return ret;
 }
 
-static void do_audio_out(OutputFile *of, OutputStream *ost,
-                         AVFrame *frame)
+static double psnr(double d)
 {
+    return -10.0 * log10(d);
+}
+
+static void update_video_stats(OutputStream *ost, const AVPacket *pkt, int write_vstats)
+{
+    const uint8_t *sd = av_packet_get_side_data(pkt, AV_PKT_DATA_QUALITY_STATS,
+                                                NULL);
     AVCodecContext *enc = ost->enc_ctx;
-    AVPacket *pkt = ost->pkt;
-    int ret;
+    int64_t frame_number;
+    double ti1, bitrate, avg_bitrate;
 
-    adjust_frame_pts_to_encoder_tb(of, ost, frame);
+    ost->quality   = sd ? AV_RL32(sd) : -1;
+    ost->pict_type = sd ? sd[4] : AV_PICTURE_TYPE_NONE;
 
-    if (!check_recording_time(ost))
+    for (int i = 0; i<FF_ARRAY_ELEMS(ost->error); i++) {
+        if (sd && i < sd[5])
+            ost->error[i] = AV_RL64(sd + 8 + 8*i);
+        else
+            ost->error[i] = -1;
+    }
+
+    if (!write_vstats)
         return;
 
-    if (frame->pts == AV_NOPTS_VALUE || audio_sync_method < 0)
-        frame->pts = ost->sync_opts;
-    ost->sync_opts = frame->pts + frame->nb_samples;
-    ost->samples_encoded += frame->nb_samples;
-    ost->frames_encoded++;
+    /* this is executed just the first time update_video_stats is called */
+    if (!vstats_file) {
+        vstats_file = fopen(vstats_filename, "w");
+        if (!vstats_file) {
+            perror("fopen");
+            exit_program(1);
+        }
+    }
 
-    update_benchmark(NULL);
-    if (debug_ts) {
-        av_log(NULL, AV_LOG_INFO, "encoder <- type:audio "
-               "frame_pts:%s frame_pts_time:%s time_base:%d/%d\n",
-               av_ts2str(frame->pts), av_ts2timestr(frame->pts, &enc->time_base),
-               enc->time_base.num, enc->time_base.den);
+    frame_number = ost->packets_encoded;
+    if (vstats_version <= 1) {
+        fprintf(vstats_file, "frame= %5"PRId64" q= %2.1f ", frame_number,
+                ost->quality / (float)FF_QP2LAMBDA);
+    } else  {
+        fprintf(vstats_file, "out= %2d st= %2d frame= %5"PRId64" q= %2.1f ", ost->file_index, ost->index, frame_number,
+                ost->quality / (float)FF_QP2LAMBDA);
+    }
+
+    if (ost->error[0]>=0 && (enc->flags & AV_CODEC_FLAG_PSNR))
+        fprintf(vstats_file, "PSNR= %6.2f ", psnr(ost->error[0] / (enc->width * enc->height * 255.0 * 255.0)));
+
+    fprintf(vstats_file,"f_size= %6d ", pkt->size);
+    /* compute pts value */
+    ti1 = pkt->dts * av_q2d(ost->mux_timebase);
+    if (ti1 < 0.01)
+        ti1 = 0.01;
+
+    bitrate     = (pkt->size * 8) / av_q2d(enc->time_base) / 1000.0;
+    avg_bitrate = (double)(ost->data_size * 8) / ti1 / 1000.0;
+    fprintf(vstats_file, "s_size= %8.0fkB time= %0.3f br= %7.1fkbits/s avg_br= %7.1fkbits/s ",
+           (double)ost->data_size / 1024, ti1, bitrate, avg_bitrate);
+    fprintf(vstats_file, "type= %c\n", av_get_picture_type_char(ost->pict_type));
+}
+
+static int encode_frame(OutputFile *of, OutputStream *ost, AVFrame *frame)
+{
+    AVCodecContext   *enc = ost->enc_ctx;
+    AVPacket         *pkt = ost->pkt;
+    const char *type_desc = av_get_media_type_string(enc->codec_type);
+    const char    *action = frame ? "encode" : "flush";
+    int ret;
+
+    if (frame) {
+        ost->frames_encoded++;
+
+        if (debug_ts) {
+            av_log(NULL, AV_LOG_INFO, "encoder <- type:%s "
+                   "frame_pts:%s frame_pts_time:%s time_base:%d/%d\n",
+                   type_desc,
+                   av_ts2str(frame->pts), av_ts2timestr(frame->pts, &enc->time_base),
+                   enc->time_base.num, enc->time_base.den);
+        }
     }
 
+    update_benchmark(NULL);
+
     ret = avcodec_send_frame(enc, frame);
-    if (ret < 0)
-        goto error;
+    if (ret < 0 && !(ret == AVERROR_EOF && !frame)) {
+        av_log(NULL, AV_LOG_ERROR, "Error submitting %s frame to the encoder\n",
+               type_desc);
+        return ret;
+    }
 
     while (1) {
         ret = avcodec_receive_packet(enc, pkt);
-        if (ret == AVERROR(EAGAIN))
-            break;
-        if (ret < 0)
-            goto error;
+        update_benchmark("%s_%s %d.%d", action, type_desc,
+                         ost->file_index, ost->index);
 
-        update_benchmark("encode_audio %d.%d", ost->file_index, ost->index);
+        /* if two pass, output log on success and EOF */
+        if ((ret >= 0 || ret == AVERROR_EOF) && ost->logfile && enc->stats_out)
+            fprintf(ost->logfile, "%s", enc->stats_out);
+
+        if (ret == AVERROR(EAGAIN)) {
+            av_assert0(frame); // should never happen during flushing
+            return 0;
+        } else if (ret == AVERROR_EOF) {
+            output_packet(of, pkt, ost, 1);
+            return ret;
+        } else if (ret < 0) {
+            av_log(NULL, AV_LOG_ERROR, "%s encoding failed\n", type_desc);
+            return ret;
+        }
+
+        if (debug_ts) {
+            av_log(NULL, AV_LOG_INFO, "encoder -> type:%s "
+                   "pkt_pts:%s pkt_pts_time:%s pkt_dts:%s pkt_dts_time:%s "
+                   "duration:%s duration_time:%s\n",
+                   type_desc,
+                   av_ts2str(pkt->pts), av_ts2timestr(pkt->pts, &enc->time_base),
+                   av_ts2str(pkt->dts), av_ts2timestr(pkt->dts, &enc->time_base),
+                   av_ts2str(pkt->duration), av_ts2timestr(pkt->duration, &enc->time_base));
+        }
 
         av_packet_rescale_ts(pkt, enc->time_base, ost->mux_timebase);
 
         if (debug_ts) {
-            av_log(NULL, AV_LOG_INFO, "encoder -> type:audio "
-                   "pkt_pts:%s pkt_pts_time:%s pkt_dts:%s pkt_dts_time:%s\n",
+            av_log(NULL, AV_LOG_INFO, "encoder -> type:%s "
+                   "pkt_pts:%s pkt_pts_time:%s pkt_dts:%s pkt_dts_time:%s "
+                   "duration:%s duration_time:%s\n",
+                   type_desc,
                    av_ts2str(pkt->pts), av_ts2timestr(pkt->pts, &enc->time_base),
-                   av_ts2str(pkt->dts), av_ts2timestr(pkt->dts, &enc->time_base));
+                   av_ts2str(pkt->dts), av_ts2timestr(pkt->dts, &enc->time_base),
+                   av_ts2str(pkt->duration), av_ts2timestr(pkt->duration, &enc->time_base));
         }
 
+        if (enc->codec_type == AVMEDIA_TYPE_VIDEO)
+            update_video_stats(ost, pkt, !!vstats_filename);
+
+        ost->packets_encoded++;
+
         output_packet(of, pkt, ost, 0);
     }
 
-    return;
-error:
-    av_log(NULL, AV_LOG_FATAL, "Audio encoding failed\n");
-    exit_program(1);
+    av_assert0(0);
+}
+
+static void do_audio_out(OutputFile *of, OutputStream *ost,
+                         AVFrame *frame)
+{
+    int ret;
+
+    adjust_frame_pts_to_encoder_tb(of, ost, frame);
+
+    if (!check_recording_time(ost))
+        return;
+
+    if (frame->pts == AV_NOPTS_VALUE || audio_sync_method < 0)
+        frame->pts = ost->sync_opts;
+    ost->sync_opts = frame->pts + frame->nb_samples;
+    ost->samples_encoded += frame->nb_samples;
+
+    ret = encode_frame(of, ost, frame);
+    if (ret < 0)
+        exit_program(1);
 }
 
 static void do_subtitle_out(OutputFile *of,
@@ -1144,14 +1080,12 @@ static void do_video_out(OutputFile *of,
                          AVFrame *next_picture)
 {
     int ret;
-    AVPacket *pkt = ost->pkt;
     AVCodecContext *enc = ost->enc_ctx;
     AVRational frame_rate;
-    int nb_frames, nb0_frames, i;
+    int64_t nb_frames, nb0_frames, i;
     double delta, delta0;
     double duration = 0;
     double sync_ipts = AV_NOPTS_VALUE;
-    int frame_size = 0;
     InputStream *ist = NULL;
     AVFilterContext *filter = ost->filter->filter;
 
@@ -1218,7 +1152,7 @@ static void do_video_out(OutputFile *of,
             } else if (delta < -1.1)
                 nb_frames = 0;
             else if (delta > 1.1) {
-                nb_frames = lrintf(delta);
+                nb_frames = llrintf(delta);
                 if (delta0 > 1.1)
                     nb0_frames = llrintf(delta0 - 0.6);
             }
@@ -1238,6 +1172,11 @@ static void do_video_out(OutputFile *of,
         }
     }
 
+    /*
+     * For video, number of frames in == number of packets out.
+     * But there may be reordering, so we can't throw away frames on encoder
+     * flush, we need to limit them here, before they go into encoder.
+     */
     nb_frames = FFMIN(nb_frames, ost->max_frames - ost->frame_number);
     nb0_frames = FFMIN(nb0_frames, nb_frames);
 
@@ -1249,19 +1188,19 @@ static void do_video_out(OutputFile *of,
     if (nb0_frames == 0 && ost->last_dropped) {
         nb_frames_drop++;
         av_log(NULL, AV_LOG_VERBOSE,
-               "*** dropping frame %d from stream %d at ts %"PRId64"\n",
+               "*** dropping frame %"PRId64" from stream %d at ts %"PRId64"\n",
                ost->frame_number, ost->st->index, ost->last_frame->pts);
     }
     if (nb_frames > (nb0_frames && ost->last_dropped) + (nb_frames > nb0_frames)) {
         if (nb_frames > dts_error_threshold * 30) {
-            av_log(NULL, AV_LOG_ERROR, "%d frame duplication too large, skipping\n", nb_frames - 1);
+            av_log(NULL, AV_LOG_ERROR, "%"PRId64" frame duplication too large, skipping\n", nb_frames - 1);
             nb_frames_drop++;
             return;
         }
         nb_frames_dup += nb_frames - (nb0_frames && ost->last_dropped) - (nb_frames > nb0_frames);
-        av_log(NULL, AV_LOG_VERBOSE, "*** %d dup!\n", nb_frames - 1);
+        av_log(NULL, AV_LOG_VERBOSE, "*** %"PRId64" dup!\n", nb_frames - 1);
         if (nb_frames_dup > dup_warning) {
-            av_log(NULL, AV_LOG_WARNING, "More than %d frames duplicated\n", dup_warning);
+            av_log(NULL, AV_LOG_WARNING, "More than %"PRIu64" frames duplicated\n", dup_warning);
             dup_warning *= 10;
         }
     }
@@ -1339,125 +1278,17 @@ static void do_video_out(OutputFile *of,
             av_log(NULL, AV_LOG_DEBUG, "Forced keyframe at time %f\n", pts_time);
         }
 
-        update_benchmark(NULL);
-        if (debug_ts) {
-            av_log(NULL, AV_LOG_INFO, "encoder <- type:video "
-                   "frame_pts:%s frame_pts_time:%s time_base:%d/%d\n",
-                   av_ts2str(in_picture->pts), av_ts2timestr(in_picture->pts, &enc->time_base),
-                   enc->time_base.num, enc->time_base.den);
-        }
-
-        ost->frames_encoded++;
-
-        ret = avcodec_send_frame(enc, in_picture);
+        ret = encode_frame(of, ost, in_picture);
         if (ret < 0)
-            goto error;
-        // Make sure Closed Captions will not be duplicated
-        av_frame_remove_side_data(in_picture, AV_FRAME_DATA_A53_CC);
-
-        while (1) {
-            ret = avcodec_receive_packet(enc, pkt);
-            update_benchmark("encode_video %d.%d", ost->file_index, ost->index);
-            if (ret == AVERROR(EAGAIN))
-                break;
-            if (ret < 0)
-                goto error;
-
-            if (debug_ts) {
-                av_log(NULL, AV_LOG_INFO, "encoder -> type:video "
-                       "pkt_pts:%s pkt_pts_time:%s pkt_dts:%s pkt_dts_time:%s\n",
-                       av_ts2str(pkt->pts), av_ts2timestr(pkt->pts, &enc->time_base),
-                       av_ts2str(pkt->dts), av_ts2timestr(pkt->dts, &enc->time_base));
-            }
-
-            if (pkt->pts == AV_NOPTS_VALUE && !(enc->codec->capabilities & AV_CODEC_CAP_DELAY))
-                pkt->pts = ost->sync_opts;
-
-            av_packet_rescale_ts(pkt, enc->time_base, ost->mux_timebase);
-
-            if (debug_ts) {
-                av_log(NULL, AV_LOG_INFO, "encoder -> type:video "
-                    "pkt_pts:%s pkt_pts_time:%s pkt_dts:%s pkt_dts_time:%s\n",
-                    av_ts2str(pkt->pts), av_ts2timestr(pkt->pts, &ost->mux_timebase),
-                    av_ts2str(pkt->dts), av_ts2timestr(pkt->dts, &ost->mux_timebase));
-            }
-
-            frame_size = pkt->size;
-            output_packet(of, pkt, ost, 0);
+            exit_program(1);
 
-            /* if two pass, output log */
-            if (ost->logfile && enc->stats_out) {
-                fprintf(ost->logfile, "%s", enc->stats_out);
-            }
-        }
         ost->sync_opts++;
-        /*
-         * For video, number of frames in == number of packets out.
-         * But there may be reordering, so we can't throw away frames on encoder
-         * flush, we need to limit them here, before they go into encoder.
-         */
         ost->frame_number++;
-
-        if (vstats_filename && frame_size)
-            do_video_stats(ost, frame_size);
     }
 
     av_frame_unref(ost->last_frame);
     if (next_picture)
         av_frame_move_ref(ost->last_frame, next_picture);
-
-    return;
-error:
-    av_log(NULL, AV_LOG_FATAL, "Video encoding failed\n");
-    exit_program(1);
-}
-
-static double psnr(double d)
-{
-    return -10.0 * log10(d);
-}
-
-static void do_video_stats(OutputStream *ost, int frame_size)
-{
-    AVCodecContext *enc;
-    int frame_number;
-    double ti1, bitrate, avg_bitrate;
-
-    /* this is executed just the first time do_video_stats is called */
-    if (!vstats_file) {
-        vstats_file = fopen(vstats_filename, "w");
-        if (!vstats_file) {
-            perror("fopen");
-            exit_program(1);
-        }
-    }
-
-    enc = ost->enc_ctx;
-    if (enc->codec_type == AVMEDIA_TYPE_VIDEO) {
-        frame_number = ost->st->nb_frames;
-        if (vstats_version <= 1) {
-            fprintf(vstats_file, "frame= %5d q= %2.1f ", frame_number,
-                    ost->quality / (float)FF_QP2LAMBDA);
-        } else  {
-            fprintf(vstats_file, "out= %2d st= %2d frame= %5d q= %2.1f ", ost->file_index, ost->index, frame_number,
-                    ost->quality / (float)FF_QP2LAMBDA);
-        }
-
-        if (ost->error[0]>=0 && (enc->flags & AV_CODEC_FLAG_PSNR))
-            fprintf(vstats_file, "PSNR= %6.2f ", psnr(ost->error[0] / (enc->width * enc->height * 255.0 * 255.0)));
-
-        fprintf(vstats_file,"f_size= %6d ", frame_size);
-        /* compute pts value */
-        ti1 = av_stream_get_end_pts(ost->st) * av_q2d(ost->st->time_base);
-        if (ti1 < 0.01)
-            ti1 = 0.01;
-
-        bitrate     = (frame_size * 8) / av_q2d(enc->time_base) / 1000.0;
-        avg_bitrate = (double)(ost->data_size * 8) / ti1 / 1000.0;
-        fprintf(vstats_file, "s_size= %8.0fkB time= %0.3f br= %7.1fkbits/s avg_br= %7.1fkbits/s ",
-               (double)ost->data_size / 1024, ti1, bitrate, avg_bitrate);
-        fprintf(vstats_file, "type= %c\n", av_get_picture_type_char(ost->pict_type));
-    }
 }
 
 static void finish_output_stream(OutputStream *ost)
@@ -1537,7 +1368,7 @@ static int reap_filters(int flush)
                 break;
             case AVMEDIA_TYPE_AUDIO:
                 if (!(enc->codec->capabilities & AV_CODEC_CAP_PARAM_CHANGE) &&
-                    enc->channels != filtered_frame->channels) {
+                    enc->ch_layout.nb_channels != filtered_frame->ch_layout.nb_channels) {
                     av_log(NULL, AV_LOG_ERROR,
                            "Audio filter graph output is not normalized and encoder does not support parameter changes\n");
                     break;
@@ -1611,7 +1442,7 @@ static void print_final_stats(int64_t to
             total_packets += ist->nb_packets;
 
             av_log(NULL, AV_LOG_VERBOSE, "  Input stream #%d:%d (%s): ",
-                   i, j, media_type_string(type));
+                   i, j, av_get_media_type_string(type));
             av_log(NULL, AV_LOG_VERBOSE, "%"PRIu64" packets read (%"PRIu64" bytes); ",
                    ist->nb_packets, ist->data_size);
 
@@ -1645,7 +1476,7 @@ static void print_final_stats(int64_t to
             total_packets += ost->packets_written;
 
             av_log(NULL, AV_LOG_VERBOSE, "  Output stream #%d:%d (%s): ",
-                   i, j, media_type_string(type));
+                   i, j, av_get_media_type_string(type));
             if (ost->encoding_needed) {
                 av_log(NULL, AV_LOG_VERBOSE, "%"PRIu64" frames encoded",
                        ost->frames_encoded);
@@ -1680,7 +1511,7 @@ static void print_report(int is_last_rep
     AVFormatContext *oc;
     int64_t total_size;
     AVCodecContext *enc;
-    int frame_number, vid, i;
+    int vid, i;
     double bitrate;
     double speed;
     int64_t pts = INT64_MIN + 1;
@@ -1731,12 +1562,12 @@ static void print_report(int is_last_rep
         }
         if (!vid && enc->codec_type == AVMEDIA_TYPE_VIDEO) {
             float fps;
+            int64_t frame_number = ost->frame_number;
 
-            frame_number = ost->frame_number;
             fps = t > 1 ? frame_number / t : 0;
-            av_bprintf(&buf, "frame=%5d fps=%3.*f q=%3.1f ",
+            av_bprintf(&buf, "frame=%5"PRId64" fps=%3.*f q=%3.1f ",
                      frame_number, fps < 9.95, fps, q);
-            av_bprintf(&buf_script, "frame=%d\n", frame_number);
+            av_bprintf(&buf_script, "frame=%"PRId64"\n", frame_number);
             av_bprintf(&buf_script, "fps=%.2f\n", fps);
             av_bprintf(&buf_script, "stream_%d_%d_q=%.1f\n",
                        ost->file_index, ost->index, q);
@@ -1840,9 +1671,9 @@ static void print_report(int is_last_rep
     }
 
     if (nb_frames_dup || nb_frames_drop)
-        av_bprintf(&buf, " dup=%d drop=%d", nb_frames_dup, nb_frames_drop);
-    av_bprintf(&buf_script, "dup_frames=%d\n", nb_frames_dup);
-    av_bprintf(&buf_script, "drop_frames=%d\n", nb_frames_drop);
+        av_bprintf(&buf, " dup=%"PRId64" drop=%"PRId64, nb_frames_dup, nb_frames_drop);
+    av_bprintf(&buf_script, "dup_frames=%"PRId64"\n", nb_frames_dup);
+    av_bprintf(&buf_script, "drop_frames=%"PRId64"\n", nb_frames_drop);
 
     if (speed < 0) {
         av_bprintf(&buf, " speed=N/A");
@@ -1883,17 +1714,22 @@ static void print_report(int is_last_rep
         print_final_stats(total_size);
 }
 
-static void ifilter_parameters_from_codecpar(InputFilter *ifilter, AVCodecParameters *par)
+static int ifilter_parameters_from_codecpar(InputFilter *ifilter, AVCodecParameters *par)
 {
+    int ret;
+
     // We never got any input. Set a fake format, which will
     // come from libavformat.
     ifilter->format                 = par->format;
     ifilter->sample_rate            = par->sample_rate;
-    ifilter->channels               = par->channels;
-    ifilter->channel_layout         = par->channel_layout;
     ifilter->width                  = par->width;
     ifilter->height                 = par->height;
     ifilter->sample_aspect_ratio    = par->sample_aspect_ratio;
+    ret = av_channel_layout_copy(&ifilter->ch_layout, &par->ch_layout);
+    if (ret < 0)
+        return ret;
+
+    return 0;
 }
 
 static void flush_encoders(void)
@@ -1921,8 +1757,11 @@ static void flush_encoders(void)
                 int x;
                 for (x = 0; x < fg->nb_inputs; x++) {
                     InputFilter *ifilter = fg->inputs[x];
-                    if (ifilter->format < 0)
-                        ifilter_parameters_from_codecpar(ifilter, ifilter->ist->st->codecpar);
+                    if (ifilter->format < 0 &&
+                        ifilter_parameters_from_codecpar(ifilter, ifilter->ist->st->codecpar) < 0) {
+                        av_log(NULL, AV_LOG_ERROR, "Error copying paramerets from input stream\n");
+                        exit_program(1);
+                    }
                 }
 
                 if (!ifilter_has_all_input_formats(fg))
@@ -1943,59 +1782,9 @@ static void flush_encoders(void)
         if (enc->codec_type != AVMEDIA_TYPE_VIDEO && enc->codec_type != AVMEDIA_TYPE_AUDIO)
             continue;
 
-        for (;;) {
-            const char *desc = NULL;
-            AVPacket *pkt = ost->pkt;
-            int pkt_size;
-
-            switch (enc->codec_type) {
-            case AVMEDIA_TYPE_AUDIO:
-                desc   = "audio";
-                break;
-            case AVMEDIA_TYPE_VIDEO:
-                desc   = "video";
-                break;
-            default:
-                av_assert0(0);
-            }
-
-            update_benchmark(NULL);
-
-            while ((ret = avcodec_receive_packet(enc, pkt)) == AVERROR(EAGAIN)) {
-                ret = avcodec_send_frame(enc, NULL);
-                if (ret < 0) {
-                    av_log(NULL, AV_LOG_FATAL, "%s encoding failed: %s\n",
-                           desc,
-                           av_err2str(ret));
-                    exit_program(1);
-                }
-            }
-
-            update_benchmark("flush_%s %d.%d", desc, ost->file_index, ost->index);
-            if (ret < 0 && ret != AVERROR_EOF) {
-                av_log(NULL, AV_LOG_FATAL, "%s encoding failed: %s\n",
-                       desc,
-                       av_err2str(ret));
-                exit_program(1);
-            }
-            if (ost->logfile && enc->stats_out) {
-                fprintf(ost->logfile, "%s", enc->stats_out);
-            }
-            if (ret == AVERROR_EOF) {
-                output_packet(of, pkt, ost, 1);
-                break;
-            }
-            if (ost->finished & MUXER_FINISHED) {
-                av_packet_unref(pkt);
-                continue;
-            }
-            av_packet_rescale_ts(pkt, enc->time_base, ost->mux_timebase);
-            pkt_size = pkt->size;
-            output_packet(of, pkt, ost, 0);
-            if (ost->enc_ctx->codec_type == AVMEDIA_TYPE_VIDEO && vstats_filename) {
-                do_video_stats(ost, pkt_size);
-            }
-        }
+        ret = encode_frame(of, ost, NULL);
+        if (ret != AVERROR_EOF)
+            exit_program(1);
     }
 }
 
@@ -2010,7 +1799,7 @@ static int check_output_constraints(Inpu
     if (ost->source_index != ist_index)
         return 0;
 
-    if (ost->finished)
+    if (ost->finished & MUXER_FINISHED)
         return 0;
 
     if (of->start_time != AV_NOPTS_VALUE && ist->pts < of->start_time)
@@ -2034,11 +1823,11 @@ static void do_streamcopy(InputStream *i
         return;
     }
 
-    if ((!ost->frame_number && !(pkt->flags & AV_PKT_FLAG_KEY)) &&
+    if (!ost->streamcopy_started && !(pkt->flags & AV_PKT_FLAG_KEY) &&
         !ost->copy_initial_nonkeyframes)
         return;
 
-    if (!ost->frame_number && !ost->copy_prior_start) {
+    if (!ost->streamcopy_started && !ost->copy_prior_start) {
         int64_t comp_start = start_time;
         if (copy_ts && f->start_time != AV_NOPTS_VALUE)
             comp_start = FFMAX(start_time, f->start_time + f->ts_offset);
@@ -2092,22 +1881,23 @@ static void do_streamcopy(InputStream *i
     ost->sync_opts += opkt->duration;
 
     output_packet(of, opkt, ost, 0);
+
+    ost->streamcopy_started = 1;
 }
 
 int guess_input_channel_layout(InputStream *ist)
 {
     AVCodecContext *dec = ist->dec_ctx;
 
-    if (!dec->channel_layout) {
+    if (dec->ch_layout.order == AV_CHANNEL_ORDER_UNSPEC) {
         char layout_name[256];
 
-        if (dec->channels > ist->guess_layout_max)
+        if (dec->ch_layout.nb_channels > ist->guess_layout_max)
             return 0;
-        dec->channel_layout = av_get_default_channel_layout(dec->channels);
-        if (!dec->channel_layout)
+        av_channel_layout_default(&dec->ch_layout, dec->ch_layout.nb_channels);
+        if (dec->ch_layout.order == AV_CHANNEL_ORDER_UNSPEC)
             return 0;
-        av_get_channel_layout_string(layout_name, sizeof(layout_name),
-                                     dec->channels, dec->channel_layout);
+        av_channel_layout_describe(&dec->ch_layout, layout_name, sizeof(layout_name));
         av_log(NULL, AV_LOG_WARNING, "Guessed Channel Layout for Input Stream "
                "#%d.%d : %s\n", ist->file_index, ist->st->index, layout_name);
     }
@@ -2160,8 +1950,7 @@ static int ifilter_send_frame(InputFilte
     switch (ifilter->ist->st->codecpar->codec_type) {
     case AVMEDIA_TYPE_AUDIO:
         need_reinit |= ifilter->sample_rate    != frame->sample_rate ||
-                       ifilter->channels       != frame->channels ||
-                       ifilter->channel_layout != frame->channel_layout;
+                       av_channel_layout_compare(&ifilter->ch_layout, &frame->ch_layout);
         break;
     case AVMEDIA_TYPE_VIDEO:
         need_reinit |= ifilter->width  != frame->width ||
@@ -2195,15 +1984,11 @@ static int ifilter_send_frame(InputFilte
             if (!tmp)
                 return AVERROR(ENOMEM);
 
-            if (!av_fifo_space(ifilter->frame_queue)) {
-                ret = av_fifo_realloc2(ifilter->frame_queue, 2 * av_fifo_size(ifilter->frame_queue));
-                if (ret < 0) {
-                    av_frame_free(&tmp);
-                    return ret;
-                }
-            }
-            av_fifo_generic_write(ifilter->frame_queue, &tmp, sizeof(tmp), NULL);
-            return 0;
+            ret = av_fifo_write(ifilter->frame_queue, &tmp, 1);
+            if (ret < 0)
+                av_frame_free(&tmp);
+
+            return ret;
         }
 
         ret = reap_filters(1);
@@ -2241,8 +2026,11 @@ static int ifilter_send_eof(InputFilter
             return ret;
     } else {
         // the filtergraph was never configured
-        if (ifilter->format < 0)
-            ifilter_parameters_from_codecpar(ifilter, ifilter->ist->st->codecpar);
+        if (ifilter->format < 0) {
+            ret = ifilter_parameters_from_codecpar(ifilter, ifilter->ist->st->codecpar);
+            if (ret < 0)
+                return ret;
+        }
         if (ifilter->format < 0 && (ifilter->type == AVMEDIA_TYPE_AUDIO || ifilter->type == AVMEDIA_TYPE_VIDEO)) {
             av_log(NULL, AV_LOG_ERROR, "Cannot determine format of input stream %d:%d after EOF\n", ifilter->ist->file_index, ifilter->ist->st->index);
             return AVERROR_INVALIDDATA;
@@ -2526,15 +2314,13 @@ static int transcode_subtitles(InputStre
         sub2video_update(ist, INT64_MIN, &subtitle);
     } else if (ist->nb_filters) {
         if (!ist->sub2video.sub_queue)
-            ist->sub2video.sub_queue = av_fifo_alloc(8 * sizeof(AVSubtitle));
+            ist->sub2video.sub_queue = av_fifo_alloc2(8, sizeof(AVSubtitle), AV_FIFO_FLAG_AUTO_GROW);
         if (!ist->sub2video.sub_queue)
             exit_program(1);
-        if (!av_fifo_space(ist->sub2video.sub_queue)) {
-            ret = av_fifo_realloc2(ist->sub2video.sub_queue, 2 * av_fifo_size(ist->sub2video.sub_queue));
-            if (ret < 0)
-                exit_program(1);
-        }
-        av_fifo_generic_write(ist->sub2video.sub_queue, &subtitle, sizeof(subtitle), NULL);
+
+        ret = av_fifo_write(ist->sub2video.sub_queue, &subtitle, 1);
+        if (ret < 0)
+            exit_program(1);
         free_sub = 0;
     }
 
@@ -2748,7 +2534,9 @@ static int process_input_packet(InputStr
         }
         ist->pts = ist->dts;
         ist->next_pts = ist->next_dts;
-    }
+    } else if (!ist->decoding_needed)
+        eof_reached = 1;
+
     for (i = 0; i < nb_output_streams; i++) {
         OutputStream *ost = output_streams[i];
 
@@ -2761,59 +2549,6 @@ static int process_input_packet(InputStr
     return !eof_reached;
 }
 
-static int print_sdp(void)
-{
-    char sdp[16384];
-    int i;
-    int j, ret;
-    AVIOContext *sdp_pb;
-    AVFormatContext **avc;
-
-    for (i = 0; i < nb_output_files; i++) {
-        if (!output_files[i]->header_written)
-            return 0;
-    }
-
-    avc = av_malloc_array(nb_output_files, sizeof(*avc));
-    if (!avc)
-        exit_program(1);
-    for (i = 0, j = 0; i < nb_output_files; i++) {
-        if (!strcmp(output_files[i]->ctx->oformat->name, "rtp")) {
-            avc[j] = output_files[i]->ctx;
-            j++;
-        }
-    }
-
-    if (!j) {
-        av_log(NULL, AV_LOG_ERROR, "No output streams in the SDP.\n");
-        ret = AVERROR(EINVAL);
-        goto fail;
-    }
-
-    ret = av_sdp_create(avc, j, sdp, sizeof(sdp));
-    if (ret < 0)
-        goto fail;
-
-    if (!sdp_filename) {
-        printf("SDP:\n%s\n", sdp);
-        fflush(stdout);
-    } else {
-        ret = avio_open2(&sdp_pb, sdp_filename, AVIO_FLAG_WRITE, &int_cb, NULL);
-        if (ret < 0) {
-            av_log(NULL, AV_LOG_ERROR, "Failed to open sdp file '%s'\n", sdp_filename);
-            goto fail;
-        }
-
-        avio_print(sdp_pb, sdp);
-        avio_closep(&sdp_pb);
-        av_freep(&sdp_filename);
-    }
-
-fail:
-    av_freep(&avc);
-    return ret;
-}
-
 static enum AVPixelFormat get_format(AVCodecContext *s, const enum AVPixelFormat *pix_fmts)
 {
     InputStream *ist = s->opaque;
@@ -2879,9 +2614,9 @@ static int init_input_stream(int ist_ind
         ist->dec_ctx->opaque                = ist;
         ist->dec_ctx->get_format            = get_format;
 #if LIBAVCODEC_VERSION_MAJOR < 60
-FF_DISABLE_DEPRECATION_WARNINGS
+        AV_NOWARN_DEPRECATED({
         ist->dec_ctx->thread_safe_callbacks = 1;
-FF_ENABLE_DEPRECATION_WARNINGS
+        })
 #endif
 
         if (ist->dec_ctx->codec_id == AV_CODEC_ID_DVB_SUBTITLE &&
@@ -2940,61 +2675,6 @@ static int compare_int64(const void *a,
     return FFDIFFSIGN(*(const int64_t *)a, *(const int64_t *)b);
 }
 
-/* open the muxer when all the streams are initialized */
-static int check_init_output_file(OutputFile *of, int file_index)
-{
-    int ret, i;
-
-    for (i = 0; i < of->ctx->nb_streams; i++) {
-        OutputStream *ost = output_streams[of->ost_index + i];
-        if (!ost->initialized)
-            return 0;
-    }
-
-    of->ctx->interrupt_callback = int_cb;
-
-    ret = avformat_write_header(of->ctx, &of->opts);
-    if (ret < 0) {
-        av_log(NULL, AV_LOG_ERROR,
-               "Could not write header for output file #%d "
-               "(incorrect codec parameters ?): %s\n",
-               file_index, av_err2str(ret));
-        return ret;
-    }
-    //assert_avoptions(of->opts);
-    of->header_written = 1;
-
-    av_dump_format(of->ctx, file_index, of->ctx->url, 1);
-    nb_output_dumped++;
-
-    if (sdp_filename || want_sdp) {
-        ret = print_sdp();
-        if (ret < 0) {
-            av_log(NULL, AV_LOG_ERROR, "Error writing the SDP.\n");
-            return ret;
-        }
-    }
-
-    /* flush the muxing queues */
-    for (i = 0; i < of->ctx->nb_streams; i++) {
-        OutputStream *ost = output_streams[of->ost_index + i];
-
-        /* try to improve muxing time_base (only possible if nothing has been written yet) */
-        if (!av_fifo_size(ost->muxing_queue))
-            ost->mux_timebase = ost->st->time_base;
-
-        while (av_fifo_size(ost->muxing_queue)) {
-            AVPacket *pkt;
-            av_fifo_generic_read(ost->muxing_queue, &pkt, sizeof(pkt), NULL);
-            ost->muxing_queue_data_size -= pkt->size;
-            write_packet(of, pkt, ost, 1);
-            av_packet_free(&pkt);
-        }
-    }
-
-    return 0;
-}
-
 static int init_output_bsfs(OutputStream *ost)
 {
     AVBSFContext *ctx = ost->bsf_ctx;
@@ -3054,9 +2734,9 @@ static int init_output_stream_streamcopy
 
     if (!codec_tag) {
         unsigned int codec_tag_tmp;
-        if (!of->ctx->oformat->codec_tag ||
-            av_codec_get_id (of->ctx->oformat->codec_tag, par_src->codec_tag) == par_src->codec_id ||
-            !av_codec_get_tag2(of->ctx->oformat->codec_tag, par_src->codec_id, &codec_tag_tmp))
+        if (!of->format->codec_tag ||
+            av_codec_get_id (of->format->codec_tag, par_src->codec_tag) == par_src->codec_id ||
+            !av_codec_get_tag2(of->format->codec_tag, par_src->codec_id, &codec_tag_tmp))
             codec_tag = par_src->codec_tag;
     }
 
@@ -3074,7 +2754,7 @@ static int init_output_stream_streamcopy
     else
         ost->st->avg_frame_rate = ist->st->avg_frame_rate;
 
-    ret = avformat_transfer_internal_stream_timing_info(of->ctx->oformat, ost->st, ist->st, copy_tb);
+    ret = avformat_transfer_internal_stream_timing_info(of->format, ost->st, ist->st, copy_tb);
     if (ret < 0)
         return ret;
 
@@ -3276,7 +2956,8 @@ static int init_output_stream_encode(Out
     InputStream *ist = get_input_stream(ost);
     AVCodecContext *enc_ctx = ost->enc_ctx;
     AVCodecContext *dec_ctx = NULL;
-    AVFormatContext *oc = output_files[ost->file_index]->ctx;
+    OutputFile      *of = output_files[ost->file_index];
+    AVFormatContext *oc = of->ctx;
     int ret;
 
     set_encoder_id(output_files[ost->file_index], ost);
@@ -3318,8 +2999,9 @@ static int init_output_stream_encode(Out
     case AVMEDIA_TYPE_AUDIO:
         enc_ctx->sample_fmt     = av_buffersink_get_format(ost->filter->filter);
         enc_ctx->sample_rate    = av_buffersink_get_sample_rate(ost->filter->filter);
-        enc_ctx->channel_layout = av_buffersink_get_channel_layout(ost->filter->filter);
-        enc_ctx->channels       = av_buffersink_get_channels(ost->filter->filter);
+        ret = av_buffersink_get_ch_layout(ost->filter->filter, &enc_ctx->ch_layout);
+        if (ret < 0)
+            return ret;
 
         if (ost->bits_per_raw_sample)
             enc_ctx->bits_per_raw_sample = ost->bits_per_raw_sample;
@@ -3335,10 +3017,12 @@ static int init_output_stream_encode(Out
 
         if (!(enc_ctx->time_base.num && enc_ctx->time_base.den))
             enc_ctx->time_base = av_buffersink_get_time_base(ost->filter->filter);
-        if (   av_q2d(enc_ctx->time_base) < 0.001 && video_sync_method != VSYNC_PASSTHROUGH
-           && (video_sync_method == VSYNC_CFR || video_sync_method == VSYNC_VSCFR || (video_sync_method == VSYNC_AUTO && !(oc->oformat->flags & AVFMT_VARIABLE_FPS)))){
+        if (   av_q2d(enc_ctx->time_base) < 0.001 && ost->vsync_method != VSYNC_PASSTHROUGH
+           && (ost->vsync_method == VSYNC_CFR || ost->vsync_method == VSYNC_VSCFR ||
+               (ost->vsync_method == VSYNC_AUTO && !(of->format->flags & AVFMT_VARIABLE_FPS)))){
             av_log(oc, AV_LOG_WARNING, "Frame rate very high for a muxer not efficiently supporting it.\n"
-                                       "Please consider specifying a lower framerate, a different muxer or -vsync 2\n");
+                                       "Please consider specifying a lower framerate, a different muxer or "
+                                       "setting vsync/fps_mode to vfr\n");
         }
 
         enc_ctx->width  = av_buffersink_get_w(ost->filter->filter);
@@ -3567,7 +3251,7 @@ static int init_output_stream(OutputStre
 
     ost->initialized = 1;
 
-    ret = check_init_output_file(output_files[ost->file_index], ost->file_index);
+    ret = of_check_init(output_files[ost->file_index]);
     if (ret < 0)
         return ret;
 
@@ -3669,8 +3353,8 @@ static int transcode_init(void)
     /* write headers for files with no streams */
     for (i = 0; i < nb_output_files; i++) {
         oc = output_files[i]->ctx;
-        if (oc->oformat->flags & AVFMT_NOSTREAMS && oc->nb_streams == 0) {
-            ret = check_init_output_file(output_files[i], i);
+        if (output_files[i]->format->flags & AVFMT_NOSTREAMS && oc->nb_streams == 0) {
+            ret = of_check_init(output_files[i]);
             if (ret < 0)
                 goto dump_format;
         }
@@ -3847,7 +3531,7 @@ static int check_keyboard_interaction(in
     if (received_nb_signals)
         return AVERROR_EXIT;
     /* read_key() returns 0 on EOF */
-    if(cur_time - last_time >= 100000 && !run_as_daemon){
+    if (cur_time - last_time >= 100000) {
         key =  read_key();
         last_time = cur_time;
     }else
@@ -4231,11 +3915,12 @@ static int process_input(int file_index)
         for (i = 0; i < ifile->nb_streams; i++) {
             ist = input_streams[ifile->ist_index + i];
             avctx = ist->dec_ctx;
-            if (ist->decoding_needed) {
+            if (ist->processing_needed) {
                 ret = process_input_packet(ist, NULL, 1);
                 if (ret>0)
                     return 0;
-                avcodec_flush_buffers(avctx);
+                if (ist->decoding_needed)
+                    avcodec_flush_buffers(avctx);
             }
         }
 #if HAVE_THREADS
@@ -4265,7 +3950,7 @@ static int process_input(int file_index)
 
         for (i = 0; i < ifile->nb_streams; i++) {
             ist = input_streams[ifile->ist_index + i];
-            if (ist->decoding_needed) {
+            if (ist->processing_needed) {
                 ret = process_input_packet(ist, NULL, 0);
                 if (ret>0)
                     return 0;
@@ -4315,12 +4000,13 @@ static int process_input(int file_index)
 
     if (debug_ts) {
         av_log(NULL, AV_LOG_INFO, "demuxer -> ist_index:%d type:%s "
-               "next_dts:%s next_dts_time:%s next_pts:%s next_pts_time:%s pkt_pts:%s pkt_pts_time:%s pkt_dts:%s pkt_dts_time:%s off:%s off_time:%s\n",
+               "next_dts:%s next_dts_time:%s next_pts:%s next_pts_time:%s pkt_pts:%s pkt_pts_time:%s pkt_dts:%s pkt_dts_time:%s duration:%s duration_time:%s off:%s off_time:%s\n",
                ifile->ist_index + pkt->stream_index, av_get_media_type_string(ist->dec_ctx->codec_type),
                av_ts2str(ist->next_dts), av_ts2timestr(ist->next_dts, &AV_TIME_BASE_Q),
                av_ts2str(ist->next_pts), av_ts2timestr(ist->next_pts, &AV_TIME_BASE_Q),
                av_ts2str(pkt->pts), av_ts2timestr(pkt->pts, &ist->st->time_base),
                av_ts2str(pkt->dts), av_ts2timestr(pkt->dts, &ist->st->time_base),
+               av_ts2str(pkt->duration), av_ts2timestr(pkt->duration, &ist->st->time_base),
                av_ts2str(input_files[ist->file_index]->ts_offset),
                av_ts2timestr(input_files[ist->file_index]->ts_offset, &AV_TIME_BASE_Q));
     }
@@ -4471,10 +4157,11 @@ static int process_input(int file_index)
         ifile->last_ts = av_rescale_q(pkt->dts, ist->st->time_base, AV_TIME_BASE_Q);
 
     if (debug_ts) {
-        av_log(NULL, AV_LOG_INFO, "demuxer+ffmpeg -> ist_index:%d type:%s pkt_pts:%s pkt_pts_time:%s pkt_dts:%s pkt_dts_time:%s off:%s off_time:%s\n",
+        av_log(NULL, AV_LOG_INFO, "demuxer+ffmpeg -> ist_index:%d type:%s pkt_pts:%s pkt_pts_time:%s pkt_dts:%s pkt_dts_time:%s duration:%s duration_time:%s off:%s off_time:%s\n",
                ifile->ist_index + pkt->stream_index, av_get_media_type_string(ist->dec_ctx->codec_type),
                av_ts2str(pkt->pts), av_ts2timestr(pkt->pts, &ist->st->time_base),
                av_ts2str(pkt->dts), av_ts2timestr(pkt->dts, &ist->st->time_base),
+               av_ts2str(pkt->duration), av_ts2timestr(pkt->duration, &ist->st->time_base),
                av_ts2str(input_files[ist->file_index]->ts_offset),
                av_ts2timestr(input_files[ist->file_index]->ts_offset, &AV_TIME_BASE_Q));
     }
@@ -4701,19 +4388,9 @@ static int transcode(void)
 
     /* write the trailer if needed */
     for (i = 0; i < nb_output_files; i++) {
-        os = output_files[i]->ctx;
-        if (!output_files[i]->header_written) {
-            av_log(NULL, AV_LOG_ERROR,
-                   "Nothing was written into output file %d (%s), because "
-                   "at least one of its streams received no packets.\n",
-                   i, os->url);
-            continue;
-        }
-        if ((ret = av_write_trailer(os)) < 0) {
-            av_log(NULL, AV_LOG_ERROR, "Error writing trailer of %s: %s\n", os->url, av_err2str(ret));
-            if (exit_on_error)
-                exit_program(1);
-        }
+        ret = of_write_trailer(output_files[i]);
+        if (ret < 0 && exit_on_error)
+            exit_program(1);
     }
 
     /* dump report by using the first video and audio streams */
@@ -4836,10 +4513,6 @@ static int64_t getmaxrss(void)
 #endif
 }
 
-static void log_callback_null(void *ptr, int level, const char *fmt, va_list vl)
-{
-}
-
 int main(int argc, char **argv)
 {
     int i, ret;
@@ -4854,13 +4527,6 @@ int main(int argc, char **argv)
     av_log_set_flags(AV_LOG_SKIP_REPEATED);
     parse_loglevel(argc, argv, options);
 
-    if(argc>1 && !strcmp(argv[1], "-d")){
-        run_as_daemon=1;
-        av_log_set_callback(log_callback_null);
-        argc--;
-        argv++;
-    }
-
 #if CONFIG_AVDEVICE
     avdevice_register_all();
 #endif
@@ -4886,7 +4552,7 @@ int main(int argc, char **argv)
     }
 
     for (i = 0; i < nb_output_files; i++) {
-        if (strcmp(output_files[i]->ctx->oformat->name, "rtp"))
+        if (strcmp(output_files[i]->format->name, "rtp"))
             want_sdp = 0;
     }
 
diff -pruN 7:5.0.1-3/fftools/ffmpeg_filter.c 7:5.1-1/fftools/ffmpeg_filter.c
--- 7:5.0.1-3/fftools/ffmpeg_filter.c	2022-01-14 18:45:39.000000000 +0000
+++ 7:5.1-1/fftools/ffmpeg_filter.c	2022-07-22 17:58:38.000000000 +0000
@@ -153,8 +153,25 @@ DEF_CHOOSE_FORMAT(sample_fmts, enum AVSa
 DEF_CHOOSE_FORMAT(sample_rates, int, sample_rate, sample_rates, 0,
                   "%d", )
 
-DEF_CHOOSE_FORMAT(channel_layouts, uint64_t, channel_layout, channel_layouts, 0,
-                  "0x%"PRIx64, )
+static void choose_channel_layouts(OutputFilter *ofilter, AVBPrint *bprint)
+{
+    if (av_channel_layout_check(&ofilter->ch_layout)) {
+        av_bprintf(bprint, "channel_layouts=");
+        av_channel_layout_describe_bprint(&ofilter->ch_layout, bprint);
+    } else if (ofilter->ch_layouts) {
+        const AVChannelLayout *p;
+
+        av_bprintf(bprint, "channel_layouts=");
+        for (p = ofilter->ch_layouts; p->nb_channels; p++) {
+            av_channel_layout_describe_bprint(p, bprint);
+            av_bprintf(bprint, "|");
+        }
+        if (bprint->len > 0)
+            bprint->str[--bprint->len] = '\0';
+    } else
+        return;
+    av_bprint_chars(bprint, ':', 1);
+}
 
 int init_simple_filtergraph(InputStream *ist, OutputStream *ost)
 {
@@ -178,7 +195,7 @@ int init_simple_filtergraph(InputStream
     ifilter->graph  = fg;
     ifilter->format = -1;
 
-    ifilter->frame_queue = av_fifo_alloc(8 * sizeof(AVFrame*));
+    ifilter->frame_queue = av_fifo_alloc2(8, sizeof(AVFrame*), AV_FIFO_FLAG_AUTO_GROW);
     if (!ifilter->frame_queue)
         exit_program(1);
 
@@ -277,6 +294,7 @@ static void init_input_filter(FilterGrap
 
     ist->discard         = 0;
     ist->decoding_needed |= DECODING_FOR_FILTER;
+    ist->processing_needed = 1;
     ist->st->discard = AVDISCARD_NONE;
 
     ifilter = ALLOC_ARRAY_ELEM(fg->inputs, fg->nb_inputs);
@@ -286,7 +304,7 @@ static void init_input_filter(FilterGrap
     ifilter->type   = ist->st->codecpar->codec_type;
     ifilter->name   = describe_filter_link(fg, in, 1);
 
-    ifilter->frame_queue = av_fifo_alloc(8 * sizeof(AVFrame*));
+    ifilter->frame_queue = av_fifo_alloc2(8, sizeof(AVFrame*), AV_FIFO_FLAG_AUTO_GROW);
     if (!ifilter->frame_queue)
         exit_program(1);
 
@@ -541,9 +559,10 @@ static int configure_output_audio_filter
 } while (0)
     av_bprint_init(&args, 0, AV_BPRINT_SIZE_UNLIMITED);
     if (ost->audio_channels_mapped) {
+        AVChannelLayout mapped_layout = { 0 };
         int i;
-        av_bprintf(&args, "0x%"PRIx64,
-                   av_get_default_channel_layout(ost->audio_channels_mapped));
+        av_channel_layout_default(&mapped_layout, ost->audio_channels_mapped);
+        av_channel_layout_describe_bprint(&mapped_layout, &args);
         for (i = 0; i < ost->audio_channels_mapped; i++)
             if (ost->audio_channels_map[i] != -1)
                 av_bprintf(&args, "|c%d=c%d", i, ost->audio_channels_map[i]);
@@ -552,8 +571,8 @@ static int configure_output_audio_filter
         av_bprint_clear(&args);
     }
 
-    if (codec->channels && !codec->channel_layout)
-        codec->channel_layout = av_get_default_channel_layout(codec->channels);
+    if (codec->ch_layout.order == AV_CHANNEL_ORDER_UNSPEC)
+        av_channel_layout_default(&codec->ch_layout, codec->ch_layout.nb_channels);
 
     choose_sample_fmts(ofilter,     &args);
     choose_sample_rates(ofilter,    &args);
@@ -832,11 +851,12 @@ static int configure_input_audio_filter(
              1, ifilter->sample_rate,
              ifilter->sample_rate,
              av_get_sample_fmt_name(ifilter->format));
-    if (ifilter->channel_layout)
-        av_bprintf(&args, ":channel_layout=0x%"PRIx64,
-                   ifilter->channel_layout);
-    else
-        av_bprintf(&args, ":channels=%d", ifilter->channels);
+    if (av_channel_layout_check(&ifilter->ch_layout) &&
+        ifilter->ch_layout.order != AV_CHANNEL_ORDER_UNSPEC) {
+        av_bprintf(&args, ":channel_layout=");
+        av_channel_layout_describe_bprint(&ifilter->ch_layout, &args);
+    } else
+        av_bprintf(&args, ":channels=%d", ifilter->ch_layout.nb_channels);
     snprintf(name, sizeof(name), "graph_%d_in_%d_%d", fg->index,
              ist->file_index, ist->st->index);
 
@@ -949,8 +969,8 @@ static void cleanup_filtergraph(FilterGr
 static int filter_is_buffersrc(const AVFilterContext *f)
 {
     return f->nb_inputs == 0 &&
-           (!strcmp(f->filter->name, "buffersrc") ||
-            !strcmp(f->filter->name, "abuffersrc"));
+           (!strcmp(f->filter->name, "buffer") ||
+            !strcmp(f->filter->name, "abuffer"));
 }
 
 static int graph_is_meta(AVFilterGraph *graph)
@@ -1084,7 +1104,10 @@ int configure_filtergraph(FilterGraph *f
         ofilter->height = av_buffersink_get_h(sink);
 
         ofilter->sample_rate    = av_buffersink_get_sample_rate(sink);
-        ofilter->channel_layout = av_buffersink_get_channel_layout(sink);
+        av_channel_layout_uninit(&ofilter->ch_layout);
+        ret = av_buffersink_get_ch_layout(sink, &ofilter->ch_layout);
+        if (ret < 0)
+            goto fail;
     }
 
     fg->reconfiguration = 1;
@@ -1106,9 +1129,8 @@ int configure_filtergraph(FilterGraph *f
     }
 
     for (i = 0; i < fg->nb_inputs; i++) {
-        while (av_fifo_size(fg->inputs[i]->frame_queue)) {
-            AVFrame *tmp;
-            av_fifo_generic_read(fg->inputs[i]->frame_queue, &tmp, sizeof(tmp), NULL);
+        AVFrame *tmp;
+        while (av_fifo_read(fg->inputs[i]->frame_queue, &tmp, 1) >= 0) {
             ret = av_buffersrc_add_frame(fg->inputs[i]->filter, tmp);
             av_frame_free(&tmp);
             if (ret < 0)
@@ -1129,9 +1151,8 @@ int configure_filtergraph(FilterGraph *f
     for (i = 0; i < fg->nb_inputs; i++) {
         InputStream *ist = fg->inputs[i]->ist;
         if (ist->sub2video.sub_queue && ist->sub2video.frame) {
-            while (av_fifo_size(ist->sub2video.sub_queue)) {
-                AVSubtitle tmp;
-                av_fifo_generic_read(ist->sub2video.sub_queue, &tmp, sizeof(tmp), NULL);
+            AVSubtitle tmp;
+            while (av_fifo_read(ist->sub2video.sub_queue, &tmp, 1) >= 0) {
                 sub2video_update(ist, INT64_MIN, &tmp);
                 avsubtitle_free(&tmp);
             }
@@ -1148,6 +1169,7 @@ fail:
 int ifilter_parameters_from_frame(InputFilter *ifilter, const AVFrame *frame)
 {
     AVFrameSideData *sd;
+    int ret;
 
     av_buffer_unref(&ifilter->hw_frames_ctx);
 
@@ -1158,8 +1180,9 @@ int ifilter_parameters_from_frame(InputF
     ifilter->sample_aspect_ratio = frame->sample_aspect_ratio;
 
     ifilter->sample_rate         = frame->sample_rate;
-    ifilter->channels            = frame->channels;
-    ifilter->channel_layout      = frame->channel_layout;
+    ret = av_channel_layout_copy(&ifilter->ch_layout, &frame->ch_layout);
+    if (ret < 0)
+        return ret;
 
     av_freep(&ifilter->displaymatrix);
     sd = av_frame_get_side_data(frame, AV_FRAME_DATA_DISPLAYMATRIX);
diff -pruN 7:5.0.1-3/fftools/ffmpeg.h 7:5.1-1/fftools/ffmpeg.h
--- 7:5.0.1-3/fftools/ffmpeg.h	2022-01-14 18:45:39.000000000 +0000
+++ 7:5.1-1/fftools/ffmpeg.h	2022-07-22 17:58:38.000000000 +0000
@@ -96,6 +96,8 @@ typedef struct OptionsContext {
 
     SpecifierOpt *codec_names;
     int        nb_codec_names;
+    SpecifierOpt *audio_ch_layouts;
+    int        nb_audio_ch_layouts;
     SpecifierOpt *audio_channels;
     int        nb_audio_channels;
     SpecifierOpt *audio_sample_rate;
@@ -116,6 +118,7 @@ typedef struct OptionsContext {
     float readrate;
     int accurate_seek;
     int thread_queue_size;
+    int input_sync_ref;
 
     SpecifierOpt *ts_scale;
     int        nb_ts_scale;
@@ -174,6 +177,8 @@ typedef struct OptionsContext {
     int        nb_qscale;
     SpecifierOpt *forced_key_frames;
     int        nb_forced_key_frames;
+    SpecifierOpt *fps_mode;
+    int        nb_fps_mode;
     SpecifierOpt *force_fps;
     int        nb_force_fps;
     SpecifierOpt *frame_aspect_ratios;
@@ -241,7 +246,7 @@ typedef struct InputFilter {
     uint8_t            *name;
     enum AVMediaType    type;   // AVMEDIA_TYPE_SUBTITLE for sub2video
 
-    AVFifoBuffer *frame_queue;
+    AVFifo *frame_queue;
 
     // parameters configured for this input
     int format;
@@ -250,8 +255,7 @@ typedef struct InputFilter {
     AVRational sample_aspect_ratio;
 
     int sample_rate;
-    int channels;
-    uint64_t channel_layout;
+    AVChannelLayout ch_layout;
 
     AVBufferRef *hw_frames_ctx;
     int32_t *displaymatrix;
@@ -274,12 +278,12 @@ typedef struct OutputFilter {
     AVRational frame_rate;
     int format;
     int sample_rate;
-    uint64_t channel_layout;
+    AVChannelLayout ch_layout;
 
     // those are only set if no format is specified and the encoder gives us multiple options
     // They point directly to the relevant lists of the encoder.
     const int *formats;
-    const uint64_t *channel_layouts;
+    const AVChannelLayout *ch_layouts;
     const int *sample_rates;
 } OutputFilter;
 
@@ -307,6 +311,7 @@ typedef struct InputStream {
     int decoding_needed;     /* non zero if the packets must be decoded in 'raw_fifo', see DECODING_FOR_* */
 #define DECODING_FOR_OST    1
 #define DECODING_FOR_FILTER 2
+    int processing_needed;   /* non zero if the packets must be processed */
 
     AVCodecContext *dec_ctx;
     const AVCodec *dec;
@@ -355,7 +360,7 @@ typedef struct InputStream {
     struct sub2video {
         int64_t last_pts;
         int64_t end_pts;
-        AVFifoBuffer *sub_queue;    ///< queue of AVSubtitle* before filter init
+        AVFifo *sub_queue;    ///< queue of AVSubtitle* before filter init
         AVFrame *frame;
         int w, h;
         unsigned int initialize; ///< marks if sub2video_update should force an initialization
@@ -406,6 +411,7 @@ typedef struct InputFile {
                              at the moment when looping happens */
     AVRational time_base; /* time base of the duration */
     int64_t input_ts_offset;
+    int input_sync_ref;
 
     int64_t ts_offset;
     int64_t last_ts;
@@ -454,7 +460,7 @@ typedef struct OutputStream {
     int source_index;        /* InputStream index */
     AVStream *st;            /* stream in the output file */
     int encoding_needed;     /* true if encoding needed for this stream */
-    int frame_number;
+    int64_t frame_number;
     /* input pts and corresponding output pts
        for A/V sync */
     struct InputStream *sync_ist; /* input stream to sync against */
@@ -477,8 +483,8 @@ typedef struct OutputStream {
     AVFrame *filtered_frame;
     AVFrame *last_frame;
     AVPacket *pkt;
-    int last_dropped;
-    int last_nb0_frames[3];
+    int64_t last_dropped;
+    int64_t last_nb0_frames[3];
 
     void  *hwaccel_ctx;
 
@@ -487,6 +493,7 @@ typedef struct OutputStream {
     AVRational max_frame_rate;
     enum VideoSyncMethod vsync_method;
     int is_cfr;
+    const char *fps_mode;
     int force_fps;
     int top_field_first;
     int rotate_overridden;
@@ -534,6 +541,7 @@ typedef struct OutputStream {
     int inputs_done;
 
     const char *attachment_filename;
+    int streamcopy_started;
     int copy_initial_nonkeyframes;
     int copy_prior_start;
     char *disposition;
@@ -548,6 +556,8 @@ typedef struct OutputStream {
     // number of frames/samples sent to the encoder
     uint64_t frames_encoded;
     uint64_t samples_encoded;
+    // number of packets received from the encoder
+    uint64_t packets_encoded;
 
     /* packet quality factor */
     int quality;
@@ -555,7 +565,7 @@ typedef struct OutputStream {
     int max_muxing_queue_size;
 
     /* the packets are buffered here until the muxer is ready to be initialized */
-    AVFifoBuffer *muxing_queue;
+    AVFifo *muxing_queue;
 
     /*
      * The size of the AVPackets' buffers in queue.
@@ -574,6 +584,10 @@ typedef struct OutputStream {
 } OutputStream;
 
 typedef struct OutputFile {
+    int index;
+
+    const AVOutputFormat *format;
+
     AVFormatContext *ctx;
     AVDictionary *opts;
     int ost_index;       /* index of the first stream in output_streams */
@@ -642,6 +656,10 @@ extern char *qsv_device;
 #endif
 extern HWDevice *filter_hw_device;
 
+extern int want_sdp;
+extern unsigned nb_output_dumped;
+extern int main_return_code;
+
 
 void term_init(void);
 void term_exit(void);
@@ -678,4 +696,12 @@ int hw_device_setup_for_filter(FilterGra
 
 int hwaccel_decode_init(AVCodecContext *avctx);
 
+/* open the muxer when all the streams are initialized */
+int of_check_init(OutputFile *of);
+int of_write_trailer(OutputFile *of);
+void of_close(OutputFile **pof);
+
+void of_write_packet(OutputFile *of, AVPacket *pkt, OutputStream *ost,
+                     int unqueue);
+
 #endif /* FFTOOLS_FFMPEG_H */
diff -pruN 7:5.0.1-3/fftools/ffmpeg_mux.c 7:5.1-1/fftools/ffmpeg_mux.c
--- 7:5.0.1-3/fftools/ffmpeg_mux.c	1970-01-01 00:00:00.000000000 +0000
+++ 7:5.1-1/fftools/ffmpeg_mux.c	2022-07-22 17:58:38.000000000 +0000
@@ -0,0 +1,317 @@
+/*
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include "ffmpeg.h"
+
+#include "libavutil/fifo.h"
+#include "libavutil/intreadwrite.h"
+#include "libavutil/log.h"
+#include "libavutil/mem.h"
+#include "libavutil/timestamp.h"
+
+#include "libavcodec/packet.h"
+
+#include "libavformat/avformat.h"
+#include "libavformat/avio.h"
+
+static void close_all_output_streams(OutputStream *ost, OSTFinished this_stream, OSTFinished others)
+{
+    int i;
+    for (i = 0; i < nb_output_streams; i++) {
+        OutputStream *ost2 = output_streams[i];
+        ost2->finished |= ost == ost2 ? this_stream : others;
+    }
+}
+
+void of_write_packet(OutputFile *of, AVPacket *pkt, OutputStream *ost,
+                     int unqueue)
+{
+    AVFormatContext *s = of->ctx;
+    AVStream *st = ost->st;
+    int ret;
+
+    /*
+     * Audio encoders may split the packets --  #frames in != #packets out.
+     * But there is no reordering, so we can limit the number of output packets
+     * by simply dropping them here.
+     * Counting encoded video frames needs to be done separately because of
+     * reordering, see do_video_out().
+     * Do not count the packet when unqueued because it has been counted when queued.
+     */
+    if (!(st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && ost->encoding_needed) && !unqueue) {
+        if (ost->frame_number >= ost->max_frames) {
+            av_packet_unref(pkt);
+            return;
+        }
+        ost->frame_number++;
+    }
+
+    if (!of->header_written) {
+        AVPacket *tmp_pkt;
+        /* the muxer is not initialized yet, buffer the packet */
+        if (!av_fifo_can_write(ost->muxing_queue)) {
+            size_t cur_size = av_fifo_can_read(ost->muxing_queue);
+            unsigned int are_we_over_size =
+                (ost->muxing_queue_data_size + pkt->size) > ost->muxing_queue_data_threshold;
+            size_t limit    = are_we_over_size ? ost->max_muxing_queue_size : SIZE_MAX;
+            size_t new_size = FFMIN(2 * cur_size, limit);
+
+            if (new_size <= cur_size) {
+                av_log(NULL, AV_LOG_ERROR,
+                       "Too many packets buffered for output stream %d:%d.\n",
+                       ost->file_index, ost->st->index);
+                exit_program(1);
+            }
+            ret = av_fifo_grow2(ost->muxing_queue, new_size - cur_size);
+            if (ret < 0)
+                exit_program(1);
+        }
+        ret = av_packet_make_refcounted(pkt);
+        if (ret < 0)
+            exit_program(1);
+        tmp_pkt = av_packet_alloc();
+        if (!tmp_pkt)
+            exit_program(1);
+        av_packet_move_ref(tmp_pkt, pkt);
+        ost->muxing_queue_data_size += tmp_pkt->size;
+        av_fifo_write(ost->muxing_queue, &tmp_pkt, 1);
+        return;
+    }
+
+    if ((st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && ost->vsync_method == VSYNC_DROP) ||
+        (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && audio_sync_method < 0))
+        pkt->pts = pkt->dts = AV_NOPTS_VALUE;
+
+    if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
+        if (ost->frame_rate.num && ost->is_cfr) {
+            if (pkt->duration > 0)
+                av_log(NULL, AV_LOG_WARNING, "Overriding packet duration by frame rate, this should not happen\n");
+            pkt->duration = av_rescale_q(1, av_inv_q(ost->frame_rate),
+                                         ost->mux_timebase);
+        }
+    }
+
+    av_packet_rescale_ts(pkt, ost->mux_timebase, ost->st->time_base);
+
+    if (!(s->oformat->flags & AVFMT_NOTIMESTAMPS)) {
+        if (pkt->dts != AV_NOPTS_VALUE &&
+            pkt->pts != AV_NOPTS_VALUE &&
+            pkt->dts > pkt->pts) {
+            av_log(s, AV_LOG_WARNING, "Invalid DTS: %"PRId64" PTS: %"PRId64" in output stream %d:%d, replacing by guess\n",
+                   pkt->dts, pkt->pts,
+                   ost->file_index, ost->st->index);
+            pkt->pts =
+            pkt->dts = pkt->pts + pkt->dts + ost->last_mux_dts + 1
+                     - FFMIN3(pkt->pts, pkt->dts, ost->last_mux_dts + 1)
+                     - FFMAX3(pkt->pts, pkt->dts, ost->last_mux_dts + 1);
+        }
+        if ((st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO || st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO || st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) &&
+            pkt->dts != AV_NOPTS_VALUE &&
+            ost->last_mux_dts != AV_NOPTS_VALUE) {
+            int64_t max = ost->last_mux_dts + !(s->oformat->flags & AVFMT_TS_NONSTRICT);
+            if (pkt->dts < max) {
+                int loglevel = max - pkt->dts > 2 || st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO ? AV_LOG_WARNING : AV_LOG_DEBUG;
+                if (exit_on_error)
+                    loglevel = AV_LOG_ERROR;
+                av_log(s, loglevel, "Non-monotonous DTS in output stream "
+                       "%d:%d; previous: %"PRId64", current: %"PRId64"; ",
+                       ost->file_index, ost->st->index, ost->last_mux_dts, pkt->dts);
+                if (exit_on_error) {
+                    av_log(NULL, AV_LOG_FATAL, "aborting.\n");
+                    exit_program(1);
+                }
+                av_log(s, loglevel, "changing to %"PRId64". This may result "
+                       "in incorrect timestamps in the output file.\n",
+                       max);
+                if (pkt->pts >= pkt->dts)
+                    pkt->pts = FFMAX(pkt->pts, max);
+                pkt->dts = max;
+            }
+        }
+    }
+    ost->last_mux_dts = pkt->dts;
+
+    ost->data_size += pkt->size;
+    ost->packets_written++;
+
+    pkt->stream_index = ost->index;
+
+    if (debug_ts) {
+        av_log(NULL, AV_LOG_INFO, "muxer <- type:%s "
+                "pkt_pts:%s pkt_pts_time:%s pkt_dts:%s pkt_dts_time:%s duration:%s duration_time:%s size:%d\n",
+                av_get_media_type_string(ost->enc_ctx->codec_type),
+                av_ts2str(pkt->pts), av_ts2timestr(pkt->pts, &ost->st->time_base),
+                av_ts2str(pkt->dts), av_ts2timestr(pkt->dts, &ost->st->time_base),
+                av_ts2str(pkt->duration), av_ts2timestr(pkt->duration, &ost->st->time_base),
+                pkt->size
+              );
+    }
+
+    ret = av_interleaved_write_frame(s, pkt);
+    if (ret < 0) {
+        print_error("av_interleaved_write_frame()", ret);
+        main_return_code = 1;
+        close_all_output_streams(ost, MUXER_FINISHED | ENCODER_FINISHED, ENCODER_FINISHED);
+    }
+}
+
+static int print_sdp(void)
+{
+    char sdp[16384];
+    int i;
+    int j, ret;
+    AVIOContext *sdp_pb;
+    AVFormatContext **avc;
+
+    for (i = 0; i < nb_output_files; i++) {
+        if (!output_files[i]->header_written)
+            return 0;
+    }
+
+    avc = av_malloc_array(nb_output_files, sizeof(*avc));
+    if (!avc)
+        exit_program(1);
+    for (i = 0, j = 0; i < nb_output_files; i++) {
+        if (!strcmp(output_files[i]->ctx->oformat->name, "rtp")) {
+            avc[j] = output_files[i]->ctx;
+            j++;
+        }
+    }
+
+    if (!j) {
+        av_log(NULL, AV_LOG_ERROR, "No output streams in the SDP.\n");
+        ret = AVERROR(EINVAL);
+        goto fail;
+    }
+
+    ret = av_sdp_create(avc, j, sdp, sizeof(sdp));
+    if (ret < 0)
+        goto fail;
+
+    if (!sdp_filename) {
+        printf("SDP:\n%s\n", sdp);
+        fflush(stdout);
+    } else {
+        ret = avio_open2(&sdp_pb, sdp_filename, AVIO_FLAG_WRITE, &int_cb, NULL);
+        if (ret < 0) {
+            av_log(NULL, AV_LOG_ERROR, "Failed to open sdp file '%s'\n", sdp_filename);
+            goto fail;
+        }
+
+        avio_print(sdp_pb, sdp);
+        avio_closep(&sdp_pb);
+        av_freep(&sdp_filename);
+    }
+
+fail:
+    av_freep(&avc);
+    return ret;
+}
+
+/* open the muxer when all the streams are initialized */
+int of_check_init(OutputFile *of)
+{
+    int ret, i;
+
+    for (i = 0; i < of->ctx->nb_streams; i++) {
+        OutputStream *ost = output_streams[of->ost_index + i];
+        if (!ost->initialized)
+            return 0;
+    }
+
+    ret = avformat_write_header(of->ctx, &of->opts);
+    if (ret < 0) {
+        av_log(NULL, AV_LOG_ERROR,
+               "Could not write header for output file #%d "
+               "(incorrect codec parameters ?): %s\n",
+               of->index, av_err2str(ret));
+        return ret;
+    }
+    //assert_avoptions(of->opts);
+    of->header_written = 1;
+
+    av_dump_format(of->ctx, of->index, of->ctx->url, 1);
+    nb_output_dumped++;
+
+    if (sdp_filename || want_sdp) {
+        ret = print_sdp();
+        if (ret < 0) {
+            av_log(NULL, AV_LOG_ERROR, "Error writing the SDP.\n");
+            return ret;
+        }
+    }
+
+    /* flush the muxing queues */
+    for (i = 0; i < of->ctx->nb_streams; i++) {
+        OutputStream *ost = output_streams[of->ost_index + i];
+        AVPacket *pkt;
+
+        /* try to improve muxing time_base (only possible if nothing has been written yet) */
+        if (!av_fifo_can_read(ost->muxing_queue))
+            ost->mux_timebase = ost->st->time_base;
+
+        while (av_fifo_read(ost->muxing_queue, &pkt, 1) >= 0) {
+            ost->muxing_queue_data_size -= pkt->size;
+            of_write_packet(of, pkt, ost, 1);
+            av_packet_free(&pkt);
+        }
+    }
+
+    return 0;
+}
+
+int of_write_trailer(OutputFile *of)
+{
+    int ret;
+
+    if (!of->header_written) {
+        av_log(NULL, AV_LOG_ERROR,
+               "Nothing was written into output file %d (%s), because "
+               "at least one of its streams received no packets.\n",
+               of->index, of->ctx->url);
+        return AVERROR(EINVAL);
+    }
+
+    ret = av_write_trailer(of->ctx);
+    if (ret < 0) {
+        av_log(NULL, AV_LOG_ERROR, "Error writing trailer of %s: %s\n", of->ctx->url, av_err2str(ret));
+        return ret;
+    }
+
+    return 0;
+}
+
+void of_close(OutputFile **pof)
+{
+    OutputFile *of = *pof;
+    AVFormatContext *s;
+
+    if (!of)
+        return;
+
+    s = of->ctx;
+    if (s && s->oformat && !(s->oformat->flags & AVFMT_NOFILE))
+        avio_closep(&s->pb);
+    avformat_free_context(s);
+    av_dict_free(&of->opts);
+
+    av_freep(pof);
+}
diff -pruN 7:5.0.1-3/fftools/ffmpeg_opt.c 7:5.1-1/fftools/ffmpeg_opt.c
--- 7:5.0.1-3/fftools/ffmpeg_opt.c	2022-01-14 18:45:39.000000000 +0000
+++ 7:5.1-1/fftools/ffmpeg_opt.c	2022-07-22 17:58:38.000000000 +0000
@@ -1,4 +1,3 @@
-
 /*
  * ffmpeg option parsing
  *
@@ -19,10 +18,19 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "config.h"
+
 #include <stdint.h>
 
+#if HAVE_SYS_RESOURCE_H
+#include <sys/time.h>
+#include <sys/resource.h>
+#endif
+
 #include "ffmpeg.h"
+#include "fopen_utf8.h"
 #include "cmdutils.h"
+#include "opt_common.h"
 
 #include "libavformat/avformat.h"
 
@@ -36,6 +44,7 @@
 #include "libavutil/avutil.h"
 #include "libavutil/bprint.h"
 #include "libavutil/channel_layout.h"
+#include "libavutil/getenv_utf8.h"
 #include "libavutil/intreadwrite.h"
 #include "libavutil/fifo.h"
 #include "libavutil/mathematics.h"
@@ -55,6 +64,7 @@
 
 static const char *const opt_name_codec_names[]               = {"c", "codec", "acodec", "vcodec", "scodec", "dcodec", NULL};
 static const char *const opt_name_audio_channels[]            = {"ac", NULL};
+static const char *const opt_name_audio_ch_layouts[]          = {"channel_layout", "ch_layout", NULL};
 static const char *const opt_name_audio_sample_rate[]         = {"ar", NULL};
 static const char *const opt_name_frame_rates[]               = {"r", NULL};
 static const char *const opt_name_max_frame_rates[]           = {"fpsmax", NULL};
@@ -72,6 +82,7 @@ static const char *const opt_name_codec_
 static const char *const opt_name_sample_fmts[]               = {"sample_fmt", NULL};
 static const char *const opt_name_qscale[]                    = {"q", "qscale", NULL};
 static const char *const opt_name_forced_key_frames[]         = {"forced_key_frames", NULL};
+static const char *const opt_name_fps_mode[]                  = {"fps_mode", NULL};
 static const char *const opt_name_force_fps[]                 = {"force_fps", NULL};
 static const char *const opt_name_frame_aspect_ratios[]       = {"aspect", NULL};
 static const char *const opt_name_rc_overrides[]              = {"rc_override", NULL};
@@ -224,6 +235,7 @@ static void init_options(OptionsContext
     o->chapters_input_file = INT_MAX;
     o->accurate_seek  = 1;
     o->thread_queue_size = -1;
+    o->input_sync_ref = -1;
 }
 
 static int show_hwaccels(void *optctx, const char *opt, const char *arg)
@@ -256,6 +268,78 @@ static AVDictionary *strip_specifiers(AV
     return ret;
 }
 
+static int parse_and_set_vsync(const char *arg, int *vsync_var, int file_idx, int st_idx, int is_global)
+{
+    if      (!av_strcasecmp(arg, "cfr"))         *vsync_var = VSYNC_CFR;
+    else if (!av_strcasecmp(arg, "vfr"))         *vsync_var = VSYNC_VFR;
+    else if (!av_strcasecmp(arg, "passthrough")) *vsync_var = VSYNC_PASSTHROUGH;
+    else if (!av_strcasecmp(arg, "drop"))        *vsync_var = VSYNC_DROP;
+    else if (!is_global && !av_strcasecmp(arg, "auto"))  *vsync_var = VSYNC_AUTO;
+    else if (!is_global) {
+        av_log(NULL, AV_LOG_FATAL, "Invalid value %s specified for fps_mode of #%d:%d.\n", arg, file_idx, st_idx);
+        exit_program(1);
+    }
+
+    if (is_global && *vsync_var == VSYNC_AUTO) {
+        video_sync_method = parse_number_or_die("vsync", arg, OPT_INT, VSYNC_AUTO, VSYNC_VFR);
+        av_log(NULL, AV_LOG_WARNING, "Passing a number to -vsync is deprecated,"
+               " use a string argument as described in the manual.\n");
+    }
+    return 0;
+}
+
+static int apply_sync_offsets(void)
+{
+    for (int i = 0; i < nb_input_files; i++) {
+        InputFile *ref, *self = input_files[i];
+        int64_t adjustment;
+        int64_t self_start_time, ref_start_time, self_seek_start, ref_seek_start;
+        int start_times_set = 1;
+
+        if (self->input_sync_ref == -1 || self->input_sync_ref == i) continue;
+        if (self->input_sync_ref >= nb_input_files || self->input_sync_ref < -1) {
+            av_log(NULL, AV_LOG_FATAL, "-isync for input %d references non-existent input %d.\n", i, self->input_sync_ref);
+            exit_program(1);
+        }
+
+        if (copy_ts && !start_at_zero) {
+            av_log(NULL, AV_LOG_FATAL, "Use of -isync requires that start_at_zero be set if copyts is set.\n");
+            exit_program(1);
+        }
+
+        ref = input_files[self->input_sync_ref];
+        if (ref->input_sync_ref != -1 && ref->input_sync_ref != self->input_sync_ref) {
+            av_log(NULL, AV_LOG_ERROR, "-isync for input %d references a resynced input %d. Sync not set.\n", i, self->input_sync_ref);
+            continue;
+        }
+
+        if (self->ctx->start_time_realtime != AV_NOPTS_VALUE && ref->ctx->start_time_realtime != AV_NOPTS_VALUE) {
+            self_start_time = self->ctx->start_time_realtime;
+            ref_start_time  =  ref->ctx->start_time_realtime;
+        } else if (self->ctx->start_time != AV_NOPTS_VALUE && ref->ctx->start_time != AV_NOPTS_VALUE) {
+            self_start_time = self->ctx->start_time;
+            ref_start_time  =  ref->ctx->start_time;
+        } else {
+            start_times_set = 0;
+        }
+
+        if (start_times_set) {
+            self_seek_start = self->start_time == AV_NOPTS_VALUE ? 0 : self->start_time;
+            ref_seek_start  =  ref->start_time == AV_NOPTS_VALUE ? 0 :  ref->start_time;
+
+            adjustment = (self_start_time - ref_start_time) + !copy_ts*(self_seek_start - ref_seek_start) + ref->input_ts_offset;
+
+            self->ts_offset += adjustment;
+
+            av_log(NULL, AV_LOG_INFO, "Adjusted ts offset for Input #%d by %"PRId64" us to sync with Input #%d.\n", i, adjustment, self->input_sync_ref);
+        } else {
+            av_log(NULL, AV_LOG_INFO, "Unable to identify start times for Inputs #%d and %d both. No sync adjustment made.\n", i, self->input_sync_ref);
+        }
+    }
+
+    return 0;
+}
+
 static int opt_filter_threads(void *optctx, const char *opt, const char *arg)
 {
     av_free(filter_nbthreads);
@@ -507,7 +591,7 @@ static int opt_map_channel(void *optctx,
     /* allow trailing ? to map_channel */
     if (allow_unused = strchr(mapchan, '?'))
         *allow_unused = 0;
-    if (m->channel_idx < 0 || m->channel_idx >= st->codecpar->channels ||
+    if (m->channel_idx < 0 || m->channel_idx >= st->codecpar->ch_layout.nb_channels ||
         input_streams[input_files[m->file_idx]->ist_index + m->stream_idx]->user_set_discard == AVDISCARD_ALL) {
         if (allow_unused) {
             av_log(NULL, AV_LOG_VERBOSE, "mapchan: invalid audio channel #%d.%d.%d\n",
@@ -784,7 +868,7 @@ static void add_input_streams(OptionsCon
     for (i = 0; i < ic->nb_streams; i++) {
         AVStream *st = ic->streams[i];
         AVCodecParameters *par = st->codecpar;
-        InputStream *ist = av_mallocz(sizeof(*ist));
+        InputStream *ist;
         char *framerate = NULL, *hwaccel_device = NULL;
         const char *hwaccel = NULL;
         char *hwaccel_output_format = NULL;
@@ -795,12 +879,7 @@ static void add_input_streams(OptionsCon
         const AVOption *discard_opt = av_opt_find(&cc, "skip_frame", NULL,
                                                   0, AV_OPT_SEARCH_FAKE_OBJ);
 
-        if (!ist)
-            exit_program(1);
-
-        GROW_ARRAY(input_streams, nb_input_streams);
-        input_streams[nb_input_streams - 1] = ist;
-
+        ist = ALLOC_ARRAY_ELEM(input_streams, nb_input_streams);
         ist->st = st;
         ist->file_index = nb_input_files;
         ist->discard = 1;
@@ -1120,13 +1199,20 @@ static int open_input_file(OptionsContex
     }
     if (o->nb_audio_channels) {
         const AVClass *priv_class;
-        /* because we set audio_channels based on both the "ac" and
-         * "channel_layout" options, we need to check that the specified
-         * demuxer actually has the "channels" option before setting it */
         if (file_iformat && (priv_class = file_iformat->priv_class) &&
-            av_opt_find(&priv_class, "channels", NULL, 0,
+            av_opt_find(&priv_class, "ch_layout", NULL, 0,
                         AV_OPT_SEARCH_FAKE_OBJ)) {
-            av_dict_set_int(&o->g->format_opts, "channels", o->audio_channels[o->nb_audio_channels - 1].u.i, 0);
+            char buf[32];
+            snprintf(buf, sizeof(buf), "%dC", o->audio_channels[o->nb_audio_channels - 1].u.i);
+            av_dict_set(&o->g->format_opts, "ch_layout", buf, 0);
+        }
+    }
+    if (o->nb_audio_ch_layouts) {
+        const AVClass *priv_class;
+        if (file_iformat && (priv_class = file_iformat->priv_class) &&
+            av_opt_find(&priv_class, "ch_layout", NULL, 0,
+                        AV_OPT_SEARCH_FAKE_OBJ)) {
+            av_dict_set(&o->g->format_opts, "ch_layout", o->audio_ch_layouts[o->nb_audio_ch_layouts - 1].u.str, 0);
         }
     }
     if (o->nb_frame_rates) {
@@ -1272,6 +1358,7 @@ static int open_input_file(OptionsContex
     f->ist_index  = nb_input_streams - ic->nb_streams;
     f->start_time = o->start_time;
     f->recording_time = o->recording_time;
+    f->input_sync_ref = o->input_sync_ref;
     f->input_ts_offset = o->input_ts_offset;
     f->ts_offset  = o->input_ts_offset - (copy_ts ? (start_at_zero && ic->start_time != AV_NOPTS_VALUE ? ic->start_time : 0) : timestamp);
     f->nb_streams = ic->nb_streams;
@@ -1370,8 +1457,10 @@ static int get_preset_file_2(const char
 {
     int i, ret = -1;
     char filename[1000];
-    const char *base[3] = { getenv("AVCONV_DATADIR"),
-                            getenv("HOME"),
+    char *env_avconv_datadir = getenv_utf8("AVCONV_DATADIR");
+    char *env_home = getenv_utf8("HOME");
+    const char *base[3] = { env_avconv_datadir,
+                            env_home,
                             AVCONV_DATADIR,
                             };
 
@@ -1389,6 +1478,8 @@ static int get_preset_file_2(const char
             ret = avio_open2(s, filename, AVIO_FLAG_READ, &int_cb, NULL);
         }
     }
+    freeenv_utf8(env_home);
+    freeenv_utf8(env_avconv_datadir);
     return ret;
 }
 
@@ -1445,10 +1536,7 @@ static OutputStream *new_output_stream(O
     if (oc->nb_streams - 1 < o->nb_streamid_map)
         st->id = o->streamid_map[oc->nb_streams - 1];
 
-    GROW_ARRAY(output_streams, nb_output_streams);
-    if (!(ost = av_mallocz(sizeof(*ost))))
-        exit_program(1);
-    output_streams[nb_output_streams - 1] = ost;
+    ost = ALLOC_ARRAY_ELEM(output_streams, nb_output_streams);
 
     ost->file_index = nb_output_files - 1;
     ost->index      = idx;
@@ -1589,8 +1677,6 @@ static OutputStream *new_output_stream(O
 
     ost->max_muxing_queue_size = 128;
     MATCH_PER_STREAM_OPT(max_muxing_queue_size, i, ost->max_muxing_queue_size, oc, st);
-    ost->max_muxing_queue_size = FFMIN(ost->max_muxing_queue_size, INT_MAX / sizeof(ost->pkt));
-    ost->max_muxing_queue_size *= sizeof(ost->pkt);
 
     ost->muxing_queue_data_size = 0;
 
@@ -1617,10 +1703,13 @@ static OutputStream *new_output_stream(O
     }
     ost->last_mux_dts = AV_NOPTS_VALUE;
 
-    ost->muxing_queue = av_fifo_alloc(8 * sizeof(AVPacket));
+    ost->muxing_queue = av_fifo_alloc2(8, sizeof(AVPacket*), 0);
     if (!ost->muxing_queue)
         exit_program(1);
 
+    MATCH_PER_STREAM_OPT(copy_initial_nonkeyframes, i,
+                         ost->copy_initial_nonkeyframes, oc, st);
+
     return ost;
 }
 
@@ -1859,7 +1948,7 @@ static OutputStream *new_video_stream(Op
             snprintf(logfilename, sizeof(logfilename), "%s-%d.log",
                      ost->logfile_prefix ? ost->logfile_prefix :
                                            DEFAULT_PASS_LOGFILENAME_PREFIX,
-                     i);
+                     nb_output_streams - 1);
             if (!strcmp(ost->enc->name, "libx264")) {
                 av_dict_set(&ost->encoder_opts, "stats", logfilename, AV_DICT_DONT_OVERWRITE);
             } else {
@@ -1874,7 +1963,7 @@ static OutputStream *new_video_stream(Op
                     video_enc->stats_in = logbuffer;
                 }
                 if (video_enc->flags & AV_CODEC_FLAG_PASS1) {
-                    f = av_fopen_utf8(logfilename, "wb");
+                    f = fopen_utf8(logfilename, "wb");
                     if (!f) {
                         av_log(NULL, AV_LOG_FATAL,
                                "Cannot write log file '%s' for pass-1 encoding: %s\n",
@@ -1896,6 +1985,10 @@ static OutputStream *new_video_stream(Op
         MATCH_PER_STREAM_OPT(top_field_first, i, ost->top_field_first, oc, st);
 
         ost->vsync_method = video_sync_method;
+        MATCH_PER_STREAM_OPT(fps_mode, str, ost->fps_mode, oc, st);
+        if (ost->fps_mode)
+            parse_and_set_vsync(ost->fps_mode, &ost->vsync_method, ost->file_index, ost->index, 0);
+
         if (ost->vsync_method == VSYNC_AUTO) {
             if (!strcmp(oc->oformat->name, "avi")) {
                 ost->vsync_method = VSYNC_VFR;
@@ -1927,8 +2020,6 @@ static OutputStream *new_video_stream(Op
         ost->last_frame = av_frame_alloc();
         if (!ost->last_frame)
             exit_program(1);
-    } else {
-        MATCH_PER_STREAM_OPT(copy_initial_nonkeyframes, i, ost->copy_initial_nonkeyframes, oc ,st);
     }
 
     if (ost->stream_copy)
@@ -1954,9 +2045,36 @@ static OutputStream *new_audio_stream(Op
     MATCH_PER_STREAM_OPT(filters,        str, ost->filters,        oc, st);
 
     if (!ost->stream_copy) {
+        int channels = 0;
+        char *layout = NULL;
         char *sample_fmt = NULL;
 
-        MATCH_PER_STREAM_OPT(audio_channels, i, audio_enc->channels, oc, st);
+        MATCH_PER_STREAM_OPT(audio_channels, i, channels, oc, st);
+        if (channels) {
+            audio_enc->ch_layout.order       = AV_CHANNEL_ORDER_UNSPEC;
+            audio_enc->ch_layout.nb_channels = channels;
+        }
+
+        MATCH_PER_STREAM_OPT(audio_ch_layouts, str, layout, oc, st);
+        if (layout) {
+            if (av_channel_layout_from_string(&audio_enc->ch_layout, layout) < 0) {
+#if FF_API_OLD_CHANNEL_LAYOUT
+                uint64_t mask;
+                AV_NOWARN_DEPRECATED({
+                mask = av_get_channel_layout(layout);
+                })
+                if (!mask) {
+#endif
+                    av_log(NULL, AV_LOG_FATAL, "Unknown channel layout: %s\n", layout);
+                    exit_program(1);
+#if FF_API_OLD_CHANNEL_LAYOUT
+                }
+                av_log(NULL, AV_LOG_WARNING, "Channel layout '%s' uses a deprecated syntax.\n",
+                       layout);
+                av_channel_layout_from_mask(&audio_enc->ch_layout, mask);
+#endif
+            }
+        }
 
         MATCH_PER_STREAM_OPT(sample_fmts, str, sample_fmt, oc, st);
         if (sample_fmt &&
@@ -2056,8 +2174,6 @@ static OutputStream *new_subtitle_stream
 
     subtitle_enc->codec_type = AVMEDIA_TYPE_SUBTITLE;
 
-    MATCH_PER_STREAM_OPT(copy_initial_nonkeyframes, i, ost->copy_initial_nonkeyframes, oc, st);
-
     if (!ost->stream_copy) {
         char *frame_size = NULL;
 
@@ -2094,10 +2210,10 @@ static int opt_streamid(void *optctx, co
     return 0;
 }
 
-static int copy_chapters(InputFile *ifile, OutputFile *ofile, int copy_metadata)
+static int copy_chapters(InputFile *ifile, OutputFile *ofile, AVFormatContext *os,
+                         int copy_metadata)
 {
     AVFormatContext *is = ifile->ctx;
-    AVFormatContext *os = ofile->ctx;
     AVChapter **tmp;
     int i;
 
@@ -2137,14 +2253,14 @@ static int copy_chapters(InputFile *ifil
     return 0;
 }
 
-static int set_dispositions(OutputFile *of)
+static int set_dispositions(OutputFile *of, AVFormatContext *ctx)
 {
     int nb_streams[AVMEDIA_TYPE_NB]   = { 0 };
     int have_default[AVMEDIA_TYPE_NB] = { 0 };
     int have_manual = 0;
 
     // first, copy the input dispositions
-    for (int i = 0; i< of->ctx->nb_streams; i++) {
+    for (int i = 0; i < ctx->nb_streams; i++) {
         OutputStream *ost = output_streams[of->ost_index + i];
 
         nb_streams[ost->st->codecpar->codec_type]++;
@@ -2161,7 +2277,7 @@ static int set_dispositions(OutputFile *
 
     if (have_manual) {
         // process manually set dispositions - they override the above copy
-        for (int i = 0; i< of->ctx->nb_streams; i++) {
+        for (int i = 0; i < ctx->nb_streams; i++) {
             OutputStream *ost = output_streams[of->ost_index + i];
             int ret;
 
@@ -2187,7 +2303,7 @@ static int set_dispositions(OutputFile *
         // For each media type with more than one stream, find a suitable stream to
         // mark as default, unless one is already marked default.
         // "Suitable" means the first of that type, skipping attached pictures.
-        for (int i = 0; i< of->ctx->nb_streams; i++) {
+        for (int i = 0; i < ctx->nb_streams; i++) {
             OutputStream *ost = output_streams[of->ost_index + i];
             enum AVMediaType type = ost->st->codecpar->codec_type;
 
@@ -2283,6 +2399,7 @@ static int open_output_file(OptionsConte
 
     of = ALLOC_ARRAY_ELEM(output_files, nb_output_files);
 
+    of->index          = nb_output_files - 1;
     of->ost_index      = nb_output_streams;
     of->recording_time = o->recording_time;
     of->start_time     = o->start_time;
@@ -2300,6 +2417,7 @@ static int open_output_file(OptionsConte
     }
 
     of->ctx = oc;
+    of->format = oc->oformat;
     if (o->recording_time != INT64_MAX)
         oc->duration = o->recording_time;
 
@@ -2378,7 +2496,7 @@ static int open_output_file(OptionsConte
                 for (i = 0; i < ifile->nb_streams; i++) {
                     int score;
                     ist = input_streams[ifile->ist_index + i];
-                    score = ist->st->codecpar->channels
+                    score = ist->st->codecpar->ch_layout.nb_channels
                             + 100000000 * !!(ist->st->event_flags & AVSTREAM_EVENT_FLAG_NEW_PACKETS)
                             + 5000000*!!(ist->st->disposition & AV_DISPOSITION_DEFAULT);
                     if (ist->user_set_discard == AVDISCARD_ALL)
@@ -2612,6 +2730,7 @@ loop_end:
         if (ost->encoding_needed && ost->source_index >= 0) {
             InputStream *ist = input_streams[ost->source_index];
             ist->decoding_needed |= DECODING_FOR_OST;
+            ist->processing_needed = 1;
 
             if (ost->st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO ||
                 ost->st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
@@ -2624,6 +2743,9 @@ loop_end:
                     exit_program(1);
                 }
             }
+        } else if (ost->stream_copy && ost->source_index >= 0) {
+            InputStream *ist = input_streams[ost->source_index];
+            ist->processing_needed = 1;
         }
 
         /* set the filter output constraints */
@@ -2651,10 +2773,10 @@ loop_end:
                 } else {
                     f->sample_rates = ost->enc->supported_samplerates;
                 }
-                if (ost->enc_ctx->channels) {
-                    f->channel_layout = av_get_default_channel_layout(ost->enc_ctx->channels);
-                } else {
-                    f->channel_layouts = ost->enc->channel_layouts;
+                if (ost->enc_ctx->ch_layout.nb_channels) {
+                    av_channel_layout_default(&f->ch_layout, ost->enc_ctx->ch_layout.nb_channels);
+                } else if (ost->enc->ch_layouts) {
+                    f->ch_layouts = ost->enc->ch_layouts;
                 }
                 break;
             }
@@ -2725,7 +2847,7 @@ loop_end:
         }
     }
     if (o->chapters_input_file >= 0)
-        copy_chapters(input_files[o->chapters_input_file], of,
+        copy_chapters(input_files[o->chapters_input_file], of, oc,
                       !o->metadata_chapters_manual);
 
     /* copy global metadata by default */
@@ -2878,7 +3000,7 @@ loop_end:
         }
     }
 
-    err = set_dispositions(of);
+    err = set_dispositions(of, oc);
     if (err < 0) {
         av_log(NULL, AV_LOG_FATAL, "Error setting output stream dispositions\n");
         exit_program(1);
@@ -3210,16 +3332,8 @@ static int opt_audio_filters(void *optct
 
 static int opt_vsync(void *optctx, const char *opt, const char *arg)
 {
-    if      (!av_strcasecmp(arg, "cfr"))         video_sync_method = VSYNC_CFR;
-    else if (!av_strcasecmp(arg, "vfr"))         video_sync_method = VSYNC_VFR;
-    else if (!av_strcasecmp(arg, "passthrough")) video_sync_method = VSYNC_PASSTHROUGH;
-    else if (!av_strcasecmp(arg, "drop"))        video_sync_method = VSYNC_DROP;
-
-    if (video_sync_method == VSYNC_AUTO) {
-        video_sync_method = parse_number_or_die("vsync", arg, OPT_INT, VSYNC_AUTO, VSYNC_VFR);
-        av_log(NULL, AV_LOG_WARNING, "Passing a number to -vsync is deprecated,"
-               " use a string argument as described in the manual.\n");
-    }
+    av_log(NULL, AV_LOG_WARNING, "-vsync is deprecated. Use -fps_mode\n");
+    parse_and_set_vsync(arg, &video_sync_method, -1, -1, 1);
     return 0;
 }
 
@@ -3237,42 +3351,6 @@ static int opt_timecode(void *optctx, co
     return ret;
 }
 
-static int opt_channel_layout(void *optctx, const char *opt, const char *arg)
-{
-    OptionsContext *o = optctx;
-    char layout_str[32];
-    char *stream_str;
-    char *ac_str;
-    int ret, channels, ac_str_size;
-    uint64_t layout;
-
-    layout = av_get_channel_layout(arg);
-    if (!layout) {
-        av_log(NULL, AV_LOG_ERROR, "Unknown channel layout: %s\n", arg);
-        return AVERROR(EINVAL);
-    }
-    snprintf(layout_str, sizeof(layout_str), "%"PRIu64, layout);
-    ret = opt_default_new(o, opt, layout_str);
-    if (ret < 0)
-        return ret;
-
-    /* set 'ac' option based on channel layout */
-    channels = av_get_channel_layout_nb_channels(layout);
-    snprintf(layout_str, sizeof(layout_str), "%d", channels);
-    stream_str = strchr(opt, ':');
-    ac_str_size = 3 + (stream_str ? strlen(stream_str) : 0);
-    ac_str = av_mallocz(ac_str_size);
-    if (!ac_str)
-        return AVERROR(ENOMEM);
-    av_strlcpy(ac_str, "ac", 3);
-    if (stream_str)
-        av_strlcat(ac_str, stream_str, ac_str_size);
-    ret = parse_option(o, ac_str, layout_str, options);
-    av_free(ac_str);
-
-    return ret;
-}
-
 static int opt_audio_qscale(void *optctx, const char *opt, const char *arg)
 {
     OptionsContext *o = optctx;
@@ -3281,9 +3359,8 @@ static int opt_audio_qscale(void *optctx
 
 static int opt_filter_complex(void *optctx, const char *opt, const char *arg)
 {
-    FilterGraph *fg;
-    ALLOC_ARRAY_ELEM(filtergraphs, nb_filtergraphs);
-    fg = filtergraphs[nb_filtergraphs - 1];
+    FilterGraph *fg = ALLOC_ARRAY_ELEM(filtergraphs, nb_filtergraphs);
+
     fg->index      = nb_filtergraphs - 1;
     fg->graph_desc = av_strdup(arg);
     if (!fg->graph_desc)
@@ -3466,6 +3543,8 @@ int ffmpeg_parse_options(int argc, char
         goto fail;
     }
 
+    apply_sync_offsets();
+
     /* create the complex filtergraphs */
     ret = init_complex_filters();
     if (ret < 0) {
@@ -3508,6 +3587,19 @@ static int opt_progress(void *optctx, co
     return 0;
 }
 
+int opt_timelimit(void *optctx, const char *opt, const char *arg)
+{
+#if HAVE_SETRLIMIT
+    int lim = parse_number_or_die(opt, arg, OPT_INT64, 0, INT_MAX);
+    struct rlimit rl = { lim, lim + 1 };
+    if (setrlimit(RLIMIT_CPU, &rl))
+        perror("setrlimit");
+#else
+    av_log(NULL, AV_LOG_WARNING, "-%s not implemented on this OS\n", opt);
+#endif
+    return 0;
+}
+
 #define OFFSET(x) offsetof(OptionsContext, x)
 const OptionDef options[] = {
     /* main options */
@@ -3567,6 +3659,9 @@ const OptionDef options[] = {
     { "accurate_seek",  OPT_BOOL | OPT_OFFSET | OPT_EXPERT |
                         OPT_INPUT,                                   { .off = OFFSET(accurate_seek) },
         "enable/disable accurate seeking with -ss" },
+    { "isync",          HAS_ARG | OPT_INT | OPT_OFFSET |
+                        OPT_EXPERT | OPT_INPUT,                      { .off = OFFSET(input_sync_ref) },
+        "Indicate the input index for sync reference", "sync ref" },
     { "itsoffset",      HAS_ARG | OPT_TIME | OPT_OFFSET |
                         OPT_EXPERT | OPT_INPUT,                      { .off = OFFSET(input_ts_offset) },
         "set the input ts offset", "time_off" },
@@ -3606,7 +3701,7 @@ const OptionDef options[] = {
         "specify target file type (\"vcd\", \"svcd\", \"dvd\", \"dv\" or \"dv50\" "
         "with optional prefixes \"pal-\", \"ntsc-\" or \"film-\")", "type" },
     { "vsync",          HAS_ARG | OPT_EXPERT,                        { .func_arg = opt_vsync },
-        "video sync method", "" },
+        "set video sync method globally; deprecated, use -fps_mode", "" },
     { "frame_drop_threshold", HAS_ARG | OPT_FLOAT | OPT_EXPERT,      { &frame_drop_threshold },
         "frame drop threshold", "" },
     { "async",          HAS_ARG | OPT_INT | OPT_EXPERT,              { &audio_sync_method },
@@ -3763,6 +3858,9 @@ const OptionDef options[] = {
         "force video tag/fourcc", "fourcc/tag" },
     { "qphist",       OPT_VIDEO | OPT_BOOL | OPT_EXPERT ,                        { &qp_hist },
         "show QP histogram" },
+    { "fps_mode",     OPT_VIDEO | HAS_ARG | OPT_STRING | OPT_EXPERT |
+                      OPT_SPEC | OPT_OUTPUT,                                     { .off = OFFSET(fps_mode) },
+        "set framerate mode for matching video streams; overrides vsync" },
     { "force_fps",    OPT_VIDEO | OPT_BOOL | OPT_EXPERT  | OPT_SPEC |
                       OPT_OUTPUT,                                                { .off = OFFSET(force_fps) },
         "force the selected framerate, disable the best supported framerate selection" },
@@ -3818,8 +3916,11 @@ const OptionDef options[] = {
     { "sample_fmt",     OPT_AUDIO | HAS_ARG  | OPT_EXPERT | OPT_SPEC |
                         OPT_STRING | OPT_INPUT | OPT_OUTPUT,                       { .off = OFFSET(sample_fmts) },
         "set sample format", "format" },
-    { "channel_layout", OPT_AUDIO | HAS_ARG  | OPT_EXPERT | OPT_PERFILE |
-                        OPT_INPUT | OPT_OUTPUT,                                    { .func_arg = opt_channel_layout },
+    { "channel_layout", OPT_AUDIO | HAS_ARG  | OPT_EXPERT | OPT_SPEC |
+                        OPT_STRING | OPT_INPUT | OPT_OUTPUT,                       { .off = OFFSET(audio_ch_layouts) },
+        "set channel layout", "layout" },
+    { "ch_layout",      OPT_AUDIO | HAS_ARG  | OPT_EXPERT | OPT_SPEC |
+                        OPT_STRING | OPT_INPUT | OPT_OUTPUT,                       { .off = OFFSET(audio_ch_layouts) },
         "set channel layout", "layout" },
     { "af",             OPT_AUDIO | HAS_ARG  | OPT_PERFILE | OPT_OUTPUT,           { .func_arg = opt_audio_filters },
         "set audio filters", "filter_graph" },
diff -pruN 7:5.0.1-3/fftools/ffplay.c 7:5.1-1/fftools/ffplay.c
--- 7:5.0.1-3/fftools/ffplay.c	2022-01-14 18:45:39.000000000 +0000
+++ 7:5.1-1/fftools/ffplay.c	2022-07-22 17:58:38.000000000 +0000
@@ -24,6 +24,7 @@
  */
 
 #include "config.h"
+#include "config_components.h"
 #include <inttypes.h>
 #include <math.h>
 #include <limits.h>
@@ -59,6 +60,7 @@
 #include <SDL_thread.h>
 
 #include "cmdutils.h"
+#include "opt_common.h"
 
 const char program_name[] = "ffplay";
 const int program_birth_year = 2003;
@@ -115,7 +117,7 @@ typedef struct MyAVPacketList {
 } MyAVPacketList;
 
 typedef struct PacketQueue {
-    AVFifoBuffer *pkt_list;
+    AVFifo *pkt_list;
     int nb_packets;
     int size;
     int64_t duration;
@@ -132,8 +134,7 @@ typedef struct PacketQueue {
 
 typedef struct AudioParams {
     int freq;
-    int channels;
-    int64_t channel_layout;
+    AVChannelLayout ch_layout;
     enum AVSampleFormat fmt;
     int frame_size;
     int bytes_per_sec;
@@ -412,31 +413,21 @@ int cmp_audio_fmts(enum AVSampleFormat f
         return channel_count1 != channel_count2 || fmt1 != fmt2;
 }
 
-static inline
-int64_t get_valid_channel_layout(int64_t channel_layout, int channels)
-{
-    if (channel_layout && av_get_channel_layout_nb_channels(channel_layout) == channels)
-        return channel_layout;
-    else
-        return 0;
-}
-
 static int packet_queue_put_private(PacketQueue *q, AVPacket *pkt)
 {
     MyAVPacketList pkt1;
+    int ret;
 
     if (q->abort_request)
        return -1;
 
-    if (av_fifo_space(q->pkt_list) < sizeof(pkt1)) {
-        if (av_fifo_grow(q->pkt_list, sizeof(pkt1)) < 0)
-            return -1;
-    }
 
     pkt1.pkt = pkt;
     pkt1.serial = q->serial;
 
-    av_fifo_generic_write(q->pkt_list, &pkt1, sizeof(pkt1), NULL);
+    ret = av_fifo_write(q->pkt_list, &pkt1, 1);
+    if (ret < 0)
+        return ret;
     q->nb_packets++;
     q->size += pkt1.pkt->size + sizeof(pkt1);
     q->duration += pkt1.pkt->duration;
@@ -477,7 +468,7 @@ static int packet_queue_put_nullpacket(P
 static int packet_queue_init(PacketQueue *q)
 {
     memset(q, 0, sizeof(PacketQueue));
-    q->pkt_list = av_fifo_alloc(sizeof(MyAVPacketList));
+    q->pkt_list = av_fifo_alloc2(1, sizeof(MyAVPacketList), AV_FIFO_FLAG_AUTO_GROW);
     if (!q->pkt_list)
         return AVERROR(ENOMEM);
     q->mutex = SDL_CreateMutex();
@@ -499,10 +490,8 @@ static void packet_queue_flush(PacketQue
     MyAVPacketList pkt1;
 
     SDL_LockMutex(q->mutex);
-    while (av_fifo_size(q->pkt_list) >= sizeof(pkt1)) {
-        av_fifo_generic_read(q->pkt_list, &pkt1, sizeof(pkt1), NULL);
+    while (av_fifo_read(q->pkt_list, &pkt1, 1) >= 0)
         av_packet_free(&pkt1.pkt);
-    }
     q->nb_packets = 0;
     q->size = 0;
     q->duration = 0;
@@ -513,7 +502,7 @@ static void packet_queue_flush(PacketQue
 static void packet_queue_destroy(PacketQueue *q)
 {
     packet_queue_flush(q);
-    av_fifo_freep(&q->pkt_list);
+    av_fifo_freep2(&q->pkt_list);
     SDL_DestroyMutex(q->mutex);
     SDL_DestroyCond(q->cond);
 }
@@ -551,8 +540,7 @@ static int packet_queue_get(PacketQueue
             break;
         }
 
-        if (av_fifo_size(q->pkt_list) >= sizeof(pkt1)) {
-            av_fifo_generic_read(q->pkt_list, &pkt1, sizeof(pkt1), NULL);
+        if (av_fifo_read(q->pkt_list, &pkt1, 1) >= 0) {
             q->nb_packets--;
             q->size -= pkt1.pkt->size + sizeof(pkt1);
             q->duration -= pkt1.pkt->duration;
@@ -1023,15 +1011,17 @@ static void video_image_display(VideoSta
     }
 
     calculate_display_rect(&rect, is->xleft, is->ytop, is->width, is->height, vp->width, vp->height, vp->sar);
+    set_sdl_yuv_conversion_mode(vp->frame);
 
     if (!vp->uploaded) {
-        if (upload_texture(&is->vid_texture, vp->frame, &is->img_convert_ctx) < 0)
+        if (upload_texture(&is->vid_texture, vp->frame, &is->img_convert_ctx) < 0) {
+            set_sdl_yuv_conversion_mode(NULL);
             return;
+        }
         vp->uploaded = 1;
         vp->flip_v = vp->frame->linesize[0] < 0;
     }
 
-    set_sdl_yuv_conversion_mode(vp->frame);
     SDL_RenderCopyEx(renderer, is->vid_texture, NULL, &rect, 0, NULL, vp->flip_v ? SDL_FLIP_VERTICAL : 0);
     set_sdl_yuv_conversion_mode(NULL);
     if (sp) {
@@ -1070,7 +1060,7 @@ static void video_audio_display(VideoSta
     nb_freq = 1 << (rdft_bits - 1);
 
     /* compute display index : center on currently output samples */
-    channels = s->audio_tgt.channels;
+    channels = s->audio_tgt.ch_layout.nb_channels;
     nb_display_channels = channels;
     if (!s->paused) {
         int data_used= s->show_mode == SHOW_MODE_WAVES ? s->width : (2*nb_freq);
@@ -1468,13 +1458,13 @@ static void check_external_clock_speed(V
 }
 
 /* seek in the stream */
-static void stream_seek(VideoState *is, int64_t pos, int64_t rel, int seek_by_bytes)
+static void stream_seek(VideoState *is, int64_t pos, int64_t rel, int by_bytes)
 {
     if (!is->seek_req) {
         is->seek_pos = pos;
         is->seek_rel = rel;
         is->seek_flags &= ~AVSEEK_FLAG_BYTE;
-        if (seek_by_bytes)
+        if (by_bytes)
             is->seek_flags |= AVSEEK_FLAG_BYTE;
         is->seek_req = 1;
         SDL_CondSignal(is->continue_read_thread);
@@ -1956,11 +1946,10 @@ static int configure_audio_filters(Video
 {
     static const enum AVSampleFormat sample_fmts[] = { AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE };
     int sample_rates[2] = { 0, -1 };
-    int64_t channel_layouts[2] = { 0, -1 };
-    int channels[2] = { 0, -1 };
     AVFilterContext *filt_asrc = NULL, *filt_asink = NULL;
     char aresample_swr_opts[512] = "";
     const AVDictionaryEntry *e = NULL;
+    AVBPrint bp;
     char asrc_args[256];
     int ret;
 
@@ -1969,20 +1958,20 @@ static int configure_audio_filters(Video
         return AVERROR(ENOMEM);
     is->agraph->nb_threads = filter_nbthreads;
 
+    av_bprint_init(&bp, 0, AV_BPRINT_SIZE_AUTOMATIC);
+
     while ((e = av_dict_get(swr_opts, "", e, AV_DICT_IGNORE_SUFFIX)))
         av_strlcatf(aresample_swr_opts, sizeof(aresample_swr_opts), "%s=%s:", e->key, e->value);
     if (strlen(aresample_swr_opts))
         aresample_swr_opts[strlen(aresample_swr_opts)-1] = '\0';
     av_opt_set(is->agraph, "aresample_swr_opts", aresample_swr_opts, 0);
 
+    av_channel_layout_describe_bprint(&is->audio_filter_src.ch_layout, &bp);
+
     ret = snprintf(asrc_args, sizeof(asrc_args),
-                   "sample_rate=%d:sample_fmt=%s:channels=%d:time_base=%d/%d",
+                   "sample_rate=%d:sample_fmt=%s:time_base=%d/%d:channel_layout=%s",
                    is->audio_filter_src.freq, av_get_sample_fmt_name(is->audio_filter_src.fmt),
-                   is->audio_filter_src.channels,
-                   1, is->audio_filter_src.freq);
-    if (is->audio_filter_src.channel_layout)
-        snprintf(asrc_args + ret, sizeof(asrc_args) - ret,
-                 ":channel_layout=0x%"PRIx64,  is->audio_filter_src.channel_layout);
+                   1, is->audio_filter_src.freq, bp.str);
 
     ret = avfilter_graph_create_filter(&filt_asrc,
                                        avfilter_get_by_name("abuffer"), "ffplay_abuffer",
@@ -2003,14 +1992,10 @@ static int configure_audio_filters(Video
         goto end;
 
     if (force_output_format) {
-        channel_layouts[0] = is->audio_tgt.channel_layout;
-        channels       [0] = is->audio_tgt.channel_layout ? -1 : is->audio_tgt.channels;
         sample_rates   [0] = is->audio_tgt.freq;
         if ((ret = av_opt_set_int(filt_asink, "all_channel_counts", 0, AV_OPT_SEARCH_CHILDREN)) < 0)
             goto end;
-        if ((ret = av_opt_set_int_list(filt_asink, "channel_layouts", channel_layouts,  -1, AV_OPT_SEARCH_CHILDREN)) < 0)
-            goto end;
-        if ((ret = av_opt_set_int_list(filt_asink, "channel_counts" , channels       ,  -1, AV_OPT_SEARCH_CHILDREN)) < 0)
+        if ((ret = av_opt_set(filt_asink, "ch_layouts", bp.str, AV_OPT_SEARCH_CHILDREN)) < 0)
             goto end;
         if ((ret = av_opt_set_int_list(filt_asink, "sample_rates"   , sample_rates   ,  -1, AV_OPT_SEARCH_CHILDREN)) < 0)
             goto end;
@@ -2026,6 +2011,8 @@ static int configure_audio_filters(Video
 end:
     if (ret < 0)
         avfilter_graph_free(&is->agraph);
+    av_bprint_finalize(&bp, NULL);
+
     return ret;
 }
 #endif  /* CONFIG_AVFILTER */
@@ -2037,7 +2024,6 @@ static int audio_thread(void *arg)
     Frame *af;
 #if CONFIG_AVFILTER
     int last_serial = -1;
-    int64_t dec_channel_layout;
     int reconfigure;
 #endif
     int got_frame = 0;
@@ -2055,27 +2041,26 @@ static int audio_thread(void *arg)
                 tb = (AVRational){1, frame->sample_rate};
 
 #if CONFIG_AVFILTER
-                dec_channel_layout = get_valid_channel_layout(frame->channel_layout, frame->channels);
-
                 reconfigure =
-                    cmp_audio_fmts(is->audio_filter_src.fmt, is->audio_filter_src.channels,
-                                   frame->format, frame->channels)    ||
-                    is->audio_filter_src.channel_layout != dec_channel_layout ||
+                    cmp_audio_fmts(is->audio_filter_src.fmt, is->audio_filter_src.ch_layout.nb_channels,
+                                   frame->format, frame->ch_layout.nb_channels)    ||
+                    av_channel_layout_compare(&is->audio_filter_src.ch_layout, &frame->ch_layout) ||
                     is->audio_filter_src.freq           != frame->sample_rate ||
                     is->auddec.pkt_serial               != last_serial;
 
                 if (reconfigure) {
                     char buf1[1024], buf2[1024];
-                    av_get_channel_layout_string(buf1, sizeof(buf1), -1, is->audio_filter_src.channel_layout);
-                    av_get_channel_layout_string(buf2, sizeof(buf2), -1, dec_channel_layout);
+                    av_channel_layout_describe(&is->audio_filter_src.ch_layout, buf1, sizeof(buf1));
+                    av_channel_layout_describe(&frame->ch_layout, buf2, sizeof(buf2));
                     av_log(NULL, AV_LOG_DEBUG,
                            "Audio frame changed from rate:%d ch:%d fmt:%s layout:%s serial:%d to rate:%d ch:%d fmt:%s layout:%s serial:%d\n",
-                           is->audio_filter_src.freq, is->audio_filter_src.channels, av_get_sample_fmt_name(is->audio_filter_src.fmt), buf1, last_serial,
-                           frame->sample_rate, frame->channels, av_get_sample_fmt_name(frame->format), buf2, is->auddec.pkt_serial);
+                           is->audio_filter_src.freq, is->audio_filter_src.ch_layout.nb_channels, av_get_sample_fmt_name(is->audio_filter_src.fmt), buf1, last_serial,
+                           frame->sample_rate, frame->ch_layout.nb_channels, av_get_sample_fmt_name(frame->format), buf2, is->auddec.pkt_serial);
 
                     is->audio_filter_src.fmt            = frame->format;
-                    is->audio_filter_src.channels       = frame->channels;
-                    is->audio_filter_src.channel_layout = dec_channel_layout;
+                    ret = av_channel_layout_copy(&is->audio_filter_src.ch_layout, &frame->ch_layout);
+                    if (ret < 0)
+                        goto the_end;
                     is->audio_filter_src.freq           = frame->sample_rate;
                     last_serial                         = is->auddec.pkt_serial;
 
@@ -2341,7 +2326,6 @@ static int synchronize_audio(VideoState
 static int audio_decode_frame(VideoState *is)
 {
     int data_size, resampled_data_size;
-    int64_t dec_channel_layout;
     av_unused double audio_clock0;
     int wanted_nb_samples;
     Frame *af;
@@ -2362,34 +2346,31 @@ static int audio_decode_frame(VideoState
         frame_queue_next(&is->sampq);
     } while (af->serial != is->audioq.serial);
 
-    data_size = av_samples_get_buffer_size(NULL, af->frame->channels,
+    data_size = av_samples_get_buffer_size(NULL, af->frame->ch_layout.nb_channels,
                                            af->frame->nb_samples,
                                            af->frame->format, 1);
 
-    dec_channel_layout =
-        (af->frame->channel_layout && af->frame->channels == av_get_channel_layout_nb_channels(af->frame->channel_layout)) ?
-        af->frame->channel_layout : av_get_default_channel_layout(af->frame->channels);
     wanted_nb_samples = synchronize_audio(is, af->frame->nb_samples);
 
     if (af->frame->format        != is->audio_src.fmt            ||
-        dec_channel_layout       != is->audio_src.channel_layout ||
+        av_channel_layout_compare(&af->frame->ch_layout, &is->audio_src.ch_layout) ||
         af->frame->sample_rate   != is->audio_src.freq           ||
         (wanted_nb_samples       != af->frame->nb_samples && !is->swr_ctx)) {
         swr_free(&is->swr_ctx);
-        is->swr_ctx = swr_alloc_set_opts(NULL,
-                                         is->audio_tgt.channel_layout, is->audio_tgt.fmt, is->audio_tgt.freq,
-                                         dec_channel_layout,           af->frame->format, af->frame->sample_rate,
-                                         0, NULL);
+        swr_alloc_set_opts2(&is->swr_ctx,
+                            &is->audio_tgt.ch_layout, is->audio_tgt.fmt, is->audio_tgt.freq,
+                            &af->frame->ch_layout, af->frame->format, af->frame->sample_rate,
+                            0, NULL);
         if (!is->swr_ctx || swr_init(is->swr_ctx) < 0) {
             av_log(NULL, AV_LOG_ERROR,
                    "Cannot create sample rate converter for conversion of %d Hz %s %d channels to %d Hz %s %d channels!\n",
-                    af->frame->sample_rate, av_get_sample_fmt_name(af->frame->format), af->frame->channels,
-                    is->audio_tgt.freq, av_get_sample_fmt_name(is->audio_tgt.fmt), is->audio_tgt.channels);
+                    af->frame->sample_rate, av_get_sample_fmt_name(af->frame->format), af->frame->ch_layout.nb_channels,
+                    is->audio_tgt.freq, av_get_sample_fmt_name(is->audio_tgt.fmt), is->audio_tgt.ch_layout.nb_channels);
             swr_free(&is->swr_ctx);
             return -1;
         }
-        is->audio_src.channel_layout = dec_channel_layout;
-        is->audio_src.channels       = af->frame->channels;
+        if (av_channel_layout_copy(&is->audio_src.ch_layout, &af->frame->ch_layout) < 0)
+            return -1;
         is->audio_src.freq = af->frame->sample_rate;
         is->audio_src.fmt = af->frame->format;
     }
@@ -2398,7 +2379,7 @@ static int audio_decode_frame(VideoState
         const uint8_t **in = (const uint8_t **)af->frame->extended_data;
         uint8_t **out = &is->audio_buf1;
         int out_count = (int64_t)wanted_nb_samples * is->audio_tgt.freq / af->frame->sample_rate + 256;
-        int out_size  = av_samples_get_buffer_size(NULL, is->audio_tgt.channels, out_count, is->audio_tgt.fmt, 0);
+        int out_size  = av_samples_get_buffer_size(NULL, is->audio_tgt.ch_layout.nb_channels, out_count, is->audio_tgt.fmt, 0);
         int len2;
         if (out_size < 0) {
             av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size() failed\n");
@@ -2425,7 +2406,7 @@ static int audio_decode_frame(VideoState
                 swr_free(&is->swr_ctx);
         }
         is->audio_buf = is->audio_buf1;
-        resampled_data_size = len2 * is->audio_tgt.channels * av_get_bytes_per_sample(is->audio_tgt.fmt);
+        resampled_data_size = len2 * is->audio_tgt.ch_layout.nb_channels * av_get_bytes_per_sample(is->audio_tgt.fmt);
     } else {
         is->audio_buf = af->frame->data[0];
         resampled_data_size = data_size;
@@ -2494,24 +2475,26 @@ static void sdl_audio_callback(void *opa
     }
 }
 
-static int audio_open(void *opaque, int64_t wanted_channel_layout, int wanted_nb_channels, int wanted_sample_rate, struct AudioParams *audio_hw_params)
+static int audio_open(void *opaque, AVChannelLayout *wanted_channel_layout, int wanted_sample_rate, struct AudioParams *audio_hw_params)
 {
     SDL_AudioSpec wanted_spec, spec;
     const char *env;
     static const int next_nb_channels[] = {0, 0, 1, 6, 2, 6, 4, 6};
     static const int next_sample_rates[] = {0, 44100, 48000, 96000, 192000};
     int next_sample_rate_idx = FF_ARRAY_ELEMS(next_sample_rates) - 1;
+    int wanted_nb_channels = wanted_channel_layout->nb_channels;
 
     env = SDL_getenv("SDL_AUDIO_CHANNELS");
     if (env) {
         wanted_nb_channels = atoi(env);
-        wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels);
+        av_channel_layout_uninit(wanted_channel_layout);
+        av_channel_layout_default(wanted_channel_layout, wanted_nb_channels);
     }
-    if (!wanted_channel_layout || wanted_nb_channels != av_get_channel_layout_nb_channels(wanted_channel_layout)) {
-        wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels);
-        wanted_channel_layout &= ~AV_CH_LAYOUT_STEREO_DOWNMIX;
+    if (wanted_channel_layout->order != AV_CHANNEL_ORDER_NATIVE) {
+        av_channel_layout_uninit(wanted_channel_layout);
+        av_channel_layout_default(wanted_channel_layout, wanted_nb_channels);
     }
-    wanted_nb_channels = av_get_channel_layout_nb_channels(wanted_channel_layout);
+    wanted_nb_channels = wanted_channel_layout->nb_channels;
     wanted_spec.channels = wanted_nb_channels;
     wanted_spec.freq = wanted_sample_rate;
     if (wanted_spec.freq <= 0 || wanted_spec.channels <= 0) {
@@ -2538,7 +2521,7 @@ static int audio_open(void *opaque, int6
                 return -1;
             }
         }
-        wanted_channel_layout = av_get_default_channel_layout(wanted_spec.channels);
+        av_channel_layout_default(wanted_channel_layout, wanted_spec.channels);
     }
     if (spec.format != AUDIO_S16SYS) {
         av_log(NULL, AV_LOG_ERROR,
@@ -2546,8 +2529,9 @@ static int audio_open(void *opaque, int6
         return -1;
     }
     if (spec.channels != wanted_spec.channels) {
-        wanted_channel_layout = av_get_default_channel_layout(spec.channels);
-        if (!wanted_channel_layout) {
+        av_channel_layout_uninit(wanted_channel_layout);
+        av_channel_layout_default(wanted_channel_layout, spec.channels);
+        if (wanted_channel_layout->order != AV_CHANNEL_ORDER_NATIVE) {
             av_log(NULL, AV_LOG_ERROR,
                    "SDL advised channel count %d is not supported!\n", spec.channels);
             return -1;
@@ -2556,10 +2540,10 @@ static int audio_open(void *opaque, int6
 
     audio_hw_params->fmt = AV_SAMPLE_FMT_S16;
     audio_hw_params->freq = spec.freq;
-    audio_hw_params->channel_layout = wanted_channel_layout;
-    audio_hw_params->channels =  spec.channels;
-    audio_hw_params->frame_size = av_samples_get_buffer_size(NULL, audio_hw_params->channels, 1, audio_hw_params->fmt, 1);
-    audio_hw_params->bytes_per_sec = av_samples_get_buffer_size(NULL, audio_hw_params->channels, audio_hw_params->freq, audio_hw_params->fmt, 1);
+    if (av_channel_layout_copy(&audio_hw_params->ch_layout, wanted_channel_layout) < 0)
+        return -1;
+    audio_hw_params->frame_size = av_samples_get_buffer_size(NULL, audio_hw_params->ch_layout.nb_channels, 1, audio_hw_params->fmt, 1);
+    audio_hw_params->bytes_per_sec = av_samples_get_buffer_size(NULL, audio_hw_params->ch_layout.nb_channels, audio_hw_params->freq, audio_hw_params->fmt, 1);
     if (audio_hw_params->bytes_per_sec <= 0 || audio_hw_params->frame_size <= 0) {
         av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size failed\n");
         return -1;
@@ -2576,8 +2560,8 @@ static int stream_component_open(VideoSt
     const char *forced_codec_name = NULL;
     AVDictionary *opts = NULL;
     const AVDictionaryEntry *t = NULL;
-    int sample_rate, nb_channels;
-    int64_t channel_layout;
+    int sample_rate;
+    AVChannelLayout ch_layout = { 0 };
     int ret = 0;
     int stream_lowres = lowres;
 
@@ -2645,24 +2629,27 @@ static int stream_component_open(VideoSt
             AVFilterContext *sink;
 
             is->audio_filter_src.freq           = avctx->sample_rate;
-            is->audio_filter_src.channels       = avctx->channels;
-            is->audio_filter_src.channel_layout = get_valid_channel_layout(avctx->channel_layout, avctx->channels);
+            ret = av_channel_layout_copy(&is->audio_filter_src.ch_layout, &avctx->ch_layout);
+            if (ret < 0)
+                goto fail;
             is->audio_filter_src.fmt            = avctx->sample_fmt;
             if ((ret = configure_audio_filters(is, afilters, 0)) < 0)
                 goto fail;
             sink = is->out_audio_filter;
             sample_rate    = av_buffersink_get_sample_rate(sink);
-            nb_channels    = av_buffersink_get_channels(sink);
-            channel_layout = av_buffersink_get_channel_layout(sink);
+            ret = av_buffersink_get_ch_layout(sink, &ch_layout);
+            if (ret < 0)
+                goto fail;
         }
 #else
         sample_rate    = avctx->sample_rate;
-        nb_channels    = avctx->channels;
-        channel_layout = avctx->channel_layout;
+        ret = av_channel_layout_copy(&ch_layout, &avctx->ch_layout);
+        if (ret < 0)
+            goto fail;
 #endif
 
         /* prepare audio output */
-        if ((ret = audio_open(is, channel_layout, nb_channels, sample_rate, &is->audio_tgt)) < 0)
+        if ((ret = audio_open(is, &ch_layout, sample_rate, &is->audio_tgt)) < 0)
             goto fail;
         is->audio_hw_buf_size = ret;
         is->audio_src = is->audio_tgt;
@@ -2716,6 +2703,7 @@ static int stream_component_open(VideoSt
 fail:
     avcodec_free_context(&avctx);
 out:
+    av_channel_layout_uninit(&ch_layout);
     av_dict_free(&opts);
 
     return ret;
@@ -2835,7 +2823,9 @@ static int read_thread(void *arg)
         ic->pb->eof_reached = 0; // FIXME hack, ffplay maybe should not use avio_feof() to test for the end
 
     if (seek_by_bytes < 0)
-        seek_by_bytes = !!(ic->iformat->flags & AVFMT_TS_DISCONT) && strcmp("ogg", ic->iformat->name);
+        seek_by_bytes = !(ic->iformat->flags & AVFMT_NO_BYTE_SEEK) &&
+                        !!(ic->iformat->flags & AVFMT_TS_DISCONT) &&
+                        strcmp("ogg", ic->iformat->name);
 
     is->max_frame_duration = (ic->iformat->flags & AVFMT_TS_DISCONT) ? 10.0 : 3600.0;
 
@@ -3188,7 +3178,7 @@ static void stream_cycle_channel(VideoSt
             switch (codec_type) {
             case AVMEDIA_TYPE_AUDIO:
                 if (st->codecpar->sample_rate != 0 &&
-                    st->codecpar->channels != 0)
+                    st->codecpar->ch_layout.nb_channels != 0)
                     goto the_end;
                 break;
             case AVMEDIA_TYPE_VIDEO:
@@ -3474,12 +3464,6 @@ static void event_loop(VideoState *cur_s
     }
 }
 
-static int opt_frame_size(void *optctx, const char *opt, const char *arg)
-{
-    av_log(NULL, AV_LOG_WARNING, "Option -s is deprecated, use -video_size.\n");
-    return opt_default(NULL, "video_size", arg);
-}
-
 static int opt_width(void *optctx, const char *opt, const char *arg)
 {
     screen_width = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
@@ -3502,12 +3486,6 @@ static int opt_format(void *optctx, cons
     return 0;
 }
 
-static int opt_frame_pix_fmt(void *optctx, const char *opt, const char *arg)
-{
-    av_log(NULL, AV_LOG_WARNING, "Option -pix_fmt is deprecated, use -pixel_format.\n");
-    return opt_default(NULL, "pixel_format", arg);
-}
-
 static int opt_sync(void *optctx, const char *opt, const char *arg)
 {
     if (!strcmp(arg, "audio"))
@@ -3585,7 +3563,6 @@ static const OptionDef options[] = {
     CMDUTILS_COMMON_OPTIONS
     { "x", HAS_ARG, { .func_arg = opt_width }, "force displayed width", "width" },
     { "y", HAS_ARG, { .func_arg = opt_height }, "force displayed height", "height" },
-    { "s", HAS_ARG | OPT_VIDEO, { .func_arg = opt_frame_size }, "set frame size (WxH or abbreviation)", "size" },
     { "fs", OPT_BOOL, { &is_full_screen }, "force full screen" },
     { "an", OPT_BOOL, { &audio_disable }, "disable audio" },
     { "vn", OPT_BOOL, { &video_disable }, "disable video" },
@@ -3602,7 +3579,6 @@ static const OptionDef options[] = {
     { "alwaysontop", OPT_BOOL, { &alwaysontop }, "window always on top" },
     { "volume", OPT_INT | HAS_ARG, { &startup_volume}, "set startup volume 0=min 100=max", "volume" },
     { "f", HAS_ARG, { .func_arg = opt_format }, "force format", "fmt" },
-    { "pix_fmt", HAS_ARG | OPT_EXPERT | OPT_VIDEO, { .func_arg = opt_frame_pix_fmt }, "set pixel format", "format" },
     { "stats", OPT_BOOL | OPT_EXPERT, { &show_status }, "show status", "" },
     { "fast", OPT_BOOL | OPT_EXPERT, { &fast }, "non spec compliant optimizations", "" },
     { "genpts", OPT_BOOL | OPT_EXPERT, { &genpts }, "generate pts", "" },
@@ -3624,7 +3600,6 @@ static const OptionDef options[] = {
 #endif
     { "rdftspeed", OPT_INT | HAS_ARG| OPT_AUDIO | OPT_EXPERT, { &rdftspeed }, "rdft speed", "msecs" },
     { "showmode", HAS_ARG, { .func_arg = opt_show_mode}, "select show mode (0 = video, 1 = waves, 2 = RDFT)", "mode" },
-    { "default", HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, { .func_arg = opt_default }, "generic catch all option", "" },
     { "i", OPT_BOOL, { &dummy}, "read specified file", "input_file"},
     { "codec", HAS_ARG, { .func_arg = opt_codec}, "force decoder", "decoder_name" },
     { "acodec", HAS_ARG | OPT_STRING | OPT_EXPERT, {    &audio_codec_name }, "force audio decoder",    "decoder_name" },
diff -pruN 7:5.0.1-3/fftools/ffprobe.c 7:5.1-1/fftools/ffprobe.c
--- 7:5.0.1-3/fftools/ffprobe.c	2022-01-14 18:45:39.000000000 +0000
+++ 7:5.1-1/fftools/ffprobe.c	2022-07-22 17:58:38.000000000 +0000
@@ -29,7 +29,9 @@
 #include <string.h>
 
 #include "libavformat/avformat.h"
+#include "libavformat/version.h"
 #include "libavcodec/avcodec.h"
+#include "libavcodec/version.h"
 #include "libavutil/avassert.h"
 #include "libavutil/avstring.h"
 #include "libavutil/bprint.h"
@@ -38,6 +40,7 @@
 #include "libavutil/hash.h"
 #include "libavutil/hdr_dynamic_metadata.h"
 #include "libavutil/mastering_display_metadata.h"
+#include "libavutil/hdr_dynamic_vivid_metadata.h"
 #include "libavutil/dovi_meta.h"
 #include "libavutil/opt.h"
 #include "libavutil/pixdesc.h"
@@ -50,10 +53,16 @@
 #include "libavutil/timecode.h"
 #include "libavutil/timestamp.h"
 #include "libavdevice/avdevice.h"
+#include "libavdevice/version.h"
 #include "libswscale/swscale.h"
+#include "libswscale/version.h"
 #include "libswresample/swresample.h"
+#include "libswresample/version.h"
 #include "libpostproc/postprocess.h"
+#include "libpostproc/version.h"
+#include "libavfilter/version.h"
 #include "cmdutils.h"
+#include "opt_common.h"
 
 #include "libavutil/thread.h"
 
@@ -223,7 +232,7 @@ static struct section sections[] = {
     [SECTION_ID_FRAME] =              { SECTION_ID_FRAME, "frame", 0, { SECTION_ID_FRAME_TAGS, SECTION_ID_FRAME_SIDE_DATA_LIST, SECTION_ID_FRAME_LOGS, -1 } },
     [SECTION_ID_FRAME_TAGS] =         { SECTION_ID_FRAME_TAGS, "tags", SECTION_FLAG_HAS_VARIABLE_FIELDS, { -1 }, .element_name = "tag", .unique_name = "frame_tags" },
     [SECTION_ID_FRAME_SIDE_DATA_LIST] ={ SECTION_ID_FRAME_SIDE_DATA_LIST, "side_data_list", SECTION_FLAG_IS_ARRAY, { SECTION_ID_FRAME_SIDE_DATA, -1 }, .element_name = "side_data", .unique_name = "frame_side_data_list" },
-    [SECTION_ID_FRAME_SIDE_DATA] =     { SECTION_ID_FRAME_SIDE_DATA, "side_data", 0, { SECTION_ID_FRAME_SIDE_DATA_TIMECODE_LIST, SECTION_ID_FRAME_SIDE_DATA_COMPONENT_LIST, -1 } },
+    [SECTION_ID_FRAME_SIDE_DATA] =     { SECTION_ID_FRAME_SIDE_DATA, "side_data", 0, { SECTION_ID_FRAME_SIDE_DATA_TIMECODE_LIST, SECTION_ID_FRAME_SIDE_DATA_COMPONENT_LIST, -1 }, .unique_name = "frame_side_data" },
     [SECTION_ID_FRAME_SIDE_DATA_TIMECODE_LIST] =  { SECTION_ID_FRAME_SIDE_DATA_TIMECODE_LIST, "timecodes", SECTION_FLAG_IS_ARRAY, { SECTION_ID_FRAME_SIDE_DATA_TIMECODE, -1 } },
     [SECTION_ID_FRAME_SIDE_DATA_TIMECODE] =       { SECTION_ID_FRAME_SIDE_DATA_TIMECODE, "timecode", 0, { -1 } },
     [SECTION_ID_FRAME_SIDE_DATA_COMPONENT_LIST] = { SECTION_ID_FRAME_SIDE_DATA_COMPONENT_LIST, "components", SECTION_FLAG_IS_ARRAY, { SECTION_ID_FRAME_SIDE_DATA_COMPONENT, -1 } },
@@ -239,7 +248,7 @@ static struct section sections[] = {
     [SECTION_ID_PACKET] =             { SECTION_ID_PACKET, "packet", 0, { SECTION_ID_PACKET_TAGS, SECTION_ID_PACKET_SIDE_DATA_LIST, -1 } },
     [SECTION_ID_PACKET_TAGS] =        { SECTION_ID_PACKET_TAGS, "tags", SECTION_FLAG_HAS_VARIABLE_FIELDS, { -1 }, .element_name = "tag", .unique_name = "packet_tags" },
     [SECTION_ID_PACKET_SIDE_DATA_LIST] ={ SECTION_ID_PACKET_SIDE_DATA_LIST, "side_data_list", SECTION_FLAG_IS_ARRAY, { SECTION_ID_PACKET_SIDE_DATA, -1 }, .element_name = "side_data", .unique_name = "packet_side_data_list" },
-    [SECTION_ID_PACKET_SIDE_DATA] =     { SECTION_ID_PACKET_SIDE_DATA, "side_data", 0, { -1 } },
+    [SECTION_ID_PACKET_SIDE_DATA] =     { SECTION_ID_PACKET_SIDE_DATA, "side_data", 0, { -1 }, .unique_name = "packet_side_data" },
     [SECTION_ID_PIXEL_FORMATS] =      { SECTION_ID_PIXEL_FORMATS, "pixel_formats", SECTION_FLAG_IS_ARRAY, { SECTION_ID_PIXEL_FORMAT, -1 } },
     [SECTION_ID_PIXEL_FORMAT] =       { SECTION_ID_PIXEL_FORMAT, "pixel_format", 0, { SECTION_ID_PIXEL_FORMAT_FLAGS, SECTION_ID_PIXEL_FORMAT_COMPONENTS, -1 } },
     [SECTION_ID_PIXEL_FORMAT_FLAGS] = { SECTION_ID_PIXEL_FORMAT_FLAGS, "flags", 0, { -1 }, .unique_name = "pixel_format_flags" },
@@ -262,7 +271,7 @@ static struct section sections[] = {
     [SECTION_ID_STREAM_DISPOSITION] = { SECTION_ID_STREAM_DISPOSITION, "disposition", 0, { -1 }, .unique_name = "stream_disposition" },
     [SECTION_ID_STREAM_TAGS] =        { SECTION_ID_STREAM_TAGS, "tags", SECTION_FLAG_HAS_VARIABLE_FIELDS, { -1 }, .element_name = "tag", .unique_name = "stream_tags" },
     [SECTION_ID_STREAM_SIDE_DATA_LIST] ={ SECTION_ID_STREAM_SIDE_DATA_LIST, "side_data_list", SECTION_FLAG_IS_ARRAY, { SECTION_ID_STREAM_SIDE_DATA, -1 }, .element_name = "side_data", .unique_name = "stream_side_data_list" },
-    [SECTION_ID_STREAM_SIDE_DATA] =     { SECTION_ID_STREAM_SIDE_DATA, "side_data", 0, { -1 } },
+    [SECTION_ID_STREAM_SIDE_DATA] =     { SECTION_ID_STREAM_SIDE_DATA, "side_data", 0, { -1 }, .unique_name = "stream_side_data" },
     [SECTION_ID_SUBTITLE] =           { SECTION_ID_SUBTITLE, "subtitle", 0, { -1 } },
 };
 
@@ -272,6 +281,7 @@ static const OptionDef *options;
 static const char *input_filename;
 static const char *print_input_filename;
 static const AVInputFormat *iformat = NULL;
+static const char *output_filename = NULL;
 
 static struct AVHashContext *hash;
 
@@ -467,6 +477,12 @@ typedef struct Writer {
 struct WriterContext {
     const AVClass *class;           ///< class of the writer
     const Writer *writer;           ///< the Writer of which this is an instance
+    AVIOContext *avio;              ///< the I/O context used to write
+
+    void (* writer_w8)(WriterContext *wctx, int b);
+    void (* writer_put_str)(WriterContext *wctx, const char *str);
+    void (* writer_printf)(WriterContext *wctx, const char *fmt, ...);
+
     char *name;                     ///< name of this writer instance
     void *priv;                     ///< private data for use by the filter
 
@@ -529,12 +545,13 @@ static const AVClass writer_class = {
     .child_next = writer_child_next,
 };
 
-static void writer_close(WriterContext **wctx)
+static int writer_close(WriterContext **wctx)
 {
     int i;
+    int ret = 0;
 
     if (!*wctx)
-        return;
+        return -1;
 
     if ((*wctx)->writer->uninit)
         (*wctx)->writer->uninit(*wctx);
@@ -544,7 +561,12 @@ static void writer_close(WriterContext *
         av_opt_free((*wctx)->priv);
     av_freep(&((*wctx)->priv));
     av_opt_free(*wctx);
+    if ((*wctx)->avio) {
+        avio_flush((*wctx)->avio);
+        ret = avio_close((*wctx)->avio);
+    }
     av_freep(wctx);
+    return ret;
 }
 
 static void bprint_bytes(AVBPrint *bp, const uint8_t *ubuf, size_t ubuf_size)
@@ -555,9 +577,46 @@ static void bprint_bytes(AVBPrint *bp, c
         av_bprintf(bp, "%02X", ubuf[i]);
 }
 
+static inline void writer_w8_avio(WriterContext *wctx, int b)
+{
+    avio_w8(wctx->avio, b);
+}
+
+static inline void writer_put_str_avio(WriterContext *wctx, const char *str)
+{
+    avio_write(wctx->avio, str, strlen(str));
+}
+
+static inline void writer_printf_avio(WriterContext *wctx, const char *fmt, ...)
+{
+    va_list ap;
+
+    va_start(ap, fmt);
+    avio_vprintf(wctx->avio, fmt, ap);
+    va_end(ap);
+}
+
+static inline void writer_w8_printf(WriterContext *wctx, int b)
+{
+    printf("%c", b);
+}
+
+static inline void writer_put_str_printf(WriterContext *wctx, const char *str)
+{
+    printf("%s", str);
+}
+
+static inline void writer_printf_printf(WriterContext *wctx, const char *fmt, ...)
+{
+    va_list ap;
+
+    va_start(ap, fmt);
+    vprintf(fmt, ap);
+    va_end(ap);
+}
 
 static int writer_open(WriterContext **wctx, const Writer *writer, const char *args,
-                       const struct section *sections, int nb_sections)
+                       const struct section *sections, int nb_sections, const char *output)
 {
     int i, ret = 0;
 
@@ -628,6 +687,21 @@ static int writer_open(WriterContext **w
         }
     }
 
+    if (!output_filename) {
+        (*wctx)->writer_w8 = writer_w8_printf;
+        (*wctx)->writer_put_str = writer_put_str_printf;
+        (*wctx)->writer_printf = writer_printf_printf;
+    } else {
+        if ((ret = avio_open(&(*wctx)->avio, output, AVIO_FLAG_WRITE)) < 0) {
+            av_log(*wctx, AV_LOG_ERROR,
+                   "Failed to open output '%s' with error: %s\n", output, av_err2str(ret));
+            goto fail;
+        }
+        (*wctx)->writer_w8 = writer_w8_avio;
+        (*wctx)->writer_put_str = writer_put_str_avio;
+        (*wctx)->writer_printf = writer_printf_avio;
+    }
+
     for (i = 0; i < SECTION_MAX_NB_LEVELS; i++)
         av_bprint_init(&(*wctx)->section_pbuf[i], 1, AV_BPRINT_SIZE_UNLIMITED);
 
@@ -827,7 +901,7 @@ static void writer_print_ts(WriterContex
 }
 
 static void writer_print_data(WriterContext *wctx, const char *name,
-                              uint8_t *data, int size)
+                              const uint8_t *data, int size)
 {
     AVBPrint bp;
     int offset = 0, l, i;
@@ -855,7 +929,7 @@ static void writer_print_data(WriterCont
 }
 
 static void writer_print_data_hash(WriterContext *wctx, const char *name,
-                                   uint8_t *data, int size)
+                                   const uint8_t *data, int size)
 {
     char *p, buf[AV_HASH_MAX_SIZE * 2 + 64] = { 0 };
 
@@ -895,6 +969,10 @@ static void writer_print_integers(Writer
     av_bprint_finalize(&bp, NULL);
 }
 
+#define writer_w8(wctx_, b_) (wctx_)->writer_w8(wctx_, b_)
+#define writer_put_str(wctx_, str_) (wctx_)->writer_put_str(wctx_, str_)
+#define writer_printf(wctx_, fmt_, ...) (wctx_)->writer_printf(wctx_, fmt_, __VA_ARGS__)
+
 #define MAX_REGISTERED_WRITERS_NB 64
 
 static const Writer *registered_writers[MAX_REGISTERED_WRITERS_NB + 1];
@@ -989,7 +1067,7 @@ static void default_print_section_header
         return;
 
     if (!(section->flags & (SECTION_FLAG_IS_WRAPPER|SECTION_FLAG_IS_ARRAY)))
-        printf("[%s]\n", upcase_string(buf, sizeof(buf), section->name));
+        writer_printf(wctx, "[%s]\n", upcase_string(buf, sizeof(buf), section->name));
 }
 
 static void default_print_section_footer(WriterContext *wctx)
@@ -1002,7 +1080,7 @@ static void default_print_section_footer
         return;
 
     if (!(section->flags & (SECTION_FLAG_IS_WRAPPER|SECTION_FLAG_IS_ARRAY)))
-        printf("[/%s]\n", upcase_string(buf, sizeof(buf), section->name));
+        writer_printf(wctx, "[/%s]\n", upcase_string(buf, sizeof(buf), section->name));
 }
 
 static void default_print_str(WriterContext *wctx, const char *key, const char *value)
@@ -1010,8 +1088,8 @@ static void default_print_str(WriterCont
     DefaultContext *def = wctx->priv;
 
     if (!def->nokey)
-        printf("%s%s=", wctx->section_pbuf[wctx->level].str, key);
-    printf("%s\n", value);
+        writer_printf(wctx, "%s%s=", wctx->section_pbuf[wctx->level].str, key);
+    writer_printf(wctx, "%s\n", value);
 }
 
 static void default_print_int(WriterContext *wctx, const char *key, long long int value)
@@ -1019,8 +1097,8 @@ static void default_print_int(WriterCont
     DefaultContext *def = wctx->priv;
 
     if (!def->nokey)
-        printf("%s%s=", wctx->section_pbuf[wctx->level].str, key);
-    printf("%lld\n", value);
+        writer_printf(wctx, "%s%s=", wctx->section_pbuf[wctx->level].str, key);
+    writer_printf(wctx, "%lld\n", value);
 }
 
 static const Writer default_writer = {
@@ -1162,10 +1240,10 @@ static void compact_print_section_header
         }
         if (parent_section && !(parent_section->flags & (SECTION_FLAG_IS_WRAPPER|SECTION_FLAG_IS_ARRAY)) &&
             wctx->level && wctx->nb_item[wctx->level-1])
-            printf("%c", compact->item_sep);
+            writer_w8(wctx, compact->item_sep);
         if (compact->print_section &&
             !(section->flags & (SECTION_FLAG_IS_WRAPPER|SECTION_FLAG_IS_ARRAY)))
-            printf("%s%c", section->name, compact->item_sep);
+            writer_printf(wctx, "%s%c", section->name, compact->item_sep);
     }
 }
 
@@ -1176,7 +1254,7 @@ static void compact_print_section_footer
     if (!compact->nested_section[wctx->level] &&
         compact->terminate_line[wctx->level] &&
         !(wctx->section[wctx->level]->flags & (SECTION_FLAG_IS_WRAPPER|SECTION_FLAG_IS_ARRAY)))
-        printf("\n");
+        writer_w8(wctx, '\n');
 }
 
 static void compact_print_str(WriterContext *wctx, const char *key, const char *value)
@@ -1184,11 +1262,11 @@ static void compact_print_str(WriterCont
     CompactContext *compact = wctx->priv;
     AVBPrint buf;
 
-    if (wctx->nb_item[wctx->level]) printf("%c", compact->item_sep);
+    if (wctx->nb_item[wctx->level]) writer_w8(wctx, compact->item_sep);
     if (!compact->nokey)
-        printf("%s%s=", wctx->section_pbuf[wctx->level].str, key);
+        writer_printf(wctx, "%s%s=", wctx->section_pbuf[wctx->level].str, key);
     av_bprint_init(&buf, 1, AV_BPRINT_SIZE_UNLIMITED);
-    printf("%s", compact->escape_str(&buf, value, compact->item_sep, wctx));
+    writer_put_str(wctx, compact->escape_str(&buf, value, compact->item_sep, wctx));
     av_bprint_finalize(&buf, NULL);
 }
 
@@ -1196,10 +1274,10 @@ static void compact_print_int(WriterCont
 {
     CompactContext *compact = wctx->priv;
 
-    if (wctx->nb_item[wctx->level]) printf("%c", compact->item_sep);
+    if (wctx->nb_item[wctx->level]) writer_w8(wctx, compact->item_sep);
     if (!compact->nokey)
-        printf("%s%s=", wctx->section_pbuf[wctx->level].str, key);
-    printf("%lld", value);
+        writer_printf(wctx, "%s%s=", wctx->section_pbuf[wctx->level].str, key);
+    writer_printf(wctx, "%lld", value);
 }
 
 static const Writer compact_writer = {
@@ -1342,7 +1420,7 @@ static void flat_print_section_header(Wr
 
 static void flat_print_int(WriterContext *wctx, const char *key, long long int value)
 {
-    printf("%s%s=%lld\n", wctx->section_pbuf[wctx->level].str, key, value);
+    writer_printf(wctx, "%s%s=%lld\n", wctx->section_pbuf[wctx->level].str, key, value);
 }
 
 static void flat_print_str(WriterContext *wctx, const char *key, const char *value)
@@ -1350,11 +1428,11 @@ static void flat_print_str(WriterContext
     FlatContext *flat = wctx->priv;
     AVBPrint buf;
 
-    printf("%s", wctx->section_pbuf[wctx->level].str);
+    writer_put_str(wctx, wctx->section_pbuf[wctx->level].str);
     av_bprint_init(&buf, 1, AV_BPRINT_SIZE_UNLIMITED);
-    printf("%s=", flat_escape_key_str(&buf, key, flat->sep));
+    writer_printf(wctx, "%s=", flat_escape_key_str(&buf, key, flat->sep));
     av_bprint_clear(&buf);
-    printf("\"%s\"\n", flat_escape_value_str(&buf, value));
+    writer_printf(wctx, "\"%s\"\n", flat_escape_value_str(&buf, value));
     av_bprint_finalize(&buf, NULL);
 }
 
@@ -1424,12 +1502,12 @@ static void ini_print_section_header(Wri
 
     av_bprint_clear(buf);
     if (!parent_section) {
-        printf("# ffprobe output\n\n");
+        writer_put_str(wctx, "# ffprobe output\n\n");
         return;
     }
 
     if (wctx->nb_item[wctx->level-1])
-        printf("\n");
+        writer_w8(wctx, '\n');
 
     av_bprintf(buf, "%s", wctx->section_pbuf[wctx->level-1].str);
     if (ini->hierarchical ||
@@ -1444,7 +1522,7 @@ static void ini_print_section_header(Wri
     }
 
     if (!(section->flags & (SECTION_FLAG_IS_ARRAY|SECTION_FLAG_IS_WRAPPER)))
-        printf("[%s]\n", buf->str);
+        writer_printf(wctx, "[%s]\n", buf->str);
 }
 
 static void ini_print_str(WriterContext *wctx, const char *key, const char *value)
@@ -1452,15 +1530,15 @@ static void ini_print_str(WriterContext
     AVBPrint buf;
 
     av_bprint_init(&buf, 1, AV_BPRINT_SIZE_UNLIMITED);
-    printf("%s=", ini_escape_str(&buf, key));
+    writer_printf(wctx, "%s=", ini_escape_str(&buf, key));
     av_bprint_clear(&buf);
-    printf("%s\n", ini_escape_str(&buf, value));
+    writer_printf(wctx, "%s\n", ini_escape_str(&buf, value));
     av_bprint_finalize(&buf, NULL);
 }
 
 static void ini_print_int(WriterContext *wctx, const char *key, long long int value)
 {
-    printf("%s=%lld\n", key, value);
+    writer_printf(wctx, "%s=%lld\n", key, value);
 }
 
 static const Writer ini_writer = {
@@ -1523,7 +1601,7 @@ static const char *json_escape_str(AVBPr
     return dst->str;
 }
 
-#define JSON_INDENT() printf("%*c", json->indent_level * 4, ' ')
+#define JSON_INDENT() writer_printf(wctx, "%*c", json->indent_level * 4, ' ')
 
 static void json_print_section_header(WriterContext *wctx)
 {
@@ -1534,10 +1612,10 @@ static void json_print_section_header(Wr
         wctx->section[wctx->level-1] : NULL;
 
     if (wctx->level && wctx->nb_item[wctx->level-1])
-        printf(",\n");
+        writer_put_str(wctx, ",\n");
 
     if (section->flags & SECTION_FLAG_IS_WRAPPER) {
-        printf("{\n");
+        writer_put_str(wctx, "{\n");
         json->indent_level++;
     } else {
         av_bprint_init(&buf, 1, AV_BPRINT_SIZE_UNLIMITED);
@@ -1546,17 +1624,18 @@ static void json_print_section_header(Wr
 
         json->indent_level++;
         if (section->flags & SECTION_FLAG_IS_ARRAY) {
-            printf("\"%s\": [\n", buf.str);
+            writer_printf(wctx, "\"%s\": [\n", buf.str);
         } else if (parent_section && !(parent_section->flags & SECTION_FLAG_IS_ARRAY)) {
-            printf("\"%s\": {%s", buf.str, json->item_start_end);
+            writer_printf(wctx, "\"%s\": {%s", buf.str, json->item_start_end);
         } else {
-            printf("{%s", json->item_start_end);
+            writer_printf(wctx, "{%s", json->item_start_end);
 
             /* this is required so the parser can distinguish between packets and frames */
             if (parent_section && parent_section->id == SECTION_ID_PACKETS_AND_FRAMES) {
                 if (!json->compact)
                     JSON_INDENT();
-                printf("\"type\": \"%s\"", section->name);
+                writer_printf(wctx, "\"type\": \"%s\"", section->name);
+                wctx->nb_item[wctx->level]++;
             }
         }
         av_bprint_finalize(&buf, NULL);
@@ -1570,18 +1649,18 @@ static void json_print_section_footer(Wr
 
     if (wctx->level == 0) {
         json->indent_level--;
-        printf("\n}\n");
+        writer_put_str(wctx, "\n}\n");
     } else if (section->flags & SECTION_FLAG_IS_ARRAY) {
-        printf("\n");
+        writer_w8(wctx, '\n');
         json->indent_level--;
         JSON_INDENT();
-        printf("]");
+        writer_w8(wctx, ']');
     } else {
-        printf("%s", json->item_start_end);
+        writer_put_str(wctx, json->item_start_end);
         json->indent_level--;
         if (!json->compact)
             JSON_INDENT();
-        printf("}");
+        writer_w8(wctx, '}');
     }
 }
 
@@ -1591,9 +1670,9 @@ static inline void json_print_item_str(W
     AVBPrint buf;
 
     av_bprint_init(&buf, 1, AV_BPRINT_SIZE_UNLIMITED);
-    printf("\"%s\":", json_escape_str(&buf, key,   wctx));
+    writer_printf(wctx, "\"%s\":", json_escape_str(&buf, key,   wctx));
     av_bprint_clear(&buf);
-    printf(" \"%s\"", json_escape_str(&buf, value, wctx));
+    writer_printf(wctx, " \"%s\"", json_escape_str(&buf, value, wctx));
     av_bprint_finalize(&buf, NULL);
 }
 
@@ -1604,7 +1683,7 @@ static void json_print_str(WriterContext
         wctx->section[wctx->level-1] : NULL;
 
     if (wctx->nb_item[wctx->level] || (parent_section && parent_section->id == SECTION_ID_PACKETS_AND_FRAMES))
-        printf("%s", json->item_sep);
+        writer_put_str(wctx, json->item_sep);
     if (!json->compact)
         JSON_INDENT();
     json_print_item_str(wctx, key, value);
@@ -1618,12 +1697,12 @@ static void json_print_int(WriterContext
     AVBPrint buf;
 
     if (wctx->nb_item[wctx->level] || (parent_section && parent_section->id == SECTION_ID_PACKETS_AND_FRAMES))
-        printf("%s", json->item_sep);
+        writer_put_str(wctx, json->item_sep);
     if (!json->compact)
         JSON_INDENT();
 
     av_bprint_init(&buf, 1, AV_BPRINT_SIZE_UNLIMITED);
-    printf("\"%s\": %lld", json_escape_str(&buf, key, wctx), value);
+    writer_printf(wctx, "\"%s\": %lld", json_escape_str(&buf, key, wctx), value);
     av_bprint_finalize(&buf, NULL);
 }
 
@@ -1683,7 +1762,7 @@ static av_cold int xml_init(WriterContex
     return 0;
 }
 
-#define XML_INDENT() printf("%*c", xml->indent_level * 4, ' ')
+#define XML_INDENT() writer_printf(wctx, "%*c", xml->indent_level * 4, ' ')
 
 static void xml_print_section_header(WriterContext *wctx)
 {
@@ -1697,8 +1776,8 @@ static void xml_print_section_header(Wri
             "xmlns:ffprobe=\"http://www.ffmpeg.org/schema/ffprobe\" "
             "xsi:schemaLocation=\"http://www.ffmpeg.org/schema/ffprobe ffprobe.xsd\"";
 
-        printf("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
-        printf("<%sffprobe%s>\n",
+        writer_put_str(wctx, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
+        writer_printf(wctx, "<%sffprobe%s>\n",
                xml->fully_qualified ? "ffprobe:" : "",
                xml->fully_qualified ? qual : "");
         return;
@@ -1706,20 +1785,20 @@ static void xml_print_section_header(Wri
 
     if (xml->within_tag) {
         xml->within_tag = 0;
-        printf(">\n");
+        writer_put_str(wctx, ">\n");
     }
     if (section->flags & SECTION_FLAG_HAS_VARIABLE_FIELDS) {
         xml->indent_level++;
     } else {
         if (parent_section && (parent_section->flags & SECTION_FLAG_IS_WRAPPER) &&
             wctx->level && wctx->nb_item[wctx->level-1])
-            printf("\n");
+            writer_w8(wctx, '\n');
         xml->indent_level++;
 
         if (section->flags & SECTION_FLAG_IS_ARRAY) {
-            XML_INDENT(); printf("<%s>\n", section->name);
+            XML_INDENT(); writer_printf(wctx, "<%s>\n", section->name);
         } else {
-            XML_INDENT(); printf("<%s ", section->name);
+            XML_INDENT(); writer_printf(wctx, "<%s ", section->name);
             xml->within_tag = 1;
         }
     }
@@ -1731,15 +1810,15 @@ static void xml_print_section_footer(Wri
     const struct section *section = wctx->section[wctx->level];
 
     if (wctx->level == 0) {
-        printf("</%sffprobe>\n", xml->fully_qualified ? "ffprobe:" : "");
+        writer_printf(wctx, "</%sffprobe>\n", xml->fully_qualified ? "ffprobe:" : "");
     } else if (xml->within_tag) {
         xml->within_tag = 0;
-        printf("/>\n");
+        writer_put_str(wctx, "/>\n");
         xml->indent_level--;
     } else if (section->flags & SECTION_FLAG_HAS_VARIABLE_FIELDS) {
         xml->indent_level--;
     } else {
-        XML_INDENT(); printf("</%s>\n", section->name);
+        XML_INDENT(); writer_printf(wctx, "</%s>\n", section->name);
         xml->indent_level--;
     }
 }
@@ -1756,20 +1835,20 @@ static void xml_print_str(WriterContext
         XML_INDENT();
         av_bprint_escape(&buf, key, NULL,
                          AV_ESCAPE_MODE_XML, AV_ESCAPE_FLAG_XML_DOUBLE_QUOTES);
-        printf("<%s key=\"%s\"",
-               section->element_name, buf.str);
+        writer_printf(wctx, "<%s key=\"%s\"",
+                      section->element_name, buf.str);
         av_bprint_clear(&buf);
 
         av_bprint_escape(&buf, value, NULL,
                          AV_ESCAPE_MODE_XML, AV_ESCAPE_FLAG_XML_DOUBLE_QUOTES);
-        printf(" value=\"%s\"/>\n", buf.str);
+        writer_printf(wctx, " value=\"%s\"/>\n", buf.str);
     } else {
         if (wctx->nb_item[wctx->level])
-            printf(" ");
+            writer_w8(wctx, ' ');
 
         av_bprint_escape(&buf, value, NULL,
                          AV_ESCAPE_MODE_XML, AV_ESCAPE_FLAG_XML_DOUBLE_QUOTES);
-        printf("%s=\"%s\"", key, buf.str);
+        writer_printf(wctx, "%s=\"%s\"", key, buf.str);
     }
 
     av_bprint_finalize(&buf, NULL);
@@ -1778,8 +1857,8 @@ static void xml_print_str(WriterContext
 static void xml_print_int(WriterContext *wctx, const char *key, long long int value)
 {
     if (wctx->nb_item[wctx->level])
-        printf(" ");
-    printf("%s=\"%lld\"", key, value);
+        writer_w8(wctx, ' ');
+    writer_printf(wctx, "%s=\"%lld\"", key, value);
 }
 
 static Writer xml_writer = {
@@ -2118,6 +2197,74 @@ static void print_dynamic_hdr10_plus(Wri
     }
 }
 
+static void print_dynamic_hdr_vivid(WriterContext *w, const AVDynamicHDRVivid *metadata)
+{
+    if (!metadata)
+        return;
+    print_int("system_start_code", metadata->system_start_code);
+    print_int("num_windows", metadata->num_windows);
+
+    for (int n = 0; n < metadata->num_windows; n++) {
+        const AVHDRVividColorTransformParams *params = &metadata->params[n];
+
+        print_q("minimum_maxrgb", params->minimum_maxrgb, '/');
+        print_q("average_maxrgb", params->average_maxrgb, '/');
+        print_q("variance_maxrgb", params->variance_maxrgb, '/');
+        print_q("maximum_maxrgb", params->maximum_maxrgb, '/');
+    }
+
+    for (int n = 0; n < metadata->num_windows; n++) {
+        const AVHDRVividColorTransformParams *params = &metadata->params[n];
+
+        print_int("tone_mapping_mode_flag", params->tone_mapping_mode_flag);
+        print_int("tone_mapping_param_num", params->tone_mapping_param_num);
+        if (params->tone_mapping_mode_flag) {
+            for (int i = 0; i < params->tone_mapping_param_num; i++) {
+                const AVHDRVividColorToneMappingParams *tm_params = &params->tm_params[i];
+
+                print_q("targeted_system_display_maximum_luminance",
+                        tm_params->targeted_system_display_maximum_luminance, '/');
+                print_int("base_enable_flag", tm_params->base_enable_flag);
+                if (tm_params->base_enable_flag) {
+                    print_q("base_param_m_p", tm_params->base_param_m_p, '/');
+                    print_q("base_param_m_m", tm_params->base_param_m_m, '/');
+                    print_q("base_param_m_a", tm_params->base_param_m_a, '/');
+                    print_q("base_param_m_b", tm_params->base_param_m_b, '/');
+                    print_q("base_param_m_n", tm_params->base_param_m_n, '/');
+
+                    print_int("base_param_k1", tm_params->base_param_k1);
+                    print_int("base_param_k2", tm_params->base_param_k2);
+                    print_int("base_param_k3", tm_params->base_param_k3);
+                    print_int("base_param_Delta_enable_mode",
+                              tm_params->base_param_Delta_enable_mode);
+                    print_q("base_param_Delta", tm_params->base_param_Delta, '/');
+                }
+                print_int("3Spline_enable_flag", tm_params->three_Spline_enable_flag);
+                if (tm_params->three_Spline_enable_flag) {
+                    print_int("3Spline_num", tm_params->three_Spline_num);
+                    print_int("3Spline_TH_mode", tm_params->three_Spline_TH_mode);
+
+                    for (int j = 0; j < tm_params->three_Spline_num; j++) {
+                        print_q("3Spline_TH_enable_MB", tm_params->three_Spline_TH_enable_MB, '/');
+                        print_q("3Spline_TH_enable", tm_params->three_Spline_TH_enable, '/');
+                        print_q("3Spline_TH_Delta1", tm_params->three_Spline_TH_Delta1, '/');
+                        print_q("3Spline_TH_Delta2", tm_params->three_Spline_TH_Delta2, '/');
+                        print_q("3Spline_enable_Strength", tm_params->three_Spline_enable_Strength, '/');
+                    }
+                }
+            }
+        }
+
+        print_int("color_saturation_mapping_flag", params->color_saturation_mapping_flag);
+        if (params->color_saturation_mapping_flag) {
+            print_int("color_saturation_num", params->color_saturation_num);
+            for (int i = 0; i < params->color_saturation_num; i++) {
+                print_q("color_saturation_gain", params->color_saturation_gain[i], '/');
+            }
+        }
+    }
+}
+
 static void print_pkt_side_data(WriterContext *w,
                                 AVCodecParameters *par,
                                 const AVPacketSideData *side_data,
@@ -2214,6 +2361,8 @@ static void print_pkt_side_data(WriterCo
             if (do_show_data)
                 writer_print_data(w, "data", sd->data, sd->size);
             writer_print_data_hash(w, "data_hash", sd->data, sd->size);
+        } else if (sd->type == AV_PKT_DATA_AFD && sd->size > 0) {
+            print_int("active_format", *sd->data);
         }
         writer_print_section_footer(w);
     }
@@ -2462,12 +2611,10 @@ static void show_frame(WriterContext *w,
         if (s) print_str    ("sample_fmt", s);
         else   print_str_opt("sample_fmt", "unknown");
         print_int("nb_samples",         frame->nb_samples);
-        print_int("channels", frame->channels);
-        if (frame->channel_layout) {
-            av_bprint_clear(&pbuf);
-            av_bprint_channel_layout(&pbuf, frame->channels,
-                                     frame->channel_layout);
-            print_str    ("channel_layout", pbuf.str);
+        print_int("channels", frame->ch_layout.nb_channels);
+        if (frame->ch_layout.order != AV_CHANNEL_ORDER_UNSPEC) {
+            av_channel_layout_describe(&frame->ch_layout, val_str, sizeof(val_str));
+            print_str    ("channel_layout", val_str);
         } else
             print_str_opt("channel_layout", "unknown");
         break;
@@ -2488,6 +2635,8 @@ static void show_frame(WriterContext *w,
             if (sd->type == AV_FRAME_DATA_DISPLAYMATRIX && sd->size >= 9*4) {
                 writer_print_integers(w, "displaymatrix", sd->data, 9, " %11d", 3, 4, 1);
                 print_int("rotation", av_display_rotation_get((int32_t *)sd->data));
+            } else if (sd->type == AV_FRAME_DATA_AFD && sd->size > 0) {
+                print_int("active_format", *sd->data);
             } else if (sd->type == AV_FRAME_DATA_GOP_TIMECODE && sd->size >= 8) {
                 char tcbuf[AV_TIMECODE_STR_SIZE];
                 av_timecode_make_mpeg_tc_string(tcbuf, *(int64_t *)(sd->data));
@@ -2537,6 +2686,9 @@ static void show_frame(WriterContext *w,
                 print_int("size", sd->size);
             } else if (sd->type == AV_FRAME_DATA_DOVI_METADATA) {
                 print_dovi_metadata(w, (const AVDOVIMetadata *)sd->data);
+            } else if (sd->type == AV_FRAME_DATA_DYNAMIC_HDR_VIVID) {
+                AVDynamicHDRVivid *metadata = (AVDynamicHDRVivid *)sd->data;
+                print_dynamic_hdr_vivid(w, metadata);
             }
             writer_print_section_footer(w);
         }
@@ -2561,7 +2713,7 @@ static av_always_inline int process_fram
     int ret = 0, got_frame = 0;
 
     clear_log(1);
-    if (dec_ctx && dec_ctx->codec) {
+    if (dec_ctx) {
         switch (par->codec_type) {
         case AVMEDIA_TYPE_VIDEO:
         case AVMEDIA_TYPE_AUDIO:
@@ -2730,8 +2882,11 @@ static int read_interval_packets(WriterC
     //Flush remaining frames that are cached in the decoder
     for (i = 0; i < fmt_ctx->nb_streams; i++) {
         pkt->stream_index = i;
-        if (do_read_frames)
+        if (do_read_frames) {
             while (process_frame(w, ifile, frame, pkt, &(int){1}) > 0);
+            if (ifile->streams[i].dec_ctx)
+                avcodec_flush_buffers(ifile->streams[i].dec_ctx);
+        }
     }
 
 end:
@@ -2873,12 +3028,11 @@ static int show_stream(WriterContext *w,
         if (s) print_str    ("sample_fmt", s);
         else   print_str_opt("sample_fmt", "unknown");
         print_val("sample_rate",     par->sample_rate, unit_hertz_str);
-        print_int("channels",        par->channels);
+        print_int("channels",        par->ch_layout.nb_channels);
 
-        if (par->channel_layout) {
-            av_bprint_clear(&pbuf);
-            av_bprint_channel_layout(&pbuf, par->channels, par->channel_layout);
-            print_str    ("channel_layout", pbuf.str);
+        if (par->ch_layout.order != AV_CHANNEL_ORDER_UNSPEC) {
+            av_channel_layout_describe(&par->ch_layout, val_str, sizeof(val_str));
+            print_str    ("channel_layout", val_str);
         } else {
             print_str_opt("channel_layout", "unknown");
         }
@@ -2898,7 +3052,7 @@ static int show_stream(WriterContext *w,
         break;
     }
 
-    if (dec_ctx && dec_ctx->codec && dec_ctx->codec->priv_class && show_private_data) {
+    if (dec_ctx && dec_ctx->codec->priv_class && show_private_data) {
         const AVOption *opt = NULL;
         while (opt = av_opt_next(dec_ctx->priv_data,opt)) {
             uint8_t *str;
@@ -3337,7 +3491,7 @@ end:
 static void show_usage(void)
 {
     av_log(NULL, AV_LOG_INFO, "Simple multimedia streams analyzer\n");
-    av_log(NULL, AV_LOG_INFO, "usage: %s [OPTIONS] [INPUT_FILE]\n", program_name);
+    av_log(NULL, AV_LOG_INFO, "usage: %s [OPTIONS] INPUT_FILE\n", program_name);
     av_log(NULL, AV_LOG_INFO, "\n");
 }
 
@@ -3542,22 +3696,6 @@ static int opt_show_entries(void *optctx
     return ret;
 }
 
-static int opt_show_format_entry(void *optctx, const char *opt, const char *arg)
-{
-    char *buf = av_asprintf("format=%s", arg);
-    int ret;
-
-    if (!buf)
-        return AVERROR(ENOMEM);
-
-    av_log(NULL, AV_LOG_WARNING,
-           "Option '%s' is deprecated, use '-show_entries format=%s' instead\n",
-           opt, arg);
-    ret = opt_show_entries(optctx, opt, buf);
-    av_free(buf);
-    return ret;
-}
-
 static void opt_input_file(void *optctx, const char *arg)
 {
     if (input_filename) {
@@ -3577,6 +3715,25 @@ static int opt_input_file_i(void *optctx
     return 0;
 }
 
+static void opt_output_file(void *optctx, const char *arg)
+{
+    if (output_filename) {
+        av_log(NULL, AV_LOG_ERROR,
+                "Argument '%s' provided as output filename, but '%s' was already specified.\n",
+                arg, output_filename);
+        exit_program(1);
+    }
+    if (!strcmp(arg, "-"))
+        arg = "pipe:";
+    output_filename = arg;
+}
+
+static int opt_output_file_o(void *optctx, const char *opt, const char *arg)
+{
+    opt_output_file(optctx, arg);
+    return 0;
+}
+
 static int opt_print_filename(void *optctx, const char *opt, const char *arg)
 {
     print_input_filename = arg;
@@ -3818,8 +3975,6 @@ static const OptionDef real_options[] =
     { "show_error",   0, { .func_arg = &opt_show_error },  "show probing error" },
     { "show_format",  0, { .func_arg = &opt_show_format }, "show format/container info" },
     { "show_frames",  0, { .func_arg = &opt_show_frames }, "show frames info" },
-    { "show_format_entry", HAS_ARG, {.func_arg = opt_show_format_entry},
-      "show a particular entry from the format/container info", "entry" },
     { "show_entries", HAS_ARG, {.func_arg = opt_show_entries},
       "show a set of specified entries", "entry_list" },
 #if HAVE_THREADS
@@ -3840,8 +3995,8 @@ static const OptionDef real_options[] =
     { "private",           OPT_BOOL, { &show_private_data }, "same as show_private_data" },
     { "bitexact", OPT_BOOL, {&do_bitexact}, "force bitexact output" },
     { "read_intervals", HAS_ARG, {.func_arg = opt_read_intervals}, "set read intervals", "read_intervals" },
-    { "default", HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, {.func_arg = opt_default}, "generic catch all option", "" },
     { "i", HAS_ARG, {.func_arg = opt_input_file_i}, "read specified file", "input_file"},
+    { "o", HAS_ARG, {.func_arg = opt_output_file_o}, "write to specified output", "output_file"},
     { "print_filename", HAS_ARG, {.func_arg = opt_print_filename}, "override the printed input filename", "print_file"},
     { "find_stream_info", OPT_BOOL | OPT_INPUT | OPT_EXPERT, { &find_stream_info },
         "read and decode the streams to fill missing information with heuristics" },
@@ -3969,7 +4124,7 @@ int main(int argc, char **argv)
     }
 
     if ((ret = writer_open(&wctx, w, w_args,
-                           sections, FF_ARRAY_ELEMS(sections))) >= 0) {
+                           sections, FF_ARRAY_ELEMS(sections), output_filename)) >= 0) {
         if (w == &xml_writer)
             wctx->string_validation_utf8_flags |= AV_UTF8_FLAG_EXCLUDE_XML_INVALID_CONTROL_CODES;
 
@@ -3996,7 +4151,9 @@ int main(int argc, char **argv)
         }
 
         writer_print_section_footer(wctx);
-        writer_close(&wctx);
+        ret = writer_close(&wctx);
+        if (ret < 0)
+            av_log(NULL, AV_LOG_ERROR, "Writing output failed: %s\n", av_err2str(ret));
     }
 
 end:
diff -pruN 7:5.0.1-3/fftools/fopen_utf8.h 7:5.1-1/fftools/fopen_utf8.h
--- 7:5.0.1-3/fftools/fopen_utf8.h	1970-01-01 00:00:00.000000000 +0000
+++ 7:5.1-1/fftools/fopen_utf8.h	2022-07-22 17:58:38.000000000 +0000
@@ -0,0 +1,71 @@
+/*
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef FFTOOLS_FOPEN_UTF8_H
+#define FFTOOLS_FOPEN_UTF8_H
+
+#include <stdio.h>
+
+/* The fopen_utf8 function here is essentially equivalent to avpriv_fopen_utf8,
+ * except that it doesn't set O_CLOEXEC, and that it isn't exported
+ * from a different library. (On Windows, each DLL might use a different
+ * CRT, and FILE* handles can't be shared across them.) */
+
+#ifdef _WIN32
+#include "libavutil/wchar_filename.h"
+
+static inline FILE *fopen_utf8(const char *path_utf8, const char *mode)
+{
+    wchar_t *path_w, *mode_w;
+    FILE *f;
+
+    /* convert UTF-8 to wide chars */
+    if (get_extended_win32_path(path_utf8, &path_w)) /* This sets errno on error. */
+        return NULL;
+    if (!path_w)
+        goto fallback;
+
+    if (utf8towchar(mode, &mode_w))
+        return NULL;
+    if (!mode_w) {
+        /* If failing to interpret the mode string as utf8, it is an invalid
+         * parameter. */
+        av_freep(&path_w);
+        errno = EINVAL;
+        return NULL;
+    }
+
+    f = _wfopen(path_w, mode_w);
+    av_freep(&path_w);
+    av_freep(&mode_w);
+
+    return f;
+fallback:
+    /* path may be in CP_ACP */
+    return fopen(path_utf8, mode);
+}
+
+#else
+
+static inline FILE *fopen_utf8(const char *path, const char *mode)
+{
+    return fopen(path, mode);
+}
+#endif
+
+#endif /* FFTOOLS_FOPEN_UTF8_H */
diff -pruN 7:5.0.1-3/fftools/Makefile 7:5.1-1/fftools/Makefile
--- 7:5.0.1-3/fftools/Makefile	2022-01-14 18:45:39.000000000 +0000
+++ 7:5.1-1/fftools/Makefile	2022-07-22 17:58:38.000000000 +0000
@@ -9,10 +9,14 @@ AVBASENAMES  = ffmpeg ffplay ffprobe
 ALLAVPROGS   = $(AVBASENAMES:%=%$(PROGSSUF)$(EXESUF))
 ALLAVPROGS_G = $(AVBASENAMES:%=%$(PROGSSUF)_g$(EXESUF))
 
-OBJS-ffmpeg                        += fftools/ffmpeg_opt.o fftools/ffmpeg_filter.o fftools/ffmpeg_hw.o
+OBJS-ffmpeg +=                  \
+    fftools/ffmpeg_filter.o     \
+    fftools/ffmpeg_hw.o         \
+    fftools/ffmpeg_mux.o        \
+    fftools/ffmpeg_opt.o        \
 
 define DOFFTOOL
-OBJS-$(1) += fftools/cmdutils.o fftools/$(1).o $(OBJS-$(1)-yes)
+OBJS-$(1) += fftools/cmdutils.o fftools/opt_common.o fftools/$(1).o $(OBJS-$(1)-yes)
 $(1)$(PROGSSUF)_g$(EXESUF): $$(OBJS-$(1))
 $$(OBJS-$(1)): | fftools
 $$(OBJS-$(1)): CFLAGS  += $(CFLAGS-$(1))
diff -pruN 7:5.0.1-3/fftools/opt_common.c 7:5.1-1/fftools/opt_common.c
--- 7:5.0.1-3/fftools/opt_common.c	1970-01-01 00:00:00.000000000 +0000
+++ 7:5.1-1/fftools/opt_common.c	2022-07-22 17:58:38.000000000 +0000
@@ -0,0 +1,1465 @@
+/*
+ * Option handlers shared between the tools.
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+
+#include "cmdutils.h"
+#include "opt_common.h"
+
+#include "libavutil/avassert.h"
+#include "libavutil/avstring.h"
+#include "libavutil/bprint.h"
+#include "libavutil/channel_layout.h"
+#include "libavutil/cpu.h"
+#include "libavutil/dict.h"
+#include "libavutil/error.h"
+#include "libavutil/ffversion.h"
+#include "libavutil/log.h"
+#include "libavutil/mem.h"
+#include "libavutil/parseutils.h"
+#include "libavutil/pixdesc.h"
+#include "libavutil/version.h"
+
+#include "libavcodec/avcodec.h"
+#include "libavcodec/bsf.h"
+#include "libavcodec/codec.h"
+#include "libavcodec/codec_desc.h"
+#include "libavcodec/version.h"
+
+#include "libavformat/avformat.h"
+#include "libavformat/version.h"
+
+#include "libavdevice/avdevice.h"
+#include "libavdevice/version.h"
+
+#include "libavfilter/avfilter.h"
+#include "libavfilter/version.h"
+
+#include "libswscale/swscale.h"
+#include "libswscale/version.h"
+
+#include "libswresample/swresample.h"
+#include "libswresample/version.h"
+
+#include "libpostproc/postprocess.h"
+#include "libpostproc/version.h"
+
+enum show_muxdemuxers {
+    SHOW_DEFAULT,
+    SHOW_DEMUXERS,
+    SHOW_MUXERS,
+};
+
+static FILE *report_file;
+static int report_file_level = AV_LOG_DEBUG;
+
+int show_license(void *optctx, const char *opt, const char *arg)
+{
+#if CONFIG_NONFREE
+    printf(
+    "This version of %s has nonfree parts compiled in.\n"
+    "Therefore it is not legally redistributable.\n",
+    program_name );
+#elif CONFIG_GPLV3
+    printf(
+    "%s is free software; you can redistribute it and/or modify\n"
+    "it under the terms of the GNU General Public License as published by\n"
+    "the Free Software Foundation; either version 3 of the License, or\n"
+    "(at your option) any later version.\n"
+    "\n"
+    "%s is distributed in the hope that it will be useful,\n"
+    "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+    "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
+    "GNU General Public License for more details.\n"
+    "\n"
+    "You should have received a copy of the GNU General Public License\n"
+    "along with %s.  If not, see <http://www.gnu.org/licenses/>.\n",
+    program_name, program_name, program_name );
+#elif CONFIG_GPL
+    printf(
+    "%s is free software; you can redistribute it and/or modify\n"
+    "it under the terms of the GNU General Public License as published by\n"
+    "the Free Software Foundation; either version 2 of the License, or\n"
+    "(at your option) any later version.\n"
+    "\n"
+    "%s is distributed in the hope that it will be useful,\n"
+    "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+    "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
+    "GNU General Public License for more details.\n"
+    "\n"
+    "You should have received a copy of the GNU General Public License\n"
+    "along with %s; if not, write to the Free Software\n"
+    "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n",
+    program_name, program_name, program_name );
+#elif CONFIG_LGPLV3
+    printf(
+    "%s is free software; you can redistribute it and/or modify\n"
+    "it under the terms of the GNU Lesser General Public License as published by\n"
+    "the Free Software Foundation; either version 3 of the License, or\n"
+    "(at your option) any later version.\n"
+    "\n"
+    "%s is distributed in the hope that it will be useful,\n"
+    "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+    "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
+    "GNU Lesser General Public License for more details.\n"
+    "\n"
+    "You should have received a copy of the GNU Lesser General Public License\n"
+    "along with %s.  If not, see <http://www.gnu.org/licenses/>.\n",
+    program_name, program_name, program_name );
+#else
+    printf(
+    "%s is free software; you can redistribute it and/or\n"
+    "modify it under the terms of the GNU Lesser General Public\n"
+    "License as published by the Free Software Foundation; either\n"
+    "version 2.1 of the License, or (at your option) any later version.\n"
+    "\n"
+    "%s is distributed in the hope that it will be useful,\n"
+    "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+    "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n"
+    "Lesser General Public License for more details.\n"
+    "\n"
+    "You should have received a copy of the GNU Lesser General Public\n"
+    "License along with %s; if not, write to the Free Software\n"
+    "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n",
+    program_name, program_name, program_name );
+#endif
+
+    return 0;
+}
+
+static int warned_cfg = 0;
+
+#define INDENT        1
+#define SHOW_VERSION  2
+#define SHOW_CONFIG   4
+#define SHOW_COPYRIGHT 8
+
+#define PRINT_LIB_INFO(libname, LIBNAME, flags, level)                  \
+    if (CONFIG_##LIBNAME) {                                             \
+        const char *indent = flags & INDENT? "  " : "";                 \
+        if (flags & SHOW_VERSION) {                                     \
+            unsigned int version = libname##_version();                 \
+            av_log(NULL, level,                                         \
+                   "%slib%-11s %2d.%3d.%3d / %2d.%3d.%3d\n",            \
+                   indent, #libname,                                    \
+                   LIB##LIBNAME##_VERSION_MAJOR,                        \
+                   LIB##LIBNAME##_VERSION_MINOR,                        \
+                   LIB##LIBNAME##_VERSION_MICRO,                        \
+                   AV_VERSION_MAJOR(version), AV_VERSION_MINOR(version),\
+                   AV_VERSION_MICRO(version));                          \
+        }                                                               \
+        if (flags & SHOW_CONFIG) {                                      \
+            const char *cfg = libname##_configuration();                \
+            if (strcmp(FFMPEG_CONFIGURATION, cfg)) {                    \
+                if (!warned_cfg) {                                      \
+                    av_log(NULL, level,                                 \
+                            "%sWARNING: library configuration mismatch\n", \
+                            indent);                                    \
+                    warned_cfg = 1;                                     \
+                }                                                       \
+                av_log(NULL, level, "%s%-11s configuration: %s\n",      \
+                        indent, #libname, cfg);                         \
+            }                                                           \
+        }                                                               \
+    }                                                                   \
+
+static void print_all_libs_info(int flags, int level)
+{
+    PRINT_LIB_INFO(avutil,     AVUTIL,     flags, level);
+    PRINT_LIB_INFO(avcodec,    AVCODEC,    flags, level);
+    PRINT_LIB_INFO(avformat,   AVFORMAT,   flags, level);
+    PRINT_LIB_INFO(avdevice,   AVDEVICE,   flags, level);
+    PRINT_LIB_INFO(avfilter,   AVFILTER,   flags, level);
+    PRINT_LIB_INFO(swscale,    SWSCALE,    flags, level);
+    PRINT_LIB_INFO(swresample, SWRESAMPLE, flags, level);
+    PRINT_LIB_INFO(postproc,   POSTPROC,   flags, level);
+}
+
+static void print_program_info(int flags, int level)
+{
+    const char *indent = flags & INDENT? "  " : "";
+
+    av_log(NULL, level, "%s version " FFMPEG_VERSION, program_name);
+    if (flags & SHOW_COPYRIGHT)
+        av_log(NULL, level, " Copyright (c) %d-%d the FFmpeg developers",
+               program_birth_year, CONFIG_THIS_YEAR);
+    av_log(NULL, level, "\n");
+    av_log(NULL, level, "%sbuilt with %s\n", indent, CC_IDENT);
+
+    av_log(NULL, level, "%sconfiguration: " FFMPEG_CONFIGURATION "\n", indent);
+}
+
+static void print_buildconf(int flags, int level)
+{
+    const char *indent = flags & INDENT ? "  " : "";
+    char str[] = { FFMPEG_CONFIGURATION };
+    char *conflist, *remove_tilde, *splitconf;
+
+    // Change all the ' --' strings to '~--' so that
+    // they can be identified as tokens.
+    while ((conflist = strstr(str, " --")) != NULL) {
+        conflist[0] = '~';
+    }
+
+    // Compensate for the weirdness this would cause
+    // when passing 'pkg-config --static'.
+    while ((remove_tilde = strstr(str, "pkg-config~")) != NULL) {
+        remove_tilde[sizeof("pkg-config~") - 2] = ' ';
+    }
+
+    splitconf = strtok(str, "~");
+    av_log(NULL, level, "\n%sconfiguration:\n", indent);
+    while (splitconf != NULL) {
+        av_log(NULL, level, "%s%s%s\n", indent, indent, splitconf);
+        splitconf = strtok(NULL, "~");
+    }
+}
+
+void show_banner(int argc, char **argv, const OptionDef *options)
+{
+    int idx = locate_option(argc, argv, options, "version");
+    if (hide_banner || idx)
+        return;
+
+    print_program_info (INDENT|SHOW_COPYRIGHT, AV_LOG_INFO);
+    print_all_libs_info(INDENT|SHOW_CONFIG,  AV_LOG_INFO);
+    print_all_libs_info(INDENT|SHOW_VERSION, AV_LOG_INFO);
+}
+
+int show_version(void *optctx, const char *opt, const char *arg)
+{
+    av_log_set_callback(log_callback_help);
+    print_program_info (SHOW_COPYRIGHT, AV_LOG_INFO);
+    print_all_libs_info(SHOW_VERSION, AV_LOG_INFO);
+
+    return 0;
+}
+
+int show_buildconf(void *optctx, const char *opt, const char *arg)
+{
+    av_log_set_callback(log_callback_help);
+    print_buildconf      (INDENT|0, AV_LOG_INFO);
+
+    return 0;
+}
+
+#define PRINT_CODEC_SUPPORTED(codec, field, type, list_name, term, get_name) \
+    if (codec->field) {                                                      \
+        const type *p = codec->field;                                        \
+                                                                             \
+        printf("    Supported " list_name ":");                              \
+        while (*p != term) {                                                 \
+            get_name(*p);                                                    \
+            printf(" %s", name);                                             \
+            p++;                                                             \
+        }                                                                    \
+        printf("\n");                                                        \
+    }                                                                        \
+
+static void print_codec(const AVCodec *c)
+{
+    int encoder = av_codec_is_encoder(c);
+
+    printf("%s %s [%s]:\n", encoder ? "Encoder" : "Decoder", c->name,
+           c->long_name ? c->long_name : "");
+
+    printf("    General capabilities: ");
+    if (c->capabilities & AV_CODEC_CAP_DRAW_HORIZ_BAND)
+        printf("horizband ");
+    if (c->capabilities & AV_CODEC_CAP_DR1)
+        printf("dr1 ");
+    if (c->capabilities & AV_CODEC_CAP_DELAY)
+        printf("delay ");
+    if (c->capabilities & AV_CODEC_CAP_SMALL_LAST_FRAME)
+        printf("small ");
+    if (c->capabilities & AV_CODEC_CAP_SUBFRAMES)
+        printf("subframes ");
+    if (c->capabilities & AV_CODEC_CAP_EXPERIMENTAL)
+        printf("exp ");
+    if (c->capabilities & AV_CODEC_CAP_CHANNEL_CONF)
+        printf("chconf ");
+    if (c->capabilities & AV_CODEC_CAP_PARAM_CHANGE)
+        printf("paramchange ");
+    if (c->capabilities & AV_CODEC_CAP_VARIABLE_FRAME_SIZE)
+        printf("variable ");
+    if (c->capabilities & (AV_CODEC_CAP_FRAME_THREADS |
+                           AV_CODEC_CAP_SLICE_THREADS |
+                           AV_CODEC_CAP_OTHER_THREADS))
+        printf("threads ");
+    if (c->capabilities & AV_CODEC_CAP_AVOID_PROBING)
+        printf("avoidprobe ");
+    if (c->capabilities & AV_CODEC_CAP_HARDWARE)
+        printf("hardware ");
+    if (c->capabilities & AV_CODEC_CAP_HYBRID)
+        printf("hybrid ");
+    if (!c->capabilities)
+        printf("none");
+    printf("\n");
+
+    if (c->type == AVMEDIA_TYPE_VIDEO ||
+        c->type == AVMEDIA_TYPE_AUDIO) {
+        printf("    Threading capabilities: ");
+        switch (c->capabilities & (AV_CODEC_CAP_FRAME_THREADS |
+                                   AV_CODEC_CAP_SLICE_THREADS |
+                                   AV_CODEC_CAP_OTHER_THREADS)) {
+        case AV_CODEC_CAP_FRAME_THREADS |
+             AV_CODEC_CAP_SLICE_THREADS: printf("frame and slice"); break;
+        case AV_CODEC_CAP_FRAME_THREADS: printf("frame");           break;
+        case AV_CODEC_CAP_SLICE_THREADS: printf("slice");           break;
+        case AV_CODEC_CAP_OTHER_THREADS: printf("other");           break;
+        default:                         printf("none");            break;
+        }
+        printf("\n");
+    }
+
+    if (avcodec_get_hw_config(c, 0)) {
+        printf("    Supported hardware devices: ");
+        for (int i = 0;; i++) {
+            const AVCodecHWConfig *config = avcodec_get_hw_config(c, i);
+            if (!config)
+                break;
+            printf("%s ", av_hwdevice_get_type_name(config->device_type));
+        }
+        printf("\n");
+    }
+
+    if (c->supported_framerates) {
+        const AVRational *fps = c->supported_framerates;
+
+        printf("    Supported framerates:");
+        while (fps->num) {
+            printf(" %d/%d", fps->num, fps->den);
+            fps++;
+        }
+        printf("\n");
+    }
+    PRINT_CODEC_SUPPORTED(c, pix_fmts, enum AVPixelFormat, "pixel formats",
+                          AV_PIX_FMT_NONE, GET_PIX_FMT_NAME);
+    PRINT_CODEC_SUPPORTED(c, supported_samplerates, int, "sample rates", 0,
+                          GET_SAMPLE_RATE_NAME);
+    PRINT_CODEC_SUPPORTED(c, sample_fmts, enum AVSampleFormat, "sample formats",
+                          AV_SAMPLE_FMT_NONE, GET_SAMPLE_FMT_NAME);
+
+    if (c->ch_layouts) {
+        const AVChannelLayout *p = c->ch_layouts;
+
+        printf("    Supported channel layouts:");
+        while (p->nb_channels) {
+            char name[128];
+            av_channel_layout_describe(p, name, sizeof(name));
+            printf(" %s", name);
+            p++;
+        }
+        printf("\n");
+    }
+
+    if (c->priv_class) {
+        show_help_children(c->priv_class,
+                           AV_OPT_FLAG_ENCODING_PARAM |
+                           AV_OPT_FLAG_DECODING_PARAM);
+    }
+}
+
+static const AVCodec *next_codec_for_id(enum AVCodecID id, void **iter,
+                                        int encoder)
+{
+    const AVCodec *c;
+    while ((c = av_codec_iterate(iter))) {
+        if (c->id == id &&
+            (encoder ? av_codec_is_encoder(c) : av_codec_is_decoder(c)))
+            return c;
+    }
+    return NULL;
+}
+
+static void show_help_codec(const char *name, int encoder)
+{
+    const AVCodecDescriptor *desc;
+    const AVCodec *codec;
+
+    if (!name) {
+        av_log(NULL, AV_LOG_ERROR, "No codec name specified.\n");
+        return;
+    }
+
+    codec = encoder ? avcodec_find_encoder_by_name(name) :
+                      avcodec_find_decoder_by_name(name);
+
+    if (codec)
+        print_codec(codec);
+    else if ((desc = avcodec_descriptor_get_by_name(name))) {
+        void *iter = NULL;
+        int printed = 0;
+
+        while ((codec = next_codec_for_id(desc->id, &iter, encoder))) {
+            printed = 1;
+            print_codec(codec);
+        }
+
+        if (!printed) {
+            av_log(NULL, AV_LOG_ERROR, "Codec '%s' is known to FFmpeg, "
+                   "but no %s for it are available. FFmpeg might need to be "
+                   "recompiled with additional external libraries.\n",
+                   name, encoder ? "encoders" : "decoders");
+        }
+    } else {
+        av_log(NULL, AV_LOG_ERROR, "Codec '%s' is not recognized by FFmpeg.\n",
+               name);
+    }
+}
+
+static void show_help_demuxer(const char *name)
+{
+    const AVInputFormat *fmt = av_find_input_format(name);
+
+    if (!fmt) {
+        av_log(NULL, AV_LOG_ERROR, "Unknown format '%s'.\n", name);
+        return;
+    }
+
+    printf("Demuxer %s [%s]:\n", fmt->name, fmt->long_name);
+
+    if (fmt->extensions)
+        printf("    Common extensions: %s.\n", fmt->extensions);
+
+    if (fmt->priv_class)
+        show_help_children(fmt->priv_class, AV_OPT_FLAG_DECODING_PARAM);
+}
+
+static void show_help_protocol(const char *name)
+{
+    const AVClass *proto_class;
+
+    if (!name) {
+        av_log(NULL, AV_LOG_ERROR, "No protocol name specified.\n");
+        return;
+    }
+
+    proto_class = avio_protocol_get_class(name);
+    if (!proto_class) {
+        av_log(NULL, AV_LOG_ERROR, "Unknown protocol '%s'.\n", name);
+        return;
+    }
+
+    show_help_children(proto_class, AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_ENCODING_PARAM);
+}
+
+static void show_help_muxer(const char *name)
+{
+    const AVCodecDescriptor *desc;
+    const AVOutputFormat *fmt = av_guess_format(name, NULL, NULL);
+
+    if (!fmt) {
+        av_log(NULL, AV_LOG_ERROR, "Unknown format '%s'.\n", name);
+        return;
+    }
+
+    printf("Muxer %s [%s]:\n", fmt->name, fmt->long_name);
+
+    if (fmt->extensions)
+        printf("    Common extensions: %s.\n", fmt->extensions);
+    if (fmt->mime_type)
+        printf("    Mime type: %s.\n", fmt->mime_type);
+    if (fmt->video_codec != AV_CODEC_ID_NONE &&
+        (desc = avcodec_descriptor_get(fmt->video_codec))) {
+        printf("    Default video codec: %s.\n", desc->name);
+    }
+    if (fmt->audio_codec != AV_CODEC_ID_NONE &&
+        (desc = avcodec_descriptor_get(fmt->audio_codec))) {
+        printf("    Default audio codec: %s.\n", desc->name);
+    }
+    if (fmt->subtitle_codec != AV_CODEC_ID_NONE &&
+        (desc = avcodec_descriptor_get(fmt->subtitle_codec))) {
+        printf("    Default subtitle codec: %s.\n", desc->name);
+    }
+
+    if (fmt->priv_class)
+        show_help_children(fmt->priv_class, AV_OPT_FLAG_ENCODING_PARAM);
+}
+
+#if CONFIG_AVFILTER
+static void show_help_filter(const char *name)
+{
+#if CONFIG_AVFILTER
+    const AVFilter *f = avfilter_get_by_name(name);
+    int i, count;
+
+    if (!name) {
+        av_log(NULL, AV_LOG_ERROR, "No filter name specified.\n");
+        return;
+    } else if (!f) {
+        av_log(NULL, AV_LOG_ERROR, "Unknown filter '%s'.\n", name);
+        return;
+    }
+
+    printf("Filter %s\n", f->name);
+    if (f->description)
+        printf("  %s\n", f->description);
+
+    if (f->flags & AVFILTER_FLAG_SLICE_THREADS)
+        printf("    slice threading supported\n");
+
+    printf("    Inputs:\n");
+    count = avfilter_filter_pad_count(f, 0);
+    for (i = 0; i < count; i++) {
+        printf("       #%d: %s (%s)\n", i, avfilter_pad_get_name(f->inputs, i),
+               av_get_media_type_string(avfilter_pad_get_type(f->inputs, i)));
+    }
+    if (f->flags & AVFILTER_FLAG_DYNAMIC_INPUTS)
+        printf("        dynamic (depending on the options)\n");
+    else if (!count)
+        printf("        none (source filter)\n");
+
+    printf("    Outputs:\n");
+    count = avfilter_filter_pad_count(f, 1);
+    for (i = 0; i < count; i++) {
+        printf("       #%d: %s (%s)\n", i, avfilter_pad_get_name(f->outputs, i),
+               av_get_media_type_string(avfilter_pad_get_type(f->outputs, i)));
+    }
+    if (f->flags & AVFILTER_FLAG_DYNAMIC_OUTPUTS)
+        printf("        dynamic (depending on the options)\n");
+    else if (!count)
+        printf("        none (sink filter)\n");
+
+    if (f->priv_class)
+        show_help_children(f->priv_class, AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_FILTERING_PARAM |
+                                          AV_OPT_FLAG_AUDIO_PARAM);
+    if (f->flags & AVFILTER_FLAG_SUPPORT_TIMELINE)
+        printf("This filter has support for timeline through the 'enable' option.\n");
+#else
+    av_log(NULL, AV_LOG_ERROR, "Build without libavfilter; "
+           "can not to satisfy request\n");
+#endif
+}
+#endif
+
+static void show_help_bsf(const char *name)
+{
+    const AVBitStreamFilter *bsf = av_bsf_get_by_name(name);
+
+    if (!name) {
+        av_log(NULL, AV_LOG_ERROR, "No bitstream filter name specified.\n");
+        return;
+    } else if (!bsf) {
+        av_log(NULL, AV_LOG_ERROR, "Unknown bit stream filter '%s'.\n", name);
+        return;
+    }
+
+    printf("Bit stream filter %s\n", bsf->name);
+    PRINT_CODEC_SUPPORTED(bsf, codec_ids, enum AVCodecID, "codecs",
+                          AV_CODEC_ID_NONE, GET_CODEC_NAME);
+    if (bsf->priv_class)
+        show_help_children(bsf->priv_class, AV_OPT_FLAG_BSF_PARAM);
+}
+
+int show_help(void *optctx, const char *opt, const char *arg)
+{
+    char *topic, *par;
+    av_log_set_callback(log_callback_help);
+
+    topic = av_strdup(arg ? arg : "");
+    if (!topic)
+        return AVERROR(ENOMEM);
+    par = strchr(topic, '=');
+    if (par)
+        *par++ = 0;
+
+    if (!*topic) {
+        show_help_default(topic, par);
+    } else if (!strcmp(topic, "decoder")) {
+        show_help_codec(par, 0);
+    } else if (!strcmp(topic, "encoder")) {
+        show_help_codec(par, 1);
+    } else if (!strcmp(topic, "demuxer")) {
+        show_help_demuxer(par);
+    } else if (!strcmp(topic, "muxer")) {
+        show_help_muxer(par);
+    } else if (!strcmp(topic, "protocol")) {
+        show_help_protocol(par);
+#if CONFIG_AVFILTER
+    } else if (!strcmp(topic, "filter")) {
+        show_help_filter(par);
+#endif
+    } else if (!strcmp(topic, "bsf")) {
+        show_help_bsf(par);
+    } else {
+        show_help_default(topic, par);
+    }
+
+    av_freep(&topic);
+    return 0;
+}
+
+static void print_codecs_for_id(enum AVCodecID id, int encoder)
+{
+    void *iter = NULL;
+    const AVCodec *codec;
+
+    printf(" (%s: ", encoder ? "encoders" : "decoders");
+
+    while ((codec = next_codec_for_id(id, &iter, encoder)))
+        printf("%s ", codec->name);
+
+    printf(")");
+}
+
+static int compare_codec_desc(const void *a, const void *b)
+{
+    const AVCodecDescriptor * const *da = a;
+    const AVCodecDescriptor * const *db = b;
+
+    return (*da)->type != (*db)->type ? FFDIFFSIGN((*da)->type, (*db)->type) :
+           strcmp((*da)->name, (*db)->name);
+}
+
+static unsigned get_codecs_sorted(const AVCodecDescriptor ***rcodecs)
+{
+    const AVCodecDescriptor *desc = NULL;
+    const AVCodecDescriptor **codecs;
+    unsigned nb_codecs = 0, i = 0;
+
+    while ((desc = avcodec_descriptor_next(desc)))
+        nb_codecs++;
+    if (!(codecs = av_calloc(nb_codecs, sizeof(*codecs)))) {
+        av_log(NULL, AV_LOG_ERROR, "Out of memory\n");
+        exit_program(1);
+    }
+    desc = NULL;
+    while ((desc = avcodec_descriptor_next(desc)))
+        codecs[i++] = desc;
+    av_assert0(i == nb_codecs);
+    qsort(codecs, nb_codecs, sizeof(*codecs), compare_codec_desc);
+    *rcodecs = codecs;
+    return nb_codecs;
+}
+
+static char get_media_type_char(enum AVMediaType type)
+{
+    switch (type) {
+        case AVMEDIA_TYPE_VIDEO:    return 'V';
+        case AVMEDIA_TYPE_AUDIO:    return 'A';
+        case AVMEDIA_TYPE_DATA:     return 'D';
+        case AVMEDIA_TYPE_SUBTITLE: return 'S';
+        case AVMEDIA_TYPE_ATTACHMENT:return 'T';
+        default:                    return '?';
+    }
+}
+
+int show_codecs(void *optctx, const char *opt, const char *arg)
+{
+    const AVCodecDescriptor **codecs;
+    unsigned i, nb_codecs = get_codecs_sorted(&codecs);
+
+    printf("Codecs:\n"
+           " D..... = Decoding supported\n"
+           " .E.... = Encoding supported\n"
+           " ..V... = Video codec\n"
+           " ..A... = Audio codec\n"
+           " ..S... = Subtitle codec\n"
+           " ..D... = Data codec\n"
+           " ..T... = Attachment codec\n"
+           " ...I.. = Intra frame-only codec\n"
+           " ....L. = Lossy compression\n"
+           " .....S = Lossless compression\n"
+           " -------\n");
+    for (i = 0; i < nb_codecs; i++) {
+        const AVCodecDescriptor *desc = codecs[i];
+        const AVCodec *codec;
+        void *iter = NULL;
+
+        if (strstr(desc->name, "_deprecated"))
+            continue;
+
+        printf(" ");
+        printf(avcodec_find_decoder(desc->id) ? "D" : ".");
+        printf(avcodec_find_encoder(desc->id) ? "E" : ".");
+
+        printf("%c", get_media_type_char(desc->type));
+        printf((desc->props & AV_CODEC_PROP_INTRA_ONLY) ? "I" : ".");
+        printf((desc->props & AV_CODEC_PROP_LOSSY)      ? "L" : ".");
+        printf((desc->props & AV_CODEC_PROP_LOSSLESS)   ? "S" : ".");
+
+        printf(" %-20s %s", desc->name, desc->long_name ? desc->long_name : "");
+
+        /* print decoders/encoders when there's more than one or their
+         * names are different from codec name */
+        while ((codec = next_codec_for_id(desc->id, &iter, 0))) {
+            if (strcmp(codec->name, desc->name)) {
+                print_codecs_for_id(desc->id, 0);
+                break;
+            }
+        }
+        iter = NULL;
+        while ((codec = next_codec_for_id(desc->id, &iter, 1))) {
+            if (strcmp(codec->name, desc->name)) {
+                print_codecs_for_id(desc->id, 1);
+                break;
+            }
+        }
+
+        printf("\n");
+    }
+    av_free(codecs);
+    return 0;
+}
+
+static void print_codecs(int encoder)
+{
+    const AVCodecDescriptor **codecs;
+    unsigned i, nb_codecs = get_codecs_sorted(&codecs);
+
+    printf("%s:\n"
+           " V..... = Video\n"
+           " A..... = Audio\n"
+           " S..... = Subtitle\n"
+           " .F.... = Frame-level multithreading\n"
+           " ..S... = Slice-level multithreading\n"
+           " ...X.. = Codec is experimental\n"
+           " ....B. = Supports draw_horiz_band\n"
+           " .....D = Supports direct rendering method 1\n"
+           " ------\n",
+           encoder ? "Encoders" : "Decoders");
+    for (i = 0; i < nb_codecs; i++) {
+        const AVCodecDescriptor *desc = codecs[i];
+        const AVCodec *codec;
+        void *iter = NULL;
+
+        while ((codec = next_codec_for_id(desc->id, &iter, encoder))) {
+            printf(" %c", get_media_type_char(desc->type));
+            printf((codec->capabilities & AV_CODEC_CAP_FRAME_THREADS) ? "F" : ".");
+            printf((codec->capabilities & AV_CODEC_CAP_SLICE_THREADS) ? "S" : ".");
+            printf((codec->capabilities & AV_CODEC_CAP_EXPERIMENTAL)  ? "X" : ".");
+            printf((codec->capabilities & AV_CODEC_CAP_DRAW_HORIZ_BAND)?"B" : ".");
+            printf((codec->capabilities & AV_CODEC_CAP_DR1)           ? "D" : ".");
+
+            printf(" %-20s %s", codec->name, codec->long_name ? codec->long_name : "");
+            if (strcmp(codec->name, desc->name))
+                printf(" (codec %s)", desc->name);
+
+            printf("\n");
+        }
+    }
+    av_free(codecs);
+}
+
+int show_decoders(void *optctx, const char *opt, const char *arg)
+{
+    print_codecs(0);
+    return 0;
+}
+
+int show_encoders(void *optctx, const char *opt, const char *arg)
+{
+    print_codecs(1);
+    return 0;
+}
+
+int show_bsfs(void *optctx, const char *opt, const char *arg)
+{
+    const AVBitStreamFilter *bsf = NULL;
+    void *opaque = NULL;
+
+    printf("Bitstream filters:\n");
+    while ((bsf = av_bsf_iterate(&opaque)))
+        printf("%s\n", bsf->name);
+    printf("\n");
+    return 0;
+}
+
+int show_filters(void *optctx, const char *opt, const char *arg)
+{
+#if CONFIG_AVFILTER
+    const AVFilter *filter = NULL;
+    char descr[64], *descr_cur;
+    void *opaque = NULL;
+    int i, j;
+    const AVFilterPad *pad;
+
+    printf("Filters:\n"
+           "  T.. = Timeline support\n"
+           "  .S. = Slice threading\n"
+           "  ..C = Command support\n"
+           "  A = Audio input/output\n"
+           "  V = Video input/output\n"
+           "  N = Dynamic number and/or type of input/output\n"
+           "  | = Source or sink filter\n");
+    while ((filter = av_filter_iterate(&opaque))) {
+        descr_cur = descr;
+        for (i = 0; i < 2; i++) {
+            unsigned nb_pads;
+            if (i) {
+                *(descr_cur++) = '-';
+                *(descr_cur++) = '>';
+            }
+            pad = i ? filter->outputs : filter->inputs;
+            nb_pads = avfilter_filter_pad_count(filter, i);
+            for (j = 0; j < nb_pads; j++) {
+                if (descr_cur >= descr + sizeof(descr) - 4)
+                    break;
+                *(descr_cur++) = get_media_type_char(avfilter_pad_get_type(pad, j));
+            }
+            if (!j)
+                *(descr_cur++) = ((!i && (filter->flags & AVFILTER_FLAG_DYNAMIC_INPUTS)) ||
+                                  ( i && (filter->flags & AVFILTER_FLAG_DYNAMIC_OUTPUTS))) ? 'N' : '|';
+        }
+        *descr_cur = 0;
+        printf(" %c%c%c %-17s %-10s %s\n",
+               filter->flags & AVFILTER_FLAG_SUPPORT_TIMELINE ? 'T' : '.',
+               filter->flags & AVFILTER_FLAG_SLICE_THREADS    ? 'S' : '.',
+               filter->process_command                        ? 'C' : '.',
+               filter->name, descr, filter->description);
+    }
+#else
+    printf("No filters available: libavfilter disabled\n");
+#endif
+    return 0;
+}
+
+static int is_device(const AVClass *avclass)
+{
+    if (!avclass)
+        return 0;
+    return AV_IS_INPUT_DEVICE(avclass->category) || AV_IS_OUTPUT_DEVICE(avclass->category);
+}
+
+static int show_formats_devices(void *optctx, const char *opt, const char *arg, int device_only, int muxdemuxers)
+{
+    void *ifmt_opaque = NULL;
+    const AVInputFormat *ifmt  = NULL;
+    void *ofmt_opaque = NULL;
+    const AVOutputFormat *ofmt = NULL;
+    const char *last_name;
+    int is_dev;
+
+    printf("%s\n"
+           " D. = Demuxing supported\n"
+           " .E = Muxing supported\n"
+           " --\n", device_only ? "Devices:" : "File formats:");
+    last_name = "000";
+    for (;;) {
+        int decode = 0;
+        int encode = 0;
+        const char *name      = NULL;
+        const char *long_name = NULL;
+
+        if (muxdemuxers !=SHOW_DEMUXERS) {
+            ofmt_opaque = NULL;
+            while ((ofmt = av_muxer_iterate(&ofmt_opaque))) {
+                is_dev = is_device(ofmt->priv_class);
+                if (!is_dev && device_only)
+                    continue;
+                if ((!name || strcmp(ofmt->name, name) < 0) &&
+                    strcmp(ofmt->name, last_name) > 0) {
+                    name      = ofmt->name;
+                    long_name = ofmt->long_name;
+                    encode    = 1;
+                }
+            }
+        }
+        if (muxdemuxers != SHOW_MUXERS) {
+            ifmt_opaque = NULL;
+            while ((ifmt = av_demuxer_iterate(&ifmt_opaque))) {
+                is_dev = is_device(ifmt->priv_class);
+                if (!is_dev && device_only)
+                    continue;
+                if ((!name || strcmp(ifmt->name, name) < 0) &&
+                    strcmp(ifmt->name, last_name) > 0) {
+                    name      = ifmt->name;
+                    long_name = ifmt->long_name;
+                    encode    = 0;
+                }
+                if (name && strcmp(ifmt->name, name) == 0)
+                    decode = 1;
+            }
+        }
+        if (!name)
+            break;
+        last_name = name;
+
+        printf(" %c%c %-15s %s\n",
+               decode ? 'D' : ' ',
+               encode ? 'E' : ' ',
+               name,
+            long_name ? long_name:" ");
+    }
+    return 0;
+}
+
+int show_formats(void *optctx, const char *opt, const char *arg)
+{
+    return show_formats_devices(optctx, opt, arg, 0, SHOW_DEFAULT);
+}
+
+int show_muxers(void *optctx, const char *opt, const char *arg)
+{
+    return show_formats_devices(optctx, opt, arg, 0, SHOW_MUXERS);
+}
+
+int show_demuxers(void *optctx, const char *opt, const char *arg)
+{
+    return show_formats_devices(optctx, opt, arg, 0, SHOW_DEMUXERS);
+}
+
+int show_devices(void *optctx, const char *opt, const char *arg)
+{
+    return show_formats_devices(optctx, opt, arg, 1, SHOW_DEFAULT);
+}
+
+int show_protocols(void *optctx, const char *opt, const char *arg)
+{
+    void *opaque = NULL;
+    const char *name;
+
+    printf("Supported file protocols:\n"
+           "Input:\n");
+    while ((name = avio_enum_protocols(&opaque, 0)))
+        printf("  %s\n", name);
+    printf("Output:\n");
+    while ((name = avio_enum_protocols(&opaque, 1)))
+        printf("  %s\n", name);
+    return 0;
+}
+
+int show_colors(void *optctx, const char *opt, const char *arg)
+{
+    const char *name;
+    const uint8_t *rgb;
+    int i;
+
+    printf("%-32s #RRGGBB\n", "name");
+
+    for (i = 0; name = av_get_known_color_name(i, &rgb); i++)
+        printf("%-32s #%02x%02x%02x\n", name, rgb[0], rgb[1], rgb[2]);
+
+    return 0;
+}
+
+int show_pix_fmts(void *optctx, const char *opt, const char *arg)
+{
+    const AVPixFmtDescriptor *pix_desc = NULL;
+
+    printf("Pixel formats:\n"
+           "I.... = Supported Input  format for conversion\n"
+           ".O... = Supported Output format for conversion\n"
+           "..H.. = Hardware accelerated format\n"
+           "...P. = Paletted format\n"
+           "....B = Bitstream format\n"
+           "FLAGS NAME            NB_COMPONENTS BITS_PER_PIXEL BIT_DEPTHS\n"
+           "-----\n");
+
+#if !CONFIG_SWSCALE
+#   define sws_isSupportedInput(x)  0
+#   define sws_isSupportedOutput(x) 0
+#endif
+
+    while ((pix_desc = av_pix_fmt_desc_next(pix_desc))) {
+        enum AVPixelFormat av_unused pix_fmt = av_pix_fmt_desc_get_id(pix_desc);
+        printf("%c%c%c%c%c %-16s       %d            %3d      %d",
+               sws_isSupportedInput (pix_fmt)              ? 'I' : '.',
+               sws_isSupportedOutput(pix_fmt)              ? 'O' : '.',
+               pix_desc->flags & AV_PIX_FMT_FLAG_HWACCEL   ? 'H' : '.',
+               pix_desc->flags & AV_PIX_FMT_FLAG_PAL       ? 'P' : '.',
+               pix_desc->flags & AV_PIX_FMT_FLAG_BITSTREAM ? 'B' : '.',
+               pix_desc->name,
+               pix_desc->nb_components,
+               av_get_bits_per_pixel(pix_desc),
+               pix_desc->comp[0].depth);
+
+        for (unsigned i = 1; i < pix_desc->nb_components; i++)
+            printf("-%d", pix_desc->comp[i].depth);
+        printf("\n");
+    }
+    return 0;
+}
+
+int show_layouts(void *optctx, const char *opt, const char *arg)
+{
+    const AVChannelLayout *ch_layout;
+    void *iter = NULL;
+    char buf[128], buf2[128];
+    int i = 0;
+
+    printf("Individual channels:\n"
+           "NAME           DESCRIPTION\n");
+    for (i = 0; i < 63; i++) {
+        av_channel_name(buf, sizeof(buf), i);
+        if (strstr(buf, "USR"))
+            continue;
+        av_channel_description(buf2, sizeof(buf2), i);
+        printf("%-14s %s\n", buf, buf2);
+    }
+    printf("\nStandard channel layouts:\n"
+           "NAME           DECOMPOSITION\n");
+    while (ch_layout = av_channel_layout_standard(&iter)) {
+            av_channel_layout_describe(ch_layout, buf, sizeof(buf));
+            printf("%-14s ", buf);
+            for (i = 0; i < 63; i++) {
+                int idx = av_channel_layout_index_from_channel(ch_layout, i);
+                if (idx >= 0) {
+                    av_channel_name(buf2, sizeof(buf2), i);
+                    printf("%s%s", idx ? "+" : "", buf2);
+                }
+            }
+            printf("\n");
+    }
+    return 0;
+}
+
+int show_sample_fmts(void *optctx, const char *opt, const char *arg)
+{
+    int i;
+    char fmt_str[128];
+    for (i = -1; i < AV_SAMPLE_FMT_NB; i++)
+        printf("%s\n", av_get_sample_fmt_string(fmt_str, sizeof(fmt_str), i));
+    return 0;
+}
+
+int show_dispositions(void *optctx, const char *opt, const char *arg)
+{
+    for (int i = 0; i < 32; i++) {
+        const char *str = av_disposition_to_string(1U << i);
+        if (str)
+            printf("%s\n", str);
+    }
+    return 0;
+}
+
+int opt_cpuflags(void *optctx, const char *opt, const char *arg)
+{
+    int ret;
+    unsigned flags = av_get_cpu_flags();
+
+    if ((ret = av_parse_cpu_caps(&flags, arg)) < 0)
+        return ret;
+
+    av_force_cpu_flags(flags);
+    return 0;
+}
+
+int opt_cpucount(void *optctx, const char *opt, const char *arg)
+{
+    int ret;
+    int count;
+
+    static const AVOption opts[] = {
+        {"count", NULL, 0, AV_OPT_TYPE_INT, { .i64 = -1}, -1, INT_MAX},
+        {NULL},
+    };
+    static const AVClass class = {
+        .class_name = "cpucount",
+        .item_name  = av_default_item_name,
+        .option     = opts,
+        .version    = LIBAVUTIL_VERSION_INT,
+    };
+    const AVClass *pclass = &class;
+
+    ret = av_opt_eval_int(&pclass, opts, arg, &count);
+
+    if (!ret) {
+        av_cpu_force_count(count);
+    }
+
+    return ret;
+}
+
+static void expand_filename_template(AVBPrint *bp, const char *template,
+                                     struct tm *tm)
+{
+    int c;
+
+    while ((c = *(template++))) {
+        if (c == '%') {
+            if (!(c = *(template++)))
+                break;
+            switch (c) {
+            case 'p':
+                av_bprintf(bp, "%s", program_name);
+                break;
+            case 't':
+                av_bprintf(bp, "%04d%02d%02d-%02d%02d%02d",
+                           tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
+                           tm->tm_hour, tm->tm_min, tm->tm_sec);
+                break;
+            case '%':
+                av_bprint_chars(bp, c, 1);
+                break;
+            }
+        } else {
+            av_bprint_chars(bp, c, 1);
+        }
+    }
+}
+
+static void log_callback_report(void *ptr, int level, const char *fmt, va_list vl)
+{
+    va_list vl2;
+    char line[1024];
+    static int print_prefix = 1;
+
+    va_copy(vl2, vl);
+    av_log_default_callback(ptr, level, fmt, vl);
+    av_log_format_line(ptr, level, fmt, vl2, line, sizeof(line), &print_prefix);
+    va_end(vl2);
+    if (report_file_level >= level) {
+        fputs(line, report_file);
+        fflush(report_file);
+    }
+}
+
+int init_report(const char *env, FILE **file)
+{
+    char *filename_template = NULL;
+    char *key, *val;
+    int ret, count = 0;
+    int prog_loglevel, envlevel = 0;
+    time_t now;
+    struct tm *tm;
+    AVBPrint filename;
+
+    if (report_file) /* already opened */
+        return 0;
+    time(&now);
+    tm = localtime(&now);
+
+    while (env && *env) {
+        if ((ret = av_opt_get_key_value(&env, "=", ":", 0, &key, &val)) < 0) {
+            if (count)
+                av_log(NULL, AV_LOG_ERROR,
+                       "Failed to parse FFREPORT environment variable: %s\n",
+                       av_err2str(ret));
+            break;
+        }
+        if (*env)
+            env++;
+        count++;
+        if (!strcmp(key, "file")) {
+            av_free(filename_template);
+            filename_template = val;
+            val = NULL;
+        } else if (!strcmp(key, "level")) {
+            char *tail;
+            report_file_level = strtol(val, &tail, 10);
+            if (*tail) {
+                av_log(NULL, AV_LOG_FATAL, "Invalid report file level\n");
+                exit_program(1);
+            }
+            envlevel = 1;
+        } else {
+            av_log(NULL, AV_LOG_ERROR, "Unknown key '%s' in FFREPORT\n", key);
+        }
+        av_free(val);
+        av_free(key);
+    }
+
+    av_bprint_init(&filename, 0, AV_BPRINT_SIZE_AUTOMATIC);
+    expand_filename_template(&filename,
+                             av_x_if_null(filename_template, "%p-%t.log"), tm);
+    av_free(filename_template);
+    if (!av_bprint_is_complete(&filename)) {
+        av_log(NULL, AV_LOG_ERROR, "Out of memory building report file name\n");
+        return AVERROR(ENOMEM);
+    }
+
+    prog_loglevel = av_log_get_level();
+    if (!envlevel)
+        report_file_level = FFMAX(report_file_level, prog_loglevel);
+
+    report_file = fopen(filename.str, "w");
+    if (!report_file) {
+        int ret = AVERROR(errno);
+        av_log(NULL, AV_LOG_ERROR, "Failed to open report \"%s\": %s\n",
+               filename.str, strerror(errno));
+        return ret;
+    }
+    av_log_set_callback(log_callback_report);
+    av_log(NULL, AV_LOG_INFO,
+           "%s started on %04d-%02d-%02d at %02d:%02d:%02d\n"
+           "Report written to \"%s\"\n"
+           "Log level: %d\n",
+           program_name,
+           tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
+           tm->tm_hour, tm->tm_min, tm->tm_sec,
+           filename.str, report_file_level);
+    av_bprint_finalize(&filename, NULL);
+
+    if (file)
+        *file = report_file;
+
+    return 0;
+}
+
+int opt_report(void *optctx, const char *opt, const char *arg)
+{
+    return init_report(NULL, NULL);
+}
+
+int opt_max_alloc(void *optctx, const char *opt, const char *arg)
+{
+    char *tail;
+    size_t max;
+
+    max = strtol(arg, &tail, 10);
+    if (*tail) {
+        av_log(NULL, AV_LOG_FATAL, "Invalid max_alloc \"%s\".\n", arg);
+        exit_program(1);
+    }
+    av_max_alloc(max);
+    return 0;
+}
+
+int opt_loglevel(void *optctx, const char *opt, const char *arg)
+{
+    const struct { const char *name; int level; } log_levels[] = {
+        { "quiet"  , AV_LOG_QUIET   },
+        { "panic"  , AV_LOG_PANIC   },
+        { "fatal"  , AV_LOG_FATAL   },
+        { "error"  , AV_LOG_ERROR   },
+        { "warning", AV_LOG_WARNING },
+        { "info"   , AV_LOG_INFO    },
+        { "verbose", AV_LOG_VERBOSE },
+        { "debug"  , AV_LOG_DEBUG   },
+        { "trace"  , AV_LOG_TRACE   },
+    };
+    const char *token;
+    char *tail;
+    int flags = av_log_get_flags();
+    int level = av_log_get_level();
+    int cmd, i = 0;
+
+    av_assert0(arg);
+    while (*arg) {
+        token = arg;
+        if (*token == '+' || *token == '-') {
+            cmd = *token++;
+        } else {
+            cmd = 0;
+        }
+        if (!i && !cmd) {
+            flags = 0;  /* missing relative prefix, build absolute value */
+        }
+        if (av_strstart(token, "repeat", &arg)) {
+            if (cmd == '-') {
+                flags |= AV_LOG_SKIP_REPEATED;
+            } else {
+                flags &= ~AV_LOG_SKIP_REPEATED;
+            }
+        } else if (av_strstart(token, "level", &arg)) {
+            if (cmd == '-') {
+                flags &= ~AV_LOG_PRINT_LEVEL;
+            } else {
+                flags |= AV_LOG_PRINT_LEVEL;
+            }
+        } else {
+            break;
+        }
+        i++;
+    }
+    if (!*arg) {
+        goto end;
+    } else if (*arg == '+') {
+        arg++;
+    } else if (!i) {
+        flags = av_log_get_flags();  /* level value without prefix, reset flags */
+    }
+
+    for (i = 0; i < FF_ARRAY_ELEMS(log_levels); i++) {
+        if (!strcmp(log_levels[i].name, arg)) {
+            level = log_levels[i].level;
+            goto end;
+        }
+    }
+
+    level = strtol(arg, &tail, 10);
+    if (*tail) {
+        av_log(NULL, AV_LOG_FATAL, "Invalid loglevel \"%s\". "
+               "Possible levels are numbers or:\n", arg);
+        for (i = 0; i < FF_ARRAY_ELEMS(log_levels); i++)
+            av_log(NULL, AV_LOG_FATAL, "\"%s\"\n", log_levels[i].name);
+        exit_program(1);
+    }
+
+end:
+    av_log_set_flags(flags);
+    av_log_set_level(level);
+    return 0;
+}
+
+#if CONFIG_AVDEVICE
+static void print_device_list(const AVDeviceInfoList *device_list)
+{
+    // print devices
+    for (int i = 0; i < device_list->nb_devices; i++) {
+        const AVDeviceInfo *device = device_list->devices[i];
+        printf("%c %s [%s] (", device_list->default_device == i ? '*' : ' ',
+            device->device_name, device->device_description);
+        if (device->nb_media_types > 0) {
+            for (int j = 0; j < device->nb_media_types; ++j) {
+                const char* media_type = av_get_media_type_string(device->media_types[j]);
+                if (j > 0)
+                    printf(", ");
+                printf("%s", media_type ? media_type : "unknown");
+            }
+        } else {
+            printf("none");
+        }
+        printf(")\n");
+    }
+}
+
+static int print_device_sources(const AVInputFormat *fmt, AVDictionary *opts)
+{
+    int ret;
+    AVDeviceInfoList *device_list = NULL;
+
+    if (!fmt || !fmt->priv_class  || !AV_IS_INPUT_DEVICE(fmt->priv_class->category))
+        return AVERROR(EINVAL);
+
+    printf("Auto-detected sources for %s:\n", fmt->name);
+    if ((ret = avdevice_list_input_sources(fmt, NULL, opts, &device_list)) < 0) {
+        printf("Cannot list sources: %s\n", av_err2str(ret));
+        goto fail;
+    }
+
+    print_device_list(device_list);
+
+  fail:
+    avdevice_free_list_devices(&device_list);
+    return ret;
+}
+
+static int print_device_sinks(const AVOutputFormat *fmt, AVDictionary *opts)
+{
+    int ret;
+    AVDeviceInfoList *device_list = NULL;
+
+    if (!fmt || !fmt->priv_class  || !AV_IS_OUTPUT_DEVICE(fmt->priv_class->category))
+        return AVERROR(EINVAL);
+
+    printf("Auto-detected sinks for %s:\n", fmt->name);
+    if ((ret = avdevice_list_output_sinks(fmt, NULL, opts, &device_list)) < 0) {
+        printf("Cannot list sinks: %s\n", av_err2str(ret));
+        goto fail;
+    }
+
+    print_device_list(device_list);
+
+  fail:
+    avdevice_free_list_devices(&device_list);
+    return ret;
+}
+
+static int show_sinks_sources_parse_arg(const char *arg, char **dev, AVDictionary **opts)
+{
+    int ret;
+    if (arg) {
+        char *opts_str = NULL;
+        av_assert0(dev && opts);
+        *dev = av_strdup(arg);
+        if (!*dev)
+            return AVERROR(ENOMEM);
+        if ((opts_str = strchr(*dev, ','))) {
+            *(opts_str++) = '\0';
+            if (opts_str[0] && ((ret = av_dict_parse_string(opts, opts_str, "=", ":", 0)) < 0)) {
+                av_freep(dev);
+                return ret;
+            }
+        }
+    } else
+        printf("\nDevice name is not provided.\n"
+                "You can pass devicename[,opt1=val1[,opt2=val2...]] as an argument.\n\n");
+    return 0;
+}
+
+int show_sources(void *optctx, const char *opt, const char *arg)
+{
+    const AVInputFormat *fmt = NULL;
+    char *dev = NULL;
+    AVDictionary *opts = NULL;
+    int ret = 0;
+    int error_level = av_log_get_level();
+
+    av_log_set_level(AV_LOG_WARNING);
+
+    if ((ret = show_sinks_sources_parse_arg(arg, &dev, &opts)) < 0)
+        goto fail;
+
+    do {
+        fmt = av_input_audio_device_next(fmt);
+        if (fmt) {
+            if (!strcmp(fmt->name, "lavfi"))
+                continue; //it's pointless to probe lavfi
+            if (dev && !av_match_name(dev, fmt->name))
+                continue;
+            print_device_sources(fmt, opts);
+        }
+    } while (fmt);
+    do {
+        fmt = av_input_video_device_next(fmt);
+        if (fmt) {
+            if (dev && !av_match_name(dev, fmt->name))
+                continue;
+            print_device_sources(fmt, opts);
+        }
+    } while (fmt);
+  fail:
+    av_dict_free(&opts);
+    av_free(dev);
+    av_log_set_level(error_level);
+    return ret;
+}
+
+int show_sinks(void *optctx, const char *opt, const char *arg)
+{
+    const AVOutputFormat *fmt = NULL;
+    char *dev = NULL;
+    AVDictionary *opts = NULL;
+    int ret = 0;
+    int error_level = av_log_get_level();
+
+    av_log_set_level(AV_LOG_WARNING);
+
+    if ((ret = show_sinks_sources_parse_arg(arg, &dev, &opts)) < 0)
+        goto fail;
+
+    do {
+        fmt = av_output_audio_device_next(fmt);
+        if (fmt) {
+            if (dev && !av_match_name(dev, fmt->name))
+                continue;
+            print_device_sinks(fmt, opts);
+        }
+    } while (fmt);
+    do {
+        fmt = av_output_video_device_next(fmt);
+        if (fmt) {
+            if (dev && !av_match_name(dev, fmt->name))
+                continue;
+            print_device_sinks(fmt, opts);
+        }
+    } while (fmt);
+  fail:
+    av_dict_free(&opts);
+    av_free(dev);
+    av_log_set_level(error_level);
+    return ret;
+}
+#endif /* CONFIG_AVDEVICE */
diff -pruN 7:5.0.1-3/fftools/opt_common.h 7:5.1-1/fftools/opt_common.h
--- 7:5.0.1-3/fftools/opt_common.h	1970-01-01 00:00:00.000000000 +0000
+++ 7:5.1-1/fftools/opt_common.h	2022-07-22 17:58:38.000000000 +0000
@@ -0,0 +1,231 @@
+/*
+ * Option handlers shared between the tools.
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef FFTOOLS_OPT_COMMON_H
+#define FFTOOLS_OPT_COMMON_H
+
+#include "config.h"
+
+#include "cmdutils.h"
+
+#if CONFIG_AVDEVICE
+/**
+ * Print a listing containing autodetected sinks of the output device.
+ * Device name with options may be passed as an argument to limit results.
+ */
+int show_sinks(void *optctx, const char *opt, const char *arg);
+
+/**
+ * Print a listing containing autodetected sources of the input device.
+ * Device name with options may be passed as an argument to limit results.
+ */
+int show_sources(void *optctx, const char *opt, const char *arg);
+#endif
+
+#if CONFIG_AVDEVICE
+#define CMDUTILS_COMMON_OPTIONS_AVDEVICE                                                                                \
+    { "sources"    , OPT_EXIT | HAS_ARG, { .func_arg = show_sources },                                                  \
+      "list sources of the input device", "device" },                                                                   \
+    { "sinks"      , OPT_EXIT | HAS_ARG, { .func_arg = show_sinks },                                                    \
+      "list sinks of the output device", "device" },                                                                    \
+
+#else
+#define CMDUTILS_COMMON_OPTIONS_AVDEVICE
+#endif
+
+/**
+ * Print the license of the program to stdout. The license depends on
+ * the license of the libraries compiled into the program.
+ * This option processing function does not utilize the arguments.
+ */
+int show_license(void *optctx, const char *opt, const char *arg);
+
+/**
+ * Generic -h handler common to all fftools.
+ */
+int show_help(void *optctx, const char *opt, const char *arg);
+
+/**
+ * Print the version of the program to stdout. The version message
+ * depends on the current versions of the repository and of the libav*
+ * libraries.
+ * This option processing function does not utilize the arguments.
+ */
+int show_version(void *optctx, const char *opt, const char *arg);
+
+/**
+ * Print the build configuration of the program to stdout. The contents
+ * depend on the definition of FFMPEG_CONFIGURATION.
+ * This option processing function does not utilize the arguments.
+ */
+int show_buildconf(void *optctx, const char *opt, const char *arg);
+
+/**
+ * Print a listing containing all the formats supported by the
+ * program (including devices).
+ * This option processing function does not utilize the arguments.
+ */
+int show_formats(void *optctx, const char *opt, const char *arg);
+
+/**
+ * Print a listing containing all the muxers supported by the
+ * program (including devices).
+ * This option processing function does not utilize the arguments.
+ */
+int show_muxers(void *optctx, const char *opt, const char *arg);
+
+/**
+ * Print a listing containing all the demuxer supported by the
+ * program (including devices).
+ * This option processing function does not utilize the arguments.
+ */
+int show_demuxers(void *optctx, const char *opt, const char *arg);
+
+/**
+ * Print a listing containing all the devices supported by the
+ * program.
+ * This option processing function does not utilize the arguments.
+ */
+int show_devices(void *optctx, const char *opt, const char *arg);
+
+/**
+ * Print a listing containing all the codecs supported by the
+ * program.
+ * This option processing function does not utilize the arguments.
+ */
+int show_codecs(void *optctx, const char *opt, const char *arg);
+
+/**
+ * Print a listing containing all the decoders supported by the
+ * program.
+ */
+int show_decoders(void *optctx, const char *opt, const char *arg);
+
+/**
+ * Print a listing containing all the encoders supported by the
+ * program.
+ */
+int show_encoders(void *optctx, const char *opt, const char *arg);
+
+/**
+ * Print a listing containing all the bit stream filters supported by the
+ * program.
+ * This option processing function does not utilize the arguments.
+ */
+int show_bsfs(void *optctx, const char *opt, const char *arg);
+
+/**
+ * Print a listing containing all the protocols supported by the
+ * program.
+ * This option processing function does not utilize the arguments.
+ */
+int show_protocols(void *optctx, const char *opt, const char *arg);
+
+/**
+ * Print a listing containing all the filters supported by the
+ * program.
+ * This option processing function does not utilize the arguments.
+ */
+int show_filters(void *optctx, const char *opt, const char *arg);
+
+/**
+ * Print a listing containing all the pixel formats supported by the
+ * program.
+ * This option processing function does not utilize the arguments.
+ */
+int show_pix_fmts(void *optctx, const char *opt, const char *arg);
+
+/**
+ * Print a listing containing all the standard channel layouts supported by
+ * the program.
+ * This option processing function does not utilize the arguments.
+ */
+int show_layouts(void *optctx, const char *opt, const char *arg);
+
+/**
+ * Print a listing containing all the sample formats supported by the
+ * program.
+ */
+int show_sample_fmts(void *optctx, const char *opt, const char *arg);
+
+/**
+ * Print a listing containing all supported stream dispositions.
+ */
+int show_dispositions(void *optctx, const char *opt, const char *arg);
+
+/**
+ * Print a listing containing all the color names and values recognized
+ * by the program.
+ */
+int show_colors(void *optctx, const char *opt, const char *arg);
+
+/**
+ * Set the libav* libraries log level.
+ */
+int opt_loglevel(void *optctx, const char *opt, const char *arg);
+
+int opt_report(void *optctx, const char *opt, const char *arg);
+int init_report(const char *env, FILE **file);
+
+int opt_max_alloc(void *optctx, const char *opt, const char *arg);
+
+/**
+ * Override the cpuflags.
+ */
+int opt_cpuflags(void *optctx, const char *opt, const char *arg);
+
+/**
+ * Override the cpucount.
+ */
+int opt_cpucount(void *optctx, const char *opt, const char *arg);
+
+#define CMDUTILS_COMMON_OPTIONS                                                                                         \
+    { "L",           OPT_EXIT,             { .func_arg = show_license },     "show license" },                          \
+    { "h",           OPT_EXIT,             { .func_arg = show_help },        "show help", "topic" },                    \
+    { "?",           OPT_EXIT,             { .func_arg = show_help },        "show help", "topic" },                    \
+    { "help",        OPT_EXIT,             { .func_arg = show_help },        "show help", "topic" },                    \
+    { "-help",       OPT_EXIT,             { .func_arg = show_help },        "show help", "topic" },                    \
+    { "version",     OPT_EXIT,             { .func_arg = show_version },     "show version" },                          \
+    { "buildconf",   OPT_EXIT,             { .func_arg = show_buildconf },   "show build configuration" },              \
+    { "formats",     OPT_EXIT,             { .func_arg = show_formats },     "show available formats" },                \
+    { "muxers",      OPT_EXIT,             { .func_arg = show_muxers },      "show available muxers" },                 \
+    { "demuxers",    OPT_EXIT,             { .func_arg = show_demuxers },    "show available demuxers" },               \
+    { "devices",     OPT_EXIT,             { .func_arg = show_devices },     "show available devices" },                \
+    { "codecs",      OPT_EXIT,             { .func_arg = show_codecs },      "show available codecs" },                 \
+    { "decoders",    OPT_EXIT,             { .func_arg = show_decoders },    "show available decoders" },               \
+    { "encoders",    OPT_EXIT,             { .func_arg = show_encoders },    "show available encoders" },               \
+    { "bsfs",        OPT_EXIT,             { .func_arg = show_bsfs },        "show available bit stream filters" },     \
+    { "protocols",   OPT_EXIT,             { .func_arg = show_protocols },   "show available protocols" },              \
+    { "filters",     OPT_EXIT,             { .func_arg = show_filters },     "show available filters" },                \
+    { "pix_fmts",    OPT_EXIT,             { .func_arg = show_pix_fmts },    "show available pixel formats" },          \
+    { "layouts",     OPT_EXIT,             { .func_arg = show_layouts },     "show standard channel layouts" },         \
+    { "sample_fmts", OPT_EXIT,             { .func_arg = show_sample_fmts }, "show available audio sample formats" },   \
+    { "dispositions", OPT_EXIT,            { .func_arg = show_dispositions}, "show available stream dispositions" },    \
+    { "colors",      OPT_EXIT,             { .func_arg = show_colors },      "show available color names" },            \
+    { "loglevel",    HAS_ARG,              { .func_arg = opt_loglevel },     "set logging level", "loglevel" },         \
+    { "v",           HAS_ARG,              { .func_arg = opt_loglevel },     "set logging level", "loglevel" },         \
+    { "report",      0,                    { .func_arg = opt_report },       "generate a report" },                     \
+    { "max_alloc",   HAS_ARG,              { .func_arg = opt_max_alloc },    "set maximum size of a single allocated block", "bytes" }, \
+    { "cpuflags",    HAS_ARG | OPT_EXPERT, { .func_arg = opt_cpuflags },     "force specific cpu flags", "flags" },     \
+    { "cpucount",    HAS_ARG | OPT_EXPERT, { .func_arg = opt_cpucount },     "force specific cpu count", "count" },     \
+    { "hide_banner", OPT_BOOL | OPT_EXPERT, {&hide_banner},     "do not show program banner", "hide_banner" },          \
+    CMDUTILS_COMMON_OPTIONS_AVDEVICE                                                                                    \
+
+#endif /* FFTOOLS_OPT_COMMON_H */
diff -pruN 7:5.0.1-3/libavcodec/012v.c 7:5.1-1/libavcodec/012v.c
--- 7:5.0.1-3/libavcodec/012v.c	2022-01-14 18:45:39.000000000 +0000
+++ 7:5.1-1/libavcodec/012v.c	2022-07-22 17:58:38.000000000 +0000
@@ -21,6 +21,7 @@
  */
 
 #include "avcodec.h"
+#include "codec_internal.h"
 #include "internal.h"
 #include "libavutil/intreadwrite.h"
 
@@ -35,12 +36,11 @@ static av_cold int zero12v_decode_init(A
     return 0;
 }
 
-static int zero12v_decode_frame(AVCodecContext *avctx, void *data,
+static int zero12v_decode_frame(AVCodecContext *avctx, AVFrame *pic,
                                 int *got_frame, AVPacket *avpkt)
 {
     int line, ret;
     const int width = avctx->width;
-    AVFrame *pic = data;
     uint16_t *y, *u, *v;
     const uint8_t *line_end, *src = avpkt->data;
     int stride = avctx->width * 8 / 3;
@@ -144,13 +144,13 @@ static int zero12v_decode_frame(AVCodecC
     return avpkt->size;
 }
 
-const AVCodec ff_zero12v_decoder = {
-    .name           = "012v",
-    .long_name      = NULL_IF_CONFIG_SMALL("Uncompressed 4:2:2 10-bit"),
-    .type           = AVMEDIA_TYPE_VIDEO,
-    .id             = AV_CODEC_ID_012V,
+const FFCodec ff_zero12v_decoder = {
+    .p.name         = "012v",
+    .p.long_name    = NULL_IF_CONFIG_SMALL("Uncompressed 4:2:2 10-bit"),
+    .p.type         = AVMEDIA_TYPE_VIDEO,
+    .p.id           = AV_CODEC_ID_012V,
     .init           = zero12v_decode_init,
-    .decode         = zero12v_decode_frame,
-    .capabilities   = AV_CODEC_CAP_DR1,
+    FF_CODEC_DECODE_CB(zero12v_decode_frame),
+    .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff -pruN 7:5.0.1-3/libavcodec/4xm.c 7:5.1-1/libavcodec/4xm.c
--- 7:5.0.1-3/libavcodec/4xm.c	2022-01-14 18:45:39.000000000 +0000
+++ 7:5.1-1/libavcodec/4xm.c	2022-07-22 17:58:38.000000000 +0000
@@ -36,6 +36,7 @@
 #include "blockdsp.h"
 #include "bswapdsp.h"
 #include "bytestream.h"
+#include "codec_internal.h"
 #include "get_bits.h"
 #include "internal.h"
 
@@ -249,7 +250,7 @@ static void idct(int16_t block[64])
 
 static av_cold void init_vlcs(void)
 {
-    static VLC_TYPE table[2][4][32][2];
+    static VLCElem table[2][4][32];
     int i, j;
 
     for (i = 0; i < 2; i++) {
@@ -833,13 +834,12 @@ static int decode_i_frame(FourXContext *
     return 0;
 }
 
-static int decode_frame(AVCodecContext *avctx, void *data,
+static int decode_frame(AVCodecContext *avctx, AVFrame *picture,
                         int *got_frame, AVPacket *avpkt)
 {
     const uint8_t *buf    = avpkt->data;
     int buf_size          = avpkt->size;
     FourXContext *const f = avctx->priv_data;
-    AVFrame *picture      = data;
     int i, frame_4cc, frame_size, ret;
 
     if (buf_size < 20)
@@ -1008,10 +1008,8 @@ static av_cold int decode_init(AVCodecCo
 
     f->frame_buffer      = av_mallocz(avctx->width * avctx->height * 2);
     f->last_frame_buffer = av_mallocz(avctx->width * avctx->height * 2);
-    if (!f->frame_buffer || !f->last_frame_buffer) {
-        decode_end(avctx);
+    if (!f->frame_buffer || !f->last_frame_buffer)
         return AVERROR(ENOMEM);
-    }
 
     f->version = AV_RL32(avctx->extradata) >> 16;
     ff_blockdsp_init(&f->bdsp, avctx);
@@ -1028,15 +1026,15 @@ static av_cold int decode_init(AVCodecCo
     return 0;
 }
 
-const AVCodec ff_fourxm_decoder = {
-    .name           = "4xm",
-    .long_name      = NULL_IF_CONFIG_SMALL("4X Movie"),
-    .type           = AVMEDIA_TYPE_VIDEO,
-    .id             = AV_CODEC_ID_4XM,
+const FFCodec ff_fourxm_decoder = {
+    .p.name         = "4xm",
+    .p.long_name    = NULL_IF_CONFIG_SMALL("4X Movie"),
+    .p.type         = AVMEDIA_TYPE_VIDEO,
+    .p.id           = AV_CODEC_ID_4XM,
     .priv_data_size = sizeof(FourXContext),
     .init           = decode_init,
     .close          = decode_end,
-    .decode         = decode_frame,
-    .capabilities   = AV_CODEC_CAP_DR1,
-    .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
+    FF_CODEC_DECODE_CB(decode_frame),
+    .p.capabilities = AV_CODEC_CAP_DR1,
+    .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
 };
diff -pruN 7:5.0.1-3/libavcodec/8bps.c 7:5.1-1/libavcodec/8bps.c
--- 7:5.0.1-3/libavcodec/8bps.c	2022-01-14 18:45:39.000000000 +0000
+++ 7:5.1-1/libavcodec/8bps.c	2022-07-22 17:58:38.000000000 +0000
@@ -37,6 +37,7 @@
 #include "libavutil/internal.h"
 #include "libavutil/intreadwrite.h"
 #include "avcodec.h"
+#include "codec_internal.h"
 #include "decode.h"
 #include "internal.h"
 
@@ -53,10 +54,9 @@ typedef struct EightBpsContext {
     uint32_t pal[256];
 } EightBpsContext;
 
-static int decode_frame(AVCodecContext *avctx, void *data,
+static int decode_frame(AVCodecContext *avctx, AVFrame *frame,
                         int *got_frame, AVPacket *avpkt)
 {
-    AVFrame *frame = data;
     const uint8_t *buf = avpkt->data;
     int buf_size       = avpkt->size;
     EightBpsContext * const c = avctx->priv_data;
@@ -173,13 +173,14 @@ static av_cold int decode_init(AVCodecCo
     return 0;
 }
 
-const AVCodec ff_eightbps_decoder = {
-    .name           = "8bps",
-    .long_name      = NULL_IF_CONFIG_SMALL("QuickTime 8BPS video"),
-    .type           = AVMEDIA_TYPE_VIDEO,
-    .id             = AV_CODEC_ID_8BPS,
+const FFCodec ff_eightbps_decoder = {
+    .p.name         = "8bps",
+    .p.long_name    = NULL_IF_CONFIG_SMALL("QuickTime 8BPS video"),
+    .p.type         = AVMEDIA_TYPE_VIDEO,
+    .p.id           = AV_CODEC_ID_8BPS,
     .priv_data_size = sizeof(EightBpsContext),
     .init           = decode_init,
-    .decode         = decode_frame,
-    .capabilities   = AV_CODEC_CAP_DR1,
+    FF_CODEC_DECODE_CB(decode_frame),
+    .p.capabilities = AV_CODEC_CAP_DR1,
+    .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff -pruN 7:5.0.1-3/libavcodec/8svx.c 7:5.1-1/libavcodec/8svx.c
--- 7:5.0.1-3/libavcodec/8svx.c	2022-01-14 18:45:39.000000000 +0000
+++ 7:5.1-1/libavcodec/8svx.c	2022-07-22 17:58:38.000000000 +0000
@@ -37,8 +37,11 @@
  * http://aminet.net/mods/smpl/
  */
 
+#include "config_components.h"
+
 #include "libavutil/avassert.h"
 #include "avcodec.h"
+#include "codec_internal.h"
 #include "internal.h"
 #include "libavutil/common.h"
 
@@ -83,43 +86,43 @@ static void delta_decode(uint8_t *dst, c
 }
 
 /** decode a frame */
-static int eightsvx_decode_frame(AVCodecContext *avctx, void *data,
+static int eightsvx_decode_frame(AVCodecContext *avctx, AVFrame *frame,
                                  int *got_frame_ptr, AVPacket *avpkt)
 {
     EightSvxContext *esc = avctx->priv_data;
-    AVFrame *frame       = data;
+    int channels         = avctx->ch_layout.nb_channels;
     int buf_size;
     int ch, ret;
     int hdr_size = 2;
 
     /* decode and interleave the first packet */
     if (!esc->data[0] && avpkt) {
-        int chan_size = avpkt->size / avctx->channels - hdr_size;
+        int chan_size = avpkt->size / channels - hdr_size;
 
-        if (avpkt->size % avctx->channels) {
+        if (avpkt->size % channels) {
             av_log(avctx, AV_LOG_WARNING, "Packet with odd size, ignoring last byte\n");
         }
-        if (avpkt->size < (hdr_size + 1) * avctx->channels) {
+        if (avpkt->size < (hdr_size + 1) * channels) {
             av_log(avctx, AV_LOG_ERROR, "packet size is too small\n");
             return AVERROR_INVALIDDATA;
         }
 
         esc->fib_acc[0] = avpkt->data[1] + 128;
-        if (avctx->channels == 2)
+        if (channels == 2)
             esc->fib_acc[1] = avpkt->data[2+chan_size+1] + 128;
 
         esc->data_idx  = 0;
         esc->data_size = chan_size;
         if (!(esc->data[0] = av_malloc(chan_size)))
             return AVERROR(ENOMEM);
-        if (avctx->channels == 2) {
+        if (channels == 2) {
             if (!(esc->data[1] = av_malloc(chan_size))) {
                 av_freep(&esc->data[0]);
                 return AVERROR(ENOMEM);
             }
         }
         memcpy(esc->data[0], &avpkt->data[hdr_size], chan_size);
-        if (avctx->channels == 2)
+        if (channels == 2)
             memcpy(esc->data[1], &avpkt->data[2*hdr_size+chan_size], chan_size);
     }
     if (!esc->data[0]) {
@@ -139,7 +142,7 @@ static int eightsvx_decode_frame(AVCodec
     if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
         return ret;
 
-    for (ch = 0; ch < avctx->channels; ch++) {
+    for (ch = 0; ch < channels; ch++) {
         delta_decode(frame->data[ch], &esc->data[ch][esc->data_idx],
                      buf_size, &esc->fib_acc[ch], esc->table);
     }
@@ -148,14 +151,14 @@ static int eightsvx_decode_frame(AVCodec
 
     *got_frame_ptr = 1;
 
-    return ((avctx->frame_number == 0)*hdr_size + buf_size)*avctx->channels;
+    return ((avctx->frame_number == 0) * hdr_size + buf_size) * channels;
 }
 
 static av_cold int eightsvx_decode_init(AVCodecContext *avctx)
 {
     EightSvxContext *esc = avctx->priv_data;
 
-    if (avctx->channels < 1 || avctx->channels > 2) {
+    if (avctx->ch_layout.nb_channels < 1 || avctx->ch_layout.nb_channels > 2) {
         av_log(avctx, AV_LOG_ERROR, "8SVX does not support more than 2 channels\n");
         return AVERROR_INVALIDDATA;
     }
@@ -184,33 +187,33 @@ static av_cold int eightsvx_decode_close
 }
 
 #if CONFIG_EIGHTSVX_FIB_DECODER
-const AVCodec ff_eightsvx_fib_decoder = {
-  .name           = "8svx_fib",
-  .long_name      = NULL_IF_CONFIG_SMALL("8SVX fibonacci"),
-  .type           = AVMEDIA_TYPE_AUDIO,
-  .id             = AV_CODEC_ID_8SVX_FIB,
+const FFCodec ff_eightsvx_fib_decoder = {
+  .p.name         = "8svx_fib",
+  .p.long_name    = NULL_IF_CONFIG_SMALL("8SVX fibonacci"),
+  .p.type         = AVMEDIA_TYPE_AUDIO,
+  .p.id           = AV_CODEC_ID_8SVX_FIB,
   .priv_data_size = sizeof (EightSvxContext),
   .init           = eightsvx_decode_init,
-  .decode         = eightsvx_decode_frame,
+  FF_CODEC_DECODE_CB(eightsvx_decode_frame),
   .close          = eightsvx_decode_close,
-  .capabilities   = AV_CODEC_CAP_DR1,
-  .sample_fmts    = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_U8P,
+  .p.capabilities = AV_CODEC_CAP_DR1,
+  .p.sample_fmts  = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_U8P,
                                                     AV_SAMPLE_FMT_NONE },
   .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
 #endif
 #if CONFIG_EIGHTSVX_EXP_DECODER
-const AVCodec ff_eightsvx_exp_decoder = {
-  .name           = "8svx_exp",
-  .long_name      = NULL_IF_CONFIG_SMALL("8SVX exponential"),
-  .type           = AVMEDIA_TYPE_AUDIO,
-  .id             = AV_CODEC_ID_8SVX_EXP,
+const FFCodec ff_eightsvx_exp_decoder = {
+  .p.name         = "8svx_exp",
+  .p.long_name    = NULL_IF_CONFIG_SMALL("8SVX exponential"),
+  .p.type         = AVMEDIA_TYPE_AUDIO,
+  .p.id           = AV_CODEC_ID_8SVX_EXP,
   .priv_data_size = sizeof (EightSvxContext),
   .init           = eightsvx_decode_init,
-  .decode         = eightsvx_decode_frame,
+  FF_CODEC_DECODE_CB(eightsvx_decode_frame),
   .close          = eightsvx_decode_close,
-  .capabilities   = AV_CODEC_CAP_DR1,
-  .sample_fmts    = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_U8P,
+  .p.capabilities = AV_CODEC_CAP_DR1,
+  .p.sample_fmts  = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_U8P,
                                                     AV_SAMPLE_FMT_NONE },
   .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff -pruN 7:5.0.1-3/libavcodec/a64multienc.c 7:5.1-1/libavcodec/a64multienc.c
--- 7:5.0.1-3/libavcodec/a64multienc.c	2022-01-14 18:45:39.000000000 +0000
+++ 7:5.1-1/libavcodec/a64multienc.c	2022-07-22 17:58:38.000000000 +0000
@@ -24,11 +24,13 @@
  * a64 video encoder - multicolor modes
  */
 
+#include "config_components.h"
+
 #include "a64colors.h"
 #include "a64tables.h"
+#include "codec_internal.h"
 #include "elbg.h"
 #include "encode.h"
-#include "internal.h"
 #include "libavutil/avassert.h"
 #include "libavutil/common.h"
 #include "libavutil/intreadwrite.h"
@@ -391,32 +393,32 @@ static int a64multi_encode_frame(AVCodec
 }
 
 #if CONFIG_A64MULTI_ENCODER
-const AVCodec ff_a64multi_encoder = {
-    .name           = "a64multi",
-    .long_name      = NULL_IF_CONFIG_SMALL("Multicolor charset for Commodore 64"),
-    .type           = AVMEDIA_TYPE_VIDEO,
-    .id             = AV_CODEC_ID_A64_MULTI,
-    .capabilities   = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY,
+const FFCodec ff_a64multi_encoder = {
+    .p.name         = "a64multi",
+    .p.long_name    = NULL_IF_CONFIG_SMALL("Multicolor charset for Commodore 64"),
+    .p.type         = AVMEDIA_TYPE_VIDEO,
+    .p.id           = AV_CODEC_ID_A64_MULTI,
+    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY,
     .priv_data_size = sizeof(A64Context),
     .init           = a64multi_encode_init,
-    .encode2        = a64multi_encode_frame,
+    FF_CODEC_ENCODE_CB(a64multi_encode_frame),
     .close          = a64multi_close_encoder,
-    .pix_fmts       = (const enum AVPixelFormat[]) {AV_PIX_FMT_GRAY8, AV_PIX_FMT_NONE},
+    .p.pix_fmts     = (const enum AVPixelFormat[]) {AV_PIX_FMT_GRAY8, AV_PIX_FMT_NONE},
     .caps_internal  = FF_CODEC_CAP_INIT_CLEANUP | FF_CODEC_CAP_INIT_THREADSAFE,
 };
 #endif
 #if CONFIG_A64MULTI5_ENCODER
-const AVCodec ff_a64multi5_encoder = {
-    .name           = "a64multi5",
-    .long_name      = NULL_IF_CONFIG_SMALL("Multicolor charset for Commodore 64, extended with 5th color (colram)"),
-    .type           = AVMEDIA_TYPE_VIDEO,
-    .id             = AV_CODEC_ID_A64_MULTI5,
-    .capabilities   = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY,
+const FFCodec ff_a64multi5_encoder = {
+    .p.name         = "a64multi5",
+    .p.long_name    = NULL_IF_CONFIG_SMALL("Multicolor charset for Commodore 64, extended with 5th color (colram)"),
+    .p.type         = AVMEDIA_TYPE_VIDEO,
+    .p.id           = AV_CODEC_ID_A64_MULTI5,
+    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY,
     .priv_data_size = sizeof(A64Context),
     .init           = a64multi_encode_init,
-    .encode2        = a64multi_encode_frame,
+    FF_CODEC_ENCODE_CB(a64multi_encode_frame),
     .close          = a64multi_close_encoder,
-    .pix_fmts       = (const enum AVPixelFormat[]) {AV_PIX_FMT_GRAY8, AV_PIX_FMT_NONE},
+    .p.pix_fmts     = (const enum AVPixelFormat[]) {AV_PIX_FMT_GRAY8, AV_PIX_FMT_NONE},
     .caps_internal  = FF_CODEC_CAP_INIT_CLEANUP | FF_CODEC_CAP_INIT_THREADSAFE,
 };
 #endif
diff -pruN 7:5.0.1-3/libavcodec/aac_ac3_parser.c 7:5.1-1/libavcodec/aac_ac3_parser.c
--- 7:5.0.1-3/libavcodec/aac_ac3_parser.c	2021-10-24 20:47:07.000000000 +0000
+++ 7:5.1-1/libavcodec/aac_ac3_parser.c	2022-07-22 17:58:38.000000000 +0000
@@ -20,6 +20,8 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "config_components.h"
+
 #include "libavutil/channel_layout.h"
 #include "libavutil/common.h"
 #include "parser.h"
@@ -90,8 +92,19 @@ get_next:
         if (avctx->codec_id != AV_CODEC_ID_AAC) {
             avctx->sample_rate = s->sample_rate;
             if (!CONFIG_EAC3_DECODER || avctx->codec_id != AV_CODEC_ID_EAC3) {
-                avctx->channels = s->channels;
+                av_channel_layout_uninit(&avctx->ch_layout);
+                if (s->channel_layout) {
+                    av_channel_layout_from_mask(&avctx->ch_layout, s->channel_layout);
+                } else {
+                    avctx->ch_layout.order       = AV_CHANNEL_ORDER_UNSPEC;
+                    avctx->ch_layout.nb_channels = s->channels;
+                }
+#if FF_API_OLD_CHANNEL_LAYOUT
+FF_DISABLE_DEPRECATION_WARNINGS
+                avctx->channels = avctx->ch_layout.nb_channels;
                 avctx->channel_layout = s->channel_layout;
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
             }
             s1->duration = s->samples;
             avctx->audio_service_type = s->service_type;
diff -pruN 7:5.0.1-3/libavcodec/aac_adtstoasc_bsf.c 7:5.1-1/libavcodec/aac_adtstoasc_bsf.c
--- 7:5.0.1-3/libavcodec/aac_adtstoasc_bsf.c	2021-10-21 17:06:35.000000000 +0000
+++ 7:5.1-1/libavcodec/aac_adtstoasc_bsf.c	2022-07-22 17:58:38.000000000 +0000
@@ -26,7 +26,6 @@
 #include "put_bits.h"
 #include "get_bits.h"
 #include "mpeg4audio.h"
-#include "internal.h"
 
 typedef struct AACBSFContext {
     int first_frame_done;
@@ -149,10 +148,10 @@ static const enum AVCodecID codec_ids[]
     AV_CODEC_ID_AAC, AV_CODEC_ID_NONE,
 };
 
-const AVBitStreamFilter ff_aac_adtstoasc_bsf = {
-    .name           = "aac_adtstoasc",
+const FFBitStreamFilter ff_aac_adtstoasc_bsf = {
+    .p.name         = "aac_adtstoasc",
+    .p.codec_ids    = codec_ids,
     .priv_data_size = sizeof(AACBSFContext),
     .init           = aac_adtstoasc_init,
     .filter         = aac_adtstoasc_filter,
-    .codec_ids      = codec_ids,
 };
diff -pruN 7:5.0.1-3/libavcodec/aaccoder.c 7:5.1-1/libavcodec/aaccoder.c
--- 7:5.0.1-3/libavcodec/aaccoder.c	2022-01-14 18:45:39.000000000 +0000
+++ 7:5.1-1/libavcodec/aaccoder.c	2022-07-22 17:58:38.000000000 +0000
@@ -397,7 +397,7 @@ static void search_for_quantizers_fast(A
                                        const float lambda)
 {
     int start = 0, i, w, w2, g;
-    int destbits = avctx->bit_rate * 1024.0 / avctx->sample_rate / avctx->channels * (lambda / 120.f);
+    int destbits = avctx->bit_rate * 1024.0 / avctx->sample_rate / avctx->ch_layout.nb_channels * (lambda / 120.f);
     float dists[128] = { 0 }, uplims[128] = { 0 };
     float maxvals[128];
     int fflag, minscaler;
@@ -556,7 +556,7 @@ static void search_for_pns(AACEncContext
     const float pns_transient_energy_r = FFMIN(0.7f, lambda / 140.f);
 
     int refbits = avctx->bit_rate * 1024.0 / avctx->sample_rate
-        / ((avctx->flags & AV_CODEC_FLAG_QSCALE) ? 2.0f : avctx->channels)
+        / ((avctx->flags & AV_CODEC_FLAG_QSCALE) ? 2.0f : avctx->ch_layout.nb_channels)
         * (lambda / 120.f);
 
     /** Keep this in sync with twoloop's cutoff selection */
@@ -564,7 +564,7 @@ static void search_for_pns(AACEncContext
     int prev = -1000, prev_sf = -1;
     int frame_bit_rate = (avctx->flags & AV_CODEC_FLAG_QSCALE)
         ? (refbits * rate_bandwidth_multiplier * avctx->sample_rate / 1024)
-        : (avctx->bit_rate / avctx->channels);
+        : (avctx->bit_rate / avctx->ch_layout.nb_channels);
 
     frame_bit_rate *= 1.15f;
 
@@ -693,14 +693,14 @@ static void mark_pns(AACEncContext *s, A
     const float pns_transient_energy_r = FFMIN(0.7f, lambda / 140.f);
 
     int refbits = avctx->bit_rate * 1024.0 / avctx->sample_rate
-        / ((avctx->flags & AV_CODEC_FLAG_QSCALE) ? 2.0f : avctx->channels)
+        / ((avctx->flags & AV_CODEC_FLAG_QSCALE) ? 2.0f : avctx->ch_layout.nb_channels)
         * (lambda / 120.f);
 
     /** Keep this in sync with twoloop's cutoff selection */
     float rate_bandwidth_multiplier = 1.5f;
     int frame_bit_rate = (avctx->flags & AV_CODEC_FLAG_QSCALE)
         ? (refbits * rate_bandwidth_multiplier * avctx->sample_rate / 1024)
-        : (avctx->bit_rate / avctx->channels);
+        : (avctx->bit_rate / avctx->ch_layout.nb_channels);
 
     frame_bit_rate *= 1.15f;
 
diff -pruN 7:5.0.1-3/libavcodec/aaccoder_twoloop.h 7:5.1-1/libavcodec/aaccoder_twoloop.h
--- 7:5.0.1-3/libavcodec/aaccoder_twoloop.h	2021-10-21 17:06:35.000000000 +0000
+++ 7:5.1-1/libavcodec/aaccoder_twoloop.h	2022-07-22 17:58:38.000000000 +0000
@@ -71,7 +71,7 @@ static void search_for_quantizers_twoloo
 {
     int start = 0, i, w, w2, g, recomprd;
     int destbits = avctx->bit_rate * 1024.0 / avctx->sample_rate
-        / ((avctx->flags & AV_CODEC_FLAG_QSCALE) ? 2.0f : avctx->channels)
+        / ((avctx->flags & AV_CODEC_FLAG_QSCALE) ? 2.0f : avctx->ch_layout.nb_channels)
         * (lambda / 120.f);
     int refbits = destbits;
     int toomanybits, toofewbits;
@@ -186,7 +186,7 @@ static void search_for_quantizers_twoloo
         float rate_bandwidth_multiplier = 1.5f;
         int frame_bit_rate = (avctx->flags & AV_CODEC_FLAG_QSCALE)
             ? (refbits * rate_bandwidth_multiplier * avctx->sample_rate / 1024)
-            : (avctx->bit_rate / avctx->channels);
+            : (avctx->bit_rate / avctx->ch_layout.nb_channels);
 
         /** Compensate for extensions that increase efficiency */
         if (s->options.pns || s->options.intensity_stereo)
diff -pruN 7:5.0.1-3/libavcodec/aacdec.c 7:5.1-1/libavcodec/aacdec.c
--- 7:5.0.1-3/libavcodec/aacdec.c	2022-01-14 18:45:39.000000000 +0000
+++ 7:5.1-1/libavcodec/aacdec.c	2022-07-22 17:58:38.000000000 +0000
@@ -38,7 +38,7 @@
 #include "libavutil/float_dsp.h"
 #include "libavutil/opt.h"
 #include "avcodec.h"
-#include "internal.h"
+#include "codec_internal.h"
 #include "get_bits.h"
 #include "fft.h"
 #include "mdct15.h"
@@ -480,7 +480,7 @@ static int read_audio_mux_element(struct
 }
 
 
-static int latm_decode_frame(AVCodecContext *avctx, void *out,
+static int latm_decode_frame(AVCodecContext *avctx, AVFrame *out,
                              int *got_frame_ptr, AVPacket *avpkt)
 {
     struct LATMContext *latmctx = avctx->priv_data;
@@ -552,24 +552,27 @@ static av_cold int latm_decode_init(AVCo
     return ret;
 }
 
-const AVCodec ff_aac_decoder = {
-    .name            = "aac",
-    .long_name       = NULL_IF_CONFIG_SMALL("AAC (Advanced Audio Coding)"),
-    .type            = AVMEDIA_TYPE_AUDIO,
-    .id              = AV_CODEC_ID_AAC,
+const FFCodec ff_aac_decoder = {
+    .p.name          = "aac",
+    .p.long_name     = NULL_IF_CONFIG_SMALL("AAC (Advanced Audio Coding)"),
+    .p.type          = AVMEDIA_TYPE_AUDIO,
+    .p.id            = AV_CODEC_ID_AAC,
     .priv_data_size  = sizeof(AACContext),
     .init            = aac_decode_init,
     .close           = aac_decode_close,
-    .decode          = aac_decode_frame,
-    .sample_fmts     = (const enum AVSampleFormat[]) {
+    FF_CODEC_DECODE_CB(aac_decode_frame),
+    .p.sample_fmts   = (const enum AVSampleFormat[]) {
         AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE
     },
-    .capabilities    = AV_CODEC_CAP_CHANNEL_CONF | AV_CODEC_CAP_DR1,
+    .p.capabilities  = AV_CODEC_CAP_CHANNEL_CONF | AV_CODEC_CAP_DR1,
     .caps_internal   = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
-    .channel_layouts = aac_channel_layout,
+#if FF_API_OLD_CHANNEL_LAYOUT
+    .p.channel_layouts = aac_channel_layout,
+#endif
+    .p.ch_layouts    = aac_ch_layout,
     .flush = flush,
-    .priv_class      = &aac_decoder_class,
-    .profiles        = NULL_IF_CONFIG_SMALL(ff_aac_profiles),
+    .p.priv_class    = &aac_decoder_class,
+    .p.profiles      = NULL_IF_CONFIG_SMALL(ff_aac_profiles),
 };
 
 /*
@@ -577,21 +580,24 @@ const AVCodec ff_aac_decoder = {
     in MPEG transport streams which only contain one program.
     To do a more complex LATM demuxing a separate LATM demuxer should be used.
 */
-const AVCodec ff_aac_latm_decoder = {
-    .name            = "aac_latm",
-    .long_name       = NULL_IF_CONFIG_SMALL("AAC LATM (Advanced Audio Coding LATM syntax)"),
-    .type            = AVMEDIA_TYPE_AUDIO,
-    .id              = AV_CODEC_ID_AAC_LATM,
+const FFCodec ff_aac_latm_decoder = {
+    .p.name          = "aac_latm",
+    .p.long_name     = NULL_IF_CONFIG_SMALL("AAC LATM (Advanced Audio Coding LATM syntax)"),
+    .p.type          = AVMEDIA_TYPE_AUDIO,
+    .p.id            = AV_CODEC_ID_AAC_LATM,
     .priv_data_size  = sizeof(struct LATMContext),
     .init            = latm_decode_init,
     .close           = aac_decode_close,
-    .decode          = latm_decode_frame,
-    .sample_fmts     = (const enum AVSampleFormat[]) {
+    FF_CODEC_DECODE_CB(latm_decode_frame),
+    .p.sample_fmts   = (const enum AVSampleFormat[]) {
         AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE
     },
-    .capabilities    = AV_CODEC_CAP_CHANNEL_CONF | AV_CODEC_CAP_DR1,
+    .p.capabilities  = AV_CODEC_CAP_CHANNEL_CONF | AV_CODEC_CAP_DR1,
     .caps_internal   = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
-    .channel_layouts = aac_channel_layout,
+#if FF_API_OLD_CHANNEL_LAYOUT
+    .p.channel_layouts = aac_channel_layout,
+#endif
+    .p.ch_layouts    = aac_ch_layout,
     .flush = flush,
-    .profiles        = NULL_IF_CONFIG_SMALL(ff_aac_profiles),
+    .p.profiles      = NULL_IF_CONFIG_SMALL(ff_aac_profiles),
 };
diff -pruN 7:5.0.1-3/libavcodec/aacdec_fixed.c 7:5.1-1/libavcodec/aacdec_fixed.c
--- 7:5.0.1-3/libavcodec/aacdec_fixed.c	2022-01-14 18:45:39.000000000 +0000
+++ 7:5.1-1/libavcodec/aacdec_fixed.c	2022-07-22 17:58:38.000000000 +0000
@@ -64,7 +64,7 @@
 #include "libavutil/fixed_dsp.h"
 #include "libavutil/opt.h"
 #include "avcodec.h"
-#include "internal.h"
+#include "codec_internal.h"
 #include "get_bits.h"
 #include "fft.h"
 #include "lpc.h"
@@ -450,21 +450,24 @@ static void apply_independent_coupling_f
 
 #include "aacdec_template.c"
 
-const AVCodec ff_aac_fixed_decoder = {
-    .name            = "aac_fixed",
-    .long_name       = NULL_IF_CONFIG_SMALL("AAC (Advanced Audio Coding)"),
-    .type            = AVMEDIA_TYPE_AUDIO,
-    .id              = AV_CODEC_ID_AAC,
+const FFCodec ff_aac_fixed_decoder = {
+    .p.name          = "aac_fixed",
+    .p.long_name     = NULL_IF_CONFIG_SMALL("AAC (Advanced Audio Coding)"),
+    .p.type          = AVMEDIA_TYPE_AUDIO,
+    .p.id            = AV_CODEC_ID_AAC,
     .priv_data_size  = sizeof(AACContext),
     .init            = aac_decode_init,
     .close           = aac_decode_close,
-    .decode          = aac_decode_frame,
-    .sample_fmts     = (const enum AVSampleFormat[]) {
+    FF_CODEC_DECODE_CB(aac_decode_frame),
+    .p.sample_fmts   = (const enum AVSampleFormat[]) {
         AV_SAMPLE_FMT_S32P, AV_SAMPLE_FMT_NONE
     },
-    .capabilities    = AV_CODEC_CAP_CHANNEL_CONF | AV_CODEC_CAP_DR1,
+    .p.capabilities  = AV_CODEC_CAP_CHANNEL_CONF | AV_CODEC_CAP_DR1,
     .caps_internal   = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
-    .channel_layouts = aac_channel_layout,
-    .profiles        = NULL_IF_CONFIG_SMALL(ff_aac_profiles),
+#if FF_API_OLD_CHANNEL_LAYOUT
+    .p.channel_layouts = aac_channel_layout,
+#endif
+    .p.ch_layouts    = aac_ch_layout,
+    .p.profiles      = NULL_IF_CONFIG_SMALL(ff_aac_profiles),
     .flush = flush,
 };
diff -pruN 7:5.0.1-3/libavcodec/aacdectab.h 7:5.1-1/libavcodec/aacdectab.h
--- 7:5.0.1-3/libavcodec/aacdectab.h	2021-10-24 20:47:07.000000000 +0000
+++ 7:5.1-1/libavcodec/aacdectab.h	2022-07-22 17:58:38.000000000 +0000
@@ -72,6 +72,7 @@ static const uint8_t aac_channel_layout_
     /* TODO: Add 7+1 TOP configuration */
 };
 
+#if FF_API_OLD_CHANNEL_LAYOUT
 static const uint64_t aac_channel_layout[16] = {
     AV_CH_LAYOUT_MONO,
     AV_CH_LAYOUT_STEREO,
@@ -89,5 +90,24 @@ static const uint64_t aac_channel_layout
     0,
     /* AV_CH_LAYOUT_7POINT1_TOP, */
 };
+#endif
+
+static const AVChannelLayout aac_ch_layout[16] = {
+    AV_CHANNEL_LAYOUT_MONO,
+    AV_CHANNEL_LAYOUT_STEREO,
+    AV_CHANNEL_LAYOUT_SURROUND,
+    AV_CHANNEL_LAYOUT_4POINT0,
+    AV_CHANNEL_LAYOUT_5POINT0_BACK,
+    AV_CHANNEL_LAYOUT_5POINT1_BACK,
+    AV_CHANNEL_LAYOUT_7POINT1_WIDE_BACK,
+    { 0 },
+    { 0 },
+    { 0 },
+    AV_CHANNEL_LAYOUT_6POINT1,
+    AV_CHANNEL_LAYOUT_7POINT1,
+    AV_CHANNEL_LAYOUT_22POINT2,
+    { 0 },
+    /* AV_CHANNEL_LAYOUT_7POINT1_TOP, */
+};
 
 #endif /* AVCODEC_AACDECTAB_H */
diff -pruN 7:5.0.1-3/libavcodec/aacdec_template.c 7:5.1-1/libavcodec/aacdec_template.c
--- 7:5.0.1-3/libavcodec/aacdec_template.c	2022-01-14 18:45:39.000000000 +0000
+++ 7:5.1-1/libavcodec/aacdec_template.c	2022-07-22 17:58:38.000000000 +0000
@@ -91,6 +91,7 @@
 
 #include "libavutil/channel_layout.h"
 #include "libavutil/thread.h"
+#include "internal.h"
 
 static VLC vlc_scalefactors;
 static VLC vlc_spectral[11];
@@ -174,7 +175,7 @@ static int frame_configure_elements(AVCo
 
     /* get output buffer */
     av_frame_unref(ac->frame);
-    if (!avctx->channels)
+    if (!avctx->ch_layout.nb_channels)
         return 1;
 
     ac->frame->nb_samples = 2048;
@@ -182,7 +183,7 @@ static int frame_configure_elements(AVCo
         return ret;
 
     /* map output channel pointers to AVFrame data */
-    for (ch = 0; ch < avctx->channels; ch++) {
+    for (ch = 0; ch < avctx->ch_layout.nb_channels; ch++) {
         if (ac->output_element[ch])
             ac->output_element[ch]->ret = (INTFLOAT *)ac->frame->extended_data[ch];
     }
@@ -517,8 +518,7 @@ static int push_output_configuration(AAC
 static void pop_output_configuration(AACContext *ac) {
     if (ac->oc[1].status != OC_LOCKED && ac->oc[0].status != OC_NONE) {
         ac->oc[1] = ac->oc[0];
-        ac->avctx->channels = ac->oc[1].channels;
-        ac->avctx->channel_layout = ac->oc[1].channel_layout;
+        ac->avctx->ch_layout = ac->oc[1].ch_layout;
         output_configure(ac, ac->oc[1].layout_map, ac->oc[1].layout_map_tags,
                          ac->oc[1].status, 0);
     }
@@ -555,7 +555,14 @@ static int output_configure(AACContext *
     }
     // Try to sniff a reasonable channel order, otherwise output the
     // channels in the order the PCE declared them.
-    if (avctx->request_channel_layout != AV_CH_LAYOUT_NATIVE)
+#if FF_API_OLD_CHANNEL_LAYOUT
+FF_DISABLE_DEPRECATION_WARNINGS
+    if (avctx->request_channel_layout == AV_CH_LAYOUT_NATIVE)
+        ac->output_channel_order = CHANNEL_ORDER_CODED;
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
+
+    if (ac->output_channel_order == CHANNEL_ORDER_DEFAULT)
         layout = sniff_channel_order(layout_map, tags);
     for (i = 0; i < tags; i++) {
         int type =     layout_map[i][0];
@@ -577,9 +584,15 @@ static int output_configure(AACContext *
         }
     }
 
-    if (layout) avctx->channel_layout = layout;
-                            ac->oc[1].channel_layout = layout;
-    avctx->channels       = ac->oc[1].channels       = channels;
+    av_channel_layout_uninit(&ac->oc[1].ch_layout);
+    if (layout)
+        av_channel_layout_from_mask(&ac->oc[1].ch_layout, layout);
+    else {
+        ac->oc[1].ch_layout.order       = AV_CHANNEL_ORDER_UNSPEC;
+        ac->oc[1].ch_layout.nb_channels = channels;
+    }
+
+    av_channel_layout_copy(&avctx->ch_layout, &ac->oc[1].ch_layout);
     ac->oc[1].status = oc_type;
 
     if (get_new_frame) {
@@ -688,14 +701,15 @@ static ChannelElement *get_che(AACContex
 
         av_log(ac->avctx, AV_LOG_DEBUG, "stereo with SCE\n");
 
-        if (set_default_channel_config(ac, ac->avctx, layout_map,
-                                       &layout_map_tags, 1) < 0)
-            return NULL;
+        layout_map_tags = 2;
+        layout_map[0][0] = layout_map[1][0] = TYPE_SCE;
+        layout_map[0][2] = layout_map[1][2] = AAC_CHANNEL_FRONT;
+        layout_map[0][1] = 0;
+        layout_map[1][1] = 1;
         if (output_configure(ac, layout_map, layout_map_tags,
                              OC_TRIAL_FRAME, 1) < 0)
             return NULL;
 
-        ac->oc[1].m4ac.chan_config = 1;
         if (ac->oc[1].m4ac.sbr)
             ac->oc[1].m4ac.ps = -1;
     }
@@ -773,8 +787,10 @@ static ChannelElement *get_che(AACContex
             type == TYPE_CPE) {
             ac->tags_mapped++;
             return ac->tag_che_map[TYPE_CPE][elem_id] = ac->che[TYPE_CPE][0];
-        } else if (ac->oc[1].m4ac.chan_config == 2) {
-            return NULL;
+        } else if (ac->tags_mapped == 1 && ac->oc[1].m4ac.chan_config == 2 &&
+            type == TYPE_SCE) {
+            ac->tags_mapped++;
+            return ac->tag_che_map[TYPE_SCE][elem_id] = ac->che[TYPE_SCE][1];
         }
     case 1:
         if (!ac->tags_mapped && type == TYPE_SCE) {
@@ -1208,8 +1224,8 @@ static void aacdec_init(AACContext *ac);
 
 static av_cold void aac_static_table_init(void)
 {
-    static VLC_TYPE vlc_buf[304 + 270 + 550 + 300 + 328 +
-                            294 + 306 + 268 + 510 + 366 + 462][2];
+    static VLCElem vlc_buf[304 + 270 + 550 + 300 + 328 +
+                           294 + 306 + 268 + 510 + 366 + 462];
     for (unsigned i = 0, offset = 0; i < 11; i++) {
         vlc_spectral[i].table           = &vlc_buf[offset];
         vlc_spectral[i].table_allocated = FF_ARRAY_ELEMS(vlc_buf) - offset;
@@ -1292,12 +1308,12 @@ static av_cold int aac_decode_init(AVCod
 
         sr = sample_rate_idx(avctx->sample_rate);
         ac->oc[1].m4ac.sampling_index = sr;
-        ac->oc[1].m4ac.channels = avctx->channels;
+        ac->oc[1].m4ac.channels = avctx->ch_layout.nb_channels;
         ac->oc[1].m4ac.sbr = -1;
         ac->oc[1].m4ac.ps = -1;
 
         for (i = 0; i < FF_ARRAY_ELEMS(ff_mpeg4audio_channels); i++)
-            if (ff_mpeg4audio_channels[i] == avctx->channels)
+            if (ff_mpeg4audio_channels[i] == avctx->ch_layout.nb_channels)
                 break;
         if (i == FF_ARRAY_ELEMS(ff_mpeg4audio_channels)) {
             i = 0;
@@ -1315,7 +1331,7 @@ static av_cold int aac_decode_init(AVCod
         }
     }
 
-    if (avctx->channels > MAX_CHANNELS) {
+    if (avctx->ch_layout.nb_channels > MAX_CHANNELS) {
         av_log(avctx, AV_LOG_ERROR, "Too many channels\n");
         return AVERROR_INVALIDDATA;
     }
@@ -1808,7 +1824,7 @@ static int decode_spectrum_and_dequant(A
 #if !USE_FIXED
                 const float *vq = ff_aac_codebook_vector_vals[cbt_m1];
 #endif /* !USE_FIXED */
-                VLC_TYPE (*vlc_tab)[2] = vlc_spectral[cbt_m1].table;
+                const VLCElem *vlc_tab = vlc_spectral[cbt_m1].table;
                 OPEN_READER(re, gb);
 
                 switch (cbt_m1 >> 1) {
@@ -2556,7 +2572,8 @@ static int decode_extension_payload(AACC
             av_log(ac->avctx, AV_LOG_ERROR, "Implicit SBR was found with a first occurrence after the first frame.\n");
             skip_bits_long(gb, 8 * cnt - 4);
             return res;
-        } else if (ac->oc[1].m4ac.ps == -1 && ac->oc[1].status < OC_LOCKED && ac->avctx->channels == 1) {
+        } else if (ac->oc[1].m4ac.ps == -1 && ac->oc[1].status < OC_LOCKED &&
+                   ac->avctx->ch_layout.nb_channels == 1) {
             ac->oc[1].m4ac.sbr = 1;
             ac->oc[1].m4ac.ps = 1;
             ac->avctx->profile = FF_PROFILE_AAC_HE_V2;
@@ -3221,7 +3238,7 @@ static int aac_decode_er_frame(AVCodecCo
     return 0;
 }
 
-static int aac_decode_frame_int(AVCodecContext *avctx, void *data,
+static int aac_decode_frame_int(AVCodecContext *avctx, AVFrame *frame,
                                 int *got_frame_ptr, GetBitContext *gb,
                                 const AVPacket *avpkt)
 {
@@ -3234,7 +3251,7 @@ static int aac_decode_frame_int(AVCodecC
     int payload_alignment;
     uint8_t che_presence[4][MAX_ELEM_ID] = {{0}};
 
-    ac->frame = data;
+    ac->frame = frame;
 
     if (show_bits(gb, 12) == 0xfff) {
         if ((err = parse_adts_frame_header(ac, gb)) < 0) {
@@ -3264,7 +3281,7 @@ static int aac_decode_frame_int(AVCodecC
         if (avctx->debug & FF_DEBUG_STARTCODE)
             av_log(avctx, AV_LOG_DEBUG, "Elem type:%x id:%x\n", elem_type, elem_id);
 
-        if (!avctx->channels && elem_type != TYPE_PCE) {
+        if (!avctx->ch_layout.nb_channels && elem_type != TYPE_PCE) {
             err = AVERROR_INVALIDDATA;
             goto fail;
         }
@@ -3385,7 +3402,7 @@ static int aac_decode_frame_int(AVCodecC
         }
     }
 
-    if (!avctx->channels) {
+    if (!avctx->ch_layout.nb_channels) {
         *got_frame_ptr = 0;
         return 0;
     }
@@ -3419,12 +3436,13 @@ static int aac_decode_frame_int(AVCodecC
 
     /* for dual-mono audio (SCE + SCE) */
     is_dmono = ac->dmono_mode && sce_count == 2 &&
-               ac->oc[1].channel_layout == (AV_CH_FRONT_LEFT | AV_CH_FRONT_RIGHT);
+               !av_channel_layout_compare(&ac->oc[1].ch_layout,
+                                          &(AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO);
     if (is_dmono) {
         if (ac->dmono_mode == 1)
-            ((AVFrame *)data)->data[1] =((AVFrame *)data)->data[0];
+            frame->data[1] = frame->data[0];
         else if (ac->dmono_mode == 2)
-            ((AVFrame *)data)->data[0] =((AVFrame *)data)->data[1];
+            frame->data[0] = frame->data[1];
     }
 
     return 0;
@@ -3433,7 +3451,7 @@ fail:
     return err;
 }
 
-static int aac_decode_frame(AVCodecContext *avctx, void *data,
+static int aac_decode_frame(AVCodecContext *avctx, AVFrame *frame,
                             int *got_frame_ptr, AVPacket *avpkt)
 {
     AACContext *ac = avctx->priv_data;
@@ -3480,10 +3498,10 @@ static int aac_decode_frame(AVCodecConte
     case AOT_ER_AAC_LTP:
     case AOT_ER_AAC_LD:
     case AOT_ER_AAC_ELD:
-        err = aac_decode_er_frame(avctx, data, got_frame_ptr, &gb);
+        err = aac_decode_er_frame(avctx, frame, got_frame_ptr, &gb);
         break;
     default:
-        err = aac_decode_frame_int(avctx, data, got_frame_ptr, &gb, avpkt);
+        err = aac_decode_frame_int(avctx, frame, got_frame_ptr, &gb, avpkt);
     }
     if (err < 0)
         return err;
@@ -3535,8 +3553,9 @@ static void aacdec_init(AACContext *c)
 #endif
 
 #if !USE_FIXED
-    if(ARCH_MIPS)
-        ff_aacdec_init_mips(c);
+#if ARCH_MIPS
+    ff_aacdec_init_mips(c);
+#endif
 #endif /* !USE_FIXED */
 }
 /**
@@ -3553,6 +3572,14 @@ static const AVOption options[] = {
     {"sub" , "Select Sub/Right channel", 0, AV_OPT_TYPE_CONST, {.i64= 2}, INT_MIN, INT_MAX, AACDEC_FLAGS, "dual_mono_mode"},
     {"both", "Select both channels",     0, AV_OPT_TYPE_CONST, {.i64= 0}, INT_MIN, INT_MAX, AACDEC_FLAGS, "dual_mono_mode"},
 
+    { "channel_order", "Order in which the channels are to be exported",
+        offsetof(AACContext, output_channel_order), AV_OPT_TYPE_INT,
+        { .i64 = CHANNEL_ORDER_DEFAULT }, 0, 1, AACDEC_FLAGS, "channel_order" },
+      { "default", "normal libavcodec channel order", 0, AV_OPT_TYPE_CONST,
+        { .i64 = CHANNEL_ORDER_DEFAULT }, .flags = AACDEC_FLAGS, "channel_order" },
+      { "coded",    "order in which the channels are coded in the bitstream",
+        0, AV_OPT_TYPE_CONST, { .i64 = CHANNEL_ORDER_CODED }, .flags = AACDEC_FLAGS, "channel_order" },
+
     {NULL},
 };
 
diff -pruN 7:5.0.1-3/libavcodec/aacenc.c 7:5.1-1/libavcodec/aacenc.c
--- 7:5.0.1-3/libavcodec/aacenc.c	2022-01-14 18:45:39.000000000 +0000
+++ 7:5.1-1/libavcodec/aacenc.c	2022-07-22 17:58:38.000000000 +0000
@@ -35,12 +35,13 @@
 #include "libavutil/float_dsp.h"
 #include "libavutil/opt.h"
 #include "avcodec.h"
+#include "codec_internal.h"
 #include "encode.h"
 #include "put_bits.h"
-#include "internal.h"
 #include "mpeg4audio.h"
 #include "sinewin.h"
 #include "profiles.h"
+#include "version.h"
 
 #include "aac.h"
 #include "aactab.h"
@@ -962,11 +963,11 @@ static av_cold int aac_encode_init(AVCod
     s->lambda = avctx->global_quality > 0 ? avctx->global_quality : 120;
 
     /* Channel map and unspecified bitrate guessing */
-    s->channels = avctx->channels;
+    s->channels = avctx->ch_layout.nb_channels;
 
     s->needs_pce = 1;
     for (i = 0; i < FF_ARRAY_ELEMS(aac_normal_chan_layouts); i++) {
-        if (avctx->channel_layout == aac_normal_chan_layouts[i]) {
+        if (!av_channel_layout_compare(&avctx->ch_layout, &aac_normal_chan_layouts[i])) {
             s->needs_pce = s->options.pce;
             break;
         }
@@ -975,10 +976,13 @@ static av_cold int aac_encode_init(AVCod
     if (s->needs_pce) {
         char buf[64];
         for (i = 0; i < FF_ARRAY_ELEMS(aac_pce_configs); i++)
-            if (avctx->channel_layout == aac_pce_configs[i].layout)
+            if (!av_channel_layout_compare(&avctx->ch_layout, &aac_pce_configs[i].layout))
                 break;
-        av_get_channel_layout_string(buf, sizeof(buf), -1, avctx->channel_layout);
-        ERROR_IF(i == FF_ARRAY_ELEMS(aac_pce_configs), "Unsupported channel layout \"%s\"\n", buf);
+        av_channel_layout_describe(&avctx->ch_layout, buf, sizeof(buf));
+        if (i == FF_ARRAY_ELEMS(aac_pce_configs)) {
+            av_log(avctx, AV_LOG_ERROR, "Unsupported channel layout \"%s\"\n", buf);
+            return AVERROR(EINVAL);
+        }
         av_log(avctx, AV_LOG_INFO, "Using a PCE to encode channel layout \"%s\"\n", buf);
         s->pce = aac_pce_configs[i];
         s->reorder_map = s->pce.reorder_map;
@@ -1092,11 +1096,13 @@ static av_cold int aac_encode_init(AVCod
     s->abs_pow34   = abs_pow34_v;
     s->quant_bands = quantize_bands;
 
-    if (ARCH_X86)
-        ff_aac_dsp_init_x86(s);
-
-    if (HAVE_MIPSDSP)
-        ff_aac_coder_init_mips(s);
+#if ARCH_X86
+    ff_aac_dsp_init_x86(s);
+#endif
+
+#if HAVE_MIPSDSP
+    ff_aac_coder_init_mips(s);
+#endif
 
     ff_af_queue_init(avctx, &s->afq);
     ff_aac_tableinit();
@@ -1128,25 +1134,25 @@ static const AVClass aacenc_class = {
     .version    = LIBAVUTIL_VERSION_INT,
 };
 
-static const AVCodecDefault aac_encode_defaults[] = {
+static const FFCodecDefault aac_encode_defaults[] = {
     { "b", "0" },
     { NULL }
 };
 
-const AVCodec ff_aac_encoder = {
-    .name           = "aac",
-    .long_name      = NULL_IF_CONFIG_SMALL("AAC (Advanced Audio Coding)"),
-    .type           = AVMEDIA_TYPE_AUDIO,
-    .id             = AV_CODEC_ID_AAC,
+const FFCodec ff_aac_encoder = {
+    .p.name         = "aac",
+    .p.long_name    = NULL_IF_CONFIG_SMALL("AAC (Advanced Audio Coding)"),
+    .p.type         = AVMEDIA_TYPE_AUDIO,
+    .p.id           = AV_CODEC_ID_AAC,
     .priv_data_size = sizeof(AACEncContext),
     .init           = aac_encode_init,
-    .encode2        = aac_encode_frame,
+    FF_CODEC_ENCODE_CB(aac_encode_frame),
     .close          = aac_encode_end,
     .defaults       = aac_encode_defaults,
-    .supported_samplerates = ff_mpeg4audio_sample_rates,
+    .p.supported_samplerates = ff_mpeg4audio_sample_rates,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
-    .capabilities   = AV_CODEC_CAP_SMALL_LAST_FRAME | AV_CODEC_CAP_DELAY,
-    .sample_fmts    = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_FLTP,
+    .p.capabilities = AV_CODEC_CAP_SMALL_LAST_FRAME | AV_CODEC_CAP_DELAY,
+    .p.sample_fmts  = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_FLTP,
                                                      AV_SAMPLE_FMT_NONE },
-    .priv_class     = &aacenc_class,
+    .p.priv_class   = &aacenc_class,
 };
diff -pruN 7:5.0.1-3/libavcodec/aacenc.h 7:5.1-1/libavcodec/aacenc.h
--- 7:5.0.1-3/libavcodec/aacenc.h	2022-01-14 18:45:39.000000000 +0000
+++ 7:5.1-1/libavcodec/aacenc.h	2022-07-22 17:58:38.000000000 +0000
@@ -94,7 +94,7 @@ typedef struct AACQuantizeBandCostCacheE
 } AACQuantizeBandCostCacheEntry;
 
 typedef struct AACPCEInfo {
-    int64_t layout;
+    AVChannelLayout layout;
     int num_ele[4];                              ///< front, side, back, lfe
     int pairing[3][8];                           ///< front, side, back
     int index[4][8];                             ///< front, side, back, lfe
@@ -139,7 +139,7 @@ typedef struct AACPCEInfo {
  */
 static const AACPCEInfo aac_pce_configs[] = {
     {
-        .layout = AV_CH_LAYOUT_MONO,
+        .layout = AV_CHANNEL_LAYOUT_MONO,
         .num_ele = { 1, 0, 0, 0 },
         .pairing = { { 0 }, },
         .index = { { 0 }, },
@@ -147,7 +147,7 @@ static const AACPCEInfo aac_pce_configs[
         .reorder_map = { 0 },
     },
     {
-        .layout = AV_CH_LAYOUT_STEREO,
+        .layout = AV_CHANNEL_LAYOUT_STEREO,
         .num_ele = { 1, 0, 0, 0 },
         .pairing = { { 1 }, },
         .index = { { 0 }, },
@@ -155,7 +155,7 @@ static const AACPCEInfo aac_pce_configs[
         .reorder_map = { 0, 1 },
     },
     {
-        .layout = AV_CH_LAYOUT_2POINT1,
+        .layout = AV_CHANNEL_LAYOUT_2POINT1,
         .num_ele = { 1, 0, 0, 1 },
         .pairing = { { 1 }, },
         .index = { { 0 },{ 0 },{ 0 },{ 0 } },
@@ -163,7 +163,7 @@ static const AACPCEInfo aac_pce_configs[
         .reorder_map = { 0, 1, 2 },
     },
     {
-        .layout = AV_CH_LAYOUT_2_1,
+        .layout = AV_CHANNEL_LAYOUT_2_1,
         .num_ele = { 1, 0, 1, 0 },
         .pairing = { { 1 },{ 0 },{ 0 } },
         .index = { { 0 },{ 0 },{ 0 }, },
@@ -171,7 +171,7 @@ static const AACPCEInfo aac_pce_configs[
         .reorder_map = { 0, 1, 2 },
     },
     {
-        .layout = AV_CH_LAYOUT_SURROUND,
+        .layout = AV_CHANNEL_LAYOUT_SURROUND,
         .num_ele = { 2, 0, 0, 0 },
         .pairing = { { 1, 0 }, },
         .index = { { 0, 0 }, },
@@ -179,7 +179,7 @@ static const AACPCEInfo aac_pce_configs[
         .reorder_map = { 0, 1, 2 },
     },
     {
-        .layout = AV_CH_LAYOUT_3POINT1,
+        .layout = AV_CHANNEL_LAYOUT_3POINT1,
         .num_ele = { 2, 0, 0, 1 },
         .pairing = { { 1, 0 }, },
         .index = { { 0, 0 }, { 0 }, { 0 }, { 0 }, },
@@ -187,7 +187,7 @@ static const AACPCEInfo aac_pce_configs[
         .reorder_map = { 0, 1, 2, 3 },
     },
     {
-        .layout = AV_CH_LAYOUT_4POINT0,
+        .layout = AV_CHANNEL_LAYOUT_4POINT0,
         .num_ele = { 2, 0, 1, 0 },
         .pairing = { { 1, 0 }, { 0 }, { 0 }, },
         .index = { { 0, 0 }, { 0 }, { 1 } },
@@ -195,7 +195,7 @@ static const AACPCEInfo aac_pce_configs[
         .reorder_map = {  0, 1, 2, 3 },
     },
     {
-        .layout = AV_CH_LAYOUT_4POINT1,
+        .layout = AV_CHANNEL_LAYOUT_4POINT1,
         .num_ele = { 2, 1, 1, 0 },
         .pairing = { { 1, 0 }, { 0 }, { 0 }, },
         .index = { { 0, 0 }, { 1 }, { 2 }, { 0 } },
@@ -203,7 +203,7 @@ static const AACPCEInfo aac_pce_configs[
         .reorder_map = { 0, 1, 2, 3, 4 },
     },
     {
-        .layout = AV_CH_LAYOUT_2_2,
+        .layout = AV_CHANNEL_LAYOUT_2_2,
         .num_ele = { 1, 1, 0, 0 },
         .pairing = { { 1 }, { 1 }, },
         .index = { { 0 }, { 1 }, },
@@ -211,7 +211,7 @@ static const AACPCEInfo aac_pce_configs[
         .reorder_map = { 0, 1, 2, 3 },
     },
     {
-        .layout = AV_CH_LAYOUT_QUAD,
+        .layout = AV_CHANNEL_LAYOUT_QUAD,
         .num_ele = { 1, 0, 1, 0 },
         .pairing = { { 1 }, { 0 }, { 1 }, },
         .index = { { 0 }, { 0 }, { 1 } },
@@ -219,7 +219,7 @@ static const AACPCEInfo aac_pce_configs[
         .reorder_map = { 0, 1, 2, 3 },
     },
     {
-        .layout = AV_CH_LAYOUT_5POINT0,
+        .layout = AV_CHANNEL_LAYOUT_5POINT0,
         .num_ele = { 2, 1, 0, 0 },
         .pairing = { { 1, 0 }, { 1 }, },
         .index = { { 0, 0 }, { 1 } },
@@ -227,7 +227,7 @@ static const AACPCEInfo aac_pce_configs[
         .reorder_map = { 0, 1, 2, 3, 4 },
     },
     {
-        .layout = AV_CH_LAYOUT_5POINT1,
+        .layout = AV_CHANNEL_LAYOUT_5POINT1,
         .num_ele = { 2, 1, 1, 0 },
         .pairing = { { 1, 0 }, { 0 }, { 1 }, },
         .index = { { 0, 0 }, { 1 }, { 1 } },
@@ -235,7 +235,7 @@ static const AACPCEInfo aac_pce_configs[
         .reorder_map = { 0, 1, 2, 3, 4, 5 },
     },
     {
-        .layout = AV_CH_LAYOUT_5POINT0_BACK,
+        .layout = AV_CHANNEL_LAYOUT_5POINT0_BACK,
         .num_ele = { 2, 0, 1, 0 },
         .pairing = { { 1, 0 }, { 0 }, { 1 } },
         .index = { { 0, 0 }, { 0 }, { 1 } },
@@ -243,7 +243,7 @@ static const AACPCEInfo aac_pce_configs[
         .reorder_map = { 0, 1, 2, 3, 4 },
     },
     {
-        .layout = AV_CH_LAYOUT_5POINT1_BACK,
+        .layout = AV_CHANNEL_LAYOUT_5POINT1_BACK,
         .num_ele = { 2, 1, 1, 0 },
         .pairing = { { 1, 0 }, { 0 }, { 1 }, },
         .index = { { 0, 0 }, { 1 }, { 1 } },
@@ -251,7 +251,7 @@ static const AACPCEInfo aac_pce_configs[
         .reorder_map = { 0, 1, 2, 3, 4, 5 },
     },
     {
-        .layout = AV_CH_LAYOUT_6POINT0,
+        .layout = AV_CHANNEL_LAYOUT_6POINT0,
         .num_ele = { 2, 1, 1, 0 },
         .pairing = { { 1, 0 }, { 1 }, { 0 }, },
         .index = { { 0, 0 }, { 1 }, { 1 } },
@@ -259,7 +259,7 @@ static const AACPCEInfo aac_pce_configs[
         .reorder_map = { 0, 1, 2, 3, 4, 5 },
     },
     {
-        .layout = AV_CH_LAYOUT_6POINT0_FRONT,
+        .layout = AV_CHANNEL_LAYOUT_6POINT0_FRONT,
         .num_ele = { 2, 1, 0, 0 },
         .pairing = { { 1, 1 }, { 1 } },
         .index = { { 1, 0 }, { 2 }, },
@@ -267,7 +267,7 @@ static const AACPCEInfo aac_pce_configs[
         .reorder_map = { 0, 1, 2, 3, 4, 5 },
     },
     {
-        .layout = AV_CH_LAYOUT_HEXAGONAL,
+        .layout = AV_CHANNEL_LAYOUT_HEXAGONAL,
         .num_ele = { 2, 0, 2, 0 },
         .pairing = { { 1, 0 },{ 0 },{ 1, 0 }, },
         .index = { { 0, 0 },{ 0 },{ 1, 1 } },
@@ -275,7 +275,7 @@ static const AACPCEInfo aac_pce_configs[
         .reorder_map = { 0, 1, 2, 3, 4, 5 },
     },
     {
-        .layout = AV_CH_LAYOUT_6POINT1,
+        .layout = AV_CHANNEL_LAYOUT_6POINT1,
         .num_ele = { 2, 1, 2, 0 },
         .pairing = { { 1, 0 },{ 0 },{ 1, 0 }, },
         .index = { { 0, 0 },{ 1 },{ 1, 2 } },
@@ -283,7 +283,7 @@ static const AACPCEInfo aac_pce_configs[
         .reorder_map = { 0, 1, 2, 3, 4, 5, 6 },
     },
     {
-        .layout = AV_CH_LAYOUT_6POINT1_BACK,
+        .layout = AV_CHANNEL_LAYOUT_6POINT1_BACK,
         .num_ele = { 2, 1, 2, 0 },
         .pairing = { { 1, 0 }, { 0 }, { 1, 0 }, },
         .index = { { 0, 0 }, { 1 }, { 1, 2 } },
@@ -291,7 +291,7 @@ static const AACPCEInfo aac_pce_configs[
         .reorder_map = { 0, 1, 2, 3, 4, 5, 6 },
     },
     {
-        .layout = AV_CH_LAYOUT_6POINT1_FRONT,
+        .layout = AV_CHANNEL_LAYOUT_6POINT1_FRONT,
         .num_ele = { 2, 1, 2, 0 },
         .pairing = { { 1, 0 }, { 0 }, { 1, 0 }, },
         .index = { { 0, 0 }, { 1 }, { 1, 2 } },
@@ -299,7 +299,7 @@ static const AACPCEInfo aac_pce_configs[
         .reorder_map = { 0, 1, 2, 3, 4, 5, 6 },
     },
     {
-        .layout = AV_CH_LAYOUT_7POINT0,
+        .layout = AV_CHANNEL_LAYOUT_7POINT0,
         .num_ele = { 2, 1, 1, 0 },
         .pairing = { { 1, 0 }, { 1 }, { 1 }, },
         .index = { { 0, 0 }, { 1 }, { 2 }, },
@@ -307,7 +307,7 @@ static const AACPCEInfo aac_pce_configs[
         .reorder_map = { 0, 1, 2, 3, 4, 5, 6 },
     },
     {
-        .layout = AV_CH_LAYOUT_7POINT0_FRONT,
+        .layout = AV_CHANNEL_LAYOUT_7POINT0_FRONT,
         .num_ele = { 2, 1, 1, 0 },
         .pairing = { { 1, 0 }, { 1 }, { 1 }, },
         .index = { { 0, 0 }, { 1 }, { 2 }, },
@@ -315,7 +315,7 @@ static const AACPCEInfo aac_pce_configs[
         .reorder_map = { 0, 1, 2, 3, 4, 5, 6 },
     },
     {
-        .layout = AV_CH_LAYOUT_7POINT1,
+        .layout = AV_CHANNEL_LAYOUT_7POINT1,
         .num_ele = { 2, 1, 2, 0 },
         .pairing = { { 1, 0 }, { 0 }, { 1, 1 }, },
         .index = { { 0, 0 }, { 1 }, { 1, 2 }, { 0 } },
@@ -323,7 +323,7 @@ static const AACPCEInfo aac_pce_configs[
         .reorder_map = { 0, 1, 2, 3, 4, 5, 6, 7 },
     },
     {
-        .layout = AV_CH_LAYOUT_7POINT1_WIDE,
+        .layout = AV_CHANNEL_LAYOUT_7POINT1_WIDE,
         .num_ele = { 2, 1, 2, 0 },
         .pairing = { { 1, 0 }, { 0 },{  1, 1 }, },
         .index = { { 0, 0 }, { 1 }, { 1, 2 }, { 0 } },
@@ -331,7 +331,7 @@ static const AACPCEInfo aac_pce_configs[
         .reorder_map = { 0, 1, 2, 3, 4, 5, 6, 7 },
     },
     {
-        .layout = AV_CH_LAYOUT_7POINT1_WIDE_BACK,
+        .layout = AV_CHANNEL_LAYOUT_7POINT1_WIDE_BACK,
         .num_ele = { 2, 1, 2, 0 },
         .pairing = { { 1, 0 }, { 0 }, { 1, 1 }, },
         .index = { { 0, 0 }, { 1 }, { 1, 2 }, { 0 } },
@@ -339,7 +339,7 @@ static const AACPCEInfo aac_pce_configs[
         .reorder_map = { 0, 1, 2, 3, 4, 5, 6, 7 },
     },
     {
-        .layout = AV_CH_LAYOUT_OCTAGONAL,
+        .layout = AV_CHANNEL_LAYOUT_OCTAGONAL,
         .num_ele = { 2, 1, 2, 0 },
         .pairing = { { 1, 0 }, { 1 }, { 1, 0 }, },
         .index = { { 0, 0 }, { 1 }, { 2, 1 } },
@@ -347,7 +347,8 @@ static const AACPCEInfo aac_pce_configs[
         .reorder_map = { 0, 1, 2, 3, 4, 5, 6, 7 },
     },
     {   /* Meant for order 2/mixed ambisonics */
-        .layout = AV_CH_LAYOUT_OCTAGONAL | AV_CH_TOP_CENTER,
+        .layout = { .order = AV_CHANNEL_ORDER_NATIVE, .nb_channels = 9,
+                    .u.mask = AV_CH_LAYOUT_OCTAGONAL | AV_CH_TOP_CENTER },
         .num_ele = { 2, 2, 2, 0 },
         .pairing = { { 1, 0 }, { 1, 0 }, { 1, 0 }, },
         .index = { { 0, 0 }, { 1, 1 }, { 2, 2 } },
@@ -355,8 +356,9 @@ static const AACPCEInfo aac_pce_configs[
         .reorder_map = { 0, 1, 2, 3, 4, 5, 6, 7, 8 },
     },
     {   /* Meant for order 2/mixed ambisonics */
-        .layout = AV_CH_LAYOUT_6POINT0_FRONT | AV_CH_BACK_CENTER |
-                  AV_CH_BACK_LEFT | AV_CH_BACK_RIGHT | AV_CH_TOP_CENTER,
+        .layout = { .order = AV_CHANNEL_ORDER_NATIVE, .nb_channels = 10,
+                    .u.mask = AV_CH_LAYOUT_6POINT0_FRONT | AV_CH_BACK_CENTER |
+                              AV_CH_BACK_LEFT | AV_CH_BACK_RIGHT | AV_CH_TOP_CENTER },
         .num_ele = { 2, 2, 2, 0 },
         .pairing = { { 1, 1 }, { 1, 0 }, { 1, 0 }, },
         .index = { { 0, 1 }, { 2, 0 }, { 3, 1 } },
@@ -364,7 +366,7 @@ static const AACPCEInfo aac_pce_configs[
         .reorder_map = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 },
     },
     {
-        .layout = AV_CH_LAYOUT_HEXADECAGONAL,
+        .layout = AV_CHANNEL_LAYOUT_HEXADECAGONAL,
         .num_ele = { 4, 2, 4, 0 },
         .pairing = { { 1, 0, 1, 0 }, { 1, 1 }, { 1, 0, 1, 0 }, },
         .index = { { 0, 0, 1, 1 }, { 2, 3 }, { 4, 2, 5, 3 } },
diff -pruN 7:5.0.1-3/libavcodec/aacenctab.h 7:5.1-1/libavcodec/aacenctab.h
--- 7:5.0.1-3/libavcodec/aacenctab.h	2022-01-14 18:45:39.000000000 +0000
+++ 7:5.1-1/libavcodec/aacenctab.h	2022-07-22 17:58:38.000000000 +0000
@@ -45,14 +45,14 @@ extern const uint8_t *const ff_aac_swb_s
 extern const int      ff_aac_swb_size_128_len;
 
 /* Supported layouts without using a PCE */
-static const int64_t aac_normal_chan_layouts[7] = {
-    AV_CH_LAYOUT_MONO,
-    AV_CH_LAYOUT_STEREO,
-    AV_CH_LAYOUT_SURROUND,
-    AV_CH_LAYOUT_4POINT0,
-    AV_CH_LAYOUT_5POINT0_BACK,
-    AV_CH_LAYOUT_5POINT1_BACK,
-    AV_CH_LAYOUT_7POINT1,
+static const AVChannelLayout aac_normal_chan_layouts[7] = {
+    AV_CHANNEL_LAYOUT_MONO,
+    AV_CHANNEL_LAYOUT_STEREO,
+    AV_CHANNEL_LAYOUT_SURROUND,
+    AV_CHANNEL_LAYOUT_4POINT0,
+    AV_CHANNEL_LAYOUT_5POINT0_BACK,
+    AV_CHANNEL_LAYOUT_5POINT1_BACK,
+    AV_CHANNEL_LAYOUT_7POINT1,
 };
 
 /** default channel configurations */
diff -pruN 7:5.0.1-3/libavcodec/aac.h 7:5.1-1/libavcodec/aac.h
--- 7:5.0.1-3/libavcodec/aac.h	2021-10-24 20:47:07.000000000 +0000
+++ 7:5.1-1/libavcodec/aac.h	2022-07-22 17:58:38.000000000 +0000
@@ -32,6 +32,7 @@
 
 
 #include "aac_defines.h"
+#include "libavutil/channel_layout.h"
 #include "libavutil/float_dsp.h"
 #include "libavutil/fixed_dsp.h"
 #include "libavutil/mem_internal.h"
@@ -125,8 +126,7 @@ typedef struct OutputConfiguration {
     MPEG4AudioConfig m4ac;
     uint8_t layout_map[MAX_ELEM_ID*4][3];
     int layout_map_tags;
-    int channels;
-    uint64_t channel_layout;
+    AVChannelLayout ch_layout;
     enum OCStatus status;
 } OutputConfiguration;
 
@@ -288,6 +288,11 @@ typedef struct ChannelElement {
     SpectralBandReplication sbr;
 } ChannelElement;
 
+enum AACOutputChannelOrder {
+    CHANNEL_ORDER_DEFAULT,
+    CHANNEL_ORDER_CODED,
+};
+
 /**
  * main AAC context
  */
@@ -352,6 +357,8 @@ struct AACContext {
     int dmono_mode;      ///< 0->not dmono, 1->use first channel, 2->use second channel
     /** @} */
 
+    enum AACOutputChannelOrder output_channel_order;
+
     DECLARE_ALIGNED(32, INTFLOAT, temp)[128];
 
     OutputConfiguration oc[2];
diff -pruN 7:5.0.1-3/libavcodec/aacps_common.c 7:5.1-1/libavcodec/aacps_common.c
--- 7:5.0.1-3/libavcodec/aacps_common.c	2021-10-24 20:47:07.000000000 +0000
+++ 7:5.1-1/libavcodec/aacps_common.c	2022-07-22 17:58:38.000000000 +0000
@@ -78,7 +78,7 @@ static int read_ ## PAR ## _data(AVCodec
                         int8_t (*PAR)[PS_MAX_NR_IIDICC], int table_idx, int e, int dt) \
 { \
     int b, num = ps->nr_ ## PAR ## _par; \
-    VLC_TYPE (*vlc_table)[2] = vlc_ps[table_idx].table; \
+    const VLCElem *vlc_table = vlc_ps[table_idx].table; \
     if (dt) { \
         int e_prev = e ? e - 1 : ps->num_env_old - 1; \
         e_prev = FFMAX(e_prev, 0); \
diff -pruN 7:5.0.1-3/libavcodec/aacpsdsp_template.c 7:5.1-1/libavcodec/aacpsdsp_template.c
--- 7:5.0.1-3/libavcodec/aacpsdsp_template.c	2021-10-21 17:06:35.000000000 +0000
+++ 7:5.1-1/libavcodec/aacpsdsp_template.c	2022-07-22 17:58:38.000000000 +0000
@@ -221,13 +221,14 @@ av_cold void AAC_RENAME(ff_psdsp_init)(P
     s->stereo_interpolate[1]  = ps_stereo_interpolate_ipdopd_c;
 
 #if !USE_FIXED
-    if (ARCH_ARM)
-        ff_psdsp_init_arm(s);
-    if (ARCH_AARCH64)
-        ff_psdsp_init_aarch64(s);
-    if (ARCH_MIPS)
-        ff_psdsp_init_mips(s);
-    if (ARCH_X86)
-        ff_psdsp_init_x86(s);
+#if ARCH_ARM
+    ff_psdsp_init_arm(s);
+#elif ARCH_AARCH64
+    ff_psdsp_init_aarch64(s);
+#elif ARCH_MIPS
+    ff_psdsp_init_mips(s);
+#elif ARCH_X86
+    ff_psdsp_init_x86(s);
+#endif
 #endif /* !USE_FIXED */
 }
diff -pruN 7:5.0.1-3/libavcodec/aacpsy.c 7:5.1-1/libavcodec/aacpsy.c
--- 7:5.0.1-3/libavcodec/aacpsy.c	2022-01-14 18:45:39.000000000 +0000
+++ 7:5.1-1/libavcodec/aacpsy.c	2022-07-22 17:58:38.000000000 +0000
@@ -263,13 +263,13 @@ static av_cold void lame_window_init(Aac
 {
     int i, j;
 
-    for (i = 0; i < avctx->channels; i++) {
+    for (i = 0; i < avctx->ch_layout.nb_channels; i++) {
         AacPsyChannel *pch = &ctx->ch[i];
 
         if (avctx->flags & AV_CODEC_FLAG_QSCALE)
             pch->attack_threshold = psy_vbr_map[avctx->global_quality / FF_QP2LAMBDA].st_lrm;
         else
-            pch->attack_threshold = lame_calc_attack_threshold(avctx->bit_rate / avctx->channels / 1000);
+            pch->attack_threshold = lame_calc_attack_threshold(avctx->bit_rate / avctx->ch_layout.nb_channels / 1000);
 
         for (j = 0; j < AAC_NUM_BLOCKS_SHORT * PSY_LAME_NUM_SUBBLOCKS; j++)
             pch->prev_energy_subshort[j] = 10.0f;
@@ -303,7 +303,7 @@ static av_cold int psy_3gpp_init(FFPsyCo
     float bark;
     int i, j, g, start;
     float prev, minscale, minath, minsnr, pe_min;
-    int chan_bitrate = ctx->avctx->bit_rate / ((ctx->avctx->flags & AV_CODEC_FLAG_QSCALE) ? 2.0f : ctx->avctx->channels);
+    int chan_bitrate = ctx->avctx->bit_rate / ((ctx->avctx->flags & AV_CODEC_FLAG_QSCALE) ? 2.0f : ctx->avctx->ch_layout.nb_channels);
 
     const int bandwidth    = ctx->cutoff ? ctx->cutoff : AAC_CUTOFF(ctx->avctx);
     const float num_bark   = calc_bark((float)bandwidth);
@@ -370,7 +370,7 @@ static av_cold int psy_3gpp_init(FFPsyCo
         }
     }
 
-    pctx->ch = av_calloc(ctx->avctx->channels, sizeof(*pctx->ch));
+    pctx->ch = av_calloc(ctx->avctx->ch_layout.nb_channels, sizeof(*pctx->ch));
     if (!pctx->ch) {
         av_freep(&ctx->model_priv_data);
         return AVERROR(ENOMEM);
diff -pruN 7:5.0.1-3/libavcodec/aacsbr_template.c 7:5.1-1/libavcodec/aacsbr_template.c
--- 7:5.0.1-3/libavcodec/aacsbr_template.c	2021-10-24 20:47:07.000000000 +0000
+++ 7:5.1-1/libavcodec/aacsbr_template.c	2022-07-22 17:58:38.000000000 +0000
@@ -811,7 +811,7 @@ static int read_sbr_envelope(AACContext
 {
     int bits;
     int i, j, k;
-    VLC_TYPE (*t_huff)[2], (*f_huff)[2];
+    const VLCElem *t_huff, *f_huff;
     int t_lav, f_lav;
     const int delta = (ch == 1 && sbr->bs_coupling == 1) + 1;
     const int odd = sbr->n[1] & 1;
@@ -899,7 +899,7 @@ static int read_sbr_noise(AACContext *ac
                            SBRData *ch_data, int ch)
 {
     int i, j;
-    VLC_TYPE (*t_huff)[2], (*f_huff)[2];
+    const VLCElem *t_huff, *f_huff;
     int t_lav, f_lav;
     int delta = (ch == 1 && sbr->bs_coupling == 1) + 1;
 
@@ -1573,7 +1573,8 @@ static void aacsbr_func_ptr_init(AACSBRC
     c->sbr_hf_inverse_filter = sbr_hf_inverse_filter;
 
 #if !USE_FIXED
-    if(ARCH_MIPS)
-        ff_aacsbr_func_ptr_init_mips(c);
+#if ARCH_MIPS
+    ff_aacsbr_func_ptr_init_mips(c);
+#endif
 #endif
 }
diff -pruN 7:5.0.1-3/libavcodec/aactab.c 7:5.1-1/libavcodec/aactab.c
--- 7:5.0.1-3/libavcodec/aactab.c	2022-01-14 18:45:39.000000000 +0000
+++ 7:5.1-1/libavcodec/aactab.c	2022-07-22 17:58:38.000000000 +0000
@@ -28,6 +28,7 @@
  */
 
 #include "config.h"
+#include "config_components.h"
 #include "libavutil/mem_internal.h"
 #include "libavutil/thread.h"
 #include "aac.h"
diff -pruN 7:5.0.1-3/libavcodec/aarch64/fft_neon.S 7:5.1-1/libavcodec/aarch64/fft_neon.S
--- 7:5.0.1-3/libavcodec/aarch64/fft_neon.S	2022-01-14 18:45:39.000000000 +0000
+++ 7:5.1-1/libavcodec/aarch64/fft_neon.S	2022-07-22 17:58:38.000000000 +0000
@@ -341,6 +341,7 @@ endfunc
 .macro  def_fft n, n2, n4
 function fft\n\()_neon, align=6
         AARCH64_VALID_JUMP_TARGET
+        AARCH64_SIGN_LINK_REGISTER
         sub             sp,  sp,  #16
         stp             x28, x30, [sp]
         add             x28, x0,  #\n4*2*8
@@ -351,6 +352,7 @@ function fft\n\()_neon, align=6
         bl              fft\n4\()_neon
         sub             x0,  x28, #\n4*2*8
         ldp             x28, x30, [sp], #16
+        AARCH64_VALIDATE_LINK_REGISTER
         movrel          x4,  X(ff_cos_\n)
         mov             x2,  #\n4>>1
         b               fft_pass_neon
diff -pruN 7:5.0.1-3/libavcodec/aarch64/h264cmc_neon.S 7:5.1-1/libavcodec/aarch64/h264cmc_neon.S
--- 7:5.0.1-3/libavcodec/aarch64/h264cmc_neon.S	2021-10-21 17:06:35.000000000 +0000
+++ 7:5.1-1/libavcodec/aarch64/h264cmc_neon.S	2022-07-22 17:58:38.000000000 +0000
@@ -19,6 +19,8 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "config_components.h"
+
 #include "libavutil/aarch64/asm.S"
 
 /* chroma_mc8(uint8_t *dst, uint8_t *src, ptrdiff_t stride, int h, int x, int y) */
diff -pruN 7:5.0.1-3/libavcodec/aarch64/h264dsp_neon.S 7:5.1-1/libavcodec/aarch64/h264dsp_neon.S
--- 7:5.0.1-3/libavcodec/aarch64/h264dsp_neon.S	2022-01-14 18:45:39.000000000 +0000
+++ 7:5.1-1/libavcodec/aarch64/h264dsp_neon.S	2022-07-22 17:58:38.000000000 +0000
@@ -960,117 +960,117 @@ function ff_h264_h_loop_filter_chroma422
 endfunc
 
 .macro h264_loop_filter_chroma_intra_10
-       uabd            v26.8h,  v16.8h,  v17.8h  // abs(p0 - q0)
-       uabd            v27.8h,  v18.8h,  v16.8h  // abs(p1 - p0)
-       uabd            v28.8h,  v19.8h,  v17.8h  // abs(q1 - q0)
-       cmhi            v26.8h,  v30.8h,  v26.8h  // < alpha
-       cmhi            v27.8h,  v31.8h,  v27.8h  // < beta
-       cmhi            v28.8h,  v31.8h,  v28.8h  // < beta
-       and             v26.16b, v26.16b, v27.16b
-       and             v26.16b, v26.16b, v28.16b
-       mov             x2, v26.d[0]
-       mov             x3, v26.d[1]
-
-       shl             v4.8h,  v18.8h,  #1
-       shl             v6.8h,  v19.8h,  #1
-
-       adds            x2,  x2,  x3
-       b.eq            9f
-
-       add             v20.8h,  v16.8h,  v19.8h
-       add             v22.8h,  v17.8h,  v18.8h
-       add             v20.8h,  v20.8h,  v4.8h
-       add             v22.8h,  v22.8h,  v6.8h
-       urshr           v24.8h,  v20.8h,  #2
-       urshr           v25.8h,  v22.8h,  #2
-       bit             v16.16b, v24.16b, v26.16b
-       bit             v17.16b, v25.16b, v26.16b
+        uabd            v26.8h,  v16.8h,  v17.8h  // abs(p0 - q0)
+        uabd            v27.8h,  v18.8h,  v16.8h  // abs(p1 - p0)
+        uabd            v28.8h,  v19.8h,  v17.8h  // abs(q1 - q0)
+        cmhi            v26.8h,  v30.8h,  v26.8h  // < alpha
+        cmhi            v27.8h,  v31.8h,  v27.8h  // < beta
+        cmhi            v28.8h,  v31.8h,  v28.8h  // < beta
+        and             v26.16b, v26.16b, v27.16b
+        and             v26.16b, v26.16b, v28.16b
+        mov             x2, v26.d[0]
+        mov             x3, v26.d[1]
+
+        shl             v4.8h,  v18.8h,  #1
+        shl             v6.8h,  v19.8h,  #1
+
+        adds            x2,  x2,  x3
+        b.eq            9f
+
+        add             v20.8h,  v16.8h,  v19.8h
+        add             v22.8h,  v17.8h,  v18.8h
+        add             v20.8h,  v20.8h,  v4.8h
+        add             v22.8h,  v22.8h,  v6.8h
+        urshr           v24.8h,  v20.8h,  #2
+        urshr           v25.8h,  v22.8h,  #2
+        bit             v16.16b, v24.16b, v26.16b
+        bit             v17.16b, v25.16b, v26.16b
 .endm
 
 function ff_h264_v_loop_filter_chroma_intra_neon_10, export=1
-       h264_loop_filter_start_intra_10
-       mov             x9,  x0
-       sub             x0,  x0,  x1, lsl #1
-       ld1             {v18.8h}, [x0], x1
-       ld1             {v17.8h}, [x9], x1
-       ld1             {v16.8h}, [x0], x1
-       ld1             {v19.8h}, [x9]
-
-       h264_loop_filter_chroma_intra_10
-
-       sub             x0,  x9,  x1, lsl #1
-       st1             {v16.8h}, [x0], x1
-       st1             {v17.8h}, [x0], x1
+        h264_loop_filter_start_intra_10
+        mov             x9,  x0
+        sub             x0,  x0,  x1, lsl #1
+        ld1             {v18.8h}, [x0], x1
+        ld1             {v17.8h}, [x9], x1
+        ld1             {v16.8h}, [x0], x1
+        ld1             {v19.8h}, [x9]
+
+        h264_loop_filter_chroma_intra_10
+
+        sub             x0,  x9,  x1, lsl #1
+        st1             {v16.8h}, [x0], x1
+        st1             {v17.8h}, [x0], x1
 
 9:
-       ret
+        ret
 endfunc
 
 function ff_h264_h_loop_filter_chroma_mbaff_intra_neon_10, export=1
-       h264_loop_filter_start_intra_10
+        h264_loop_filter_start_intra_10
 
-       sub             x4,  x0,  #4
-       sub             x0,  x0,  #2
-       add             x9,  x4,  x1, lsl #1
-       ld1             {v18.8h}, [x4], x1
-       ld1             {v17.8h}, [x9], x1
-       ld1             {v16.8h}, [x4], x1
-       ld1             {v19.8h}, [x9], x1
-
-       transpose_4x8H v18, v16, v17, v19, v26, v27, v28, v29
-
-       h264_loop_filter_chroma_intra_10
-
-       st2             {v16.h,v17.h}[0], [x0], x1
-       st2             {v16.h,v17.h}[1], [x0], x1
-       st2             {v16.h,v17.h}[2], [x0], x1
-       st2             {v16.h,v17.h}[3], [x0], x1
+        sub             x4,  x0,  #4
+        sub             x0,  x0,  #2
+        add             x9,  x4,  x1, lsl #1
+        ld1             {v18.8h}, [x4], x1
+        ld1             {v17.8h}, [x9], x1
+        ld1             {v16.8h}, [x4], x1
+        ld1             {v19.8h}, [x9], x1
+
+        transpose_4x8H v18, v16, v17, v19, v26, v27, v28, v29
+
+        h264_loop_filter_chroma_intra_10
+
+        st2             {v16.h,v17.h}[0], [x0], x1
+        st2             {v16.h,v17.h}[1], [x0], x1
+        st2             {v16.h,v17.h}[2], [x0], x1
+        st2             {v16.h,v17.h}[3], [x0], x1
 
 9:
-       ret
+        ret
 endfunc
 
 function ff_h264_h_loop_filter_chroma_intra_neon_10, export=1
-       h264_loop_filter_start_intra_10
-       sub             x4,  x0,  #4
-       sub             x0,  x0,  #2
+        h264_loop_filter_start_intra_10
+        sub             x4,  x0,  #4
+        sub             x0,  x0,  #2
 h_loop_filter_chroma420_intra_10:
-       add             x9,  x4,  x1, lsl #2
-       ld1             {v18.4h},   [x4], x1
-       ld1             {v18.d}[1], [x9], x1
-       ld1             {v16.4h},   [x4], x1
-       ld1             {v16.d}[1], [x9], x1
-       ld1             {v17.4h},   [x4], x1
-       ld1             {v17.d}[1], [x9], x1
-       ld1             {v19.4h},   [x4], x1
-       ld1             {v19.d}[1], [x9], x1
-
-       transpose_4x8H v18, v16, v17, v19, v26, v27, v28, v29
-
-       h264_loop_filter_chroma_intra_10
-
-       st2             {v16.h,v17.h}[0], [x0], x1
-       st2             {v16.h,v17.h}[1], [x0], x1
-       st2             {v16.h,v17.h}[2], [x0], x1
-       st2             {v16.h,v17.h}[3], [x0], x1
-       st2             {v16.h,v17.h}[4], [x0], x1
-       st2             {v16.h,v17.h}[5], [x0], x1
-       st2             {v16.h,v17.h}[6], [x0], x1
-       st2             {v16.h,v17.h}[7], [x0], x1
+        add             x9,  x4,  x1, lsl #2
+        ld1             {v18.4h},   [x4], x1
+        ld1             {v18.d}[1], [x9], x1
+        ld1             {v16.4h},   [x4], x1
+        ld1             {v16.d}[1], [x9], x1
+        ld1             {v17.4h},   [x4], x1
+        ld1             {v17.d}[1], [x9], x1
+        ld1             {v19.4h},   [x4], x1
+        ld1             {v19.d}[1], [x9], x1
+
+        transpose_4x8H v18, v16, v17, v19, v26, v27, v28, v29
+
+        h264_loop_filter_chroma_intra_10
+
+        st2             {v16.h,v17.h}[0], [x0], x1
+        st2             {v16.h,v17.h}[1], [x0], x1
+        st2             {v16.h,v17.h}[2], [x0], x1
+        st2             {v16.h,v17.h}[3], [x0], x1
+        st2             {v16.h,v17.h}[4], [x0], x1
+        st2             {v16.h,v17.h}[5], [x0], x1
+        st2             {v16.h,v17.h}[6], [x0], x1
+        st2             {v16.h,v17.h}[7], [x0], x1
 
 9:
-       ret
+        ret
 endfunc
 
 function ff_h264_h_loop_filter_chroma422_intra_neon_10, export=1
-       h264_loop_filter_start_intra_10
-       sub             x4,  x0,  #4
-       add             x5,  x0,  x1, lsl #3
-       sub             x0,  x0,  #2
-       mov             x7,  x30
-       bl              h_loop_filter_chroma420_intra_10
-       mov             x4,  x9
-       sub             x0,  x5,  #2
-       mov             x30, x7
-       b               h_loop_filter_chroma420_intra_10
+        h264_loop_filter_start_intra_10
+        sub             x4,  x0,  #4
+        add             x5,  x0,  x1, lsl #3
+        sub             x0,  x0,  #2
+        mov             x7,  x30
+        bl              h_loop_filter_chroma420_intra_10
+        mov             x4,  x9
+        sub             x0,  x5,  #2
+        mov             x30, x7
+        b               h_loop_filter_chroma420_intra_10
 endfunc
diff -pruN 7:5.0.1-3/libavcodec/aarch64/hevcdsp_init_aarch64.c 7:5.1-1/libavcodec/aarch64/hevcdsp_init_aarch64.c
--- 7:5.0.1-3/libavcodec/aarch64/hevcdsp_init_aarch64.c	2022-01-14 18:45:39.000000000 +0000
+++ 7:5.1-1/libavcodec/aarch64/hevcdsp_init_aarch64.c	2022-07-22 17:58:38.000000000 +0000
@@ -57,8 +57,10 @@ void ff_hevc_sao_band_filter_8x8_8_neon(
                                   ptrdiff_t stride_dst, ptrdiff_t stride_src,
                                   int16_t *sao_offset_val, int sao_left_class,
                                   int width, int height);
-
-
+void ff_hevc_sao_edge_filter_16x16_8_neon(uint8_t *dst, uint8_t *src, ptrdiff_t stride_dst,
+                                          int16_t *sao_offset_val, int eo, int width, int height);
+void ff_hevc_sao_edge_filter_8x8_8_neon(uint8_t *dst, uint8_t *src, ptrdiff_t stride_dst,
+                                          int16_t *sao_offset_val, int eo, int width, int height);
 
 av_cold void ff_hevc_dsp_init_aarch64(HEVCDSPContext *c, const int bit_depth)
 {
@@ -75,11 +77,16 @@ av_cold void ff_hevc_dsp_init_aarch64(HE
         c->idct_dc[1]                  = ff_hevc_idct_8x8_dc_8_neon;
         c->idct_dc[2]                  = ff_hevc_idct_16x16_dc_8_neon;
         c->idct_dc[3]                  = ff_hevc_idct_32x32_dc_8_neon;
-        // This function is disabled, as it doesn't handle widths that aren't
-        // an even multiple of 8 correctly. fate-hevc doesn't exercise that
-        // for the current size, but if enabled for bigger sizes, the cases
-        // of non-multiple of 8 seem to arise.
-//        c->sao_band_filter[0]          = ff_hevc_sao_band_filter_8x8_8_neon;
+        c->sao_band_filter[0]          =
+        c->sao_band_filter[1]          =
+        c->sao_band_filter[2]          =
+        c->sao_band_filter[3]          =
+        c->sao_band_filter[4]          = ff_hevc_sao_band_filter_8x8_8_neon;
+        c->sao_edge_filter[0]          = ff_hevc_sao_edge_filter_8x8_8_neon;
+        c->sao_edge_filter[1]          =
+        c->sao_edge_filter[2]          =
+        c->sao_edge_filter[3]          =
+        c->sao_edge_filter[4]          = ff_hevc_sao_edge_filter_16x16_8_neon;
     }
     if (bit_depth == 10) {
         c->add_residual[0]             = ff_hevc_add_residual_4x4_10_neon;
diff -pruN 7:5.0.1-3/libavcodec/aarch64/hevcdsp_sao_neon.S 7:5.1-1/libavcodec/aarch64/hevcdsp_sao_neon.S
--- 7:5.0.1-3/libavcodec/aarch64/hevcdsp_sao_neon.S	2021-10-24 20:47:07.000000000 +0000
+++ 7:5.1-1/libavcodec/aarch64/hevcdsp_sao_neon.S	2022-07-22 17:58:38.000000000 +0000
@@ -3,7 +3,7 @@
  *
  * AArch64 NEON optimised SAO functions for HEVC decoding
  *
- * Copyright (c) 2020 Josh Dekker <josh@itanimul.li>
+ * Copyright (c) 2022 J. Dekker <jdek@itanimul.li>
  *
  * This file is part of FFmpeg.
  *
@@ -24,30 +24,35 @@
 
 #include "libavutil/aarch64/asm.S"
 
+#define MAX_PB_SIZE 64
+#define AV_INPUT_BUFFER_PADDING_SIZE 64
+#define SAO_STRIDE (2*MAX_PB_SIZE + AV_INPUT_BUFFER_PADDING_SIZE)
+
 // void sao_band_filter(uint8_t *_dst, uint8_t *_src,
 //                      ptrdiff_t stride_dst, ptrdiff_t stride_src,
 //                      int16_t *sao_offset_val, int sao_left_class,
 //                      int width, int height)
 function ff_hevc_sao_band_filter_8x8_8_neon, export=1
         sub             sp,  sp, #64
-        stp            xzr, xzr, [sp]
-        stp            xzr, xzr, [sp, #16]
-        stp            xzr, xzr, [sp, #32]
-        stp            xzr, xzr, [sp, #48]
+        stp             xzr, xzr, [sp]
+        stp             xzr, xzr, [sp, #16]
+        stp             xzr, xzr, [sp, #32]
+        stp             xzr, xzr, [sp, #48]
         mov             w8,  #4
-0:
-        ldrsh           x9, [x4,  x8, lsl #1] // x9 = sao_offset_val[k+1]
+0:      ldrsh           x9, [x4,  x8, lsl #1]      // sao_offset_val[k+1]
         subs            w8,  w8,  #1
-        add            w10,  w8,  w5 // x10 = k + sao_left_class
-        and            w10, w10, #0x1F
+        add             w10, w8,  w5               // k + sao_left_class
+        and             w10, w10, #0x1F
         strh            w9, [sp, x10, lsl #1]
         bne             0b
-        ld1            {v16.16b-v19.16b}, [sp], #64
-        movi           v20.8h,   #1
-1:      // beginning of line
-        mov             w8,  w6
-2:
-        // Simple layout for accessing 16bit values
+        add             w6,  w6,  #7
+        bic             w6,  w6,  #7
+        ld1             {v16.16b-v19.16b}, [sp], #64
+        sub             x2,  x2,  x6
+        sub             x3,  x3,  x6
+        movi            v20.8h,   #1
+1:      mov             w8,  w6                    // beginning of line
+2:      // Simple layout for accessing 16bit values
         // with 8bit LUT.
         //
         //   00  01  02  03  04  05  06  07
@@ -55,33 +60,138 @@ function ff_hevc_sao_band_filter_8x8_8_n
         // |xDE#xAD|xCA#xFE|xBE#xEF|xFE#xED|....
         // +----------------------------------->
         //    i-0     i-1     i-2     i-3
-        // dst[x] = av_clip_pixel(src[x] + offset_table[src[x] >> shift]);
-        ld1            {v2.8b}, [x1]
-        // load src[x]
-        uxtl            v0.8h,  v2.8b
-        // >> shift
-        ushr            v2.8h,  v0.8h, #3 // BIT_DEPTH - 3
-        // x2 (access lower short)
-        shl             v1.8h,  v2.8h, #1 // low (x2, accessing short)
-        // +1 access upper short
-        add             v3.8h,  v1.8h, v20.8h
-        // shift insert index to upper byte
-        sli             v1.8h,  v3.8h, #8
-        // table
-        tbx            v2.16b, {v16.16b-v19.16b}, v1.16b
-        // src[x] + table
-        add             v1.8h,  v0.8h, v2.8h
-        // clip + narrow
-        sqxtun          v4.8b,  v1.8h
-        // store
-        st1            {v4.8b}, [x0]
-        // done 8 pixels
+        ld1             {v2.8b}, [x1], #8          // dst[x] = av_clip_pixel(src[x] + offset_table[src[x] >> shift]);
         subs            w8, w8,  #8
+        uxtl            v0.8h,  v2.8b              // load src[x]
+        ushr            v2.8h,  v0.8h, #3          // >> BIT_DEPTH - 3
+        shl             v1.8h,  v2.8h, #1          // low (x2, accessing short)
+        add             v3.8h,  v1.8h, v20.8h      // +1 access upper short
+        sli             v1.8h,  v3.8h, #8          // shift insert index to upper byte
+        tbx             v2.16b, {v16.16b-v19.16b}, v1.16b // table
+        add             v1.8h,  v0.8h, v2.8h       // src[x] + table
+        sqxtun          v4.8b,  v1.8h              // clip + narrow
+        st1             {v4.8b}, [x0], #8          // store
+        // done 8 pixels
         bne             2b
-        // finished line
-        subs            w7, w7,  #1
-        add             x0, x0,  x2 // dst += stride_dst
-        add             x1, x1,  x3 // src += stride_src
+        subs            w7, w7,  #1                // finished line, prep. new
+        add             x0, x0,  x2                // dst += stride_dst
+        add             x1, x1,  x3                // src += stride_src
         bne             1b
         ret
 endfunc
+
+.Lsao_edge_pos:
+.word 1 // horizontal
+.word SAO_STRIDE // vertical
+.word SAO_STRIDE + 1 // 45 degree
+.word SAO_STRIDE - 1 // 135 degree
+
+// ff_hevc_sao_edge_filter_16x16_8_neon(char *dst, char *src, ptrdiff stride_dst,
+//                                      int16 *sao_offset_val, int eo, int width, int height)
+function ff_hevc_sao_edge_filter_16x16_8_neon, export=1
+        adr             x7, .Lsao_edge_pos
+        ld1             {v3.8h}, [x3]              // load sao_offset_val
+        add             w5,  w5,  #0xF
+        bic             w5,  w5,  #0xF
+        ldr             w4, [x7, w4, uxtw #2]      // stride_src
+        mov             v3.h[7], v3.h[0]           // reorder to [1,2,0,3,4]
+        mov             v3.h[0], v3.h[1]
+        mov             v3.h[1], v3.h[2]
+        mov             v3.h[2], v3.h[7]
+        // split 16bit values into two tables
+        uzp2            v1.16b, v3.16b, v3.16b     // sao_offset_val -> upper
+        uzp1            v0.16b, v3.16b, v3.16b     // sao_offset_val -> lower
+        movi            v2.16b, #2
+        mov             x15, #SAO_STRIDE
+        // strides between end of line and next src/dst
+        sub             x15, x15, x5               // stride_src - width
+        sub             x16, x2, x5                // stride_dst - width
+        mov             x11, x1                    // copy base src
+1:      // new line
+        mov             x14, x5                    // copy width
+        sub             x12, x11, x4               // src_a (prev) = src - sao_edge_pos
+        add             x13, x11, x4               // src_b (next) = src + sao_edge_pos
+2:      // process 16 bytes
+        ld1             {v3.16b}, [x11], #16       // load src
+        ld1             {v4.16b}, [x12], #16       // load src_a (prev)
+        ld1             {v5.16b}, [x13], #16       // load src_b (next)
+        subs            x14, x14, #16
+        cmhi            v16.16b, v4.16b, v3.16b    // (prev > cur)
+        cmhi            v17.16b, v3.16b, v4.16b    // (cur > prev)
+        cmhi            v18.16b, v5.16b, v3.16b    // (next > cur)
+        cmhi            v19.16b, v3.16b, v5.16b    // (cur > next)
+        sub             v20.16b, v16.16b, v17.16b  // diff0 = CMP(cur, prev) = (cur > prev) - (cur < prev)
+        sub             v21.16b, v18.16b, v19.16b  // diff1 = CMP(cur, next) = (cur > next) - (cur < next)
+        add             v20.16b, v20.16b, v21.16b  // diff = diff0 + diff1
+        add             v20.16b, v20.16b, v2.16b   // offset_val = diff + 2
+        tbl             v16.16b, {v0.16b}, v20.16b
+        tbl             v17.16b, {v1.16b}, v20.16b
+        uxtl            v20.8h, v3.8b              // src[0:7]
+        uxtl2           v21.8h, v3.16b             // src[7:15]
+        zip1            v18.16b, v16.16b, v17.16b  // sao_offset_val lower ->
+        zip2            v19.16b, v16.16b, v17.16b  // sao_offset_val upper ->
+        sqadd           v20.8h, v18.8h, v20.8h     // + sao_offset_val
+        sqadd           v21.8h, v19.8h, v21.8h
+        sqxtun          v3.8b, v20.8h
+        sqxtun2         v3.16b, v21.8h
+        st1             {v3.16b}, [x0], #16
+        // filtered 16 bytes
+        b.ne            2b                         // do we have width to filter?
+        // no width to filter, setup next line
+        subs            w6, w6, #1                 // filtered line
+        add             x11, x11, x15              // stride src to next line
+        add             x0, x0, x16                // stride dst to next line
+        b.ne            1b                         // do we have lines to process?
+        // no lines to filter
+        ret
+endfunc
+
+// ff_hevc_sao_edge_filter_8x8_8_neon(char *dst, char *src, ptrdiff stride_dst,
+//                                    int16 *sao_offset_val, int eo, int width, int height)
+function ff_hevc_sao_edge_filter_8x8_8_neon, export=1
+        adr             x7, .Lsao_edge_pos
+        ldr             w4, [x7, w4, uxtw #2]
+        ld1             {v3.8h}, [x3]
+        mov             v3.h[7], v3.h[0]
+        mov             v3.h[0], v3.h[1]
+        mov             v3.h[1], v3.h[2]
+        mov             v3.h[2], v3.h[7]
+        uzp2            v1.16b, v3.16b, v3.16b
+        uzp1            v0.16b, v3.16b, v3.16b
+        movi            v2.16b, #2
+        add             x16, x0, x2
+        lsl             x2,  x2, #1
+        mov             x15, #SAO_STRIDE
+        mov             x8,  x1
+        sub             x9,  x1, x4
+        add             x10, x1, x4
+1:      ld1             {v3.d}[0], [ x8], x15
+        ld1             {v4.d}[0], [ x9], x15
+        ld1             {v5.d}[0], [x10], x15
+        ld1             {v3.d}[1], [ x8], x15
+        ld1             {v4.d}[1], [ x9], x15
+        ld1             {v5.d}[1], [x10], x15
+        subs            w6, w6, #2
+        cmhi            v16.16b, v4.16b, v3.16b
+        cmhi            v17.16b, v3.16b, v4.16b
+        cmhi            v18.16b, v5.16b, v3.16b
+        cmhi            v19.16b, v3.16b, v5.16b
+        sub             v20.16b, v16.16b, v17.16b
+        sub             v21.16b, v18.16b, v19.16b
+        add             v20.16b, v20.16b, v21.16b
+        add             v20.16b, v20.16b, v2.16b
+        tbl             v16.16b, {v0.16b}, v20.16b
+        tbl             v17.16b, {v1.16b}, v20.16b
+        uxtl            v20.8h, v3.8b
+        uxtl2           v21.8h, v3.16b
+        zip1            v18.16b, v16.16b, v17.16b
+        zip2            v19.16b, v16.16b, v17.16b
+        sqadd           v20.8h, v18.8h, v20.8h
+        sqadd           v21.8h, v19.8h, v21.8h
+        sqxtun          v6.8b, v20.8h
+        sqxtun          v7.8b, v21.8h
+        st1             {v6.8b}, [ x0], x2
+        st1             {v7.8b}, [x16], x2
+        b.ne            1b
+        ret
+endfunc
diff -pruN 7:5.0.1-3/libavcodec/aarch64/idctdsp_init_aarch64.c 7:5.1-1/libavcodec/aarch64/idctdsp_init_aarch64.c
--- 7:5.0.1-3/libavcodec/aarch64/idctdsp_init_aarch64.c	2021-10-21 17:06:35.000000000 +0000
+++ 7:5.1-1/libavcodec/aarch64/idctdsp_init_aarch64.c	2022-07-22 17:58:38.000000000 +0000
@@ -27,19 +27,29 @@
 #include "libavcodec/idctdsp.h"
 #include "idct.h"
 
+void ff_put_pixels_clamped_neon(const int16_t *, uint8_t *, ptrdiff_t);
+void ff_put_signed_pixels_clamped_neon(const int16_t *, uint8_t *, ptrdiff_t);
+void ff_add_pixels_clamped_neon(const int16_t *, uint8_t *, ptrdiff_t);
+
 av_cold void ff_idctdsp_init_aarch64(IDCTDSPContext *c, AVCodecContext *avctx,
                                      unsigned high_bit_depth)
 {
     int cpu_flags = av_get_cpu_flags();
 
-    if (have_neon(cpu_flags) && !avctx->lowres && !high_bit_depth) {
-        if (avctx->idct_algo == FF_IDCT_AUTO ||
-            avctx->idct_algo == FF_IDCT_SIMPLEAUTO ||
-            avctx->idct_algo == FF_IDCT_SIMPLENEON) {
-            c->idct_put  = ff_simple_idct_put_neon;
-            c->idct_add  = ff_simple_idct_add_neon;
-            c->idct      = ff_simple_idct_neon;
-            c->perm_type = FF_IDCT_PERM_PARTTRANS;
+    if (have_neon(cpu_flags)) {
+        if (!avctx->lowres && !high_bit_depth) {
+            if (avctx->idct_algo == FF_IDCT_AUTO ||
+                avctx->idct_algo == FF_IDCT_SIMPLEAUTO ||
+                avctx->idct_algo == FF_IDCT_SIMPLENEON) {
+                c->idct_put  = ff_simple_idct_put_neon;
+                c->idct_add  = ff_simple_idct_add_neon;
+                c->idct      = ff_simple_idct_neon;
+                c->perm_type = FF_IDCT_PERM_PARTTRANS;
+            }
         }
+
+        c->add_pixels_clamped        = ff_add_pixels_clamped_neon;
+        c->put_pixels_clamped        = ff_put_pixels_clamped_neon;
+        c->put_signed_pixels_clamped = ff_put_signed_pixels_clamped_neon;
     }
 }
diff -pruN 7:5.0.1-3/libavcodec/aarch64/idctdsp_neon.S 7:5.1-1/libavcodec/aarch64/idctdsp_neon.S
--- 7:5.0.1-3/libavcodec/aarch64/idctdsp_neon.S	1970-01-01 00:00:00.000000000 +0000
+++ 7:5.1-1/libavcodec/aarch64/idctdsp_neon.S	2022-07-22 17:58:38.000000000 +0000
@@ -0,0 +1,130 @@
+/*
+ * IDCT AArch64 NEON optimisations
+ *
+ * Copyright (c) 2022 Ben Avison <bavison@riscosopen.org>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "libavutil/aarch64/asm.S"
+
+// Clamp 16-bit signed block coefficients to unsigned 8-bit
+// On entry:
+//   x0 -> array of 64x 16-bit coefficients
+//   x1 -> 8-bit results
+//   x2 = row stride for results, bytes
+function ff_put_pixels_clamped_neon, export=1
+        ld1             {v0.16b, v1.16b, v2.16b, v3.16b}, [x0], #64
+        ld1             {v4.16b, v5.16b, v6.16b, v7.16b}, [x0]
+        sqxtun          v0.8b, v0.8h
+        sqxtun          v1.8b, v1.8h
+        sqxtun          v2.8b, v2.8h
+        sqxtun          v3.8b, v3.8h
+        sqxtun          v4.8b, v4.8h
+        st1             {v0.8b}, [x1], x2
+        sqxtun          v0.8b, v5.8h
+        st1             {v1.8b}, [x1], x2
+        sqxtun          v1.8b, v6.8h
+        st1             {v2.8b}, [x1], x2
+        sqxtun          v2.8b, v7.8h
+        st1             {v3.8b}, [x1], x2
+        st1             {v4.8b}, [x1], x2
+        st1             {v0.8b}, [x1], x2
+        st1             {v1.8b}, [x1], x2
+        st1             {v2.8b}, [x1]
+        ret
+endfunc
+
+// Clamp 16-bit signed block coefficients to signed 8-bit (biased by 128)
+// On entry:
+//   x0 -> array of 64x 16-bit coefficients
+//   x1 -> 8-bit results
+//   x2 = row stride for results, bytes
+function ff_put_signed_pixels_clamped_neon, export=1
+        ld1             {v0.16b, v1.16b, v2.16b, v3.16b}, [x0], #64
+        movi            v4.8b, #128
+        ld1             {v16.16b, v17.16b, v18.16b, v19.16b}, [x0]
+        sqxtn           v0.8b, v0.8h
+        sqxtn           v1.8b, v1.8h
+        sqxtn           v2.8b, v2.8h
+        sqxtn           v3.8b, v3.8h
+        sqxtn           v5.8b, v16.8h
+        add             v0.8b, v0.8b, v4.8b
+        sqxtn           v6.8b, v17.8h
+        add             v1.8b, v1.8b, v4.8b
+        sqxtn           v7.8b, v18.8h
+        add             v2.8b, v2.8b, v4.8b
+        sqxtn           v16.8b, v19.8h
+        add             v3.8b, v3.8b, v4.8b
+        st1             {v0.8b}, [x1], x2
+        add             v0.8b, v5.8b, v4.8b
+        st1             {v1.8b}, [x1], x2
+        add             v1.8b, v6.8b, v4.8b
+        st1             {v2.8b}, [x1], x2
+        add             v2.8b, v7.8b, v4.8b
+        st1             {v3.8b}, [x1], x2
+        add             v3.8b, v16.8b, v4.8b
+        st1             {v0.8b}, [x1], x2
+        st1             {v1.8b}, [x1], x2
+        st1             {v2.8b}, [x1], x2
+        st1             {v3.8b}, [x1]
+        ret
+endfunc
+
+// Add 16-bit signed block coefficients to unsigned 8-bit
+// On entry:
+//   x0 -> array of 64x 16-bit coefficients
+//   x1 -> 8-bit input and results
+//   x2 = row stride for 8-bit input and results, bytes
+function ff_add_pixels_clamped_neon, export=1
+        ld1             {v0.16b, v1.16b, v2.16b, v3.16b}, [x0], #64
+        mov             x3, x1
+        ld1             {v4.8b}, [x1], x2
+        ld1             {v5.8b}, [x1], x2
+        ld1             {v6.8b}, [x1], x2
+        ld1             {v7.8b}, [x1], x2
+        ld1             {v16.16b, v17.16b, v18.16b, v19.16b}, [x0]
+        uaddw           v0.8h, v0.8h, v4.8b
+        uaddw           v1.8h, v1.8h, v5.8b
+        uaddw           v2.8h, v2.8h, v6.8b
+        ld1             {v4.8b}, [x1], x2
+        uaddw           v3.8h, v3.8h, v7.8b
+        ld1             {v5.8b}, [x1], x2
+        sqxtun          v0.8b, v0.8h
+        ld1             {v6.8b}, [x1], x2
+        sqxtun          v1.8b, v1.8h
+        ld1             {v7.8b}, [x1]
+        sqxtun          v2.8b, v2.8h
+        sqxtun          v3.8b, v3.8h
+        uaddw           v4.8h, v16.8h, v4.8b
+        st1             {v0.8b}, [x3], x2
+        uaddw           v0.8h, v17.8h, v5.8b
+        st1             {v1.8b}, [x3], x2
+        uaddw           v1.8h, v18.8h, v6.8b
+        st1             {v2.8b}, [x3], x2
+        uaddw           v2.8h, v19.8h, v7.8b
+        sqxtun          v4.8b, v4.8h
+        sqxtun          v0.8b, v0.8h
+        st1             {v3.8b}, [x3], x2
+        sqxtun          v1.8b, v1.8h
+        sqxtun          v2.8b, v2.8h
+        st1             {v4.8b}, [x3], x2
+        st1             {v0.8b}, [x3], x2
+        st1             {v1.8b}, [x3], x2
+        st1             {v2.8b}, [x3]
+        ret
+endfunc
diff -pruN 7:5.0.1-3/libavcodec/aarch64/idct.h 7:5.1-1/libavcodec/aarch64/idct.h
--- 7:5.0.1-3/libavcodec/aarch64/idct.h	2021-10-21 17:06:35.000000000 +0000
+++ 7:5.1-1/libavcodec/aarch64/idct.h	2022-07-22 17:58:38.000000000 +0000
@@ -19,6 +19,7 @@
 #ifndef AVCODEC_AARCH64_IDCT_H
 #define AVCODEC_AARCH64_IDCT_H
 
+#include <stddef.h>
 #include <stdint.h>
 
 void ff_simple_idct_neon(int16_t *data);
diff -pruN 7:5.0.1-3/libavcodec/aarch64/Makefile 7:5.1-1/libavcodec/aarch64/Makefile
--- 7:5.0.1-3/libavcodec/aarch64/Makefile	2021-10-24 20:47:07.000000000 +0000
+++ 7:5.1-1/libavcodec/aarch64/Makefile	2022-07-22 17:58:38.000000000 +0000
@@ -7,6 +7,7 @@ OBJS-$(CONFIG_H264PRED)
 OBJS-$(CONFIG_H264QPEL)                 += aarch64/h264qpel_init_aarch64.o
 OBJS-$(CONFIG_HPELDSP)                  += aarch64/hpeldsp_init_aarch64.o
 OBJS-$(CONFIG_IDCTDSP)                  += aarch64/idctdsp_init_aarch64.o
+OBJS-$(CONFIG_ME_CMP)                   += aarch64/me_cmp_init_aarch64.o
 OBJS-$(CONFIG_MPEGAUDIODSP)             += aarch64/mpegaudiodsp_init.o
 OBJS-$(CONFIG_NEON_CLOBBER_TEST)        += aarch64/neontest.o
 OBJS-$(CONFIG_PIXBLOCKDSP)              += aarch64/pixblockdsp_init_aarch64.o
@@ -44,10 +45,13 @@ NEON-OBJS-$(CONFIG_H264PRED)
 NEON-OBJS-$(CONFIG_H264QPEL)            += aarch64/h264qpel_neon.o             \
                                            aarch64/hpeldsp_neon.o
 NEON-OBJS-$(CONFIG_HPELDSP)             += aarch64/hpeldsp_neon.o
-NEON-OBJS-$(CONFIG_IDCTDSP)             += aarch64/simple_idct_neon.o
+NEON-OBJS-$(CONFIG_IDCTDSP)             += aarch64/idctdsp_neon.o              \
+                                           aarch64/simple_idct_neon.o
 NEON-OBJS-$(CONFIG_MDCT)                += aarch64/mdct_neon.o
+NEON-OBJS-$(CONFIG_ME_CMP)              += aarch64/me_cmp_neon.o
 NEON-OBJS-$(CONFIG_MPEGAUDIODSP)        += aarch64/mpegaudiodsp_neon.o
 NEON-OBJS-$(CONFIG_PIXBLOCKDSP)         += aarch64/pixblockdsp_neon.o
+NEON-OBJS-$(CONFIG_VC1DSP)              += aarch64/vc1dsp_neon.o
 NEON-OBJS-$(CONFIG_VP8DSP)              += aarch64/vp8dsp_neon.o
 
 # decoders/encoders
diff -pruN 7:5.0.1-3/libavcodec/aarch64/mdct_neon.S 7:5.1-1/libavcodec/aarch64/mdct_neon.S
--- 7:5.0.1-3/libavcodec/aarch64/mdct_neon.S	2020-04-27 21:48:15.000000000 +0000
+++ 7:5.1-1/libavcodec/aarch64/mdct_neon.S	2022-07-22 17:58:38.000000000 +0000
@@ -25,6 +25,7 @@
 function ff_imdct_half_neon, export=1
         sub             sp,  sp,  #32
         stp             x19, x20, [sp]
+        AARCH64_SIGN_LINK_REGISTER
         str             x30, [sp, #16]
         mov             x12, #1
         ldr             w14, [x0, #28]          // mdct_bits
@@ -121,6 +122,7 @@ function ff_imdct_half_neon, export=1
 
         ldp             x19, x20, [sp]
         ldr             x30, [sp, #16]
+        AARCH64_VALIDATE_LINK_REGISTER
         add             sp,  sp,  #32
 
         ret
@@ -129,6 +131,7 @@ endfunc
 function ff_imdct_calc_neon, export=1
         sub             sp,  sp,  #32
         stp             x19, x20, [sp]
+        AARCH64_SIGN_LINK_REGISTER
         str             x30, [sp, #16]
         ldr             w3,  [x0, #28]          // mdct_bits
         mov             x19, #1
@@ -160,8 +163,10 @@ function ff_imdct_calc_neon, export=1
         subs            x19, x19,  #16
         b.gt            1b
 
-        ldp             x19, x20, [sp], #16
-        ldr             x30, [sp], #16
+        ldp             x19, x20, [sp]
+        ldr             x30, [sp, #16]
+        AARCH64_VALIDATE_LINK_REGISTER
+        add             sp,  sp,  #32
 
         ret
 endfunc
@@ -170,6 +175,7 @@ endfunc
 function ff_mdct_calc_neon, export=1
         sub             sp,  sp,  #32
         stp             x19, x20, [sp]
+        AARCH64_SIGN_LINK_REGISTER
         str             x30, [sp, #16]
 
         mov             x12, #1
@@ -317,7 +323,10 @@ function ff_mdct_calc_neon, export=1
         st2             {v4.2s,v5.2s},  [x0]
         st2             {v6.2s,v7.2s},  [x8]
 
-        ldp             x19, x20, [sp], #16
-        ldr             x30, [sp], #16
+        ldp             x19, x20, [sp]
+        ldr             x30, [sp, #16]
+        AARCH64_VALIDATE_LINK_REGISTER
+        add             sp,  sp,  #32
+
         ret
 endfunc
diff -pruN 7:5.0.1-3/libavcodec/aarch64/me_cmp_init_aarch64.c 7:5.1-1/libavcodec/aarch64/me_cmp_init_aarch64.c
--- 7:5.0.1-3/libavcodec/aarch64/me_cmp_init_aarch64.c	1970-01-01 00:00:00.000000000 +0000
+++ 7:5.1-1/libavcodec/aarch64/me_cmp_init_aarch64.c	2022-07-22 17:58:38.000000000 +0000
@@ -0,0 +1,41 @@
+/*
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stdint.h>
+
+#include "config.h"
+#include "libavutil/attributes.h"
+#include "libavutil/aarch64/cpu.h"
+#include "libavcodec/mpegvideo.h"
+
+int ff_pix_abs16_neon(MpegEncContext *s, uint8_t *blk1, uint8_t *blk2,
+                      ptrdiff_t stride, int h);
+int ff_pix_abs16_xy2_neon(MpegEncContext *s, uint8_t *blk1, uint8_t *blk2,
+                      ptrdiff_t stride, int h);
+
+av_cold void ff_me_cmp_init_aarch64(MECmpContext *c, AVCodecContext *avctx)
+{
+    int cpu_flags = av_get_cpu_flags();
+
+    if (have_neon(cpu_flags)) {
+        c->pix_abs[0][0] = ff_pix_abs16_neon;
+        c->pix_abs[0][3] = ff_pix_abs16_xy2_neon;
+
+        c->sad[0] = ff_pix_abs16_neon;
+    }
+}
diff -pruN 7:5.0.1-3/libavcodec/aarch64/me_cmp_neon.S 7:5.1-1/libavcodec/aarch64/me_cmp_neon.S
--- 7:5.0.1-3/libavcodec/aarch64/me_cmp_neon.S	1970-01-01 00:00:00.000000000 +0000
+++ 7:5.1-1/libavcodec/aarch64/me_cmp_neon.S	2022-07-22 17:58:38.000000000 +0000
@@ -0,0 +1,205 @@
+/*
+ * Copyright (c) 2022 Jonathan Swinney <jswinney@amazon.com>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "libavutil/aarch64/asm.S"
+
+function ff_pix_abs16_neon, export=1
+        // x0           unused
+        // x1           uint8_t *pix1
+        // x2           uint8_t *pix2
+        // x3           ptrdiff_t stride
+        // w4           int h
+        cmp             w4, #4                      // if h < 4, jump to completion section
+        movi            v18.4S, #0                  // clear result accumulator
+        b.lt            2f
+1:
+        ld1             {v0.16b}, [x1], x3          // load pix1
+        ld1             {v4.16b}, [x2], x3          // load pix2
+        ld1             {v1.16b}, [x1], x3          // load pix1
+        ld1             {v5.16b}, [x2], x3          // load pix2
+        uabdl           v16.8h, v0.8b, v4.8b        // absolute difference accumulate
+        uabdl2          v17.8h, v0.16b, v4.16b
+        ld1             {v2.16b}, [x1], x3          // load pix1
+        ld1             {v6.16b}, [x2], x3          // load pix2
+        uabal           v16.8h, v1.8b, v5.8b        // absolute difference accumulate
+        uabal2          v17.8h, v1.16b, v5.16b
+        ld1             {v3.16b}, [x1], x3
+        ld1             {v7.16b}, [x2], x3
+        uabal           v16.8h, v2.8b, v6.8b
+        uabal2          v17.8h, v2.16b, v6.16b
+        sub             w4, w4, #4                  // h -= 4
+        uabal           v16.8h, v3.8b, v7.8b
+        uabal2          v17.8h, v3.16b, v7.16b
+        cmp             w4, #4                      // if h >= 4, loop
+        add             v16.8h, v16.8h, v17.8h
+        uaddlv          s16, v16.8h                 // add up everything in v16 accumulator
+        add             d18, d16, d18               // add to the end result register
+
+        b.ge            1b
+        cbnz            w4, 2f                      // if iterations remain, jump to completion section
+
+        fmov            w0, s18                     // copy result to general purpose register
+        ret
+
+2:
+        ld1             {v0.16b}, [x1], x3          // load pix1
+        ld1             {v4.16b}, [x2], x3          // load pix2
+        uabdl           v16.8h, v0.8b, v4.8b        // absolute difference accumulate
+        uabal2          v16.8h, v0.16b, v4.16b
+        subs            w4, w4, #1                  // h -= 1
+        addv            h16, v16.8h                 // add up v16
+        add             d18, d16, d18               // add to result
+        b.ne            2b
+
+        fmov            w0, s18                     // copy result to general purpose register
+        ret
+endfunc
+
+function ff_pix_abs16_xy2_neon, export=1
+        // x0           unused
+        // x1           uint8_t *pix1
+        // x2           uint8_t *pix2
+        // x3           ptrdiff_t stride
+        // w4           int h
+
+        add             x5, x2, x3                  // use x5 to hold uint8_t *pix3
+        movi            v0.2d, #0                   // initialize the result register
+
+        // Load initial pix2 values for either the unrolled version or completion version.
+        ldur            q4, [x2, #1]                // load pix2+1
+        ldr             q3, [x2]                    // load pix2
+        uaddl           v2.8h, v4.8b, v3.8b         // pix2 + pix2+1 0..7
+        uaddl2          v3.8h, v4.16b, v3.16b       // pix2 + pix2+1 8..15
+        cmp             w4, #4                      // if h < 4 jump to the completion version
+        b.lt            2f
+1:
+        // This is an unrolled implementation. It completes 4 iterations of the C for each branch.
+        // In each iteration, pix2[i+1] == pix3[i]. This means we need only three loads per iteration,
+        // plus two at the beginning to start.
+        ldur            q5, [x5, #1]                // load pix3+1
+        ld1             {v4.16b}, [x5], x3          // load pix3
+        ld1             {v1.16b}, [x1], x3          // load pix1
+
+        ldur            q7, [x5, #1]                // load pix3+1
+        ld1             {v6.16b}, [x5], x3          // load pix3
+        ld1             {v16.16b}, [x1], x3         // load pix1
+
+        ldur            q19, [x5, #1]               // load pix3+1
+        ld1             {v18.16b}, [x5], x3         // load pix3
+        ld1             {v17.16b}, [x1], x3         // load pix1
+
+        ldur            q22, [x5, #1]               // load pix3+1
+        ld1             {v21.16b}, [x5], x3         // load pix3
+        ld1             {v20.16b}, [x1], x3         // load pix1
+
+        // These blocks compute the average: avg(pix2[n], pix2[n+1], pix3[n], pix3[n+1])
+        uaddl           v30.8h, v4.8b, v5.8b        // pix3 + pix3+1 0..7
+        uaddl2          v31.8h, v4.16b, v5.16b      // pix3 + pix3+1 8..15
+        add             v23.8h, v2.8h, v30.8h       // add up 0..7, using pix2 + pix2+1 values from previous iteration
+        add             v24.8h, v3.8h, v31.8h       // add up 8..15, using pix2 + pix2+1 values from previous iteration
+        rshrn           v23.8b, v23.8h, #2          // shift right 2 0..7 (rounding shift right)
+        rshrn2          v23.16b, v24.8h, #2         // shift right 2 8..15
+
+        uaddl           v2.8h, v6.8b, v7.8b         // pix3 + pix3+1 0..7
+        uaddl2          v3.8h, v6.16b, v7.16b       // pix3 + pix3+1 8..15
+        add             v26.8h, v30.8h, v2.8h       // add up 0..7, using pix2 + pix2+1 values from pix3 above
+        add             v27.8h, v31.8h, v3.8h       // add up 8..15, using pix2 + pix2+1 values from pix3 above
+        rshrn           v26.8b, v26.8h, #2          // shift right 2 0..7 (rounding shift right)
+        rshrn2          v26.16b, v27.8h, #2         // shift right 2 8..15
+
+        uaddl           v4.8h, v18.8b, v19.8b       // pix3 + pix3+1 0..7
+        uaddl2          v5.8h, v18.16b, v19.16b     // pix3 + pix3+1 8..15
+        add             v28.8h, v2.8h, v4.8h        // add up 0..7, using pix2 + pix2+1 values from pix3 above
+        add             v29.8h, v3.8h, v5.8h        // add up 8..15, using pix2 + pix2+1 values from pix3 above
+        rshrn           v28.8b, v28.8h, #2          // shift right 2 0..7 (rounding shift right)
+        rshrn2          v28.16b, v29.8h, #2         // shift right 2 8..15
+
+        uaddl           v2.8h, v21.8b, v22.8b       // pix3 + pix3+1 0..7
+        uaddl2          v3.8h, v21.16b, v22.16b     // pix3 + pix3+1 8..15
+        add             v30.8h, v4.8h, v2.8h        // add up 0..7, using pix2 + pix2+1 values from pix3 above
+        add             v31.8h, v5.8h, v3.8h        // add up 8..15, using pix2 + pix2+1 values from pix3 above
+        rshrn           v30.8b, v30.8h, #2          // shift right 2 0..7 (rounding shift right)
+        rshrn2          v30.16b, v31.8h, #2         // shift right 2 8..15
+
+        // Averages are now stored in these registers:
+        // v23, v16, v28, v30
+        // pix1 values in these registers:
+        // v1, v16, v17, v20
+        // available:
+        // v4, v5, v7, v18, v19, v24, v25, v27, v29, v31
+
+        sub             w4, w4, #4                  // h -= 4
+
+        // Using absolute-difference instructions instead of absolute-difference-accumulate allows
+        // us to keep the results in 16b vectors instead of widening values with twice the instructions.
+        // This approach also has fewer data dependencies, allowing better instruction level parallelism.
+        uabd            v4.16b, v1.16b, v23.16b     // absolute difference 0..15, i=0
+        uabd            v5.16b, v16.16b, v26.16b    // absolute difference 0..15, i=1
+        uabd            v6.16b, v17.16b, v28.16b    // absolute difference 0..15, i=2
+        uabd            v7.16b, v20.16b, v30.16b    // absolute difference 0..15, i=3
+
+        cmp             w4, #4                      // loop if h >= 4
+
+        // Now add up all the values in each vector, v4-v7 with widening adds
+        uaddl           v19.8h, v4.8b, v5.8b
+        uaddl2          v18.8h, v4.16b, v5.16b
+        uaddl           v4.8h, v6.8b, v7.8b
+        uaddl2          v5.8h, v6.16b, v7.16b
+        add             v4.8h, v4.8h, v5.8h
+        add             v4.8h, v4.8h, v18.8h
+        add             v4.8h, v4.8h, v19.8h
+        uaddlv          s4, v4.8h                   // finish adding up accumulated values
+        add             d0, d0, d4                  // add the value to the top level accumulator
+
+        b.ge            1b
+        cbnz            w4, 2f                      // if iterations remain jump to completion section
+
+        fmov            w0, s0                      // copy result to general purpose register
+        ret
+2:
+        // v2 and v3 are set either at the end of this loop or at from the unrolled version
+        // which branches here to complete iterations when h % 4 != 0.
+        ldur            q5, [x5, #1]                // load pix3+1
+        ld1             {v4.16b}, [x5], x3          // load pix3
+        ld1             {v1.16b}, [x1], x3          // load pix1
+        subs            w4, w4, #1                  // decrement h
+
+        uaddl           v18.8h, v4.8b, v5.8b        // pix3 + pix3+1 0..7
+        uaddl2          v19.8h, v4.16b, v5.16b      // pix3 + pix3+1 8..15
+        add             v16.8h, v2.8h, v18.8h       // add up 0..7, using pix2 + pix2+1 values from previous iteration
+        add             v17.8h, v3.8h, v19.8h       // add up 8..15, using pix2 + pix2+1 values from previous iteration
+        // divide by 4 to compute the average of values summed above
+        urshr           v16.8h, v16.8h, #2          // shift right by 2 0..7 (rounding shift right)
+        urshr           v17.8h, v17.8h, #2          // shift right by 2 8..15
+
+        uxtl2           v8.8h, v1.16b               // 8->16 bits pix1 8..15
+        uxtl            v1.8h, v1.8b                // 8->16 bits pix1 0..7
+
+        uabd            v6.8h, v1.8h, v16.8h        // absolute difference 0..7
+        uaba            v6.8h, v8.8h, v17.8h        // absolute difference accumulate 8..15
+        mov             v2.16b, v18.16b             // pix3 -> pix2
+        mov             v3.16b, v19.16b             // pix3+1 -> pix2+1
+        uaddlv          s6, v6.8h                   // add up accumulator in v6
+        add             d0, d0, d6                  // add to the final result
+
+        b.ne            2b                          // loop if h > 0
+        fmov            w0, s0                      // copy result to general purpose register
+        ret
+endfunc
diff -pruN 7:5.0.1-3/libavcodec/aarch64/synth_filter_neon.S 7:5.1-1/libavcodec/aarch64/synth_filter_neon.S
--- 7:5.0.1-3/libavcodec/aarch64/synth_filter_neon.S	2021-10-21 17:06:35.000000000 +0000
+++ 7:5.1-1/libavcodec/aarch64/synth_filter_neon.S	2022-07-22 17:58:38.000000000 +0000
@@ -52,6 +52,7 @@ function ff_synth_filter_float_neon, exp
         stp             x5,  x1,  [sp, #16]
         and             x7,  x7,  #~63
         and             w8,  w8,  #511
+        AARCH64_SIGN_LINK_REGISTER
         stp             x7,  x30, [sp, #32]
         str             w8,  [x2]
         str             s0,  [sp, #48]
@@ -63,6 +64,7 @@ function ff_synth_filter_float_neon, exp
         ldp             x2,  x4,  [sp]          // synct_buf_2, window
         ldp             x13, x9,  [sp, #16]     // out, synth_buf
         ldp             x0,  x30, [sp, #32]     // *synth_buf_offset
+        AARCH64_VALIDATE_LINK_REGISTER
         ldr             s0,  [sp, #48]
 
         add             x3,  x2,  #16*4         // synct_buf_2 + 16
diff -pruN 7:5.0.1-3/libavcodec/aarch64/vc1dsp_init_aarch64.c 7:5.1-1/libavcodec/aarch64/vc1dsp_init_aarch64.c
--- 7:5.0.1-3/libavcodec/aarch64/vc1dsp_init_aarch64.c	2021-10-21 17:06:35.000000000 +0000
+++ 7:5.1-1/libavcodec/aarch64/vc1dsp_init_aarch64.c	2022-07-22 17:58:38.000000000 +0000
@@ -21,10 +21,28 @@
 #include "libavutil/attributes.h"
 #include "libavutil/cpu.h"
 #include "libavutil/aarch64/cpu.h"
+#include "libavutil/intreadwrite.h"
 #include "libavcodec/vc1dsp.h"
 
 #include "config.h"
 
+void ff_vc1_inv_trans_8x8_neon(int16_t *block);
+void ff_vc1_inv_trans_8x4_neon(uint8_t *dest, ptrdiff_t stride, int16_t *block);
+void ff_vc1_inv_trans_4x8_neon(uint8_t *dest, ptrdiff_t stride, int16_t *block);
+void ff_vc1_inv_trans_4x4_neon(uint8_t *dest, ptrdiff_t stride, int16_t *block);
+
+void ff_vc1_inv_trans_8x8_dc_neon(uint8_t *dest, ptrdiff_t stride, int16_t *block);
+void ff_vc1_inv_trans_8x4_dc_neon(uint8_t *dest, ptrdiff_t stride, int16_t *block);
+void ff_vc1_inv_trans_4x8_dc_neon(uint8_t *dest, ptrdiff_t stride, int16_t *block);
+void ff_vc1_inv_trans_4x4_dc_neon(uint8_t *dest, ptrdiff_t stride, int16_t *block);
+
+void ff_vc1_v_loop_filter4_neon(uint8_t *src, ptrdiff_t stride, int pq);
+void ff_vc1_h_loop_filter4_neon(uint8_t *src, ptrdiff_t stride, int pq);
+void ff_vc1_v_loop_filter8_neon(uint8_t *src, ptrdiff_t stride, int pq);
+void ff_vc1_h_loop_filter8_neon(uint8_t *src, ptrdiff_t stride, int pq);
+void ff_vc1_v_loop_filter16_neon(uint8_t *src, ptrdiff_t stride, int pq);
+void ff_vc1_h_loop_filter16_neon(uint8_t *src, ptrdiff_t stride, int pq);
+
 void ff_put_vc1_chroma_mc8_neon(uint8_t *dst, uint8_t *src, ptrdiff_t stride,
                                 int h, int x, int y);
 void ff_avg_vc1_chroma_mc8_neon(uint8_t *dst, uint8_t *src, ptrdiff_t stride,
@@ -34,14 +52,90 @@ void ff_put_vc1_chroma_mc4_neon(uint8_t
 void ff_avg_vc1_chroma_mc4_neon(uint8_t *dst, uint8_t *src, ptrdiff_t stride,
                                 int h, int x, int y);
 
+int ff_vc1_unescape_buffer_helper_neon(const uint8_t *src, int size, uint8_t *dst);
+
+static int vc1_unescape_buffer_neon(const uint8_t *src, int size, uint8_t *dst)
+{
+    /* Dealing with starting and stopping, and removing escape bytes, are
+     * comparatively less time-sensitive, so are more clearly expressed using
+     * a C wrapper around the assembly inner loop. Note that we assume a
+     * little-endian machine that supports unaligned loads. */
+    int dsize = 0;
+    while (size >= 4)
+    {
+        int found = 0;
+        while (!found && (((uintptr_t) dst) & 7) && size >= 4)
+        {
+            found = (AV_RL32(src) &~ 0x03000000) == 0x00030000;
+            if (!found)
+            {
+                *dst++ = *src++;
+                --size;
+                ++dsize;
+            }
+        }
+        if (!found)
+        {
+            int skip = size - ff_vc1_unescape_buffer_helper_neon(src, size, dst);
+            dst += skip;
+            src += skip;
+            size -= skip;
+            dsize += skip;
+            while (!found && size >= 4)
+            {
+                found = (AV_RL32(src) &~ 0x03000000) == 0x00030000;
+                if (!found)
+                {
+                    *dst++ = *src++;
+                    --size;
+                    ++dsize;
+                }
+            }
+        }
+        if (found)
+        {
+            *dst++ = *src++;
+            *dst++ = *src++;
+            ++src;
+            size -= 3;
+            dsize += 2;
+        }
+    }
+    while (size > 0)
+    {
+        *dst++ = *src++;
+        --size;
+        ++dsize;
+    }
+    return dsize;
+}
+
 av_cold void ff_vc1dsp_init_aarch64(VC1DSPContext *dsp)
 {
     int cpu_flags = av_get_cpu_flags();
 
     if (have_neon(cpu_flags)) {
+        dsp->vc1_inv_trans_8x8 = ff_vc1_inv_trans_8x8_neon;
+        dsp->vc1_inv_trans_8x4 = ff_vc1_inv_trans_8x4_neon;
+        dsp->vc1_inv_trans_4x8 = ff_vc1_inv_trans_4x8_neon;
+        dsp->vc1_inv_trans_4x4 = ff_vc1_inv_trans_4x4_neon;
+        dsp->vc1_inv_trans_8x8_dc = ff_vc1_inv_trans_8x8_dc_neon;
+        dsp->vc1_inv_trans_8x4_dc = ff_vc1_inv_trans_8x4_dc_neon;
+        dsp->vc1_inv_trans_4x8_dc = ff_vc1_inv_trans_4x8_dc_neon;
+        dsp->vc1_inv_trans_4x4_dc = ff_vc1_inv_trans_4x4_dc_neon;
+
+        dsp->vc1_v_loop_filter4  = ff_vc1_v_loop_filter4_neon;
+        dsp->vc1_h_loop_filter4  = ff_vc1_h_loop_filter4_neon;
+        dsp->vc1_v_loop_filter8  = ff_vc1_v_loop_filter8_neon;
+        dsp->vc1_h_loop_filter8  = ff_vc1_h_loop_filter8_neon;
+        dsp->vc1_v_loop_filter16 = ff_vc1_v_loop_filter16_neon;
+        dsp->vc1_h_loop_filter16 = ff_vc1_h_loop_filter16_neon;
+
         dsp->put_no_rnd_vc1_chroma_pixels_tab[0] = ff_put_vc1_chroma_mc8_neon;
         dsp->avg_no_rnd_vc1_chroma_pixels_tab[0] = ff_avg_vc1_chroma_mc8_neon;
         dsp->put_no_rnd_vc1_chroma_pixels_tab[1] = ff_put_vc1_chroma_mc4_neon;
         dsp->avg_no_rnd_vc1_chroma_pixels_tab[1] = ff_avg_vc1_chroma_mc4_neon;
+
+        dsp->vc1_unescape_buffer = vc1_unescape_buffer_neon;
     }
 }
diff -pruN 7:5.0.1-3/libavcodec/aarch64/vc1dsp_neon.S 7:5.1-1/libavcodec/aarch64/vc1dsp_neon.S
--- 7:5.0.1-3/libavcodec/aarch64/vc1dsp_neon.S	1970-01-01 00:00:00.000000000 +0000
+++ 7:5.1-1/libavcodec/aarch64/vc1dsp_neon.S	2022-07-22 17:58:38.000000000 +0000
@@ -0,0 +1,1546 @@
+/*
+ * VC1 AArch64 NEON optimisations
+ *
+ * Copyright (c) 2022 Ben Avison <bavison@riscosopen.org>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "libavutil/aarch64/asm.S"
+
+// VC-1 8x8 inverse transform
+// On entry:
+//   x0 -> array of 16-bit inverse transform coefficients, in column-major order
+// On exit:
+//   array at x0 updated to hold transformed block; also now held in row-major order
+function ff_vc1_inv_trans_8x8_neon, export=1
+        ld1             {v1.16b, v2.16b}, [x0], #32
+        ld1             {v3.16b, v4.16b}, [x0], #32
+        ld1             {v5.16b, v6.16b}, [x0], #32
+        shl             v1.8h, v1.8h, #2        //         8/2 * src[0]
+        sub             x1, x0, #3*32
+        ld1             {v16.16b, v17.16b}, [x0]
+        shl             v7.8h, v2.8h, #4        //          16 * src[8]
+        shl             v18.8h, v2.8h, #2       //           4 * src[8]
+        shl             v19.8h, v4.8h, #4       //                        16 * src[24]
+        ldr             d0, .Lcoeffs_it8
+        shl             v5.8h, v5.8h, #2        //                                      8/2 * src[32]
+        shl             v20.8h, v6.8h, #4       //                                       16 * src[40]
+        shl             v21.8h, v6.8h, #2       //                                        4 * src[40]
+        shl             v22.8h, v17.8h, #4      //                                                      16 * src[56]
+        ssra            v20.8h, v19.8h, #2      //                         4 * src[24] + 16 * src[40]
+        mul             v23.8h, v3.8h, v0.h[0]  //                       6/2 * src[16]
+        sub             v19.8h, v19.8h, v21.8h  //                        16 * src[24] -  4 * src[40]
+        ssra            v7.8h, v22.8h, #2       //          16 * src[8]                               +  4 * src[56]
+        sub             v18.8h, v22.8h, v18.8h  //        -  4 * src[8]                               + 16 * src[56]
+        shl             v3.8h, v3.8h, #3        //                      16/2 * src[16]
+        mls             v20.8h, v2.8h, v0.h[2]  //        - 15 * src[8] +  4 * src[24] + 16 * src[40]
+        ssra            v1.8h, v1.8h, #1        //        12/2 * src[0]
+        ssra            v5.8h, v5.8h, #1        //                                     12/2 * src[32]
+        mla             v7.8h, v4.8h, v0.h[2]   //          16 * src[8] + 15 * src[24]                +  4 * src[56]
+        shl             v21.8h, v16.8h, #3      //                                                    16/2 * src[48]
+        mls             v19.8h, v2.8h, v0.h[1]  //        -  9 * src[8] + 16 * src[24] -  4 * src[40]
+        sub             v2.8h, v23.8h, v21.8h   // t4/2 =                6/2 * src[16]              - 16/2 * src[48]
+        mla             v18.8h, v4.8h, v0.h[1]  //        -  4 * src[8] +  9 * src[24]                + 16 * src[56]
+        add             v4.8h, v1.8h, v5.8h     // t1/2 = 12/2 * src[0]              + 12/2 * src[32]
+        sub             v1.8h, v1.8h, v5.8h     // t2/2 = 12/2 * src[0]              - 12/2 * src[32]
+        mla             v3.8h, v16.8h, v0.h[0]  // t3/2 =               16/2 * src[16]              +  6/2 * src[48]
+        mla             v7.8h, v6.8h, v0.h[1]   //  t1  =   16 * src[8] + 15 * src[24] +  9 * src[40] +  4 * src[56]
+        add             v5.8h, v1.8h, v2.8h     // t6/2 = t2/2 + t4/2
+        sub             v16.8h, v1.8h, v2.8h    // t7/2 = t2/2 - t4/2
+        mla             v20.8h, v17.8h, v0.h[1] // -t2  = - 15 * src[8] +  4 * src[24] + 16 * src[40] +  9 * src[56]
+        add             v21.8h, v1.8h, v2.8h    // t6/2 = t2/2 + t4/2
+        add             v22.8h, v4.8h, v3.8h    // t5/2 = t1/2 + t3/2
+        mls             v19.8h, v17.8h, v0.h[2] // -t3  = -  9 * src[8] + 16 * src[24] -  4 * src[40] - 15 * src[56]
+        sub             v17.8h, v4.8h, v3.8h    // t8/2 = t1/2 - t3/2
+        add             v23.8h, v4.8h, v3.8h    // t5/2 = t1/2 + t3/2
+        mls             v18.8h, v6.8h, v0.h[2]  // -t4  = -  4 * src[8] +  9 * src[24] - 15 * src[40] + 16 * src[56]
+        sub             v1.8h, v1.8h, v2.8h     // t7/2 = t2/2 - t4/2
+        sub             v2.8h, v4.8h, v3.8h     // t8/2 = t1/2 - t3/2
+        neg             v3.8h, v7.8h            // -t1
+        neg             v4.8h, v20.8h           // +t2
+        neg             v6.8h, v19.8h           // +t3
+        ssra            v22.8h, v7.8h, #1       // (t5 + t1) >> 1
+        ssra            v1.8h, v19.8h, #1       // (t7 - t3) >> 1
+        neg             v7.8h, v18.8h           // +t4
+        ssra            v5.8h, v4.8h, #1        // (t6 + t2) >> 1
+        ssra            v16.8h, v6.8h, #1       // (t7 + t3) >> 1
+        ssra            v2.8h, v18.8h, #1       // (t8 - t4) >> 1
+        ssra            v17.8h, v7.8h, #1       // (t8 + t4) >> 1
+        ssra            v21.8h, v20.8h, #1      // (t6 - t2) >> 1
+        ssra            v23.8h, v3.8h, #1       // (t5 - t1) >> 1
+        srshr           v3.8h, v22.8h, #2       // (t5 + t1 + 4) >> 3
+        srshr           v4.8h, v5.8h, #2        // (t6 + t2 + 4) >> 3
+        srshr           v5.8h, v16.8h, #2       // (t7 + t3 + 4) >> 3
+        srshr           v6.8h, v17.8h, #2       // (t8 + t4 + 4) >> 3
+        srshr           v2.8h, v2.8h, #2        // (t8 - t4 + 4) >> 3
+        srshr           v1.8h, v1.8h, #2        // (t7 - t3 + 4) >> 3
+        srshr           v7.8h, v21.8h, #2       // (t6 - t2 + 4) >> 3
+        srshr           v16.8h, v23.8h, #2      // (t5 - t1 + 4) >> 3
+        trn2            v17.8h, v3.8h, v4.8h
+        trn2            v18.8h, v5.8h, v6.8h
+        trn2            v19.8h, v2.8h, v1.8h
+        trn2            v20.8h, v7.8h, v16.8h
+        trn1            v21.4s, v17.4s, v18.4s
+        trn2            v17.4s, v17.4s, v18.4s
+        trn1            v18.4s, v19.4s, v20.4s
+        trn2            v19.4s, v19.4s, v20.4s
+        trn1            v3.8h, v3.8h, v4.8h
+        trn2            v4.2d, v21.2d, v18.2d
+        trn1            v20.2d, v17.2d, v19.2d
+        trn1            v5.8h, v5.8h, v6.8h
+        trn1            v1.8h, v2.8h, v1.8h
+        trn1            v2.8h, v7.8h, v16.8h
+        trn1            v6.2d, v21.2d, v18.2d
+        trn2            v7.2d, v17.2d, v19.2d
+        shl             v16.8h, v20.8h, #4      //                        16 * src[24]
+        shl             v17.8h, v4.8h, #4       //                                       16 * src[40]
+        trn1            v18.4s, v3.4s, v5.4s
+        trn1            v19.4s, v1.4s, v2.4s
+        shl             v21.8h, v7.8h, #4       //                                                      16 * src[56]
+        shl             v22.8h, v6.8h, #2       //           4 * src[8]
+        shl             v23.8h, v4.8h, #2       //                                        4 * src[40]
+        trn2            v3.4s, v3.4s, v5.4s
+        trn2            v1.4s, v1.4s, v2.4s
+        shl             v2.8h, v6.8h, #4        //          16 * src[8]
+        sub             v5.8h, v16.8h, v23.8h   //                        16 * src[24] -  4 * src[40]
+        ssra            v17.8h, v16.8h, #2      //                         4 * src[24] + 16 * src[40]
+        sub             v16.8h, v21.8h, v22.8h  //        -  4 * src[8]                               + 16 * src[56]
+        trn1            v22.2d, v18.2d, v19.2d
+        trn2            v18.2d, v18.2d, v19.2d
+        trn1            v19.2d, v3.2d, v1.2d
+        ssra            v2.8h, v21.8h, #2       //          16 * src[8]                               +  4 * src[56]
+        mls             v17.8h, v6.8h, v0.h[2]  //        - 15 * src[8] +  4 * src[24] + 16 * src[40]
+        shl             v21.8h, v22.8h, #2      //         8/2 * src[0]
+        shl             v18.8h, v18.8h, #2      //                                      8/2 * src[32]
+        mls             v5.8h, v6.8h, v0.h[1]   //        -  9 * src[8] + 16 * src[24] -  4 * src[40]
+        shl             v6.8h, v19.8h, #3       //                      16/2 * src[16]
+        trn2            v1.2d, v3.2d, v1.2d
+        mla             v16.8h, v20.8h, v0.h[1] //        -  4 * src[8] +  9 * src[24]                + 16 * src[56]
+        ssra            v21.8h, v21.8h, #1      //        12/2 * src[0]
+        ssra            v18.8h, v18.8h, #1      //                                     12/2 * src[32]
+        mul             v3.8h, v19.8h, v0.h[0]  //                       6/2 * src[16]
+        shl             v19.8h, v1.8h, #3       //                                                    16/2 * src[48]
+        mla             v2.8h, v20.8h, v0.h[2]  //          16 * src[8] + 15 * src[24]                +  4 * src[56]
+        add             v20.8h, v21.8h, v18.8h  // t1/2 = 12/2 * src[0]              + 12/2 * src[32]
+        mla             v6.8h, v1.8h, v0.h[0]   // t3/2 =               16/2 * src[16]              +  6/2 * src[48]
+        sub             v1.8h, v21.8h, v18.8h   // t2/2 = 12/2 * src[0]              - 12/2 * src[32]
+        sub             v3.8h, v3.8h, v19.8h    // t4/2 =                6/2 * src[16]              - 16/2 * src[48]
+        mla             v17.8h, v7.8h, v0.h[1]  // -t2  = - 15 * src[8] +  4 * src[24] + 16 * src[40] +  9 * src[56]
+        mls             v5.8h, v7.8h, v0.h[2]   // -t3  = -  9 * src[8] + 16 * src[24] -  4 * src[40] - 15 * src[56]
+        add             v7.8h, v1.8h, v3.8h     // t6/2 = t2/2 + t4/2
+        add             v18.8h, v20.8h, v6.8h   // t5/2 = t1/2 + t3/2
+        mls             v16.8h, v4.8h, v0.h[2]  // -t4  = -  4 * src[8] +  9 * src[24] - 15 * src[40] + 16 * src[56]
+        sub             v19.8h, v1.8h, v3.8h    // t7/2 = t2/2 - t4/2
+        neg             v21.8h, v17.8h          // +t2
+        mla             v2.8h, v4.8h, v0.h[1]   //  t1  =   16 * src[8] + 15 * src[24] +  9 * src[40] +  4 * src[56]
+        sub             v0.8h, v20.8h, v6.8h    // t8/2 = t1/2 - t3/2
+        neg             v4.8h, v5.8h            // +t3
+        sub             v22.8h, v1.8h, v3.8h    // t7/2 = t2/2 - t4/2
+        sub             v23.8h, v20.8h, v6.8h   // t8/2 = t1/2 - t3/2
+        neg             v24.8h, v16.8h          // +t4
+        add             v6.8h, v20.8h, v6.8h    // t5/2 = t1/2 + t3/2
+        add             v1.8h, v1.8h, v3.8h     // t6/2 = t2/2 + t4/2
+        ssra            v7.8h, v21.8h, #1       // (t6 + t2) >> 1
+        neg             v3.8h, v2.8h            // -t1
+        ssra            v18.8h, v2.8h, #1       // (t5 + t1) >> 1
+        ssra            v19.8h, v4.8h, #1       // (t7 + t3) >> 1
+        ssra            v0.8h, v24.8h, #1       // (t8 + t4) >> 1
+        srsra           v23.8h, v16.8h, #1      // (t8 - t4 + 1) >> 1
+        srsra           v22.8h, v5.8h, #1       // (t7 - t3 + 1) >> 1
+        srsra           v1.8h, v17.8h, #1       // (t6 - t2 + 1) >> 1
+        srsra           v6.8h, v3.8h, #1        // (t5 - t1 + 1) >> 1
+        srshr           v2.8h, v18.8h, #6       // (t5 + t1 + 64) >> 7
+        srshr           v3.8h, v7.8h, #6        // (t6 + t2 + 64) >> 7
+        srshr           v4.8h, v19.8h, #6       // (t7 + t3 + 64) >> 7
+        srshr           v5.8h, v0.8h, #6        // (t8 + t4 + 64) >> 7
+        srshr           v16.8h, v23.8h, #6      // (t8 - t4 + 65) >> 7
+        srshr           v17.8h, v22.8h, #6      // (t7 - t3 + 65) >> 7
+        st1             {v2.16b, v3.16b}, [x1], #32
+        srshr           v0.8h, v1.8h, #6        // (t6 - t2 + 65) >> 7
+        srshr           v1.8h, v6.8h, #6        // (t5 - t1 + 65) >> 7
+        st1             {v4.16b, v5.16b}, [x1], #32
+        st1             {v16.16b, v17.16b}, [x1], #32
+        st1             {v0.16b, v1.16b}, [x1]
+        ret
+endfunc
+
+// VC-1 8x4 inverse transform
+// On entry:
+//   x0 -> array of 8-bit samples, in row-major order
+//   x1 = row stride for 8-bit sample array
+//   x2 -> array of 16-bit inverse transform coefficients, in row-major order
+// On exit:
+//   array at x0 updated by saturated addition of (narrowed) transformed block
+function ff_vc1_inv_trans_8x4_neon, export=1
+        ld1             {v1.8b, v2.8b, v3.8b, v4.8b}, [x2], #32
+        mov             x3, x0
+        ld1             {v16.8b, v17.8b, v18.8b, v19.8b}, [x2]
+        ldr             q0, .Lcoeffs_it8        // includes 4-point coefficients in upper half of vector
+        ld1             {v5.8b}, [x0], x1
+        trn2            v6.4h, v1.4h, v3.4h
+        trn2            v7.4h, v2.4h, v4.4h
+        trn1            v1.4h, v1.4h, v3.4h
+        trn1            v2.4h, v2.4h, v4.4h
+        trn2            v3.4h, v16.4h, v18.4h
+        trn2            v4.4h, v17.4h, v19.4h
+        trn1            v16.4h, v16.4h, v18.4h
+        trn1            v17.4h, v17.4h, v19.4h
+        ld1             {v18.8b}, [x0], x1
+        trn1            v19.2s, v6.2s, v3.2s
+        trn2            v3.2s, v6.2s, v3.2s
+        trn1            v6.2s, v7.2s, v4.2s
+        trn2            v4.2s, v7.2s, v4.2s
+        trn1            v7.2s, v1.2s, v16.2s
+        trn1            v20.2s, v2.2s, v17.2s
+        shl             v21.4h, v19.4h, #4      //          16 * src[1]
+        trn2            v1.2s, v1.2s, v16.2s
+        shl             v16.4h, v3.4h, #4       //                        16 * src[3]
+        trn2            v2.2s, v2.2s, v17.2s
+        shl             v17.4h, v6.4h, #4       //                                      16 * src[5]
+        ld1             {v22.8b}, [x0], x1
+        shl             v23.4h, v4.4h, #4       //                                                    16 * src[7]
+        mul             v24.4h, v1.4h, v0.h[0]  //                       6/2 * src[2]
+        ld1             {v25.8b}, [x0]
+        shl             v26.4h, v19.4h, #2      //           4 * src[1]
+        shl             v27.4h, v6.4h, #2       //                                       4 * src[5]
+        ssra            v21.4h, v23.4h, #2      //          16 * src[1]                             +  4 * src[7]
+        ssra            v17.4h, v16.4h, #2      //                         4 * src[3] + 16 * src[5]
+        sub             v23.4h, v23.4h, v26.4h  //        -  4 * src[1]                             + 16 * src[7]
+        sub             v16.4h, v16.4h, v27.4h  //                        16 * src[3] -  4 * src[5]
+        shl             v7.4h, v7.4h, #2        //         8/2 * src[0]
+        shl             v20.4h, v20.4h, #2      //                                     8/2 * src[4]
+        mla             v21.4h, v3.4h, v0.h[2]  //          16 * src[1] + 15 * src[3]               +  4 * src[7]
+        shl             v1.4h, v1.4h, #3        //                      16/2 * src[2]
+        mls             v17.4h, v19.4h, v0.h[2] //        - 15 * src[1] +  4 * src[3] + 16 * src[5]
+        ssra            v7.4h, v7.4h, #1        //        12/2 * src[0]
+        mls             v16.4h, v19.4h, v0.h[1] //        -  9 * src[1] + 16 * src[3] -  4 * src[5]
+        ssra            v20.4h, v20.4h, #1      //                                    12/2 * src[4]
+        mla             v23.4h, v3.4h, v0.h[1]  //        -  4 * src[1] +  9 * src[3]               + 16 * src[7]
+        shl             v3.4h, v2.4h, #3        //                                                  16/2 * src[6]
+        mla             v1.4h, v2.4h, v0.h[0]   // t3/2 =               16/2 * src[2]             +  6/2 * src[6]
+        mla             v21.4h, v6.4h, v0.h[1]  //  t1  =   16 * src[1] + 15 * src[3] +  9 * src[5] +  4 * src[7]
+        mla             v17.4h, v4.4h, v0.h[1]  // -t2  = - 15 * src[1] +  4 * src[3] + 16 * src[5] +  9 * src[7]
+        sub             v2.4h, v24.4h, v3.4h    // t4/2 =                6/2 * src[2]             - 16/2 * src[6]
+        mls             v16.4h, v4.4h, v0.h[2]  // -t3  = -  9 * src[1] + 16 * src[3] -  4 * src[5] - 15 * src[7]
+        add             v3.4h, v7.4h, v20.4h    // t1/2 = 12/2 * src[0]             + 12/2 * src[4]
+        mls             v23.4h, v6.4h, v0.h[2]  // -t4  = -  4 * src[1] +  9 * src[3] - 15 * src[5] + 16 * src[7]
+        sub             v4.4h, v7.4h, v20.4h    // t2/2 = 12/2 * src[0]             - 12/2 * src[4]
+        neg             v6.4h, v21.4h           // -t1
+        add             v7.4h, v3.4h, v1.4h     // t5/2 = t1/2 + t3/2
+        sub             v19.4h, v3.4h, v1.4h    // t8/2 = t1/2 - t3/2
+        add             v20.4h, v4.4h, v2.4h    // t6/2 = t2/2 + t4/2
+        sub             v24.4h, v4.4h, v2.4h    // t7/2 = t2/2 - t4/2
+        add             v26.4h, v3.4h, v1.4h    // t5/2 = t1/2 + t3/2
+        add             v27.4h, v4.4h, v2.4h    // t6/2 = t2/2 + t4/2
+        sub             v2.4h, v4.4h, v2.4h     // t7/2 = t2/2 - t4/2
+        sub             v1.4h, v3.4h, v1.4h     // t8/2 = t1/2 - t3/2
+        neg             v3.4h, v17.4h           // +t2
+        neg             v4.4h, v16.4h           // +t3
+        neg             v28.4h, v23.4h          // +t4
+        ssra            v7.4h, v21.4h, #1       // (t5 + t1) >> 1
+        ssra            v1.4h, v23.4h, #1       // (t8 - t4) >> 1
+        ssra            v20.4h, v3.4h, #1       // (t6 + t2) >> 1
+        ssra            v24.4h, v4.4h, #1       // (t7 + t3) >> 1
+        ssra            v19.4h, v28.4h, #1      // (t8 + t4) >> 1
+        ssra            v2.4h, v16.4h, #1       // (t7 - t3) >> 1
+        ssra            v27.4h, v17.4h, #1      // (t6 - t2) >> 1
+        ssra            v26.4h, v6.4h, #1       // (t5 - t1) >> 1
+        trn1            v1.2d, v7.2d, v1.2d
+        trn1            v2.2d, v20.2d, v2.2d
+        trn1            v3.2d, v24.2d, v27.2d
+        trn1            v4.2d, v19.2d, v26.2d
+        srshr           v1.8h, v1.8h, #2        // (t5 + t1 + 4) >> 3, (t8 - t4 + 4) >> 3
+        srshr           v2.8h, v2.8h, #2        // (t6 + t2 + 4) >> 3, (t7 - t3 + 4) >> 3
+        srshr           v3.8h, v3.8h, #2        // (t7 + t3 + 4) >> 3, (t6 - t2 + 4) >> 3
+        srshr           v4.8h, v4.8h, #2        // (t8 + t4 + 4) >> 3, (t5 - t1 + 4) >> 3
+        trn2            v6.8h, v1.8h, v2.8h
+        trn1            v1.8h, v1.8h, v2.8h
+        trn2            v2.8h, v3.8h, v4.8h
+        trn1            v3.8h, v3.8h, v4.8h
+        trn2            v4.4s, v6.4s, v2.4s
+        trn1            v7.4s, v1.4s, v3.4s
+        trn2            v1.4s, v1.4s, v3.4s
+        mul             v3.8h, v4.8h, v0.h[5]   //                                                           22/2 * src[24]
+        trn1            v2.4s, v6.4s, v2.4s
+        mul             v4.8h, v4.8h, v0.h[4]   //                                                           10/2 * src[24]
+        mul             v6.8h, v7.8h, v0.h[6]   //            17 * src[0]
+        mul             v1.8h, v1.8h, v0.h[6]   //                                            17 * src[16]
+        mls             v3.8h, v2.8h, v0.h[4]   //  t4/2 =                - 10/2 * src[8]                  + 22/2 * src[24]
+        mla             v4.8h, v2.8h, v0.h[5]   //  t3/2 =                  22/2 * src[8]                  + 10/2 * src[24]
+        add             v0.8h, v6.8h, v1.8h     //   t1  =    17 * src[0]                 +   17 * src[16]
+        sub             v1.8h, v6.8h, v1.8h     //   t2  =    17 * src[0]                 -   17 * src[16]
+        neg             v2.8h, v3.8h            // -t4/2
+        neg             v6.8h, v4.8h            // -t3/2
+        ssra            v4.8h, v0.8h, #1        // (t1 + t3) >> 1
+        ssra            v2.8h, v1.8h, #1        // (t2 - t4) >> 1
+        ssra            v3.8h, v1.8h, #1        // (t2 + t4) >> 1
+        ssra            v6.8h, v0.8h, #1        // (t1 - t3) >> 1
+        srshr           v0.8h, v4.8h, #6        // (t1 + t3 + 64) >> 7
+        srshr           v1.8h, v2.8h, #6        // (t2 - t4 + 64) >> 7
+        srshr           v2.8h, v3.8h, #6        // (t2 + t4 + 64) >> 7
+        srshr           v3.8h, v6.8h, #6        // (t1 - t3 + 64) >> 7
+        uaddw           v0.8h, v0.8h, v5.8b
+        uaddw           v1.8h, v1.8h, v18.8b
+        uaddw           v2.8h, v2.8h, v22.8b
+        uaddw           v3.8h, v3.8h, v25.8b
+        sqxtun          v0.8b, v0.8h
+        sqxtun          v1.8b, v1.8h
+        sqxtun          v2.8b, v2.8h
+        sqxtun          v3.8b, v3.8h
+        st1             {v0.8b}, [x3], x1
+        st1             {v1.8b}, [x3], x1
+        st1             {v2.8b}, [x3], x1
+        st1             {v3.8b}, [x3]
+        ret
+endfunc
+
+// VC-1 4x8 inverse transform
+// On entry:
+//   x0 -> array of 8-bit samples, in row-major order
+//   x1 = row stride for 8-bit sample array
+//   x2 -> array of 16-bit inverse transform coefficients, in row-major order (row stride is 8 coefficients)
+// On exit:
+//   array at x0 updated by saturated addition of (narrowed) transformed block
+function ff_vc1_inv_trans_4x8_neon, export=1
+        mov             x3, #16
+        ldr             q0, .Lcoeffs_it8        // includes 4-point coefficients in upper half of vector
+        mov             x4, x0
+        ld1             {v1.d}[0], [x2], x3     // 00 01 02 03
+        ld1             {v2.d}[0], [x2], x3     // 10 11 12 13
+        ld1             {v3.d}[0], [x2], x3     // 20 21 22 23
+        ld1             {v4.d}[0], [x2], x3     // 30 31 32 33
+        ld1             {v1.d}[1], [x2], x3     // 40 41 42 43
+        ld1             {v2.d}[1], [x2], x3     // 50 51 52 53
+        ld1             {v3.d}[1], [x2], x3     // 60 61 62 63
+        ld1             {v4.d}[1], [x2]         // 70 71 72 73
+        ld1             {v5.s}[0], [x0], x1
+        ld1             {v6.s}[0], [x0], x1
+        ld1             {v7.s}[0], [x0], x1
+        trn2            v16.8h, v1.8h, v2.8h    // 01 11 03 13 41 51 43 53
+        trn1            v1.8h, v1.8h, v2.8h     // 00 10 02 12 40 50 42 52
+        trn2            v2.8h, v3.8h, v4.8h     // 21 31 23 33 61 71 63 73
+        trn1            v3.8h, v3.8h, v4.8h     // 20 30 22 32 60 70 62 72
+        ld1             {v4.s}[0], [x0], x1
+        trn2            v17.4s, v16.4s, v2.4s   // 03 13 23 33 43 53 63 73
+        trn1            v18.4s, v1.4s, v3.4s    // 00 10 20 30 40 50 60 70
+        trn1            v2.4s, v16.4s, v2.4s    // 01 11 21 31 41 51 61 71
+        mul             v16.8h, v17.8h, v0.h[4] //                                                          10/2 * src[3]
+        ld1             {v5.s}[1], [x0], x1
+        mul             v17.8h, v17.8h, v0.h[5] //                                                          22/2 * src[3]
+        ld1             {v6.s}[1], [x0], x1
+        trn2            v1.4s, v1.4s, v3.4s     // 02 12 22 32 42 52 62 72
+        mul             v3.8h, v18.8h, v0.h[6]  //            17 * src[0]
+        ld1             {v7.s}[1], [x0], x1
+        mul             v1.8h, v1.8h, v0.h[6]   //                                            17 * src[2]
+        ld1             {v4.s}[1], [x0]
+        mla             v16.8h, v2.8h, v0.h[5]  //  t3/2 =                  22/2 * src[1]                 + 10/2 * src[3]
+        mls             v17.8h, v2.8h, v0.h[4]  //  t4/2 =                - 10/2 * src[1]                 + 22/2 * src[3]
+        add             v2.8h, v3.8h, v1.8h     //   t1  =    17 * src[0]                 +   17 * src[2]
+        sub             v1.8h, v3.8h, v1.8h     //   t2  =    17 * src[0]                 -   17 * src[2]
+        neg             v3.8h, v16.8h           // -t3/2
+        ssra            v16.8h, v2.8h, #1       // (t1 + t3) >> 1
+        neg             v18.8h, v17.8h          // -t4/2
+        ssra            v17.8h, v1.8h, #1       // (t2 + t4) >> 1
+        ssra            v3.8h, v2.8h, #1        // (t1 - t3) >> 1
+        ssra            v18.8h, v1.8h, #1       // (t2 - t4) >> 1
+        srshr           v1.8h, v16.8h, #2       // (t1 + t3 + 64) >> 3
+        srshr           v2.8h, v17.8h, #2       // (t2 + t4 + 64) >> 3
+        srshr           v3.8h, v3.8h, #2        // (t1 - t3 + 64) >> 3
+        srshr           v16.8h, v18.8h, #2      // (t2 - t4 + 64) >> 3
+        trn2            v17.8h, v2.8h, v3.8h    // 12 13 32 33 52 53 72 73
+        trn2            v18.8h, v1.8h, v16.8h   // 10 11 30 31 50 51 70 71
+        trn1            v1.8h, v1.8h, v16.8h    // 00 01 20 21 40 41 60 61
+        trn1            v2.8h, v2.8h, v3.8h     // 02 03 22 23 42 43 62 63
+        trn1            v3.4s, v18.4s, v17.4s   // 10 11 12 13 50 51 52 53
+        trn2            v16.4s, v18.4s, v17.4s  // 30 31 32 33 70 71 72 73
+        trn1            v17.4s, v1.4s, v2.4s    // 00 01 02 03 40 41 42 43
+        mov             d18, v3.d[1]            // 50 51 52 53
+        shl             v19.4h, v3.4h, #4       //          16 * src[8]
+        mov             d20, v16.d[1]           // 70 71 72 73
+        shl             v21.4h, v16.4h, #4      //                        16 * src[24]
+        mov             d22, v17.d[1]           // 40 41 42 43
+        shl             v23.4h, v3.4h, #2       //           4 * src[8]
+        shl             v24.4h, v18.4h, #4      //                                       16 * src[40]
+        shl             v25.4h, v20.4h, #4      //                                                      16 * src[56]
+        shl             v26.4h, v18.4h, #2      //                                        4 * src[40]
+        trn2            v1.4s, v1.4s, v2.4s     // 20 21 22 23 60 61 62 63
+        ssra            v24.4h, v21.4h, #2      //                         4 * src[24] + 16 * src[40]
+        sub             v2.4h, v25.4h, v23.4h   //        -  4 * src[8]                               + 16 * src[56]
+        shl             v17.4h, v17.4h, #2      //         8/2 * src[0]
+        sub             v21.4h, v21.4h, v26.4h  //                        16 * src[24] -  4 * src[40]
+        shl             v22.4h, v22.4h, #2      //                                      8/2 * src[32]
+        mov             d23, v1.d[1]            // 60 61 62 63
+        ssra            v19.4h, v25.4h, #2      //          16 * src[8]                               +  4 * src[56]
+        mul             v25.4h, v1.4h, v0.h[0]  //                       6/2 * src[16]
+        shl             v1.4h, v1.4h, #3        //                      16/2 * src[16]
+        mls             v24.4h, v3.4h, v0.h[2]  //        - 15 * src[8] +  4 * src[24] + 16 * src[40]
+        ssra            v17.4h, v17.4h, #1      //        12/2 * src[0]
+        mls             v21.4h, v3.4h, v0.h[1]  //        -  9 * src[8] + 16 * src[24] -  4 * src[40]
+        ssra            v22.4h, v22.4h, #1      //                                     12/2 * src[32]
+        mla             v2.4h, v16.4h, v0.h[1]  //        -  4 * src[8] +  9 * src[24]                + 16 * src[56]
+        shl             v3.4h, v23.4h, #3       //                                                    16/2 * src[48]
+        mla             v19.4h, v16.4h, v0.h[2] //          16 * src[8] + 15 * src[24]                +  4 * src[56]
+        mla             v1.4h, v23.4h, v0.h[0]  // t3/2 =               16/2 * src[16]              +  6/2 * src[48]
+        mla             v24.4h, v20.4h, v0.h[1] // -t2  = - 15 * src[8] +  4 * src[24] + 16 * src[40] +  9 * src[56]
+        add             v16.4h, v17.4h, v22.4h  // t1/2 = 12/2 * src[0]              + 12/2 * src[32]
+        sub             v3.4h, v25.4h, v3.4h    // t4/2 =                6/2 * src[16]              - 16/2 * src[48]
+        sub             v17.4h, v17.4h, v22.4h  // t2/2 = 12/2 * src[0]              - 12/2 * src[32]
+        mls             v21.4h, v20.4h, v0.h[2] // -t3  = -  9 * src[8] + 16 * src[24] -  4 * src[40] - 15 * src[56]
+        mla             v19.4h, v18.4h, v0.h[1] //  t1  =   16 * src[8] + 15 * src[24] +  9 * src[40] +  4 * src[56]
+        add             v20.4h, v16.4h, v1.4h   // t5/2 = t1/2 + t3/2
+        mls             v2.4h, v18.4h, v0.h[2]  // -t4  = -  4 * src[8] +  9 * src[24] - 15 * src[40] + 16 * src[56]
+        sub             v0.4h, v16.4h, v1.4h    // t8/2 = t1/2 - t3/2
+        add             v18.4h, v17.4h, v3.4h   // t6/2 = t2/2 + t4/2
+        sub             v22.4h, v17.4h, v3.4h   // t7/2 = t2/2 - t4/2
+        neg             v23.4h, v24.4h          // +t2
+        sub             v25.4h, v17.4h, v3.4h   // t7/2 = t2/2 - t4/2
+        add             v3.4h, v17.4h, v3.4h    // t6/2 = t2/2 + t4/2
+        neg             v17.4h, v21.4h          // +t3
+        sub             v26.4h, v16.4h, v1.4h   // t8/2 = t1/2 - t3/2
+        add             v1.4h, v16.4h, v1.4h    // t5/2 = t1/2 + t3/2
+        neg             v16.4h, v19.4h          // -t1
+        neg             v27.4h, v2.4h           // +t4
+        ssra            v20.4h, v19.4h, #1      // (t5 + t1) >> 1
+        srsra           v0.4h, v2.4h, #1        // (t8 - t4 + 1) >> 1
+        ssra            v18.4h, v23.4h, #1      // (t6 + t2) >> 1
+        srsra           v22.4h, v21.4h, #1      // (t7 - t3 + 1) >> 1
+        ssra            v25.4h, v17.4h, #1      // (t7 + t3) >> 1
+        srsra           v3.4h, v24.4h, #1       // (t6 - t2 + 1) >> 1
+        ssra            v26.4h, v27.4h, #1      // (t8 + t4) >> 1
+        srsra           v1.4h, v16.4h, #1       // (t5 - t1 + 1) >> 1
+        trn1            v0.2d, v20.2d, v0.2d
+        trn1            v2.2d, v18.2d, v22.2d
+        trn1            v3.2d, v25.2d, v3.2d
+        trn1            v1.2d, v26.2d, v1.2d
+        srshr           v0.8h, v0.8h, #6        // (t5 + t1 + 64) >> 7, (t8 - t4 + 65) >> 7
+        srshr           v2.8h, v2.8h, #6        // (t6 + t2 + 64) >> 7, (t7 - t3 + 65) >> 7
+        srshr           v3.8h, v3.8h, #6        // (t7 + t3 + 64) >> 7, (t6 - t2 + 65) >> 7
+        srshr           v1.8h, v1.8h, #6        // (t8 + t4 + 64) >> 7, (t5 - t1 + 65) >> 7
+        uaddw           v0.8h, v0.8h, v5.8b
+        uaddw           v2.8h, v2.8h, v6.8b
+        uaddw           v3.8h, v3.8h, v7.8b
+        uaddw           v1.8h, v1.8h, v4.8b
+        sqxtun          v0.8b, v0.8h
+        sqxtun          v2.8b, v2.8h
+        sqxtun          v3.8b, v3.8h
+        sqxtun          v1.8b, v1.8h
+        st1             {v0.s}[0], [x4], x1
+        st1             {v2.s}[0], [x4], x1
+        st1             {v3.s}[0], [x4], x1
+        st1             {v1.s}[0], [x4], x1
+        st1             {v0.s}[1], [x4], x1
+        st1             {v2.s}[1], [x4], x1
+        st1             {v3.s}[1], [x4], x1
+        st1             {v1.s}[1], [x4]
+        ret
+endfunc
+
+// VC-1 4x4 inverse transform
+// On entry:
+//   x0 -> array of 8-bit samples, in row-major order
+//   x1 = row stride for 8-bit sample array
+//   x2 -> array of 16-bit inverse transform coefficients, in row-major order (row stride is 8 coefficients)
+// On exit:
+//   array at x0 updated by saturated addition of (narrowed) transformed block
+function ff_vc1_inv_trans_4x4_neon, export=1
+        mov             x3, #16
+        ldr             d0, .Lcoeffs_it4
+        mov             x4, x0
+        ld1             {v1.d}[0], [x2], x3     // 00 01 02 03
+        ld1             {v2.d}[0], [x2], x3     // 10 11 12 13
+        ld1             {v3.d}[0], [x2], x3     // 20 21 22 23
+        ld1             {v4.d}[0], [x2]         // 30 31 32 33
+        ld1             {v5.s}[0], [x0], x1
+        ld1             {v5.s}[1], [x0], x1
+        ld1             {v6.s}[0], [x0], x1
+        trn2            v7.4h, v1.4h, v2.4h     // 01 11 03 13
+        trn1            v1.4h, v1.4h, v2.4h     // 00 10 02 12
+        ld1             {v6.s}[1], [x0]
+        trn2            v2.4h, v3.4h, v4.4h     // 21 31 23 33
+        trn1            v3.4h, v3.4h, v4.4h     // 20 30 22 32
+        trn2            v4.2s, v7.2s, v2.2s     // 03 13 23 33
+        trn1            v16.2s, v1.2s, v3.2s    // 00 10 20 30
+        trn1            v2.2s, v7.2s, v2.2s     // 01 11 21 31
+        trn2            v1.2s, v1.2s, v3.2s     // 02 12 22 32
+        mul             v3.4h, v4.4h, v0.h[0]   //                                                          10/2 * src[3]
+        mul             v4.4h, v4.4h, v0.h[1]   //                                                          22/2 * src[3]
+        mul             v7.4h, v16.4h, v0.h[2]  //            17 * src[0]
+        mul             v1.4h, v1.4h, v0.h[2]   //                                            17 * src[2]
+        mla             v3.4h, v2.4h, v0.h[1]   //  t3/2 =                  22/2 * src[1]                 + 10/2 * src[3]
+        mls             v4.4h, v2.4h, v0.h[0]   //  t4/2 =                - 10/2 * src[1]                 + 22/2 * src[3]
+        add             v2.4h, v7.4h, v1.4h     //   t1  =    17 * src[0]                 +   17 * src[2]
+        sub             v1.4h, v7.4h, v1.4h     //   t2  =    17 * src[0]                 -   17 * src[2]
+        neg             v7.4h, v3.4h            // -t3/2
+        neg             v16.4h, v4.4h           // -t4/2
+        ssra            v3.4h, v2.4h, #1        // (t1 + t3) >> 1
+        ssra            v4.4h, v1.4h, #1        // (t2 + t4) >> 1
+        ssra            v16.4h, v1.4h, #1       // (t2 - t4) >> 1
+        ssra            v7.4h, v2.4h, #1        // (t1 - t3) >> 1
+        srshr           v1.4h, v3.4h, #2        // (t1 + t3 + 64) >> 3
+        srshr           v2.4h, v4.4h, #2        // (t2 + t4 + 64) >> 3
+        srshr           v3.4h, v16.4h, #2       // (t2 - t4 + 64) >> 3
+        srshr           v4.4h, v7.4h, #2        // (t1 - t3 + 64) >> 3
+        trn2            v7.4h, v1.4h, v3.4h     // 10 11 30 31
+        trn1            v1.4h, v1.4h, v3.4h     // 00 01 20 21
+        trn2            v3.4h, v2.4h, v4.4h     // 12 13 32 33
+        trn1            v2.4h, v2.4h, v4.4h     // 02 03 22 23
+        trn2            v4.2s, v7.2s, v3.2s     // 30 31 32 33
+        trn1            v16.2s, v1.2s, v2.2s    // 00 01 02 03
+        trn1            v3.2s, v7.2s, v3.2s     // 10 11 12 13
+        trn2            v1.2s, v1.2s, v2.2s     // 20 21 22 23
+        mul             v2.4h, v4.4h, v0.h[1]   //                                                           22/2 * src[24]
+        mul             v4.4h, v4.4h, v0.h[0]   //                                                           10/2 * src[24]
+        mul             v7.4h, v16.4h, v0.h[2]  //            17 * src[0]
+        mul             v1.4h, v1.4h, v0.h[2]   //                                            17 * src[16]
+        mls             v2.4h, v3.4h, v0.h[0]   //  t4/2 =                - 10/2 * src[8]                  + 22/2 * src[24]
+        mla             v4.4h, v3.4h, v0.h[1]   //  t3/2 =                  22/2 * src[8]                  + 10/2 * src[24]
+        add             v0.4h, v7.4h, v1.4h     //   t1  =    17 * src[0]                 +   17 * src[16]
+        sub             v1.4h, v7.4h, v1.4h     //   t2  =    17 * src[0]                 -   17 * src[16]
+        neg             v3.4h, v2.4h            // -t4/2
+        neg             v7.4h, v4.4h            // -t3/2
+        ssra            v4.4h, v0.4h, #1        // (t1 + t3) >> 1
+        ssra            v3.4h, v1.4h, #1        // (t2 - t4) >> 1
+        ssra            v2.4h, v1.4h, #1        // (t2 + t4) >> 1
+        ssra            v7.4h, v0.4h, #1        // (t1 - t3) >> 1
+        trn1            v0.2d, v4.2d, v3.2d
+        trn1            v1.2d, v2.2d, v7.2d
+        srshr           v0.8h, v0.8h, #6        // (t1 + t3 + 64) >> 7, (t2 - t4 + 64) >> 7
+        srshr           v1.8h, v1.8h, #6        // (t2 + t4 + 64) >> 7, (t1 - t3 + 64) >> 7
+        uaddw           v0.8h, v0.8h, v5.8b
+        uaddw           v1.8h, v1.8h, v6.8b
+        sqxtun          v0.8b, v0.8h
+        sqxtun          v1.8b, v1.8h
+        st1             {v0.s}[0], [x4], x1
+        st1             {v0.s}[1], [x4], x1
+        st1             {v1.s}[0], [x4], x1
+        st1             {v1.s}[1], [x4]
+        ret
+endfunc
+
+// VC-1 8x8 inverse transform, DC case
+// On entry:
+//   x0 -> array of 8-bit samples, in row-major order
+//   x1 = row stride for 8-bit sample array
+//   x2 -> 16-bit inverse transform DC coefficient
+// On exit:
+//   array at x0 updated by saturated addition of (narrowed) transformed block
+function ff_vc1_inv_trans_8x8_dc_neon, export=1
+        ldrsh           w2, [x2]
+        mov             x3, x0
+        ld1             {v0.8b}, [x0], x1
+        ld1             {v1.8b}, [x0], x1
+        ld1             {v2.8b}, [x0], x1
+        add             w2, w2, w2, lsl #1
+        ld1             {v3.8b}, [x0], x1
+        ld1             {v4.8b}, [x0], x1
+        add             w2, w2, #1
+        ld1             {v5.8b}, [x0], x1
+        asr             w2, w2, #1
+        ld1             {v6.8b}, [x0], x1
+        add             w2, w2, w2, lsl #1
+        ld1             {v7.8b}, [x0]
+        add             w0, w2, #16
+        asr             w0, w0, #5
+        dup             v16.8h, w0
+        uaddw           v0.8h, v16.8h, v0.8b
+        uaddw           v1.8h, v16.8h, v1.8b
+        uaddw           v2.8h, v16.8h, v2.8b
+        uaddw           v3.8h, v16.8h, v3.8b
+        uaddw           v4.8h, v16.8h, v4.8b
+        uaddw           v5.8h, v16.8h, v5.8b
+        sqxtun          v0.8b, v0.8h
+        uaddw           v6.8h, v16.8h, v6.8b
+        sqxtun          v1.8b, v1.8h
+        uaddw           v7.8h, v16.8h, v7.8b
+        sqxtun          v2.8b, v2.8h
+        sqxtun          v3.8b, v3.8h
+        sqxtun          v4.8b, v4.8h
+        st1             {v0.8b}, [x3], x1
+        sqxtun          v0.8b, v5.8h
+        st1             {v1.8b}, [x3], x1
+        sqxtun          v1.8b, v6.8h
+        st1             {v2.8b}, [x3], x1
+        sqxtun          v2.8b, v7.8h
+        st1             {v3.8b}, [x3], x1
+        st1             {v4.8b}, [x3], x1
+        st1             {v0.8b}, [x3], x1
+        st1             {v1.8b}, [x3], x1
+        st1             {v2.8b}, [x3]
+        ret
+endfunc
+
+// VC-1 8x4 inverse transform, DC case
+// On entry:
+//   x0 -> array of 8-bit samples, in row-major order
+//   x1 = row stride for 8-bit sample array
+//   x2 -> 16-bit inverse transform DC coefficient
+// On exit:
+//   array at x0 updated by saturated addition of (narrowed) transformed block
+function ff_vc1_inv_trans_8x4_dc_neon, export=1
+        ldrsh           w2, [x2]
+        mov             x3, x0
+        ld1             {v0.8b}, [x0], x1
+        ld1             {v1.8b}, [x0], x1
+        ld1             {v2.8b}, [x0], x1
+        add             w2, w2, w2, lsl #1
+        ld1             {v3.8b}, [x0]
+        add             w0, w2, #1
+        asr             w0, w0, #1
+        add             w0, w0, w0, lsl #4
+        add             w0, w0, #64
+        asr             w0, w0, #7
+        dup             v4.8h, w0
+        uaddw           v0.8h, v4.8h, v0.8b
+        uaddw           v1.8h, v4.8h, v1.8b
+        uaddw           v2.8h, v4.8h, v2.8b
+        uaddw           v3.8h, v4.8h, v3.8b
+        sqxtun          v0.8b, v0.8h
+        sqxtun          v1.8b, v1.8h
+        sqxtun          v2.8b, v2.8h
+        sqxtun          v3.8b, v3.8h
+        st1             {v0.8b}, [x3], x1
+        st1             {v1.8b}, [x3], x1
+        st1             {v2.8b}, [x3], x1
+        st1             {v3.8b}, [x3]
+        ret
+endfunc
+
+// VC-1 4x8 inverse transform, DC case
+// On entry:
+//   x0 -> array of 8-bit samples, in row-major order
+//   x1 = row stride for 8-bit sample array
+//   x2 -> 16-bit inverse transform DC coefficient
+// On exit:
+//   array at x0 updated by saturated addition of (narrowed) transformed block
+function ff_vc1_inv_trans_4x8_dc_neon, export=1
+        ldrsh           w2, [x2]
+        mov             x3, x0
+        ld1             {v0.s}[0], [x0], x1
+        ld1             {v1.s}[0], [x0], x1
+        ld1             {v2.s}[0], [x0], x1
+        add             w2, w2, w2, lsl #4
+        ld1             {v3.s}[0], [x0], x1
+        add             w2, w2, #4
+        asr             w2, w2, #3
+        add             w2, w2, w2, lsl #1
+        ld1             {v0.s}[1], [x0], x1
+        add             w2, w2, #16
+        asr             w2, w2, #5
+        dup             v4.8h, w2
+        ld1             {v1.s}[1], [x0], x1
+        ld1             {v2.s}[1], [x0], x1
+        ld1             {v3.s}[1], [x0]
+        uaddw           v0.8h, v4.8h, v0.8b
+        uaddw           v1.8h, v4.8h, v1.8b
+        uaddw           v2.8h, v4.8h, v2.8b
+        uaddw           v3.8h, v4.8h, v3.8b
+        sqxtun          v0.8b, v0.8h
+        sqxtun          v1.8b, v1.8h
+        sqxtun          v2.8b, v2.8h
+        sqxtun          v3.8b, v3.8h
+        st1             {v0.s}[0], [x3], x1
+        st1             {v1.s}[0], [x3], x1
+        st1             {v2.s}[0], [x3], x1
+        st1             {v3.s}[0], [x3], x1
+        st1             {v0.s}[1], [x3], x1
+        st1             {v1.s}[1], [x3], x1
+        st1             {v2.s}[1], [x3], x1
+        st1             {v3.s}[1], [x3]
+        ret
+endfunc
+
+// VC-1 4x4 inverse transform, DC case
+// On entry:
+//   x0 -> array of 8-bit samples, in row-major order
+//   x1 = row stride for 8-bit sample array
+//   x2 -> 16-bit inverse transform DC coefficient
+// On exit:
+//   array at x0 updated by saturated addition of (narrowed) transformed block
+function ff_vc1_inv_trans_4x4_dc_neon, export=1
+        ldrsh           w2, [x2]
+        mov             x3, x0
+        ld1             {v0.s}[0], [x0], x1
+        ld1             {v1.s}[0], [x0], x1
+        ld1             {v0.s}[1], [x0], x1
+        add             w2, w2, w2, lsl #4
+        ld1             {v1.s}[1], [x0]
+        add             w0, w2, #4
+        asr             w0, w0, #3
+        add             w0, w0, w0, lsl #4
+        add             w0, w0, #64
+        asr             w0, w0, #7
+        dup             v2.8h, w0
+        uaddw           v0.8h, v2.8h, v0.8b
+        uaddw           v1.8h, v2.8h, v1.8b
+        sqxtun          v0.8b, v0.8h
+        sqxtun          v1.8b, v1.8h
+        st1             {v0.s}[0], [x3], x1
+        st1             {v1.s}[0], [x3], x1
+        st1             {v0.s}[1], [x3], x1
+        st1             {v1.s}[1], [x3]
+        ret
+endfunc
+
+.align  5
+.Lcoeffs_it8:
+.quad   0x000F00090003
+.Lcoeffs_it4:
+.quad   0x0011000B0005
+.Lcoeffs:
+.quad   0x00050002
+
+// VC-1 in-loop deblocking filter for 4 pixel pairs at boundary of vertically-neighbouring blocks
+// On entry:
+//   x0 -> top-left pel of lower block
+//   x1 = row stride, bytes
+//   w2 = PQUANT bitstream parameter
+function ff_vc1_v_loop_filter4_neon, export=1
+        sub             x3, x0, w1, sxtw #2
+        ldr             d0, .Lcoeffs
+        ld1             {v1.s}[0], [x0], x1     // P5
+        ld1             {v2.s}[0], [x3], x1     // P1
+        ld1             {v3.s}[0], [x3], x1     // P2
+        ld1             {v4.s}[0], [x0], x1     // P6
+        ld1             {v5.s}[0], [x3], x1     // P3
+        ld1             {v6.s}[0], [x0], x1     // P7
+        ld1             {v7.s}[0], [x3]         // P4
+        ld1             {v16.s}[0], [x0]        // P8
+        ushll           v17.8h, v1.8b, #1       // 2*P5
+        dup             v18.8h, w2              // pq
+        ushll           v2.8h, v2.8b, #1        // 2*P1
+        uxtl            v3.8h, v3.8b            // P2
+        uxtl            v4.8h, v4.8b            // P6
+        uxtl            v19.8h, v5.8b           // P3
+        mls             v2.4h, v3.4h, v0.h[1]   // 2*P1-5*P2
+        uxtl            v3.8h, v6.8b            // P7
+        mls             v17.4h, v4.4h, v0.h[1]  // 2*P5-5*P6
+        ushll           v5.8h, v5.8b, #1        // 2*P3
+        uxtl            v6.8h, v7.8b            // P4
+        mla             v17.4h, v3.4h, v0.h[1]  // 2*P5-5*P6+5*P7
+        uxtl            v3.8h, v16.8b           // P8
+        mla             v2.4h, v19.4h, v0.h[1]  // 2*P1-5*P2+5*P3
+        uxtl            v1.8h, v1.8b            // P5
+        mls             v5.4h, v6.4h, v0.h[1]   // 2*P3-5*P4
+        mls             v17.4h, v3.4h, v0.h[0]  // 2*P5-5*P6+5*P7-2*P8
+        sub             v3.4h, v6.4h, v1.4h     // P4-P5
+        mls             v2.4h, v6.4h, v0.h[0]   // 2*P1-5*P2+5*P3-2*P4
+        mla             v5.4h, v1.4h, v0.h[1]   // 2*P3-5*P4+5*P5
+        mls             v5.4h, v4.4h, v0.h[0]   // 2*P3-5*P4+5*P5-2*P6
+        abs             v4.4h, v3.4h
+        srshr           v7.4h, v17.4h, #3
+        srshr           v2.4h, v2.4h, #3
+        sshr            v4.4h, v4.4h, #1        // clip
+        srshr           v5.4h, v5.4h, #3
+        abs             v7.4h, v7.4h            // a2
+        sshr            v3.4h, v3.4h, #8        // clip_sign
+        abs             v2.4h, v2.4h            // a1
+        cmeq            v16.4h, v4.4h, #0       // test clip == 0
+        abs             v17.4h, v5.4h           // a0
+        sshr            v5.4h, v5.4h, #8        // a0_sign
+        cmhs            v19.4h, v2.4h, v7.4h    // test a1 >= a2
+        cmhs            v18.4h, v17.4h, v18.4h  // test a0 >= pq
+        sub             v3.4h, v3.4h, v5.4h     // clip_sign - a0_sign
+        bsl             v19.8b, v7.8b, v2.8b    // a3
+        orr             v2.8b, v16.8b, v18.8b   // test clip == 0 || a0 >= pq
+        uqsub           v5.4h, v17.4h, v19.4h   // a0 >= a3 ? a0-a3 : 0  (a0 > a3 in all cases where filtering is enabled, so makes more sense to subtract this way round than the opposite and then taking the abs)
+        cmhs            v7.4h, v19.4h, v17.4h   // test a3 >= a0
+        mul             v0.4h, v5.4h, v0.h[1]   // a0 >= a3 ? 5*(a0-a3) : 0
+        orr             v5.8b, v2.8b, v7.8b     // test clip == 0 || a0 >= pq || a3 >= a0
+        mov             w0, v5.s[1]             // move to gp reg
+        ushr            v0.4h, v0.4h, #3        // a0 >= a3 ? (5*(a0-a3))>>3 : 0
+        cmhs            v5.4h, v0.4h, v4.4h
+        tbnz            w0, #0, 1f              // none of the 4 pixel pairs should be updated if this one is not filtered
+        bsl             v5.8b, v4.8b, v0.8b     // FFMIN(d, clip)
+        bic             v0.8b, v5.8b, v2.8b     // set each d to zero if it should not be filtered because clip == 0 || a0 >= pq (a3 > a0 case already zeroed by saturating sub)
+        mls             v6.4h, v0.4h, v3.4h     // invert d depending on clip_sign & a0_sign, or zero it if they match, and accumulate into P4
+        mla             v1.4h, v0.4h, v3.4h     // invert d depending on clip_sign & a0_sign, or zero it if they match, and accumulate into P5
+        sqxtun          v0.8b, v6.8h
+        sqxtun          v1.8b, v1.8h
+        st1             {v0.s}[0], [x3], x1
+        st1             {v1.s}[0], [x3]
+1:      ret
+endfunc
+
+// VC-1 in-loop deblocking filter for 4 pixel pairs at boundary of horizontally-neighbouring blocks
+// On entry:
+//   x0 -> top-left pel of right block
+//   x1 = row stride, bytes
+//   w2 = PQUANT bitstream parameter
+function ff_vc1_h_loop_filter4_neon, export=1
+        sub             x3, x0, #4              // where to start reading
+        ldr             d0, .Lcoeffs
+        ld1             {v1.8b}, [x3], x1
+        sub             x0, x0, #1              // where to start writing
+        ld1             {v2.8b}, [x3], x1
+        ld1             {v3.8b}, [x3], x1
+        ld1             {v4.8b}, [x3]
+        dup             v5.8h, w2               // pq
+        trn1            v6.8b, v1.8b, v2.8b
+        trn2            v1.8b, v1.8b, v2.8b
+        trn1            v2.8b, v3.8b, v4.8b
+        trn2            v3.8b, v3.8b, v4.8b
+        trn1            v4.4h, v6.4h, v2.4h     // P1, P5
+        trn1            v7.4h, v1.4h, v3.4h     // P2, P6
+        trn2            v2.4h, v6.4h, v2.4h     // P3, P7
+        trn2            v1.4h, v1.4h, v3.4h     // P4, P8
+        ushll           v3.8h, v4.8b, #1        // 2*P1, 2*P5
+        uxtl            v6.8h, v7.8b            // P2, P6
+        uxtl            v7.8h, v2.8b            // P3, P7
+        uxtl            v1.8h, v1.8b            // P4, P8
+        mls             v3.8h, v6.8h, v0.h[1]   // 2*P1-5*P2, 2*P5-5*P6
+        ushll           v2.8h, v2.8b, #1        // 2*P3, 2*P7
+        uxtl            v4.8h, v4.8b            // P1, P5
+        mla             v3.8h, v7.8h, v0.h[1]   // 2*P1-5*P2+5*P3, 2*P5-5*P6+5*P7
+        mov             d6, v6.d[1]             // P6
+        mls             v3.8h, v1.8h, v0.h[0]   // 2*P1-5*P2+5*P3-2*P4, 2*P5-5*P6+5*P7-2*P8
+        mov             d4, v4.d[1]             // P5
+        mls             v2.4h, v1.4h, v0.h[1]   // 2*P3-5*P4
+        mla             v2.4h, v4.4h, v0.h[1]   // 2*P3-5*P4+5*P5
+        sub             v7.4h, v1.4h, v4.4h     // P4-P5
+        mls             v2.4h, v6.4h, v0.h[0]   // 2*P3-5*P4+5*P5-2*P6
+        srshr           v3.8h, v3.8h, #3
+        abs             v6.4h, v7.4h
+        sshr            v7.4h, v7.4h, #8        // clip_sign
+        srshr           v2.4h, v2.4h, #3
+        abs             v3.8h, v3.8h            // a1, a2
+        sshr            v6.4h, v6.4h, #1        // clip
+        mov             d16, v3.d[1]            // a2
+        abs             v17.4h, v2.4h           // a0
+        cmeq            v18.4h, v6.4h, #0       // test clip == 0
+        sshr            v2.4h, v2.4h, #8        // a0_sign
+        cmhs            v19.4h, v3.4h, v16.4h   // test a1 >= a2
+        cmhs            v5.4h, v17.4h, v5.4h    // test a0 >= pq
+        sub             v2.4h, v7.4h, v2.4h     // clip_sign - a0_sign
+        bsl             v19.8b, v16.8b, v3.8b   // a3
+        orr             v3.8b, v18.8b, v5.8b    // test clip == 0 || a0 >= pq
+        uqsub           v5.4h, v17.4h, v19.4h   // a0 >= a3 ? a0-a3 : 0  (a0 > a3 in all cases where filtering is enabled, so makes more sense to subtract this way round than the opposite and then taking the abs)
+        cmhs            v7.4h, v19.4h, v17.4h   // test a3 >= a0
+        mul             v0.4h, v5.4h, v0.h[1]   // a0 >= a3 ? 5*(a0-a3) : 0
+        orr             v5.8b, v3.8b, v7.8b     // test clip == 0 || a0 >= pq || a3 >= a0
+        mov             w2, v5.s[1]             // move to gp reg
+        ushr            v0.4h, v0.4h, #3        // a0 >= a3 ? (5*(a0-a3))>>3 : 0
+        cmhs            v5.4h, v0.4h, v6.4h
+        tbnz            w2, #0, 1f              // none of the 4 pixel pairs should be updated if this one is not filtered
+        bsl             v5.8b, v6.8b, v0.8b     // FFMIN(d, clip)
+        bic             v0.8b, v5.8b, v3.8b     // set each d to zero if it should not be filtered because clip == 0 || a0 >= pq (a3 > a0 case already zeroed by saturating sub)
+        mla             v4.4h, v0.4h, v2.4h     // invert d depending on clip_sign & a0_sign, or zero it if they match, and accumulate into P5
+        mls             v1.4h, v0.4h, v2.4h     // invert d depending on clip_sign & a0_sign, or zero it if they match, and accumulate into P4
+        sqxtun          v3.8b, v4.8h
+        sqxtun          v2.8b, v1.8h
+        st2             {v2.b, v3.b}[0], [x0], x1
+        st2             {v2.b, v3.b}[1], [x0], x1
+        st2             {v2.b, v3.b}[2], [x0], x1
+        st2             {v2.b, v3.b}[3], [x0]
+1:      ret
+endfunc
+
+// VC-1 in-loop deblocking filter for 8 pixel pairs at boundary of vertically-neighbouring blocks
+// On entry:
+//   x0 -> top-left pel of lower block
+//   x1 = row stride, bytes
+//   w2 = PQUANT bitstream parameter
+function ff_vc1_v_loop_filter8_neon, export=1
+        sub             x3, x0, w1, sxtw #2
+        ldr             d0, .Lcoeffs
+        ld1             {v1.8b}, [x0], x1       // P5
+        movi            v2.2d, #0x0000ffff00000000
+        ld1             {v3.8b}, [x3], x1       // P1
+        ld1             {v4.8b}, [x3], x1       // P2
+        ld1             {v5.8b}, [x0], x1       // P6
+        ld1             {v6.8b}, [x3], x1       // P3
+        ld1             {v7.8b}, [x0], x1       // P7
+        ushll           v16.8h, v1.8b, #1       // 2*P5
+        ushll           v3.8h, v3.8b, #1        // 2*P1
+        ld1             {v17.8b}, [x3]          // P4
+        uxtl            v4.8h, v4.8b            // P2
+        ld1             {v18.8b}, [x0]          // P8
+        uxtl            v5.8h, v5.8b            // P6
+        dup             v19.8h, w2              // pq
+        uxtl            v20.8h, v6.8b           // P3
+        mls             v3.8h, v4.8h, v0.h[1]   // 2*P1-5*P2
+        uxtl            v4.8h, v7.8b            // P7
+        ushll           v6.8h, v6.8b, #1        // 2*P3
+        mls             v16.8h, v5.8h, v0.h[1]  // 2*P5-5*P6
+        uxtl            v7.8h, v17.8b           // P4
+        uxtl            v17.8h, v18.8b          // P8
+        mla             v16.8h, v4.8h, v0.h[1]  // 2*P5-5*P6+5*P7
+        uxtl            v1.8h, v1.8b            // P5
+        mla             v3.8h, v20.8h, v0.h[1]  // 2*P1-5*P2+5*P3
+        sub             v4.8h, v7.8h, v1.8h     // P4-P5
+        mls             v6.8h, v7.8h, v0.h[1]   // 2*P3-5*P4
+        mls             v16.8h, v17.8h, v0.h[0] // 2*P5-5*P6+5*P7-2*P8
+        abs             v17.8h, v4.8h
+        sshr            v4.8h, v4.8h, #8        // clip_sign
+        mls             v3.8h, v7.8h, v0.h[0]   // 2*P1-5*P2+5*P3-2*P4
+        sshr            v17.8h, v17.8h, #1      // clip
+        mla             v6.8h, v1.8h, v0.h[1]   // 2*P3-5*P4+5*P5
+        srshr           v16.8h, v16.8h, #3
+        mls             v6.8h, v5.8h, v0.h[0]   // 2*P3-5*P4+5*P5-2*P6
+        cmeq            v5.8h, v17.8h, #0       // test clip == 0
+        srshr           v3.8h, v3.8h, #3
+        abs             v16.8h, v16.8h          // a2
+        abs             v3.8h, v3.8h            // a1
+        srshr           v6.8h, v6.8h, #3
+        cmhs            v18.8h, v3.8h, v16.8h   // test a1 >= a2
+        abs             v20.8h, v6.8h           // a0
+        sshr            v6.8h, v6.8h, #8        // a0_sign
+        bsl             v18.16b, v16.16b, v3.16b // a3
+        cmhs            v3.8h, v20.8h, v19.8h   // test a0 >= pq
+        sub             v4.8h, v4.8h, v6.8h     // clip_sign - a0_sign
+        uqsub           v6.8h, v20.8h, v18.8h   // a0 >= a3 ? a0-a3 : 0  (a0 > a3 in all cases where filtering is enabled, so makes more sense to subtract this way round than the opposite and then taking the abs)
+        cmhs            v16.8h, v18.8h, v20.8h  // test a3 >= a0
+        orr             v3.16b, v5.16b, v3.16b  // test clip == 0 || a0 >= pq
+        mul             v0.8h, v6.8h, v0.h[1]   // a0 >= a3 ? 5*(a0-a3) : 0
+        orr             v5.16b, v3.16b, v16.16b // test clip == 0 || a0 >= pq || a3 >= a0
+        cmtst           v2.2d, v5.2d, v2.2d     // if 2nd of each group of is not filtered, then none of the others in the group should be either
+        mov             w0, v5.s[1]             // move to gp reg
+        ushr            v0.8h, v0.8h, #3        // a0 >= a3 ? (5*(a0-a3))>>3 : 0
+        mov             w2, v5.s[3]
+        orr             v2.16b, v3.16b, v2.16b
+        cmhs            v3.8h, v0.8h, v17.8h
+        and             w0, w0, w2
+        bsl             v3.16b, v17.16b, v0.16b // FFMIN(d, clip)
+        tbnz            w0, #0, 1f              // none of the 8 pixel pairs should be updated in this case
+        bic             v0.16b, v3.16b, v2.16b  // set each d to zero if it should not be filtered
+        mls             v7.8h, v0.8h, v4.8h     // invert d depending on clip_sign & a0_sign, or zero it if they match, and accumulate into P4
+        mla             v1.8h, v0.8h, v4.8h     // invert d depending on clip_sign & a0_sign, or zero it if they match, and accumulate into P5
+        sqxtun          v0.8b, v7.8h
+        sqxtun          v1.8b, v1.8h
+        st1             {v0.8b}, [x3], x1
+        st1             {v1.8b}, [x3]
+1:      ret
+endfunc
+
+// VC-1 in-loop deblocking filter for 8 pixel pairs at boundary of horizontally-neighbouring blocks
+// On entry:
+//   x0 -> top-left pel of right block
+//   x1 = row stride, bytes
+//   w2 = PQUANT bitstream parameter
+function ff_vc1_h_loop_filter8_neon, export=1
+        sub             x3, x0, #4              // where to start reading
+        ldr             d0, .Lcoeffs
+        ld1             {v1.8b}, [x3], x1       // P1[0], P2[0]...
+        sub             x0, x0, #1              // where to start writing
+        ld1             {v2.8b}, [x3], x1
+        add             x4, x0, x1, lsl #2
+        ld1             {v3.8b}, [x3], x1
+        ld1             {v4.8b}, [x3], x1
+        ld1             {v5.8b}, [x3], x1
+        ld1             {v6.8b}, [x3], x1
+        ld1             {v7.8b}, [x3], x1
+        trn1            v16.8b, v1.8b, v2.8b    // P1[0], P1[1], P3[0]...
+        ld1             {v17.8b}, [x3]
+        trn2            v1.8b, v1.8b, v2.8b     // P2[0], P2[1], P4[0]...
+        trn1            v2.8b, v3.8b, v4.8b     // P1[2], P1[3], P3[2]...
+        trn2            v3.8b, v3.8b, v4.8b     // P2[2], P2[3], P4[2]...
+        dup             v4.8h, w2               // pq
+        trn1            v18.8b, v5.8b, v6.8b    // P1[4], P1[5], P3[4]...
+        trn2            v5.8b, v5.8b, v6.8b     // P2[4], P2[5], P4[4]...
+        trn1            v6.4h, v16.4h, v2.4h    // P1[0], P1[1], P1[2], P1[3], P5[0]...
+        trn1            v19.4h, v1.4h, v3.4h    // P2[0], P2[1], P2[2], P2[3], P6[0]...
+        trn1            v20.8b, v7.8b, v17.8b   // P1[6], P1[7], P3[6]...
+        trn2            v7.8b, v7.8b, v17.8b    // P2[6], P2[7], P4[6]...
+        trn2            v2.4h, v16.4h, v2.4h    // P3[0], P3[1], P3[2], P3[3], P7[0]...
+        trn2            v1.4h, v1.4h, v3.4h     // P4[0], P4[1], P4[2], P4[3], P8[0]...
+        trn1            v3.4h, v18.4h, v20.4h   // P1[4], P1[5], P1[6], P1[7], P5[4]...
+        trn1            v16.4h, v5.4h, v7.4h    // P2[4], P2[5], P2[6], P2[7], P6[4]...
+        trn2            v17.4h, v18.4h, v20.4h  // P3[4], P3[5], P3[6], P3[7], P7[4]...
+        trn2            v5.4h, v5.4h, v7.4h     // P4[4], P4[5], P4[6], P4[7], P8[4]...
+        trn1            v7.2s, v6.2s, v3.2s     // P1
+        trn1            v18.2s, v19.2s, v16.2s  // P2
+        trn2            v3.2s, v6.2s, v3.2s     // P5
+        trn2            v6.2s, v19.2s, v16.2s   // P6
+        trn1            v16.2s, v2.2s, v17.2s   // P3
+        trn2            v2.2s, v2.2s, v17.2s    // P7
+        ushll           v7.8h, v7.8b, #1        // 2*P1
+        trn1            v17.2s, v1.2s, v5.2s    // P4
+        ushll           v19.8h, v3.8b, #1       // 2*P5
+        trn2            v1.2s, v1.2s, v5.2s     // P8
+        uxtl            v5.8h, v18.8b           // P2
+        uxtl            v6.8h, v6.8b            // P6
+        uxtl            v18.8h, v16.8b          // P3
+        mls             v7.8h, v5.8h, v0.h[1]   // 2*P1-5*P2
+        uxtl            v2.8h, v2.8b            // P7
+        ushll           v5.8h, v16.8b, #1       // 2*P3
+        mls             v19.8h, v6.8h, v0.h[1]  // 2*P5-5*P6
+        uxtl            v16.8h, v17.8b          // P4
+        uxtl            v1.8h, v1.8b            // P8
+        mla             v19.8h, v2.8h, v0.h[1]  // 2*P5-5*P6+5*P7
+        uxtl            v2.8h, v3.8b            // P5
+        mla             v7.8h, v18.8h, v0.h[1]  // 2*P1-5*P2+5*P3
+        sub             v3.8h, v16.8h, v2.8h    // P4-P5
+        mls             v5.8h, v16.8h, v0.h[1]  // 2*P3-5*P4
+        mls             v19.8h, v1.8h, v0.h[0]  // 2*P5-5*P6+5*P7-2*P8
+        abs             v1.8h, v3.8h
+        sshr            v3.8h, v3.8h, #8        // clip_sign
+        mls             v7.8h, v16.8h, v0.h[0]  // 2*P1-5*P2+5*P3-2*P4
+        sshr            v1.8h, v1.8h, #1        // clip
+        mla             v5.8h, v2.8h, v0.h[1]   // 2*P3-5*P4+5*P5
+        srshr           v17.8h, v19.8h, #3
+        mls             v5.8h, v6.8h, v0.h[0]   // 2*P3-5*P4+5*P5-2*P6
+        cmeq            v6.8h, v1.8h, #0        // test clip == 0
+        srshr           v7.8h, v7.8h, #3
+        abs             v17.8h, v17.8h          // a2
+        abs             v7.8h, v7.8h            // a1
+        srshr           v5.8h, v5.8h, #3
+        cmhs            v18.8h, v7.8h, v17.8h   // test a1 >= a2
+        abs             v19.8h, v5.8h           // a0
+        sshr            v5.8h, v5.8h, #8        // a0_sign
+        bsl             v18.16b, v17.16b, v7.16b // a3
+        cmhs            v4.8h, v19.8h, v4.8h    // test a0 >= pq
+        sub             v3.8h, v3.8h, v5.8h     // clip_sign - a0_sign
+        uqsub           v5.8h, v19.8h, v18.8h   // a0 >= a3 ? a0-a3 : 0  (a0 > a3 in all cases where filtering is enabled, so makes more sense to subtract this way round than the opposite and then taking the abs)
+        cmhs            v7.8h, v18.8h, v19.8h   // test a3 >= a0
+        orr             v4.16b, v6.16b, v4.16b  // test clip == 0 || a0 >= pq
+        mul             v0.8h, v5.8h, v0.h[1]   // a0 >= a3 ? 5*(a0-a3) : 0
+        orr             v5.16b, v4.16b, v7.16b  // test clip == 0 || a0 >= pq || a3 >= a0
+        mov             w2, v5.s[1]             // move to gp reg
+        ushr            v0.8h, v0.8h, #3        // a0 >= a3 ? (5*(a0-a3))>>3 : 0
+        mov             w3, v5.s[3]
+        cmhs            v5.8h, v0.8h, v1.8h
+        and             w5, w2, w3
+        bsl             v5.16b, v1.16b, v0.16b  // FFMIN(d, clip)
+        tbnz            w5, #0, 2f              // none of the 8 pixel pairs should be updated in this case
+        bic             v0.16b, v5.16b, v4.16b  // set each d to zero if it should not be filtered because clip == 0 || a0 >= pq (a3 > a0 case already zeroed by saturating sub)
+        mla             v2.8h, v0.8h, v3.8h     // invert d depending on clip_sign & a0_sign, or zero it if they match, and accumulate into P5
+        mls             v16.8h, v0.8h, v3.8h    // invert d depending on clip_sign & a0_sign, or zero it if they match, and accumulate into P4
+        sqxtun          v1.8b, v2.8h
+        sqxtun          v0.8b, v16.8h
+        tbnz            w2, #0, 1f              // none of the first 4 pixel pairs should be updated if so
+        st2             {v0.b, v1.b}[0], [x0], x1
+        st2             {v0.b, v1.b}[1], [x0], x1
+        st2             {v0.b, v1.b}[2], [x0], x1
+        st2             {v0.b, v1.b}[3], [x0]
+1:      tbnz            w3, #0, 2f              // none of the second 4 pixel pairs should be updated if so
+        st2             {v0.b, v1.b}[4], [x4], x1
+        st2             {v0.b, v1.b}[5], [x4], x1
+        st2             {v0.b, v1.b}[6], [x4], x1
+        st2             {v0.b, v1.b}[7], [x4]
+2:      ret
+endfunc
+
+// VC-1 in-loop deblocking filter for 16 pixel pairs at boundary of vertically-neighbouring blocks
+// On entry:
+//   x0 -> top-left pel of lower block
+//   x1 = row stride, bytes
+//   w2 = PQUANT bitstream parameter
+function ff_vc1_v_loop_filter16_neon, export=1
+        sub             x3, x0, w1, sxtw #2
+        ldr             d0, .Lcoeffs
+        ld1             {v1.16b}, [x0], x1      // P5
+        movi            v2.2d, #0x0000ffff00000000
+        ld1             {v3.16b}, [x3], x1      // P1
+        ld1             {v4.16b}, [x3], x1      // P2
+        ld1             {v5.16b}, [x0], x1      // P6
+        ld1             {v6.16b}, [x3], x1      // P3
+        ld1             {v7.16b}, [x0], x1      // P7
+        ushll           v16.8h, v1.8b, #1       // 2*P5[0..7]
+        ushll           v17.8h, v3.8b, #1       // 2*P1[0..7]
+        ld1             {v18.16b}, [x3]         // P4
+        uxtl            v19.8h, v4.8b           // P2[0..7]
+        ld1             {v20.16b}, [x0]         // P8
+        uxtl            v21.8h, v5.8b           // P6[0..7]
+        dup             v22.8h, w2              // pq
+        ushll2          v3.8h, v3.16b, #1       // 2*P1[8..15]
+        mls             v17.8h, v19.8h, v0.h[1] // 2*P1[0..7]-5*P2[0..7]
+        ushll2          v19.8h, v1.16b, #1      // 2*P5[8..15]
+        uxtl2           v4.8h, v4.16b           // P2[8..15]
+        mls             v16.8h, v21.8h, v0.h[1] // 2*P5[0..7]-5*P6[0..7]
+        uxtl2           v5.8h, v5.16b           // P6[8..15]
+        uxtl            v23.8h, v6.8b           // P3[0..7]
+        uxtl            v24.8h, v7.8b           // P7[0..7]
+        mls             v3.8h, v4.8h, v0.h[1]   // 2*P1[8..15]-5*P2[8..15]
+        ushll           v4.8h, v6.8b, #1        // 2*P3[0..7]
+        uxtl            v25.8h, v18.8b          // P4[0..7]
+        mls             v19.8h, v5.8h, v0.h[1]  // 2*P5[8..15]-5*P6[8..15]
+        uxtl2           v26.8h, v6.16b          // P3[8..15]
+        mla             v17.8h, v23.8h, v0.h[1] // 2*P1[0..7]-5*P2[0..7]+5*P3[0..7]
+        uxtl2           v7.8h, v7.16b           // P7[8..15]
+        ushll2          v6.8h, v6.16b, #1       // 2*P3[8..15]
+        mla             v16.8h, v24.8h, v0.h[1] // 2*P5[0..7]-5*P6[0..7]+5*P7[0..7]
+        uxtl2           v18.8h, v18.16b         // P4[8..15]
+        uxtl            v23.8h, v20.8b          // P8[0..7]
+        mls             v4.8h, v25.8h, v0.h[1]  // 2*P3[0..7]-5*P4[0..7]
+        uxtl            v24.8h, v1.8b           // P5[0..7]
+        uxtl2           v20.8h, v20.16b         // P8[8..15]
+        mla             v3.8h, v26.8h, v0.h[1]  // 2*P1[8..15]-5*P2[8..15]+5*P3[8..15]
+        uxtl2           v1.8h, v1.16b           // P5[8..15]
+        sub             v26.8h, v25.8h, v24.8h  // P4[0..7]-P5[0..7]
+        mla             v19.8h, v7.8h, v0.h[1]  // 2*P5[8..15]-5*P6[8..15]+5*P7[8..15]
+        sub             v7.8h, v18.8h, v1.8h    // P4[8..15]-P5[8..15]
+        mls             v6.8h, v18.8h, v0.h[1]  // 2*P3[8..15]-5*P4[8..15]
+        abs             v27.8h, v26.8h
+        sshr            v26.8h, v26.8h, #8      // clip_sign[0..7]
+        mls             v17.8h, v25.8h, v0.h[0] // 2*P1[0..7]-5*P2[0..7]+5*P3[0..7]-2*P4[0..7]
+        abs             v28.8h, v7.8h
+        sshr            v27.8h, v27.8h, #1      // clip[0..7]
+        mls             v16.8h, v23.8h, v0.h[0] // 2*P5[0..7]-5*P6[0..7]+5*P7[0..7]-2*P8[0..7]
+        sshr            v7.8h, v7.8h, #8        // clip_sign[8..15]
+        sshr            v23.8h, v28.8h, #1      // clip[8..15]
+        mla             v4.8h, v24.8h, v0.h[1]  // 2*P3[0..7]-5*P4[0..7]+5*P5[0..7]
+        cmeq            v28.8h, v27.8h, #0      // test clip[0..7] == 0
+        srshr           v17.8h, v17.8h, #3
+        mls             v3.8h, v18.8h, v0.h[0]  // 2*P1[8..15]-5*P2[8..15]+5*P3[8..15]-2*P4[8..15]
+        cmeq            v29.8h, v23.8h, #0      // test clip[8..15] == 0
+        srshr           v16.8h, v16.8h, #3
+        mls             v19.8h, v20.8h, v0.h[0] // 2*P5[8..15]-5*P6[8..15]+5*P7[8..15]-2*P8[8..15]
+        abs             v17.8h, v17.8h          // a1[0..7]
+        mla             v6.8h, v1.8h, v0.h[1]   // 2*P3[8..15]-5*P4[8..15]+5*P5[8..15]
+        srshr           v3.8h, v3.8h, #3
+        mls             v4.8h, v21.8h, v0.h[0]  // 2*P3[0..7]-5*P4[0..7]+5*P5[0..7]-2*P6[0..7]
+        abs             v16.8h, v16.8h          // a2[0..7]
+        srshr           v19.8h, v19.8h, #3
+        mls             v6.8h, v5.8h, v0.h[0]   // 2*P3[8..15]-5*P4[8..15]+5*P5[8..15]-2*P6[8..15]
+        cmhs            v5.8h, v17.8h, v16.8h   // test a1[0..7] >= a2[0..7]
+        abs             v3.8h, v3.8h            // a1[8..15]
+        srshr           v4.8h, v4.8h, #3
+        abs             v19.8h, v19.8h          // a2[8..15]
+        bsl             v5.16b, v16.16b, v17.16b // a3[0..7]
+        srshr           v6.8h, v6.8h, #3
+        cmhs            v16.8h, v3.8h, v19.8h   // test a1[8..15] >= a2[8.15]
+        abs             v17.8h, v4.8h           // a0[0..7]
+        sshr            v4.8h, v4.8h, #8        // a0_sign[0..7]
+        bsl             v16.16b, v19.16b, v3.16b // a3[8..15]
+        uqsub           v3.8h, v17.8h, v5.8h    // a0[0..7] >= a3[0..7] ? a0[0..7]-a3[0..7] : 0  (a0 > a3 in all cases where filtering is enabled, so makes more sense to subtract this way round than the opposite and then taking the abs)
+        abs             v19.8h, v6.8h           // a0[8..15]
+        cmhs            v20.8h, v17.8h, v22.8h  // test a0[0..7] >= pq
+        cmhs            v5.8h, v5.8h, v17.8h    // test a3[0..7] >= a0[0..7]
+        sub             v4.8h, v26.8h, v4.8h    // clip_sign[0..7] - a0_sign[0..7]
+        sshr            v6.8h, v6.8h, #8        // a0_sign[8..15]
+        mul             v3.8h, v3.8h, v0.h[1]   // a0[0..7] >= a3[0..7] ? 5*(a0[0..7]-a3[0..7]) : 0
+        uqsub           v17.8h, v19.8h, v16.8h  // a0[8..15] >= a3[8..15] ? a0[8..15]-a3[8..15] : 0  (a0 > a3 in all cases where filtering is enabled, so makes more sense to subtract this way round than the opposite and then taking the abs)
+        orr             v20.16b, v28.16b, v20.16b // test clip[0..7] == 0 || a0[0..7] >= pq
+        cmhs            v21.8h, v19.8h, v22.8h  // test a0[8..15] >= pq
+        cmhs            v16.8h, v16.8h, v19.8h  // test a3[8..15] >= a0[8..15]
+        mul             v0.8h, v17.8h, v0.h[1]  // a0[8..15] >= a3[8..15] ? 5*(a0[8..15]-a3[8..15]) : 0
+        sub             v6.8h, v7.8h, v6.8h     // clip_sign[8..15] - a0_sign[8..15]
+        orr             v5.16b, v20.16b, v5.16b // test clip[0..7] == 0 || a0[0..7] >= pq || a3[0..7] >= a0[0..7]
+        ushr            v3.8h, v3.8h, #3        // a0[0..7] >= a3[0..7] ? (5*(a0[0..7]-a3[0..7]))>>3 : 0
+        orr             v7.16b, v29.16b, v21.16b // test clip[8..15] == 0 || a0[8..15] >= pq
+        cmtst           v17.2d, v5.2d, v2.2d    // if 2nd of each group of is not filtered, then none of the others in the group should be either
+        mov             w0, v5.s[1]             // move to gp reg
+        cmhs            v19.8h, v3.8h, v27.8h
+        ushr            v0.8h, v0.8h, #3        // a0[8..15] >= a3[8..15] ? (5*(a0[8..15]-a3[8..15]))>>3 : 0
+        mov             w2, v5.s[3]
+        orr             v5.16b, v7.16b, v16.16b // test clip[8..15] == 0 || a0[8..15] >= pq || a3[8..15] >= a0[8..15]
+        orr             v16.16b, v20.16b, v17.16b
+        bsl             v19.16b, v27.16b, v3.16b // FFMIN(d[0..7], clip[0..7])
+        cmtst           v2.2d, v5.2d, v2.2d
+        cmhs            v3.8h, v0.8h, v23.8h
+        mov             w4, v5.s[1]
+        mov             w5, v5.s[3]
+        and             w0, w0, w2
+        bic             v5.16b, v19.16b, v16.16b // set each d[0..7] to zero if it should not be filtered because clip[0..7] == 0 || a0[0..7] >= pq (a3 > a0 case already zeroed by saturating sub)
+        orr             v2.16b, v7.16b, v2.16b
+        bsl             v3.16b, v23.16b, v0.16b // FFMIN(d[8..15], clip[8..15])
+        mls             v25.8h, v5.8h, v4.8h    // invert d[0..7] depending on clip_sign[0..7] & a0_sign[0..7], or zero it if they match, and accumulate into P4[0..7]
+        and             w2, w4, w5
+        bic             v0.16b, v3.16b, v2.16b  // set each d[8..15] to zero if it should not be filtered because clip[8..15] == 0 || a0[8..15] >= pq (a3 > a0 case already zeroed by saturating sub)
+        mla             v24.8h, v5.8h, v4.8h    // invert d[0..7] depending on clip_sign[0..7] & a0_sign[0..7], or zero it if they match, and accumulate into P5[0..7]
+        and             w0, w0, w2
+        mls             v18.8h, v0.8h, v6.8h    // invert d[8..15] depending on clip_sign[8..15] & a0_sign[8..15], or zero it if they match, and accumulate into P4[8..15]
+        sqxtun          v2.8b, v25.8h
+        tbnz            w0, #0, 1f              // none of the 16 pixel pairs should be updated in this case
+        mla             v1.8h, v0.8h, v6.8h     // invert d[8..15] depending on clip_sign[8..15] & a0_sign[8..15], or zero it if they match, and accumulate into P5[8..15]
+        sqxtun          v0.8b, v24.8h
+        sqxtun2         v2.16b, v18.8h
+        sqxtun2         v0.16b, v1.8h
+        st1             {v2.16b}, [x3], x1
+        st1             {v0.16b}, [x3]
+1:      ret
+endfunc
+
+// VC-1 in-loop deblocking filter for 16 pixel pairs at boundary of horizontally-neighbouring blocks
+// On entry:
+//   x0 -> top-left pel of right block
+//   x1 = row stride, bytes
+//   w2 = PQUANT bitstream parameter
+function ff_vc1_h_loop_filter16_neon, export=1
+        sub             x3, x0, #4              // where to start reading
+        ldr             d0, .Lcoeffs
+        ld1             {v1.8b}, [x3], x1       // P1[0], P2[0]...
+        sub             x0, x0, #1              // where to start writing
+        ld1             {v2.8b}, [x3], x1
+        add             x4, x0, x1, lsl #3
+        ld1             {v3.8b}, [x3], x1
+        add             x5, x0, x1, lsl #2
+        ld1             {v4.8b}, [x3], x1
+        add             x6, x4, x1, lsl #2
+        ld1             {v5.8b}, [x3], x1
+        ld1             {v6.8b}, [x3], x1
+        ld1             {v7.8b}, [x3], x1
+        trn1            v16.8b, v1.8b, v2.8b    // P1[0], P1[1], P3[0]...
+        ld1             {v17.8b}, [x3], x1
+        trn2            v1.8b, v1.8b, v2.8b     // P2[0], P2[1], P4[0]...
+        ld1             {v2.8b}, [x3], x1
+        trn1            v18.8b, v3.8b, v4.8b    // P1[2], P1[3], P3[2]...
+        ld1             {v19.8b}, [x3], x1
+        trn2            v3.8b, v3.8b, v4.8b     // P2[2], P2[3], P4[2]...
+        ld1             {v4.8b}, [x3], x1
+        trn1            v20.8b, v5.8b, v6.8b    // P1[4], P1[5], P3[4]...
+        ld1             {v21.8b}, [x3], x1
+        trn2            v5.8b, v5.8b, v6.8b     // P2[4], P2[5], P4[4]...
+        ld1             {v6.8b}, [x3], x1
+        trn1            v22.8b, v7.8b, v17.8b   // P1[6], P1[7], P3[6]...
+        ld1             {v23.8b}, [x3], x1
+        trn2            v7.8b, v7.8b, v17.8b    // P2[6], P2[7], P4[6]...
+        ld1             {v17.8b}, [x3], x1
+        trn1            v24.8b, v2.8b, v19.8b   // P1[8], P1[9], P3[8]...
+        ld1             {v25.8b}, [x3]
+        trn2            v2.8b, v2.8b, v19.8b    // P2[8], P2[9], P4[8]...
+        trn1            v19.4h, v16.4h, v18.4h  // P1[0], P1[1], P1[2], P1[3], P5[0]...
+        trn1            v26.8b, v4.8b, v21.8b   // P1[10], P1[11], P3[10]...
+        trn2            v4.8b, v4.8b, v21.8b    // P2[10], P2[11], P4[10]...
+        trn1            v21.4h, v1.4h, v3.4h    // P2[0], P2[1], P2[2], P2[3], P6[0]...
+        trn1            v27.4h, v20.4h, v22.4h  // P1[4], P1[5], P1[6], P1[7], P5[4]...
+        trn1            v28.8b, v6.8b, v23.8b   // P1[12], P1[13], P3[12]...
+        trn2            v6.8b, v6.8b, v23.8b    // P2[12], P2[13], P4[12]...
+        trn1            v23.4h, v5.4h, v7.4h    // P2[4], P2[5], P2[6], P2[7], P6[4]...
+        trn1            v29.4h, v24.4h, v26.4h  // P1[8], P1[9], P1[10], P1[11], P5[8]...
+        trn1            v30.8b, v17.8b, v25.8b  // P1[14], P1[15], P3[14]...
+        trn2            v17.8b, v17.8b, v25.8b  // P2[14], P2[15], P4[14]...
+        trn1            v25.4h, v2.4h, v4.4h    // P2[8], P2[9], P2[10], P2[11], P6[8]...
+        trn1            v31.2s, v19.2s, v27.2s  // P1[0..7]
+        trn2            v19.2s, v19.2s, v27.2s  // P5[0..7]
+        trn1            v27.2s, v21.2s, v23.2s  // P2[0..7]
+        trn2            v21.2s, v21.2s, v23.2s  // P6[0..7]
+        trn1            v23.4h, v28.4h, v30.4h  // P1[12], P1[13], P1[14], P1[15], P5[12]...
+        trn2            v16.4h, v16.4h, v18.4h  // P3[0], P3[1], P3[2], P3[3], P7[0]...
+        trn1            v18.4h, v6.4h, v17.4h   // P2[12], P2[13], P2[14], P2[15], P6[12]...
+        trn2            v20.4h, v20.4h, v22.4h  // P3[4], P3[5], P3[6], P3[7], P7[4]...
+        trn2            v22.4h, v24.4h, v26.4h  // P3[8], P3[9], P3[10], P3[11], P7[8]...
+        trn1            v24.2s, v29.2s, v23.2s  // P1[8..15]
+        trn2            v23.2s, v29.2s, v23.2s  // P5[8..15]
+        trn1            v26.2s, v25.2s, v18.2s  // P2[8..15]
+        trn2            v18.2s, v25.2s, v18.2s  // P6[8..15]
+        trn2            v25.4h, v28.4h, v30.4h  // P3[12], P3[13], P3[14], P3[15], P7[12]...
+        trn2            v1.4h, v1.4h, v3.4h     // P4[0], P4[1], P4[2], P4[3], P8[0]...
+        trn2            v3.4h, v5.4h, v7.4h     // P4[4], P4[5], P4[6], P4[7], P8[4]...
+        trn2            v2.4h, v2.4h, v4.4h     // P4[8], P4[9], P4[10], P4[11], P8[8]...
+        trn2            v4.4h, v6.4h, v17.4h    // P4[12], P4[13], P4[14], P4[15], P8[12]...
+        ushll           v5.8h, v31.8b, #1       // 2*P1[0..7]
+        ushll           v6.8h, v19.8b, #1       // 2*P5[0..7]
+        trn1            v7.2s, v16.2s, v20.2s   // P3[0..7]
+        uxtl            v17.8h, v27.8b          // P2[0..7]
+        trn2            v16.2s, v16.2s, v20.2s  // P7[0..7]
+        uxtl            v20.8h, v21.8b          // P6[0..7]
+        trn1            v21.2s, v22.2s, v25.2s  // P3[8..15]
+        ushll           v24.8h, v24.8b, #1      // 2*P1[8..15]
+        trn2            v22.2s, v22.2s, v25.2s  // P7[8..15]
+        ushll           v25.8h, v23.8b, #1      // 2*P5[8..15]
+        trn1            v27.2s, v1.2s, v3.2s    // P4[0..7]
+        uxtl            v26.8h, v26.8b          // P2[8..15]
+        mls             v5.8h, v17.8h, v0.h[1]  // 2*P1[0..7]-5*P2[0..7]
+        uxtl            v17.8h, v18.8b          // P6[8..15]
+        mls             v6.8h, v20.8h, v0.h[1]  // 2*P5[0..7]-5*P6[0..7]
+        trn1            v18.2s, v2.2s, v4.2s    // P4[8..15]
+        uxtl            v28.8h, v7.8b           // P3[0..7]
+        mls             v24.8h, v26.8h, v0.h[1] // 2*P1[8..15]-5*P2[8..15]
+        uxtl            v16.8h, v16.8b          // P7[0..7]
+        uxtl            v26.8h, v21.8b          // P3[8..15]
+        mls             v25.8h, v17.8h, v0.h[1] // 2*P5[8..15]-5*P6[8..15]
+        uxtl            v22.8h, v22.8b          // P7[8..15]
+        ushll           v7.8h, v7.8b, #1        // 2*P3[0..7]
+        uxtl            v27.8h, v27.8b          // P4[0..7]
+        trn2            v1.2s, v1.2s, v3.2s     // P8[0..7]
+        ushll           v3.8h, v21.8b, #1       // 2*P3[8..15]
+        trn2            v2.2s, v2.2s, v4.2s     // P8[8..15]
+        uxtl            v4.8h, v18.8b           // P4[8..15]
+        mla             v5.8h, v28.8h, v0.h[1]  // 2*P1[0..7]-5*P2[0..7]+5*P3[0..7]
+        uxtl            v1.8h, v1.8b            // P8[0..7]
+        mla             v6.8h, v16.8h, v0.h[1]  // 2*P5[0..7]-5*P6[0..7]+5*P7[0..7]
+        uxtl            v2.8h, v2.8b            // P8[8..15]
+        uxtl            v16.8h, v19.8b          // P5[0..7]
+        mla             v24.8h, v26.8h, v0.h[1] // 2*P1[8..15]-5*P2[8..15]+5*P3[8..15]
+        uxtl            v18.8h, v23.8b          // P5[8..15]
+        dup             v19.8h, w2              // pq
+        mla             v25.8h, v22.8h, v0.h[1] // 2*P5[8..15]-5*P6[8..15]+5*P7[8..15]
+        sub             v21.8h, v27.8h, v16.8h  // P4[0..7]-P5[0..7]
+        sub             v22.8h, v4.8h, v18.8h   // P4[8..15]-P5[8..15]
+        mls             v7.8h, v27.8h, v0.h[1]  // 2*P3[0..7]-5*P4[0..7]
+        abs             v23.8h, v21.8h
+        mls             v3.8h, v4.8h, v0.h[1]   // 2*P3[8..15]-5*P4[8..15]
+        abs             v26.8h, v22.8h
+        sshr            v21.8h, v21.8h, #8      // clip_sign[0..7]
+        mls             v5.8h, v27.8h, v0.h[0]  // 2*P1[0..7]-5*P2[0..7]+5*P3[0..7]-2*P4[0..7]
+        sshr            v23.8h, v23.8h, #1      // clip[0..7]
+        sshr            v26.8h, v26.8h, #1      // clip[8..15]
+        mls             v6.8h, v1.8h, v0.h[0]   // 2*P5[0..7]-5*P6[0..7]+5*P7[0..7]-2*P8[0..7]
+        sshr            v1.8h, v22.8h, #8       // clip_sign[8..15]
+        cmeq            v22.8h, v23.8h, #0      // test clip[0..7] == 0
+        mls             v24.8h, v4.8h, v0.h[0]  // 2*P1[8..15]-5*P2[8..15]+5*P3[8..15]-2*P4[8..15]
+        cmeq            v28.8h, v26.8h, #0      // test clip[8..15] == 0
+        srshr           v5.8h, v5.8h, #3
+        mls             v25.8h, v2.8h, v0.h[0]  // 2*P5[8..15]-5*P6[8..15]+5*P7[8..15]-2*P8[8..15]
+        srshr           v2.8h, v6.8h, #3
+        mla             v7.8h, v16.8h, v0.h[1]  // 2*P3[0..7]-5*P4[0..7]+5*P5[0..7]
+        srshr           v6.8h, v24.8h, #3
+        mla             v3.8h, v18.8h, v0.h[1]  // 2*P3[8..15]-5*P4[8..15]+5*P5[8..15]
+        abs             v5.8h, v5.8h            // a1[0..7]
+        srshr           v24.8h, v25.8h, #3
+        mls             v3.8h, v17.8h, v0.h[0]  // 2*P3[8..15]-5*P4[8..15]+5*P5[8..15]-2*P6[8..15]
+        abs             v2.8h, v2.8h            // a2[0..7]
+        abs             v6.8h, v6.8h            // a1[8..15]
+        mls             v7.8h, v20.8h, v0.h[0]  // 2*P3[0..7]-5*P4[0..7]+5*P5[0..7]-2*P6[0..7]
+        abs             v17.8h, v24.8h          // a2[8..15]
+        cmhs            v20.8h, v5.8h, v2.8h    // test a1[0..7] >= a2[0..7]
+        srshr           v3.8h, v3.8h, #3
+        cmhs            v24.8h, v6.8h, v17.8h   // test a1[8..15] >= a2[8.15]
+        srshr           v7.8h, v7.8h, #3
+        bsl             v20.16b, v2.16b, v5.16b // a3[0..7]
+        abs             v2.8h, v3.8h            // a0[8..15]
+        sshr            v3.8h, v3.8h, #8        // a0_sign[8..15]
+        bsl             v24.16b, v17.16b, v6.16b // a3[8..15]
+        abs             v5.8h, v7.8h            // a0[0..7]
+        sshr            v6.8h, v7.8h, #8        // a0_sign[0..7]
+        cmhs            v7.8h, v2.8h, v19.8h    // test a0[8..15] >= pq
+        sub             v1.8h, v1.8h, v3.8h     // clip_sign[8..15] - a0_sign[8..15]
+        uqsub           v3.8h, v2.8h, v24.8h    // a0[8..15] >= a3[8..15] ? a0[8..15]-a3[8..15] : 0  (a0 > a3 in all cases where filtering is enabled, so makes more sense to subtract this way round than the opposite and then taking the abs)
+        cmhs            v2.8h, v24.8h, v2.8h    // test a3[8..15] >= a0[8..15]
+        uqsub           v17.8h, v5.8h, v20.8h   // a0[0..7] >= a3[0..7] ? a0[0..7]-a3[0..7] : 0  (a0 > a3 in all cases where filtering is enabled, so makes more sense to subtract this way round than the opposite and then taking the abs)
+        cmhs            v19.8h, v5.8h, v19.8h   // test a0[0..7] >= pq
+        orr             v7.16b, v28.16b, v7.16b // test clip[8..15] == 0 || a0[8..15] >= pq
+        sub             v6.8h, v21.8h, v6.8h    // clip_sign[0..7] - a0_sign[0..7]
+        mul             v3.8h, v3.8h, v0.h[1]   // a0[8..15] >= a3[8..15] ? 5*(a0[8..15]-a3[8..15]) : 0
+        cmhs            v5.8h, v20.8h, v5.8h    // test a3[0..7] >= a0[0..7]
+        orr             v19.16b, v22.16b, v19.16b // test clip[0..7] == 0 || a0[0..7] >= pq
+        mul             v0.8h, v17.8h, v0.h[1]  // a0[0..7] >= a3[0..7] ? 5*(a0[0..7]-a3[0..7]) : 0
+        orr             v2.16b, v7.16b, v2.16b  // test clip[8..15] == 0 || a0[8..15] >= pq || a3[8..15] >= a0[8..15]
+        orr             v5.16b, v19.16b, v5.16b // test clip[0..7] == 0 || a0[0..7] >= pq || a3[0..7] >= a0[0..7]
+        ushr            v3.8h, v3.8h, #3        // a0[8..15] >= a3[8..15] ? (5*(a0[8..15]-a3[8..15]))>>3 : 0
+        mov             w7, v2.s[1]
+        mov             w8, v2.s[3]
+        ushr            v0.8h, v0.8h, #3        // a0[0..7] >= a3[0..7] ? (5*(a0[0..7]-a3[0..7]))>>3 : 0
+        mov             w2, v5.s[1]             // move to gp reg
+        cmhs            v2.8h, v3.8h, v26.8h
+        mov             w3, v5.s[3]
+        cmhs            v5.8h, v0.8h, v23.8h
+        bsl             v2.16b, v26.16b, v3.16b // FFMIN(d[8..15], clip[8..15])
+        and             w9, w7, w8
+        bsl             v5.16b, v23.16b, v0.16b // FFMIN(d[0..7], clip[0..7])
+        and             w10, w2, w3
+        bic             v0.16b, v2.16b, v7.16b  // set each d[8..15] to zero if it should not be filtered because clip[8..15] == 0 || a0[8..15] >= pq (a3 > a0 case already zeroed by saturating sub)
+        and             w9, w10, w9
+        bic             v2.16b, v5.16b, v19.16b // set each d[0..7] to zero if it should not be filtered because clip[0..7] == 0 || a0[0..7] >= pq (a3 > a0 case already zeroed by saturating sub)
+        mls             v4.8h, v0.8h, v1.8h     // invert d[8..15] depending on clip_sign[8..15] & a0_sign[8..15], or zero it if they match, and accumulate into P4
+        tbnz            w9, #0, 4f              // none of the 16 pixel pairs should be updated in this case
+        mls             v27.8h, v2.8h, v6.8h    // invert d[0..7] depending on clip_sign[0..7] & a0_sign[0..7], or zero it if they match, and accumulate into P4
+        mla             v16.8h, v2.8h, v6.8h    // invert d[0..7] depending on clip_sign[0..7] & a0_sign[0..7], or zero it if they match, and accumulate into P5
+        sqxtun          v2.8b, v4.8h
+        mla             v18.8h, v0.8h, v1.8h    // invert d[8..15] depending on clip_sign[8..15] & a0_sign[8..15], or zero it if they match, and accumulate into P5
+        sqxtun          v0.8b, v27.8h
+        sqxtun          v1.8b, v16.8h
+        sqxtun          v3.8b, v18.8h
+        tbnz            w2, #0, 1f
+        st2             {v0.b, v1.b}[0], [x0], x1
+        st2             {v0.b, v1.b}[1], [x0], x1
+        st2             {v0.b, v1.b}[2], [x0], x1
+        st2             {v0.b, v1.b}[3], [x0]
+1:      tbnz            w3, #0, 2f
+        st2             {v0.b, v1.b}[4], [x5], x1
+        st2             {v0.b, v1.b}[5], [x5], x1
+        st2             {v0.b, v1.b}[6], [x5], x1
+        st2             {v0.b, v1.b}[7], [x5]
+2:      tbnz            w7, #0, 3f
+        st2             {v2.b, v3.b}[0], [x4], x1
+        st2             {v2.b, v3.b}[1], [x4], x1
+        st2             {v2.b, v3.b}[2], [x4], x1
+        st2             {v2.b, v3.b}[3], [x4]
+3:      tbnz            w8, #0, 4f
+        st2             {v2.b, v3.b}[4], [x6], x1
+        st2             {v2.b, v3.b}[5], [x6], x1
+        st2             {v2.b, v3.b}[6], [x6], x1
+        st2             {v2.b, v3.b}[7], [x6]
+4:      ret
+endfunc
+
+// Copy at most the specified number of bytes from source to destination buffer,
+// stopping at a multiple of 32 bytes, none of which are the start of an escape sequence
+// On entry:
+//   x0 -> source buffer
+//   w1 = max number of bytes to copy
+//   x2 -> destination buffer, optimally 8-byte aligned
+// On exit:
+//   w0 = number of bytes not copied
+function ff_vc1_unescape_buffer_helper_neon, export=1
+        // Offset by 80 to screen out cases that are too short for us to handle,
+        // and also make it easy to test for loop termination, or to determine
+        // whether we need an odd number of half-iterations of the loop.
+        subs            w1, w1, #80
+        b.mi            90f
+
+        // Set up useful constants
+        movi            v20.4s, #3, lsl #24
+        movi            v21.4s, #3, lsl #16
+
+        tst             w1, #32
+        b.ne            1f
+
+          ld1             {v0.16b, v1.16b, v2.16b}, [x0], #48
+          ext             v25.16b, v0.16b, v1.16b, #1
+          ext             v26.16b, v0.16b, v1.16b, #2
+          ext             v27.16b, v0.16b, v1.16b, #3
+          ext             v29.16b, v1.16b, v2.16b, #1
+          ext             v30.16b, v1.16b, v2.16b, #2
+          ext             v31.16b, v1.16b, v2.16b, #3
+          bic             v24.16b, v0.16b, v20.16b
+          bic             v25.16b, v25.16b, v20.16b
+          bic             v26.16b, v26.16b, v20.16b
+          bic             v27.16b, v27.16b, v20.16b
+          bic             v28.16b, v1.16b, v20.16b
+          bic             v29.16b, v29.16b, v20.16b
+          bic             v30.16b, v30.16b, v20.16b
+          bic             v31.16b, v31.16b, v20.16b
+          eor             v24.16b, v24.16b, v21.16b
+          eor             v25.16b, v25.16b, v21.16b
+          eor             v26.16b, v26.16b, v21.16b
+          eor             v27.16b, v27.16b, v21.16b
+          eor             v28.16b, v28.16b, v21.16b
+          eor             v29.16b, v29.16b, v21.16b
+          eor             v30.16b, v30.16b, v21.16b
+          eor             v31.16b, v31.16b, v21.16b
+          cmeq            v24.4s, v24.4s, #0
+          cmeq            v25.4s, v25.4s, #0
+          cmeq            v26.4s, v26.4s, #0
+          cmeq            v27.4s, v27.4s, #0
+          add             w1, w1, #32
+          b               3f
+
+1:      ld1             {v3.16b, v4.16b, v5.16b}, [x0], #48
+        ext             v25.16b, v3.16b, v4.16b, #1
+        ext             v26.16b, v3.16b, v4.16b, #2
+        ext             v27.16b, v3.16b, v4.16b, #3
+        ext             v29.16b, v4.16b, v5.16b, #1
+        ext             v30.16b, v4.16b, v5.16b, #2
+        ext             v31.16b, v4.16b, v5.16b, #3
+        bic             v24.16b, v3.16b, v20.16b
+        bic             v25.16b, v25.16b, v20.16b
+        bic             v26.16b, v26.16b, v20.16b
+        bic             v27.16b, v27.16b, v20.16b
+        bic             v28.16b, v4.16b, v20.16b
+        bic             v29.16b, v29.16b, v20.16b
+        bic             v30.16b, v30.16b, v20.16b
+        bic             v31.16b, v31.16b, v20.16b
+        eor             v24.16b, v24.16b, v21.16b
+        eor             v25.16b, v25.16b, v21.16b
+        eor             v26.16b, v26.16b, v21.16b
+        eor             v27.16b, v27.16b, v21.16b
+        eor             v28.16b, v28.16b, v21.16b
+        eor             v29.16b, v29.16b, v21.16b
+        eor             v30.16b, v30.16b, v21.16b
+        eor             v31.16b, v31.16b, v21.16b
+        cmeq            v24.4s, v24.4s, #0
+        cmeq            v25.4s, v25.4s, #0
+        cmeq            v26.4s, v26.4s, #0
+        cmeq            v27.4s, v27.4s, #0
+        // Drop through...
+2:        mov             v0.16b, v5.16b
+          ld1             {v1.16b, v2.16b}, [x0], #32
+        cmeq            v28.4s, v28.4s, #0
+        cmeq            v29.4s, v29.4s, #0
+        cmeq            v30.4s, v30.4s, #0
+        cmeq            v31.4s, v31.4s, #0
+        orr             v24.16b, v24.16b, v25.16b
+        orr             v26.16b, v26.16b, v27.16b
+        orr             v28.16b, v28.16b, v29.16b
+        orr             v30.16b, v30.16b, v31.16b
+          ext             v25.16b, v0.16b, v1.16b, #1
+        orr             v22.16b, v24.16b, v26.16b
+          ext             v26.16b, v0.16b, v1.16b, #2
+          ext             v27.16b, v0.16b, v1.16b, #3
+          ext             v29.16b, v1.16b, v2.16b, #1
+        orr             v23.16b, v28.16b, v30.16b
+          ext             v30.16b, v1.16b, v2.16b, #2
+          ext             v31.16b, v1.16b, v2.16b, #3
+          bic             v24.16b, v0.16b, v20.16b
+          bic             v25.16b, v25.16b, v20.16b
+          bic             v26.16b, v26.16b, v20.16b
+        orr             v22.16b, v22.16b, v23.16b
+          bic             v27.16b, v27.16b, v20.16b
+          bic             v28.16b, v1.16b, v20.16b
+          bic             v29.16b, v29.16b, v20.16b
+          bic             v30.16b, v30.16b, v20.16b
+          bic             v31.16b, v31.16b, v20.16b
+        addv            s22, v22.4s
+          eor             v24.16b, v24.16b, v21.16b
+          eor             v25.16b, v25.16b, v21.16b
+          eor             v26.16b, v26.16b, v21.16b
+          eor             v27.16b, v27.16b, v21.16b
+          eor             v28.16b, v28.16b, v21.16b
+        mov             w3, v22.s[0]
+          eor             v29.16b, v29.16b, v21.16b
+          eor             v30.16b, v30.16b, v21.16b
+          eor             v31.16b, v31.16b, v21.16b
+          cmeq            v24.4s, v24.4s, #0
+          cmeq            v25.4s, v25.4s, #0
+          cmeq            v26.4s, v26.4s, #0
+          cmeq            v27.4s, v27.4s, #0
+        cbnz            w3, 90f
+        st1             {v3.16b, v4.16b}, [x2], #32
+3:          mov             v3.16b, v2.16b
+            ld1             {v4.16b, v5.16b}, [x0], #32
+          cmeq            v28.4s, v28.4s, #0
+          cmeq            v29.4s, v29.4s, #0
+          cmeq            v30.4s, v30.4s, #0
+          cmeq            v31.4s, v31.4s, #0
+          orr             v24.16b, v24.16b, v25.16b
+          orr             v26.16b, v26.16b, v27.16b
+          orr             v28.16b, v28.16b, v29.16b
+          orr             v30.16b, v30.16b, v31.16b
+            ext             v25.16b, v3.16b, v4.16b, #1
+          orr             v22.16b, v24.16b, v26.16b
+            ext             v26.16b, v3.16b, v4.16b, #2
+            ext             v27.16b, v3.16b, v4.16b, #3
+            ext             v29.16b, v4.16b, v5.16b, #1
+          orr             v23.16b, v28.16b, v30.16b
+            ext             v30.16b, v4.16b, v5.16b, #2
+            ext             v31.16b, v4.16b, v5.16b, #3
+            bic             v24.16b, v3.16b, v20.16b
+            bic             v25.16b, v25.16b, v20.16b
+            bic             v26.16b, v26.16b, v20.16b
+          orr             v22.16b, v22.16b, v23.16b
+            bic             v27.16b, v27.16b, v20.16b
+            bic             v28.16b, v4.16b, v20.16b
+            bic             v29.16b, v29.16b, v20.16b
+            bic             v30.16b, v30.16b, v20.16b
+            bic             v31.16b, v31.16b, v20.16b
+          addv            s22, v22.4s
+            eor             v24.16b, v24.16b, v21.16b
+            eor             v25.16b, v25.16b, v21.16b
+            eor             v26.16b, v26.16b, v21.16b
+            eor             v27.16b, v27.16b, v21.16b
+            eor             v28.16b, v28.16b, v21.16b
+          mov             w3, v22.s[0]
+            eor             v29.16b, v29.16b, v21.16b
+            eor             v30.16b, v30.16b, v21.16b
+            eor             v31.16b, v31.16b, v21.16b
+            cmeq            v24.4s, v24.4s, #0
+            cmeq            v25.4s, v25.4s, #0
+            cmeq            v26.4s, v26.4s, #0
+            cmeq            v27.4s, v27.4s, #0
+          cbnz            w3, 91f
+          st1             {v0.16b, v1.16b}, [x2], #32
+        subs            w1, w1, #64
+        b.pl            2b
+
+90:     add             w0, w1, #80
+        ret
+
+91:     sub             w1, w1, #32
+        b               90b
+endfunc
diff -pruN 7:5.0.1-3/libavcodec/aasc.c 7:5.1-1/libavcodec/aasc.c
--- 7:5.0.1-3/libavcodec/aasc.c	2022-01-14 18:45:39.000000000 +0000
+++ 7:5.1-1/libavcodec/aasc.c	2022-07-22 17:58:38.000000000 +0000
@@ -29,6 +29,7 @@
 #include <string.h>
 
 #include "avcodec.h"
+#include "codec_internal.h"
 #include "internal.h"
 #include "msrledec.h"
 
@@ -77,9 +78,8 @@ static av_cold int aasc_decode_init(AVCo
     return 0;
 }
 
-static int aasc_decode_frame(AVCodecContext *avctx,
-                              void *data, int *got_frame,
-                              AVPacket *avpkt)
+static int aasc_decode_frame(AVCodecContext *avctx, AVFrame *rframe,
+                             int *got_frame, AVPacket *avpkt)
 {
     const uint8_t *buf = avpkt->data;
     int buf_size       = avpkt->size;
@@ -104,26 +104,26 @@ static int aasc_decode_frame(AVCodecCont
         ff_msrle_decode(avctx, s->frame, 8, &s->gb);
         break;
     case MKTAG('A', 'A', 'S', 'C'):
-    switch (compr) {
-    case 0:
-        stride = (avctx->width * psize + psize) & ~psize;
-        if (buf_size < stride * avctx->height)
+        switch (compr) {
+        case 0:
+            stride = (avctx->width * psize + psize) & ~psize;
+            if (buf_size < stride * avctx->height)
+                return AVERROR_INVALIDDATA;
+            for (i = avctx->height - 1; i >= 0; i--) {
+                memcpy(s->frame->data[0] + i * s->frame->linesize[0], buf, avctx->width * psize);
+                buf += stride;
+                buf_size -= stride;
+            }
+            break;
+        case 1:
+            bytestream2_init(&s->gb, buf, buf_size);
+            ff_msrle_decode(avctx, s->frame, 8, &s->gb);
+            break;
+        default:
+            av_log(avctx, AV_LOG_ERROR, "Unknown compression type %d\n", compr);
             return AVERROR_INVALIDDATA;
-        for (i = avctx->height - 1; i >= 0; i--) {
-            memcpy(s->frame->data[0] + i * s->frame->linesize[0], buf, avctx->width * psize);
-            buf += stride;
-            buf_size -= stride;
         }
         break;
-    case 1:
-        bytestream2_init(&s->gb, buf, buf_size);
-        ff_msrle_decode(avctx, s->frame, 8, &s->gb);
-        break;
-    default:
-        av_log(avctx, AV_LOG_ERROR, "Unknown compression type %d\n", compr);
-        return AVERROR_INVALIDDATA;
-    }
-        break;
     default:
         av_log(avctx, AV_LOG_ERROR, "Unknown FourCC: %X\n", avctx->codec_tag);
         return -1;
@@ -133,7 +133,7 @@ static int aasc_decode_frame(AVCodecCont
         memcpy(s->frame->data[1], s->palette, s->palette_size);
 
     *got_frame = 1;
-    if ((ret = av_frame_ref(data, s->frame)) < 0)
+    if ((ret = av_frame_ref(rframe, s->frame)) < 0)
         return ret;
 
     /* report that the buffer was completely consumed */
@@ -149,15 +149,15 @@ static av_cold int aasc_decode_end(AVCod
     return 0;
 }
 
-const AVCodec ff_aasc_decoder = {
-    .name           = "aasc",
-    .long_name      = NULL_IF_CONFIG_SMALL("Autodesk RLE"),
-    .type           = AVMEDIA_TYPE_VIDEO,
-    .id             = AV_CODEC_ID_AASC,
+const FFCodec ff_aasc_decoder = {
+    .p.name         = "aasc",
+    .p.long_name    = NULL_IF_CONFIG_SMALL("Autodesk RLE"),
+    .p.type         = AVMEDIA_TYPE_VIDEO,
+    .p.id           = AV_CODEC_ID_AASC,
     .priv_data_size = sizeof(AascContext),
     .init           = aasc_decode_init,
     .close          = aasc_decode_end,
-    .decode         = aasc_decode_frame,
-    .capabilities   = AV_CODEC_CAP_DR1,
+    FF_CODEC_DECODE_CB(aasc_decode_frame),
+    .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff -pruN 7:5.0.1-3/libavcodec/ac3.c 7:5.1-1/libavcodec/ac3.c
--- 7:5.0.1-3/libavcodec/ac3.c	2022-01-14 18:45:39.000000000 +0000
+++ 7:5.1-1/libavcodec/ac3.c	2022-07-22 17:58:38.000000000 +0000
@@ -24,9 +24,11 @@
  * Common code between the AC-3 encoder and decoder.
  */
 
-#include "libavutil/common.h"
+#include "libavutil/error.h"
+#include "libavutil/macros.h"
 
 #include "ac3.h"
+#include "ac3defs.h"
 
 /**
  * Starting frequency coefficient bin for each critical band.
@@ -67,6 +69,88 @@ const uint8_t ff_ac3_bin_to_band_tab[253
     49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49
 };
 
+static const uint8_t ac3_log_add_tab[260]= {
+0x40,0x3f,0x3e,0x3d,0x3c,0x3b,0x3a,0x39,0x38,0x37,
+0x36,0x35,0x34,0x34,0x33,0x32,0x31,0x30,0x2f,0x2f,
+0x2e,0x2d,0x2c,0x2c,0x2b,0x2a,0x29,0x29,0x28,0x27,
+0x26,0x26,0x25,0x24,0x24,0x23,0x23,0x22,0x21,0x21,
+0x20,0x20,0x1f,0x1e,0x1e,0x1d,0x1d,0x1c,0x1c,0x1b,
+0x1b,0x1a,0x1a,0x19,0x19,0x18,0x18,0x17,0x17,0x16,
+0x16,0x15,0x15,0x15,0x14,0x14,0x13,0x13,0x13,0x12,
+0x12,0x12,0x11,0x11,0x11,0x10,0x10,0x10,0x0f,0x0f,
+0x0f,0x0e,0x0e,0x0e,0x0d,0x0d,0x0d,0x0d,0x0c,0x0c,
+0x0c,0x0c,0x0b,0x0b,0x0b,0x0b,0x0a,0x0a,0x0a,0x0a,
+0x0a,0x09,0x09,0x09,0x09,0x09,0x08,0x08,0x08,0x08,
+0x08,0x08,0x07,0x07,0x07,0x07,0x07,0x07,0x06,0x06,
+0x06,0x06,0x06,0x06,0x06,0x06,0x05,0x05,0x05,0x05,
+0x05,0x05,0x05,0x05,0x04,0x04,0x04,0x04,0x04,0x04,
+0x04,0x04,0x04,0x04,0x04,0x03,0x03,0x03,0x03,0x03,
+0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x02,
+0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,
+0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x01,0x01,
+0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
+0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
+0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+};
+
+static const uint16_t ac3_hearing_threshold_tab[AC3_CRITICAL_BANDS][3]= {
+{ 0x04d0,0x04f0,0x0580 },
+{ 0x04d0,0x04f0,0x0580 },
+{ 0x0440,0x0460,0x04b0 },
+{ 0x0400,0x0410,0x0450 },
+{ 0x03e0,0x03e0,0x0420 },
+{ 0x03c0,0x03d0,0x03f0 },
+{ 0x03b0,0x03c0,0x03e0 },
+{ 0x03b0,0x03b0,0x03d0 },
+{ 0x03a0,0x03b0,0x03c0 },
+{ 0x03a0,0x03a0,0x03b0 },
+{ 0x03a0,0x03a0,0x03b0 },
+{ 0x03a0,0x03a0,0x03b0 },
+{ 0x03a0,0x03a0,0x03a0 },
+{ 0x0390,0x03a0,0x03a0 },
+{ 0x0390,0x0390,0x03a0 },
+{ 0x0390,0x0390,0x03a0 },
+{ 0x0380,0x0390,0x03a0 },
+{ 0x0380,0x0380,0x03a0 },
+{ 0x0370,0x0380,0x03a0 },
+{ 0x0370,0x0380,0x03a0 },
+{ 0x0360,0x0370,0x0390 },
+{ 0x0360,0x0370,0x0390 },
+{ 0x0350,0x0360,0x0390 },
+{ 0x0350,0x0360,0x0390 },
+{ 0x0340,0x0350,0x0380 },
+{ 0x0340,0x0350,0x0380 },
+{ 0x0330,0x0340,0x0380 },
+{ 0x0320,0x0340,0x0370 },
+{ 0x0310,0x0320,0x0360 },
+{ 0x0300,0x0310,0x0350 },
+{ 0x02f0,0x0300,0x0340 },
+{ 0x02f0,0x02f0,0x0330 },
+{ 0x02f0,0x02f0,0x0320 },
+{ 0x02f0,0x02f0,0x0310 },
+{ 0x0300,0x02f0,0x0300 },
+{ 0x0310,0x0300,0x02f0 },
+{ 0x0340,0x0320,0x02f0 },
+{ 0x0390,0x0350,0x02f0 },
+{ 0x03e0,0x0390,0x0300 },
+{ 0x0420,0x03e0,0x0310 },
+{ 0x0460,0x0420,0x0330 },
+{ 0x0490,0x0450,0x0350 },
+{ 0x04a0,0x04a0,0x03c0 },
+{ 0x0460,0x0490,0x0410 },
+{ 0x0440,0x0460,0x0470 },
+{ 0x0440,0x0440,0x04a0 },
+{ 0x0520,0x0480,0x0460 },
+{ 0x0800,0x0630,0x0440 },
+{ 0x0840,0x0840,0x0450 },
+{ 0x0840,0x0840,0x04e0 },
+};
+
 static inline int calc_lowcomp1(int a, int b0, int b1, int c)
 {
     if ((b0 + 256) == b1) {
@@ -108,7 +192,7 @@ void ff_ac3_bit_alloc_calc_psd(int8_t *e
             int max = FFMAX(v, psd[bin]);
             /* logadd */
             int adr = FFMIN(max - ((v + psd[bin] + 1) >> 1), 255);
-            v = max + ff_ac3_log_add_tab[adr];
+            v = max + ac3_log_add_tab[adr];
         }
         band_psd[band++] = v;
     } while (end > ff_ac3_band_start_tab[band]);
@@ -182,7 +266,7 @@ int ff_ac3_bit_alloc_calc_mask(AC3BitAll
         if (tmp > 0) {
             excite[band] += tmp >> 2;
         }
-        mask[band] = FFMAX(ff_ac3_hearing_threshold_tab[band >> s->sr_shift][s->sr_code], excite[band]);
+        mask[band] = FFMAX(ac3_hearing_threshold_tab[band >> s->sr_shift][s->sr_code], excite[band]);
     }
 
     /* delta bit allocation */
diff -pruN 7:5.0.1-3/libavcodec/ac3dec.c 7:5.1-1/libavcodec/ac3dec.c
--- 7:5.0.1-3/libavcodec/ac3dec.c	2022-01-14 18:45:39.000000000 +0000
+++ 7:5.1-1/libavcodec/ac3dec.c	2022-07-22 17:58:38.000000000 +0000
@@ -24,6 +24,8 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "config_components.h"
+
 #include <stdio.h>
 #include <stddef.h>
 #include <math.h>
@@ -32,6 +34,7 @@
 #include "libavutil/channel_layout.h"
 #include "libavutil/crc.h"
 #include "libavutil/downmix_info.h"
+#include "libavutil/intmath.h"
 #include "libavutil/opt.h"
 #include "libavutil/thread.h"
 #include "bswapdsp.h"
@@ -40,6 +43,7 @@
 #include "ac3_parser_internal.h"
 #include "ac3dec.h"
 #include "ac3dec_data.h"
+#include "ac3defs.h"
 #include "kbdwin.h"
 
 /**
@@ -186,6 +190,8 @@ static av_cold int ac3_decode_init(AVCod
 {
     static AVOnce init_static_once = AV_ONCE_INIT;
     AC3DecodeContext *s = avctx->priv_data;
+    const AVChannelLayout mono   = (AVChannelLayout)AV_CHANNEL_LAYOUT_MONO;
+    const AVChannelLayout stereo = (AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO;
     int i, ret;
 
     s->avctx = avctx;
@@ -214,12 +220,23 @@ static av_cold int ac3_decode_init(AVCod
         avctx->sample_fmt = AV_SAMPLE_FMT_FLTP;
 
     /* allow downmixing to stereo or mono */
-    if (avctx->channels > 1 &&
-        avctx->request_channel_layout == AV_CH_LAYOUT_MONO)
-        avctx->channels = 1;
-    else if (avctx->channels > 2 &&
-             avctx->request_channel_layout == AV_CH_LAYOUT_STEREO)
-        avctx->channels = 2;
+#if FF_API_OLD_CHANNEL_LAYOUT
+FF_DISABLE_DEPRECATION_WARNINGS
+    if (avctx->request_channel_layout) {
+        av_channel_layout_uninit(&s->downmix_layout);
+        av_channel_layout_from_mask(&s->downmix_layout, avctx->request_channel_layout);
+    }
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
+    if (avctx->ch_layout.nb_channels > 1 &&
+        !av_channel_layout_compare(&s->downmix_layout, &mono)) {
+        av_channel_layout_uninit(&avctx->ch_layout);
+        avctx->ch_layout = (AVChannelLayout)AV_CHANNEL_LAYOUT_MONO;
+    } else if (avctx->ch_layout.nb_channels > 2 &&
+             !av_channel_layout_compare(&s->downmix_layout, &stereo)) {
+        av_channel_layout_uninit(&avctx->ch_layout);
+        avctx->ch_layout = (AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO;
+    }
     s->downmixed = 1;
 
     for (i = 0; i < AC3_MAX_CHANNELS; i++) {
@@ -1465,10 +1482,9 @@ static int decode_audio_block(AC3DecodeC
 /**
  * Decode a single AC-3 frame.
  */
-static int ac3_decode_frame(AVCodecContext * avctx, void *data,
+static int ac3_decode_frame(AVCodecContext *avctx, AVFrame *frame,
                             int *got_frame_ptr, AVPacket *avpkt)
 {
-    AVFrame *frame     = data;
     const uint8_t *buf = avpkt->data;
     int buf_size, full_buf_size = avpkt->size;
     AC3DecodeContext *s = avctx->priv_data;
@@ -1480,6 +1496,7 @@ static int ac3_decode_frame(AVCodecConte
     const SHORTFLOAT *output[AC3_MAX_CHANNELS];
     enum AVMatrixEncoding matrix_encoding;
     AVDownmixInfo *downmix_info;
+    uint64_t mask;
 
     s->superframe_size = 0;
 
@@ -1590,11 +1607,11 @@ dependent_frame:
         if (s->lfe_on)
             s->output_mode |= AC3_OUTPUT_LFEON;
         if (s->channels > 1 &&
-            avctx->request_channel_layout == AV_CH_LAYOUT_MONO) {
+            !av_channel_layout_compare(&s->downmix_layout, &(AVChannelLayout)AV_CHANNEL_LAYOUT_MONO)) {
             s->out_channels = 1;
             s->output_mode  = AC3_CHMODE_MONO;
         } else if (s->channels > 2 &&
-                   avctx->request_channel_layout == AV_CH_LAYOUT_STEREO) {
+                   !av_channel_layout_compare(&s->downmix_layout, &(AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO)) {
             s->out_channels = 2;
             s->output_mode  = AC3_CHMODE_STEREO;
         }
@@ -1615,10 +1632,13 @@ dependent_frame:
         av_log(avctx, AV_LOG_ERROR, "unable to determine channel mode\n");
         return AVERROR_INVALIDDATA;
     }
-    avctx->channels = s->out_channels;
-    avctx->channel_layout = ff_ac3_channel_layout_tab[s->output_mode & ~AC3_OUTPUT_LFEON];
+
+    mask = ff_ac3_channel_layout_tab[s->output_mode & ~AC3_OUTPUT_LFEON];
     if (s->output_mode & AC3_OUTPUT_LFEON)
-        avctx->channel_layout |= AV_CH_LOW_FREQUENCY;
+        mask |= AV_CH_LOW_FREQUENCY;
+
+    av_channel_layout_uninit(&avctx->ch_layout);
+    av_channel_layout_from_mask(&avctx->ch_layout, mask);
 
     /* set audio service type based on bitstream mode for AC-3 */
     avctx->audio_service_type = s->bitstream_mode;
@@ -1714,20 +1734,20 @@ skip:
                 channel_layout |= ff_eac3_custom_channel_map_locations[ch][1];
             }
         }
-        if (av_get_channel_layout_nb_channels(channel_layout) > EAC3_MAX_CHANNELS) {
+        if (av_popcount64(channel_layout) > EAC3_MAX_CHANNELS) {
             av_log(avctx, AV_LOG_ERROR, "Too many channels (%d) coded\n",
-                   av_get_channel_layout_nb_channels(channel_layout));
+                   av_popcount64(channel_layout));
             return AVERROR_INVALIDDATA;
         }
 
-        avctx->channel_layout = channel_layout;
-        avctx->channels = av_get_channel_layout_nb_channels(channel_layout);
+        av_channel_layout_uninit(&avctx->ch_layout);
+        av_channel_layout_from_mask(&avctx->ch_layout, channel_layout);
 
         for (ch = 0; ch < EAC3_MAX_CHANNELS; ch++) {
             if (s->channel_map & (1 << (EAC3_MAX_CHANNELS - ch - 1))) {
                 if (ff_eac3_custom_channel_map_locations[ch][0]) {
-                    int index = av_get_channel_layout_channel_index(channel_layout,
-                                                                    ff_eac3_custom_channel_map_locations[ch][1]);
+                    int index = av_channel_layout_index_from_channel(&avctx->ch_layout,
+                                                                     ff_ctzll(ff_eac3_custom_channel_map_locations[ch][1]));
                     if (index < 0)
                         return AVERROR_INVALIDDATA;
                     if (extend >= channel_map_size)
@@ -1739,8 +1759,7 @@ skip:
 
                     for (i = 0; i < 64; i++) {
                         if ((1ULL << i) & ff_eac3_custom_channel_map_locations[ch][1]) {
-                            int index = av_get_channel_layout_channel_index(channel_layout,
-                                                                            1ULL << i);
+                            int index = av_channel_layout_index_from_channel(&avctx->ch_layout, i);
                             if (index < 0)
                                 return AVERROR_INVALIDDATA;
                             if (extend >= channel_map_size)
@@ -1759,7 +1778,7 @@ skip:
     if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
         return ret;
 
-    for (ch = 0; ch < avctx->channels; ch++) {
+    for (ch = 0; ch < avctx->ch_layout.nb_channels; ch++) {
         int map = extended_channel_map[ch];
         av_assert0(ch>=AV_NUM_DATA_POINTERS || frame->extended_data[ch] == frame->data[ch]);
         memcpy((SHORTFLOAT *)frame->extended_data[ch],
diff -pruN 7:5.0.1-3/libavcodec/ac3dec_data.c 7:5.1-1/libavcodec/ac3dec_data.c
--- 7:5.0.1-3/libavcodec/ac3dec_data.c	2020-04-27 21:48:15.000000000 +0000
+++ 7:5.1-1/libavcodec/ac3dec_data.c	2022-07-22 17:58:38.000000000 +0000
@@ -25,7 +25,6 @@
  */
 
 #include "ac3dec_data.h"
-#include "ac3.h"
 
 /**
  * Table used to ungroup 3 values stored in 5 bits.
diff -pruN 7:5.0.1-3/libavcodec/ac3dec_fixed.c 7:5.1-1/libavcodec/ac3dec_fixed.c
--- 7:5.0.1-3/libavcodec/ac3dec_fixed.c	2022-01-14 18:45:39.000000000 +0000
+++ 7:5.1-1/libavcodec/ac3dec_fixed.c	2022-07-22 17:58:38.000000000 +0000
@@ -50,6 +50,7 @@
 #define FFT_FLOAT 0
 #define USE_FIXED 1
 #include "ac3dec.h"
+#include "codec_internal.h"
 
 
 static const int end_freq_inv_tab[8] =
@@ -157,6 +158,7 @@ static const AVOption options[] = {
     { "cons_noisegen", "enable consistent noise generation", OFFSET(consistent_noise_generation), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, PAR },
     { "drc_scale", "percentage of dynamic range compression to apply", OFFSET(drc_scale), AV_OPT_TYPE_FLOAT, {.dbl = 1.0}, 0.0, 6.0, PAR },
     { "heavy_compr", "enable heavy dynamic range compression", OFFSET(heavy_compression), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, PAR },
+    { "downmix", "Request a specific channel layout from the decoder", OFFSET(downmix_layout), AV_OPT_TYPE_CHLAYOUT, {.str = NULL}, .flags = PAR },
     { NULL},
 };
 
@@ -167,19 +169,19 @@ static const AVClass ac3_decoder_class =
     .version    = LIBAVUTIL_VERSION_INT,
 };
 
-const AVCodec ff_ac3_fixed_decoder = {
-    .name           = "ac3_fixed",
-    .type           = AVMEDIA_TYPE_AUDIO,
-    .id             = AV_CODEC_ID_AC3,
+const FFCodec ff_ac3_fixed_decoder = {
+    .p.name         = "ac3_fixed",
+    .p.long_name    = NULL_IF_CONFIG_SMALL("ATSC A/52A (AC-3)"),
+    .p.type         = AVMEDIA_TYPE_AUDIO,
+    .p.id           = AV_CODEC_ID_AC3,
+    .p.priv_class   = &ac3_decoder_class,
     .priv_data_size = sizeof (AC3DecodeContext),
     .init           = ac3_decode_init,
     .close          = ac3_decode_end,
-    .decode         = ac3_decode_frame,
-    .capabilities   = AV_CODEC_CAP_CHANNEL_CONF |
+    FF_CODEC_DECODE_CB(ac3_decode_frame),
+    .p.capabilities = AV_CODEC_CAP_CHANNEL_CONF |
                       AV_CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("ATSC A/52A (AC-3)"),
-    .sample_fmts    = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16P,
+    .p.sample_fmts  = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16P,
                                                       AV_SAMPLE_FMT_NONE },
-    .priv_class     = &ac3_decoder_class,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
 };
diff -pruN 7:5.0.1-3/libavcodec/ac3dec_float.c 7:5.1-1/libavcodec/ac3dec_float.c
--- 7:5.0.1-3/libavcodec/ac3dec_float.c	2022-01-14 18:45:39.000000000 +0000
+++ 7:5.1-1/libavcodec/ac3dec_float.c	2022-07-22 17:58:38.000000000 +0000
@@ -27,7 +27,11 @@
 /**
  * Upmix delay samples from stereo to original channel layout.
  */
+
+#include "config_components.h"
+
 #include "ac3dec.h"
+#include "codec_internal.h"
 #include "eac3dec.c"
 #include "ac3dec.c"
 
@@ -43,6 +47,8 @@ static const AVOption options[] = {
 {"loro_cmixlev",   "Lo/Ro Center Mix Level",   OFFSET(loro_center_mix_level),    AV_OPT_TYPE_FLOAT, {.dbl = -1.0 }, -1.0, 2.0, 0},
 {"loro_surmixlev", "Lo/Ro Surround Mix Level", OFFSET(loro_surround_mix_level),  AV_OPT_TYPE_FLOAT, {.dbl = -1.0 }, -1.0, 2.0, 0},
 
+    { "downmix", "Request a specific channel layout from the decoder", OFFSET(downmix_layout), AV_OPT_TYPE_CHLAYOUT, {.str = NULL}, .flags = PAR },
+
     { NULL},
 };
 
@@ -53,38 +59,38 @@ static const AVClass ac3_eac3_decoder_cl
     .version    = LIBAVUTIL_VERSION_INT,
 };
 
-const AVCodec ff_ac3_decoder = {
-    .name           = "ac3",
-    .type           = AVMEDIA_TYPE_AUDIO,
-    .id             = AV_CODEC_ID_AC3,
+const FFCodec ff_ac3_decoder = {
+    .p.name         = "ac3",
+    .p.type         = AVMEDIA_TYPE_AUDIO,
+    .p.id           = AV_CODEC_ID_AC3,
     .priv_data_size = sizeof (AC3DecodeContext),
     .init           = ac3_decode_init,
     .close          = ac3_decode_end,
-    .decode         = ac3_decode_frame,
-    .capabilities   = AV_CODEC_CAP_CHANNEL_CONF |
+    FF_CODEC_DECODE_CB(ac3_decode_frame),
+    .p.capabilities = AV_CODEC_CAP_CHANNEL_CONF |
                       AV_CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("ATSC A/52A (AC-3)"),
-    .sample_fmts    = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP,
+    .p.long_name    = NULL_IF_CONFIG_SMALL("ATSC A/52A (AC-3)"),
+    .p.sample_fmts  = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP,
                                                       AV_SAMPLE_FMT_NONE },
-    .priv_class     = &ac3_eac3_decoder_class,
+    .p.priv_class   = &ac3_eac3_decoder_class,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
 };
 
 #if CONFIG_EAC3_DECODER
-const AVCodec ff_eac3_decoder = {
-    .name           = "eac3",
-    .type           = AVMEDIA_TYPE_AUDIO,
-    .id             = AV_CODEC_ID_EAC3,
+const FFCodec ff_eac3_decoder = {
+    .p.name         = "eac3",
+    .p.type         = AVMEDIA_TYPE_AUDIO,
+    .p.id           = AV_CODEC_ID_EAC3,
     .priv_data_size = sizeof (AC3DecodeContext),
     .init           = ac3_decode_init,
     .close          = ac3_decode_end,
-    .decode         = ac3_decode_frame,
-    .capabilities   = AV_CODEC_CAP_CHANNEL_CONF |
+    FF_CODEC_DECODE_CB(ac3_decode_frame),
+    .p.capabilities = AV_CODEC_CAP_CHANNEL_CONF |
                       AV_CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("ATSC A/52B (AC-3, E-AC-3)"),
-    .sample_fmts    = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP,
+    .p.long_name    = NULL_IF_CONFIG_SMALL("ATSC A/52B (AC-3, E-AC-3)"),
+    .p.sample_fmts  = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP,
                                                       AV_SAMPLE_FMT_NONE },
-    .priv_class     = &ac3_eac3_decoder_class,
+    .p.priv_class   = &ac3_eac3_decoder_class,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
 };
 #endif
diff -pruN 7:5.0.1-3/libavcodec/ac3dec.h 7:5.1-1/libavcodec/ac3dec.h
--- 7:5.0.1-3/libavcodec/ac3dec.h	2021-10-24 20:47:07.000000000 +0000
+++ 7:5.1-1/libavcodec/ac3dec.h	2022-07-22 17:58:38.000000000 +0000
@@ -251,6 +251,8 @@ typedef struct AC3DecodeContext {
     DECLARE_ALIGNED(32, uint8_t, input_buffer)[AC3_FRAME_BUFFER_SIZE + AV_INPUT_BUFFER_PADDING_SIZE]; ///< temp buffer to prevent overread
     DECLARE_ALIGNED(32, SHORTFLOAT, output_buffer)[EAC3_MAX_CHANNELS][AC3_BLOCK_SIZE * 6];  ///< final output buffer
 ///@}
+
+    AVChannelLayout downmix_layout;
 } AC3DecodeContext;
 
 /**
diff -pruN 7:5.0.1-3/libavcodec/ac3defs.h 7:5.1-1/libavcodec/ac3defs.h
--- 7:5.0.1-3/libavcodec/ac3defs.h	1970-01-01 00:00:00.000000000 +0000
+++ 7:5.1-1/libavcodec/ac3defs.h	2022-07-22 17:58:38.000000000 +0000
@@ -0,0 +1,104 @@
+/*
+ * Common AC-3 definitions
+ * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVCODEC_AC3DEFS_H
+#define AVCODEC_AC3DEFS_H
+
+#define EAC3_MAX_CHANNELS 16          /**< maximum number of channels in EAC3 */
+#define AC3_MAX_CHANNELS 7            /**< maximum number of channels, including coupling channel */
+#define CPL_CH 0                      /**< coupling channel index */
+
+#define AC3_MAX_COEFS   256
+#define AC3_BLOCK_SIZE  256
+#define AC3_MAX_BLOCKS    6
+#define AC3_FRAME_SIZE (AC3_MAX_BLOCKS * 256)
+#define AC3_WINDOW_SIZE (AC3_BLOCK_SIZE * 2)
+#define AC3_CRITICAL_BANDS 50
+#define AC3_MAX_CPL_BANDS  18
+
+/* exponent encoding strategy */
+#define EXP_REUSE 0
+#define EXP_NEW   1
+
+#define EXP_D15   1
+#define EXP_D25   2
+#define EXP_D45   3
+
+/** Delta bit allocation strategy */
+typedef enum {
+    DBA_REUSE = 0,
+    DBA_NEW,
+    DBA_NONE,
+    DBA_RESERVED
+} AC3DeltaStrategy;
+
+/** Channel mode (audio coding mode) */
+typedef enum {
+    AC3_CHMODE_DUALMONO = 0,
+    AC3_CHMODE_MONO,
+    AC3_CHMODE_STEREO,
+    AC3_CHMODE_3F,
+    AC3_CHMODE_2F1R,
+    AC3_CHMODE_3F1R,
+    AC3_CHMODE_2F2R,
+    AC3_CHMODE_3F2R
+} AC3ChannelMode;
+
+/** Dolby Surround mode */
+typedef enum AC3DolbySurroundMode {
+    AC3_DSURMOD_NOTINDICATED = 0,
+    AC3_DSURMOD_OFF,
+    AC3_DSURMOD_ON,
+    AC3_DSURMOD_RESERVED
+} AC3DolbySurroundMode;
+
+/** Dolby Surround EX mode */
+typedef enum AC3DolbySurroundEXMode {
+    AC3_DSUREXMOD_NOTINDICATED = 0,
+    AC3_DSUREXMOD_OFF,
+    AC3_DSUREXMOD_ON,
+    AC3_DSUREXMOD_PLIIZ
+} AC3DolbySurroundEXMode;
+
+/** Dolby Headphone mode */
+typedef enum AC3DolbyHeadphoneMode {
+    AC3_DHEADPHONMOD_NOTINDICATED = 0,
+    AC3_DHEADPHONMOD_OFF,
+    AC3_DHEADPHONMOD_ON,
+    AC3_DHEADPHONMOD_RESERVED
+} AC3DolbyHeadphoneMode;
+
+/** Preferred Stereo Downmix mode */
+typedef enum AC3PreferredStereoDownmixMode {
+    AC3_DMIXMOD_NOTINDICATED = 0,
+    AC3_DMIXMOD_LTRT,
+    AC3_DMIXMOD_LORO,
+    AC3_DMIXMOD_DPLII // reserved value in A/52, but used by encoders to indicate DPL2
+} AC3PreferredStereoDownmixMode;
+
+typedef enum {
+    EAC3_FRAME_TYPE_INDEPENDENT = 0,
+    EAC3_FRAME_TYPE_DEPENDENT,
+    EAC3_FRAME_TYPE_AC3_CONVERT,
+    EAC3_FRAME_TYPE_RESERVED
+} EAC3FrameType;
+
+#endif /* AVCODEC_AC3DEFS_H */
diff -pruN 7:5.0.1-3/libavcodec/ac3dsp.c 7:5.1-1/libavcodec/ac3dsp.c
--- 7:5.0.1-3/libavcodec/ac3dsp.c	2022-01-14 18:45:39.000000000 +0000
+++ 7:5.1-1/libavcodec/ac3dsp.c	2022-07-22 17:58:38.000000000 +0000
@@ -29,8 +29,9 @@
 #include "libavutil/intmath.h"
 #include "libavutil/mem_internal.h"
 
-#include "ac3.h"
+#include "ac3defs.h"
 #include "ac3dsp.h"
+#include "ac3tab.h"
 #include "mathops.h"
 
 static void ac3_exponent_min_c(uint8_t *exp, int num_reuse_blocks, int nb_coefs)
@@ -362,8 +363,9 @@ void ff_ac3dsp_downmix(AC3DSPContext *c,
             c->downmix = ac3_downmix_5_to_1_symmetric_c;
         }
 
-        if (ARCH_X86)
-            ff_ac3dsp_set_downmix_x86(c);
+#if ARCH_X86
+        ff_ac3dsp_set_downmix_x86(c);
+#endif
     }
 
     if (c->downmix)
@@ -387,10 +389,11 @@ av_cold void ff_ac3dsp_init(AC3DSPContex
     c->downmix               = NULL;
     c->downmix_fixed         = NULL;
 
-    if (ARCH_ARM)
-        ff_ac3dsp_init_arm(c, bit_exact);
-    if (ARCH_X86)
-        ff_ac3dsp_init_x86(c, bit_exact);
-    if (ARCH_MIPS)
-        ff_ac3dsp_init_mips(c, bit_exact);
+#if ARCH_ARM
+    ff_ac3dsp_init_arm(c, bit_exact);
+#elif ARCH_X86
+    ff_ac3dsp_init_x86(c, bit_exact);
+#elif ARCH_MIPS
+    ff_ac3dsp_init_mips(c, bit_exact);
+#endif
 }
diff -pruN 7:5.0.1-3/libavcodec/ac3enc.c 7:5.1-1/libavcodec/ac3enc.c
--- 7:5.0.1-3/libavcodec/ac3enc.c	2022-01-14 18:45:39.000000000 +0000
+++ 7:5.1-1/libavcodec/ac3enc.c	2022-07-22 17:58:38.000000000 +0000
@@ -38,6 +38,8 @@
 #include "libavutil/opt.h"
 #include "libavutil/thread.h"
 #include "avcodec.h"
+#include "codec_internal.h"
+#include "config_components.h"
 #include "encode.h"
 #include "internal.h"
 #include "me_cmp.h"
@@ -45,6 +47,8 @@
 #include "audiodsp.h"
 #include "ac3dsp.h"
 #include "ac3.h"
+#include "ac3defs.h"
+#include "ac3tab.h"
 #include "fft.h"
 #include "ac3enc.h"
 #include "eac3enc.h"
@@ -132,7 +136,7 @@ const AVClass ff_ac3enc_class = {
     .version    = LIBAVUTIL_VERSION_INT,
 };
 
-const AVCodecDefault ff_ac3_enc_defaults[] = {
+const FFCodecDefault ff_ac3_enc_defaults[] = {
     { "b",  "0" },
     { NULL }
 };
@@ -147,6 +151,7 @@ static uint8_t exponent_group_tab[2][3][
 /**
  * List of supported channel layouts.
  */
+#if FF_API_OLD_CHANNEL_LAYOUT
 const uint64_t ff_ac3_channel_layouts[19] = {
      AV_CH_LAYOUT_MONO,
      AV_CH_LAYOUT_STEREO,
@@ -168,6 +173,47 @@ const uint64_t ff_ac3_channel_layouts[19
      AV_CH_LAYOUT_5POINT1_BACK,
      0
 };
+#endif
+
+const AVChannelLayout ff_ac3_ch_layouts[19] = {
+    AV_CHANNEL_LAYOUT_MONO,
+    AV_CHANNEL_LAYOUT_STEREO,
+    AV_CHANNEL_LAYOUT_2_1,
+    AV_CHANNEL_LAYOUT_SURROUND,
+    AV_CHANNEL_LAYOUT_2_2,
+    AV_CHANNEL_LAYOUT_QUAD,
+    AV_CHANNEL_LAYOUT_4POINT0,
+    AV_CHANNEL_LAYOUT_5POINT0,
+    AV_CHANNEL_LAYOUT_5POINT0_BACK,
+    {
+        .nb_channels = 2,
+        .order       = AV_CHANNEL_ORDER_NATIVE,
+        .u.mask      = AV_CH_LAYOUT_MONO | AV_CH_LOW_FREQUENCY,
+    },
+    {
+        .nb_channels = 3,
+        .order       = AV_CHANNEL_ORDER_NATIVE,
+        .u.mask      = AV_CH_LAYOUT_STEREO | AV_CH_LOW_FREQUENCY,
+    },
+    {
+        .nb_channels = 4,
+        .order       = AV_CHANNEL_ORDER_NATIVE,
+        .u.mask      = AV_CH_LAYOUT_2_1 | AV_CH_LOW_FREQUENCY,
+    },
+    {
+        .nb_channels = 4,
+        .order       = AV_CHANNEL_ORDER_NATIVE,
+        .u.mask      = AV_CH_LAYOUT_SURROUND | AV_CH_LOW_FREQUENCY,
+    },
+    {
+        .nb_channels = 5,
+        .order       = AV_CHANNEL_ORDER_NATIVE,
+        .u.mask      = AV_CH_LAYOUT_4POINT0 | AV_CH_LOW_FREQUENCY,
+    },
+    AV_CHANNEL_LAYOUT_5POINT1,
+    AV_CHANNEL_LAYOUT_5POINT1_BACK,
+    { 0 },
+};
 
 /**
  * Table to remap channels from SMPTE order to AC-3 order.
@@ -1797,7 +1843,7 @@ static void dprint_options(AC3EncodeCont
     }
     ff_dlog(avctx, "bitstream_id: %s (%d)\n", strbuf, s->bitstream_id);
     ff_dlog(avctx, "sample_fmt: %s\n", av_get_sample_fmt_name(avctx->sample_fmt));
-    av_get_channel_layout_string(strbuf, 32, s->channels, avctx->channel_layout);
+    av_channel_layout_describe(&avctx->ch_layout, strbuf, sizeof(strbuf));
     ff_dlog(avctx, "channel_layout: %s\n", strbuf);
     ff_dlog(avctx, "sample_rate: %d\n", s->sample_rate);
     ff_dlog(avctx, "bit_rate: %d\n", s->bit_rate);
@@ -2041,11 +2087,11 @@ int ff_ac3_validate_metadata(AC3EncodeCo
 
     /* validate audio service type / channels combination */
     if ((avctx->audio_service_type == AV_AUDIO_SERVICE_TYPE_KARAOKE &&
-         avctx->channels == 1) ||
+         avctx->ch_layout.nb_channels == 1) ||
         ((avctx->audio_service_type == AV_AUDIO_SERVICE_TYPE_COMMENTARY ||
           avctx->audio_service_type == AV_AUDIO_SERVICE_TYPE_EMERGENCY  ||
           avctx->audio_service_type == AV_AUDIO_SERVICE_TYPE_VOICE_OVER)
-         && avctx->channels > 1)) {
+         && avctx->ch_layout.nb_channels > 1)) {
         av_log(avctx, AV_LOG_ERROR, "invalid audio service type for the "
                                     "specified number of channels\n");
         return AVERROR(EINVAL);
@@ -2167,27 +2213,29 @@ av_cold int ff_ac3_encode_close(AVCodecC
 /*
  * Set channel information during initialization.
  */
-static av_cold int set_channel_info(AC3EncodeContext *s, int channels,
-                                    uint64_t *channel_layout)
+static av_cold int set_channel_info(AVCodecContext *avctx)
 {
-    int ch_layout;
+    AC3EncodeContext *s = avctx->priv_data;
+    int channels = avctx->ch_layout.nb_channels;
+    uint64_t mask = avctx->ch_layout.u.mask;
 
     if (channels < 1 || channels > AC3_MAX_CHANNELS)
         return AVERROR(EINVAL);
-    if (*channel_layout > 0x7FF)
+    if (mask > 0x7FF)
         return AVERROR(EINVAL);
-    ch_layout = *channel_layout;
-    if (!ch_layout)
-        ch_layout = av_get_default_channel_layout(channels);
 
-    s->lfe_on       = !!(ch_layout & AV_CH_LOW_FREQUENCY);
+    if (!mask)
+        av_channel_layout_default(&avctx->ch_layout, channels);
+    mask = avctx->ch_layout.u.mask;
+
+    s->lfe_on       = !!(mask & AV_CH_LOW_FREQUENCY);
     s->channels     = channels;
     s->fbw_channels = channels - s->lfe_on;
     s->lfe_channel  = s->lfe_on ? s->fbw_channels + 1 : -1;
     if (s->lfe_on)
-        ch_layout -= AV_CH_LOW_FREQUENCY;
+        mask -= AV_CH_LOW_FREQUENCY;
 
-    switch (ch_layout) {
+    switch (mask) {
     case AV_CH_LAYOUT_MONO:           s->channel_mode = AC3_CHMODE_MONO;   break;
     case AV_CH_LAYOUT_STEREO:         s->channel_mode = AC3_CHMODE_STEREO; break;
     case AV_CH_LAYOUT_SURROUND:       s->channel_mode = AC3_CHMODE_3F;     break;
@@ -2204,9 +2252,9 @@ static av_cold int set_channel_info(AC3E
     s->has_surround =  s->channel_mode & 0x04;
 
     s->channel_map  = ac3_enc_channel_map[s->channel_mode][s->lfe_on];
-    *channel_layout = ch_layout;
     if (s->lfe_on)
-        *channel_layout |= AV_CH_LOW_FREQUENCY;
+        mask |= AV_CH_LOW_FREQUENCY;
+    av_channel_layout_from_mask(&avctx->ch_layout, mask);
 
     return 0;
 }
@@ -2218,12 +2266,12 @@ static av_cold int validate_options(AC3E
     int i, ret, max_sr;
 
     /* validate channel layout */
-    if (!avctx->channel_layout) {
+    if (!avctx->ch_layout.nb_channels) {
         av_log(avctx, AV_LOG_WARNING, "No channel layout specified. The "
                                       "encoder will guess the layout, but it "
                                       "might be incorrect.\n");
     }
-    ret = set_channel_info(s, avctx->channels, &avctx->channel_layout);
+    ret = set_channel_info(avctx);
     if (ret) {
         av_log(avctx, AV_LOG_ERROR, "invalid channel layout\n");
         return ret;
diff -pruN 7:5.0.1-3/libavcodec/ac3enc_fixed.c 7:5.1-1/libavcodec/ac3enc_fixed.c
--- 7:5.0.1-3/libavcodec/ac3enc_fixed.c	2022-01-14 18:45:39.000000000 +0000
+++ 7:5.1-1/libavcodec/ac3enc_fixed.c	2022-07-22 17:58:38.000000000 +0000
@@ -28,9 +28,9 @@
 
 #define AC3ENC_FLOAT 0
 #define FFT_FLOAT 0
-#include "internal.h"
 #include "audiodsp.h"
 #include "ac3enc.h"
+#include "codec_internal.h"
 #include "eac3enc.h"
 #include "kbdwin.h"
 
@@ -119,21 +119,26 @@ static av_cold int ac3_fixed_encode_init
 }
 
 
-const AVCodec ff_ac3_fixed_encoder = {
-    .name            = "ac3_fixed",
-    .long_name       = NULL_IF_CONFIG_SMALL("ATSC A/52A (AC-3)"),
-    .type            = AVMEDIA_TYPE_AUDIO,
-    .id              = AV_CODEC_ID_AC3,
-    .capabilities    = AV_CODEC_CAP_DR1,
+FF_DISABLE_DEPRECATION_WARNINGS
+const FFCodec ff_ac3_fixed_encoder = {
+    .p.name          = "ac3_fixed",
+    .p.long_name     = NULL_IF_CONFIG_SMALL("ATSC A/52A (AC-3)"),
+    .p.type          = AVMEDIA_TYPE_AUDIO,
+    .p.id            = AV_CODEC_ID_AC3,
+    .p.capabilities  = AV_CODEC_CAP_DR1,
     .priv_data_size  = sizeof(AC3EncodeContext),
     .init            = ac3_fixed_encode_init,
-    .encode2         = ff_ac3_fixed_encode_frame,
+    FF_CODEC_ENCODE_CB(ff_ac3_fixed_encode_frame),
     .close           = ff_ac3_encode_close,
-    .sample_fmts     = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S32P,
+    .p.sample_fmts   = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S32P,
                                                       AV_SAMPLE_FMT_NONE },
-    .priv_class      = &ff_ac3enc_class,
+    .p.priv_class    = &ff_ac3enc_class,
     .caps_internal   = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
-    .supported_samplerates = ff_ac3_sample_rate_tab,
-    .channel_layouts = ff_ac3_channel_layouts,
+    .p.supported_samplerates = ff_ac3_sample_rate_tab,
+#if FF_API_OLD_CHANNEL_LAYOUT
+    .p.channel_layouts = ff_ac3_channel_layouts,
+#endif
+    .p.ch_layouts    = ff_ac3_ch_layouts,
     .defaults        = ff_ac3_enc_defaults,
 };
+FF_ENABLE_DEPRECATION_WARNINGS
diff -pruN 7:5.0.1-3/libavcodec/ac3enc_float.c 7:5.1-1/libavcodec/ac3enc_float.c
--- 7:5.0.1-3/libavcodec/ac3enc_float.c	2022-01-14 18:45:39.000000000 +0000
+++ 7:5.1-1/libavcodec/ac3enc_float.c	2022-07-22 17:58:38.000000000 +0000
@@ -27,9 +27,9 @@
  */
 
 #define AC3ENC_FLOAT 1
-#include "internal.h"
 #include "audiodsp.h"
 #include "ac3enc.h"
+#include "codec_internal.h"
 #include "eac3enc.h"
 #include "kbdwin.h"
 
@@ -123,21 +123,26 @@ av_cold int ff_ac3_float_encode_init(AVC
     return ff_ac3_encode_init(avctx);
 }
 
-const AVCodec ff_ac3_encoder = {
-    .name            = "ac3",
-    .long_name       = NULL_IF_CONFIG_SMALL("ATSC A/52A (AC-3)"),
-    .type            = AVMEDIA_TYPE_AUDIO,
-    .id              = AV_CODEC_ID_AC3,
-    .capabilities    = AV_CODEC_CAP_DR1,
+FF_DISABLE_DEPRECATION_WARNINGS
+const FFCodec ff_ac3_encoder = {
+    .p.name          = "ac3",
+    .p.long_name     = NULL_IF_CONFIG_SMALL("ATSC A/52A (AC-3)"),
+    .p.type          = AVMEDIA_TYPE_AUDIO,
+    .p.id            = AV_CODEC_ID_AC3,
+    .p.capabilities  = AV_CODEC_CAP_DR1,
     .priv_data_size  = sizeof(AC3EncodeContext),
     .init            = ff_ac3_float_encode_init,
-    .encode2         = ff_ac3_float_encode_frame,
+    FF_CODEC_ENCODE_CB(ff_ac3_float_encode_frame),
     .close           = ff_ac3_encode_close,
-    .sample_fmts     = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_FLTP,
+    .p.sample_fmts   = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_FLTP,
                                                       AV_SAMPLE_FMT_NONE },
-    .priv_class      = &ff_ac3enc_class,
-    .supported_samplerates = ff_ac3_sample_rate_tab,
-    .channel_layouts = ff_ac3_channel_layouts,
+    .p.priv_class    = &ff_ac3enc_class,
+    .p.supported_samplerates = ff_ac3_sample_rate_tab,
+#if FF_API_OLD_CHANNEL_LAYOUT
+    .p.channel_layouts = ff_ac3_channel_layouts,
+#endif
+    .p.ch_layouts    = ff_ac3_ch_layouts,
     .defaults        = ff_ac3_enc_defaults,
     .caps_internal   = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
 };
+FF_ENABLE_DEPRECATION_WARNINGS
diff -pruN 7:5.0.1-3/libavcodec/ac3enc.h 7:5.1-1/libavcodec/ac3enc.h
--- 7:5.0.1-3/libavcodec/ac3enc.h	2022-01-14 18:45:39.000000000 +0000
+++ 7:5.1-1/libavcodec/ac3enc.h	2022-07-22 17:58:38.000000000 +0000
@@ -32,10 +32,11 @@
 
 #include "libavutil/opt.h"
 #include "ac3.h"
+#include "ac3defs.h"
 #include "ac3dsp.h"
 #include "avcodec.h"
+#include "codec_internal.h"
 #include "fft.h"
-#include "internal.h"
 #include "mathops.h"
 #include "me_cmp.h"
 #include "put_bits.h"
@@ -266,11 +267,13 @@ typedef struct AC3EncodeContext {
     void (*output_frame_header)(struct AC3EncodeContext *s);
 } AC3EncodeContext;
 
-
+#if FF_API_OLD_CHANNEL_LAYOUT
 extern const uint64_t ff_ac3_channel_layouts[19];
+#endif
+extern const AVChannelLayout ff_ac3_ch_layouts[19];
 extern const AVOption ff_ac3_enc_options[];
 extern const AVClass ff_ac3enc_class;
-extern const AVCodecDefault ff_ac3_enc_defaults[];
+extern const FFCodecDefault ff_ac3_enc_defaults[];
 
 int ff_ac3_encode_init(AVCodecContext *avctx);
 int ff_ac3_float_encode_init(AVCodecContext *avctx);
diff -pruN 7:5.0.1-3/libavcodec/ac3enc_template.c 7:5.1-1/libavcodec/ac3enc_template.c
--- 7:5.0.1-3/libavcodec/ac3enc_template.c	2021-10-24 20:47:07.000000000 +0000
+++ 7:5.1-1/libavcodec/ac3enc_template.c	2022-07-22 17:58:38.000000000 +0000
@@ -26,6 +26,8 @@
  * AC-3 encoder float/fixed template
  */
 
+#include "config_components.h"
+
 #include <stdint.h>
 
 #include "libavutil/attributes.h"
@@ -33,7 +35,6 @@
 #include "libavutil/mem_internal.h"
 
 #include "audiodsp.h"
-#include "internal.h"
 #include "ac3enc.h"
 #include "eac3enc.h"
 
diff -pruN 7:5.0.1-3/libavcodec/ac3.h 7:5.1-1/libavcodec/ac3.h
--- 7:5.0.1-3/libavcodec/ac3.h	2022-01-14 18:45:39.000000000 +0000
+++ 7:5.1-1/libavcodec/ac3.h	2022-07-22 17:58:38.000000000 +0000
@@ -30,28 +30,8 @@
 #include <math.h>
 #include <stdint.h>
 
-#define EAC3_MAX_CHANNELS 16          /**< maximum number of channels in EAC3 */
-#define AC3_MAX_CHANNELS 7            /**< maximum number of channels, including coupling channel */
-#define CPL_CH 0                      /**< coupling channel index */
-
-#define AC3_MAX_COEFS   256
-#define AC3_BLOCK_SIZE  256
-#define AC3_MAX_BLOCKS    6
-#define AC3_FRAME_SIZE (AC3_MAX_BLOCKS * 256)
-#define AC3_WINDOW_SIZE (AC3_BLOCK_SIZE * 2)
-#define AC3_CRITICAL_BANDS 50
-#define AC3_MAX_CPL_BANDS  18
-
 #include "ac3tab.h"
 
-/* exponent encoding strategy */
-#define EXP_REUSE 0
-#define EXP_NEW   1
-
-#define EXP_D15   1
-#define EXP_D25   2
-#define EXP_D45   3
-
 #ifndef USE_FIXED
 #define USE_FIXED 0
 #endif
@@ -78,6 +58,7 @@ typedef int                     INTFLOAT
 typedef int16_t                 SHORTFLOAT;
 
 #else /* USE_FIXED */
+#include "libavutil/libm.h"
 
 #define FIXR(x)                 ((float)(x))
 #define FIXR12(x)               ((float)(x))
@@ -111,58 +92,6 @@ typedef float                   SHORTFLO
 #define LEVEL_ZERO              0.0000000000000000
 #define LEVEL_ONE               1.0000000000000000
 
-/** Delta bit allocation strategy */
-typedef enum {
-    DBA_REUSE = 0,
-    DBA_NEW,
-    DBA_NONE,
-    DBA_RESERVED
-} AC3DeltaStrategy;
-
-/** Channel mode (audio coding mode) */
-typedef enum {
-    AC3_CHMODE_DUALMONO = 0,
-    AC3_CHMODE_MONO,
-    AC3_CHMODE_STEREO,
-    AC3_CHMODE_3F,
-    AC3_CHMODE_2F1R,
-    AC3_CHMODE_3F1R,
-    AC3_CHMODE_2F2R,
-    AC3_CHMODE_3F2R
-} AC3ChannelMode;
-
-/** Dolby Surround mode */
-typedef enum AC3DolbySurroundMode {
-    AC3_DSURMOD_NOTINDICATED = 0,
-    AC3_DSURMOD_OFF,
-    AC3_DSURMOD_ON,
-    AC3_DSURMOD_RESERVED
-} AC3DolbySurroundMode;
-
-/** Dolby Surround EX mode */
-typedef enum AC3DolbySurroundEXMode {
-    AC3_DSUREXMOD_NOTINDICATED = 0,
-    AC3_DSUREXMOD_OFF,
-    AC3_DSUREXMOD_ON,
-    AC3_DSUREXMOD_PLIIZ
-} AC3DolbySurroundEXMode;
-
-/** Dolby Headphone mode */
-typedef enum AC3DolbyHeadphoneMode {
-    AC3_DHEADPHONMOD_NOTINDICATED = 0,
-    AC3_DHEADPHONMOD_OFF,
-    AC3_DHEADPHONMOD_ON,
-    AC3_DHEADPHONMOD_RESERVED
-} AC3DolbyHeadphoneMode;
-
-/** Preferred Stereo Downmix mode */
-typedef enum AC3PreferredStereoDownmixMode {
-    AC3_DMIXMOD_NOTINDICATED = 0,
-    AC3_DMIXMOD_LTRT,
-    AC3_DMIXMOD_LORO,
-    AC3_DMIXMOD_DPLII // reserved value in A/52, but used by encoders to indicate DPL2
-} AC3PreferredStereoDownmixMode;
-
 typedef struct AC3BitAllocParameters {
     int sr_code;
     int sr_shift;
@@ -171,51 +100,6 @@ typedef struct AC3BitAllocParameters {
 } AC3BitAllocParameters;
 
 /**
- * @struct AC3HeaderInfo
- * Coded AC-3 header values up to the lfeon element, plus derived values.
- */
-typedef struct AC3HeaderInfo {
-    /** @name Coded elements
-     * @{
-     */
-    uint16_t sync_word;
-    uint16_t crc1;
-    uint8_t sr_code;
-    uint8_t bitstream_id;
-    uint8_t bitstream_mode;
-    uint8_t channel_mode;
-    uint8_t lfe_on;
-    uint8_t frame_type;
-    int substreamid;                        ///< substream identification
-    int center_mix_level;                   ///< Center mix level index
-    int surround_mix_level;                 ///< Surround mix level index
-    uint16_t channel_map;
-    int num_blocks;                         ///< number of audio blocks
-    int dolby_surround_mode;
-    /** @} */
-
-    /** @name Derived values
-     * @{
-     */
-    uint8_t sr_shift;
-    uint16_t sample_rate;
-    uint32_t bit_rate;
-    uint8_t channels;
-    uint16_t frame_size;
-    uint64_t channel_layout;
-    /** @} */
-} AC3HeaderInfo;
-
-typedef enum {
-    EAC3_FRAME_TYPE_INDEPENDENT = 0,
-    EAC3_FRAME_TYPE_DEPENDENT,
-    EAC3_FRAME_TYPE_AC3_CONVERT,
-    EAC3_FRAME_TYPE_RESERVED
-} EAC3FrameType;
-
-void ff_ac3_common_init(void);
-
-/**
  * Calculate the log power-spectral density of the input signal.
  * This gives a rough estimate of signal power in the frequency domain by using
  * the spectral envelope (exponents).  The psd is also separately grouped
diff -pruN 7:5.0.1-3/libavcodec/ac3_parser.c 7:5.1-1/libavcodec/ac3_parser.c
--- 7:5.0.1-3/libavcodec/ac3_parser.c	2022-01-14 18:45:39.000000000 +0000
+++ 7:5.1-1/libavcodec/ac3_parser.c	2022-07-22 17:58:38.000000000 +0000
@@ -21,9 +21,12 @@
  */
 
 #include "config.h"
+#include "config_components.h"
 
 #include "libavutil/channel_layout.h"
 #include "parser.h"
+#include "ac3defs.h"
+#include "ac3tab.h"
 #include "ac3_parser.h"
 #include "ac3_parser_internal.h"
 #include "aac_ac3_parser.h"
@@ -67,6 +70,7 @@ int ff_ac3_parse_header(GetBitContext *g
         return AAC_AC3_PARSE_ERROR_BSID;
 
     hdr->num_blocks = 6;
+    hdr->ac3_bit_rate_code = -1;
 
     /* set default mix levels */
     hdr->center_mix_level   = 5;  // -4.5dB
@@ -86,6 +90,8 @@ int ff_ac3_parse_header(GetBitContext *g
         if(frame_size_code > 37)
             return AAC_AC3_PARSE_ERROR_FRAME_SIZE;
 
+        hdr->ac3_bit_rate_code = (frame_size_code >> 1);
+
         skip_bits(gbc, 5); // skip bsid, already got it
 
         hdr->bitstream_mode = get_bits(gbc, 3);
@@ -103,7 +109,7 @@ int ff_ac3_parse_header(GetBitContext *g
 
         hdr->sr_shift = FFMAX(hdr->bitstream_id, 8) - 8;
         hdr->sample_rate = ff_ac3_sample_rate_tab[hdr->sr_code] >> hdr->sr_shift;
-        hdr->bit_rate = (ff_ac3_bitrate_tab[frame_size_code>>1] * 1000) >> hdr->sr_shift;
+        hdr->bit_rate = (ff_ac3_bitrate_tab[hdr->ac3_bit_rate_code] * 1000) >> hdr->sr_shift;
         hdr->channels = ff_ac3_channels_tab[hdr->channel_mode] + hdr->lfe_on;
         hdr->frame_size = ff_ac3_frame_size_tab[frame_size_code][hdr->sr_code] * 2;
         hdr->frame_type = EAC3_FRAME_TYPE_AC3_CONVERT; //EAC3_FRAME_TYPE_INDEPENDENT;
diff -pruN 7:5.0.1-3/libavcodec/ac3_parser_internal.h 7:5.1-1/libavcodec/ac3_parser_internal.h
--- 7:5.0.1-3/libavcodec/ac3_parser_internal.h	2021-10-21 17:06:35.000000000 +0000
+++ 7:5.1-1/libavcodec/ac3_parser_internal.h	2022-07-22 17:58:38.000000000 +0000
@@ -21,10 +21,50 @@
 #ifndef AVCODEC_AC3_PARSER_INTERNAL_H
 #define AVCODEC_AC3_PARSER_INTERNAL_H
 
-#include "ac3.h"
+#include <stddef.h>
+#include <stdint.h>
+
+#include "ac3defs.h"
 #include "get_bits.h"
 
 /**
+ * @struct AC3HeaderInfo
+ * Coded AC-3 header values up to the lfeon element, plus derived values.
+ */
+typedef struct AC3HeaderInfo {
+    /** @name Coded elements
+     * @{
+     */
+    uint16_t sync_word;
+    uint16_t crc1;
+    uint8_t sr_code;
+    uint8_t bitstream_id;
+    uint8_t bitstream_mode;
+    uint8_t channel_mode;
+    uint8_t lfe_on;
+    uint8_t frame_type;
+    int substreamid;                        ///< substream identification
+    int center_mix_level;                   ///< Center mix level index
+    int surround_mix_level;                 ///< Surround mix level index
+    uint16_t channel_map;
+    int num_blocks;                         ///< number of audio blocks
+    int dolby_surround_mode;
+    /** @} */
+
+    /** @name Derived values
+     * @{
+     */
+    uint8_t sr_shift;
+    uint16_t sample_rate;
+    uint32_t bit_rate;
+    uint8_t channels;
+    uint16_t frame_size;
+    uint64_t channel_layout;
+    int8_t ac3_bit_rate_code;
+    /** @} */
+} AC3HeaderInfo;
+
+/**
  * Parse AC-3 frame header.
  * Parse the header up to the lfeon element, which is the first 52 or 54 bits
  * depending on the audio coding mode.
diff -pruN 7:5.0.1-3/libavcodec/ac3tab.c 7:5.1-1/libavcodec/ac3tab.c
--- 7:5.0.1-3/libavcodec/ac3tab.c	2022-01-14 18:45:39.000000000 +0000
+++ 7:5.1-1/libavcodec/ac3tab.c	2022-07-22 17:58:38.000000000 +0000
@@ -26,7 +26,6 @@
 
 #include "libavutil/channel_layout.h"
 
-#include "ac3.h"
 #include "ac3tab.h"
 
 /**
@@ -114,88 +113,6 @@ const uint8_t ff_eac3_default_cpl_band_s
     0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1
 };
 
-const uint8_t ff_ac3_log_add_tab[260]= {
-0x40,0x3f,0x3e,0x3d,0x3c,0x3b,0x3a,0x39,0x38,0x37,
-0x36,0x35,0x34,0x34,0x33,0x32,0x31,0x30,0x2f,0x2f,
-0x2e,0x2d,0x2c,0x2c,0x2b,0x2a,0x29,0x29,0x28,0x27,
-0x26,0x26,0x25,0x24,0x24,0x23,0x23,0x22,0x21,0x21,
-0x20,0x20,0x1f,0x1e,0x1e,0x1d,0x1d,0x1c,0x1c,0x1b,
-0x1b,0x1a,0x1a,0x19,0x19,0x18,0x18,0x17,0x17,0x16,
-0x16,0x15,0x15,0x15,0x14,0x14,0x13,0x13,0x13,0x12,
-0x12,0x12,0x11,0x11,0x11,0x10,0x10,0x10,0x0f,0x0f,
-0x0f,0x0e,0x0e,0x0e,0x0d,0x0d,0x0d,0x0d,0x0c,0x0c,
-0x0c,0x0c,0x0b,0x0b,0x0b,0x0b,0x0a,0x0a,0x0a,0x0a,
-0x0a,0x09,0x09,0x09,0x09,0x09,0x08,0x08,0x08,0x08,
-0x08,0x08,0x07,0x07,0x07,0x07,0x07,0x07,0x06,0x06,
-0x06,0x06,0x06,0x06,0x06,0x06,0x05,0x05,0x05,0x05,
-0x05,0x05,0x05,0x05,0x04,0x04,0x04,0x04,0x04,0x04,
-0x04,0x04,0x04,0x04,0x04,0x03,0x03,0x03,0x03,0x03,
-0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x02,
-0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,
-0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x01,0x01,
-0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
-0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
-0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-};
-
-const uint16_t ff_ac3_hearing_threshold_tab[AC3_CRITICAL_BANDS][3]= {
-{ 0x04d0,0x04f0,0x0580 },
-{ 0x04d0,0x04f0,0x0580 },
-{ 0x0440,0x0460,0x04b0 },
-{ 0x0400,0x0410,0x0450 },
-{ 0x03e0,0x03e0,0x0420 },
-{ 0x03c0,0x03d0,0x03f0 },
-{ 0x03b0,0x03c0,0x03e0 },
-{ 0x03b0,0x03b0,0x03d0 },
-{ 0x03a0,0x03b0,0x03c0 },
-{ 0x03a0,0x03a0,0x03b0 },
-{ 0x03a0,0x03a0,0x03b0 },
-{ 0x03a0,0x03a0,0x03b0 },
-{ 0x03a0,0x03a0,0x03a0 },
-{ 0x0390,0x03a0,0x03a0 },
-{ 0x0390,0x0390,0x03a0 },
-{ 0x0390,0x0390,0x03a0 },
-{ 0x0380,0x0390,0x03a0 },
-{ 0x0380,0x0380,0x03a0 },
-{ 0x0370,0x0380,0x03a0 },
-{ 0x0370,0x0380,0x03a0 },
-{ 0x0360,0x0370,0x0390 },
-{ 0x0360,0x0370,0x0390 },
-{ 0x0350,0x0360,0x0390 },
-{ 0x0350,0x0360,0x0390 },
-{ 0x0340,0x0350,0x0380 },
-{ 0x0340,0x0350,0x0380 },
-{ 0x0330,0x0340,0x0380 },
-{ 0x0320,0x0340,0x0370 },
-{ 0x0310,0x0320,0x0360 },
-{ 0x0300,0x0310,0x0350 },
-{ 0x02f0,0x0300,0x0340 },
-{ 0x02f0,0x02f0,0x0330 },
-{ 0x02f0,0x02f0,0x0320 },
-{ 0x02f0,0x02f0,0x0310 },
-{ 0x0300,0x02f0,0x0300 },
-{ 0x0310,0x0300,0x02f0 },
-{ 0x0340,0x0320,0x02f0 },
-{ 0x0390,0x0350,0x02f0 },
-{ 0x03e0,0x0390,0x0300 },
-{ 0x0420,0x03e0,0x0310 },
-{ 0x0460,0x0420,0x0330 },
-{ 0x0490,0x0450,0x0350 },
-{ 0x04a0,0x04a0,0x03c0 },
-{ 0x0460,0x0490,0x0410 },
-{ 0x0440,0x0460,0x0470 },
-{ 0x0440,0x0440,0x04a0 },
-{ 0x0520,0x0480,0x0460 },
-{ 0x0800,0x0630,0x0440 },
-{ 0x0840,0x0840,0x0450 },
-{ 0x0840,0x0840,0x04e0 },
-};
-
 const uint8_t ff_ac3_bap_tab[64]= {
     0, 1, 1, 1, 1, 1, 2, 2, 3, 3,
     3, 4, 4, 5, 5, 6, 6, 6, 6, 7,
diff -pruN 7:5.0.1-3/libavcodec/ac3tab.h 7:5.1-1/libavcodec/ac3tab.h
--- 7:5.0.1-3/libavcodec/ac3tab.h	2022-01-14 18:45:39.000000000 +0000
+++ 7:5.1-1/libavcodec/ac3tab.h	2022-07-22 17:58:38.000000000 +0000
@@ -24,7 +24,7 @@
 
 #include <stdint.h>
 
-#include "ac3.h"
+#include "ac3defs.h"
 
 extern const uint16_t ff_ac3_frame_size_tab[38][3];
 extern const uint8_t  ff_ac3_channels_tab[8];
@@ -34,8 +34,6 @@ extern const int      ff_ac3_sample_rate
 extern const uint16_t ff_ac3_bitrate_tab[19];
 extern const uint8_t  ff_ac3_rematrix_band_tab[5];
 extern const uint8_t  ff_eac3_default_cpl_band_struct[18];
-extern const uint8_t  ff_ac3_log_add_tab[260];
-extern const uint16_t ff_ac3_hearing_threshold_tab[AC3_CRITICAL_BANDS][3];
 extern const uint8_t  ff_ac3_bap_tab[64];
 extern const uint8_t  ff_ac3_slow_decay_tab[4];
 extern const uint8_t  ff_ac3_fast_decay_tab[4];
diff -pruN 7:5.0.1-3/libavcodec/acelp_filters.c 7:5.1-1/libavcodec/acelp_filters.c
--- 7:5.0.1-3/libavcodec/acelp_filters.c	2022-01-14 18:45:39.000000000 +0000
+++ 7:5.1-1/libavcodec/acelp_filters.c	2022-07-22 17:58:38.000000000 +0000
@@ -152,6 +152,7 @@ void ff_acelp_filter_init(ACELPFContext
     c->acelp_interpolatef                      = ff_acelp_interpolatef;
     c->acelp_apply_order_2_transfer_function   = ff_acelp_apply_order_2_transfer_function;
 
-    if(HAVE_MIPSFPU)
-        ff_acelp_filter_init_mips(c);
+#if HAVE_MIPSFPU
+    ff_acelp_filter_init_mips(c);
+#endif
 }
diff -pruN 7:5.0.1-3/libavcodec/acelp_vectors.c 7:5.1-1/libavcodec/acelp_vectors.c
--- 7:5.0.1-3/libavcodec/acelp_vectors.c	2022-01-14 18:45:39.000000000 +0000
+++ 7:5.1-1/libavcodec/acelp_vectors.c	2022-07-22 17:58:38.000000000 +0000
@@ -259,6 +259,7 @@ void ff_acelp_vectors_init(ACELPVContext
 {
     c->weighted_vector_sumf   = ff_weighted_vector_sumf;
 
-    if(HAVE_MIPSFPU)
-        ff_acelp_vectors_init_mips(c);
+#if HAVE_MIPSFPU
+    ff_acelp_vectors_init_mips(c);
+#endif
 }
diff -pruN 7:5.0.1-3/libavcodec/adpcm.c 7:5.1-1/libavcodec/adpcm.c
--- 7:5.0.1-3/libavcodec/adpcm.c	2022-01-14 18:45:39.000000000 +0000
+++ 7:5.1-1/libavcodec/adpcm.c	2022-07-22 17:58:38.000000000 +0000
@@ -34,11 +34,15 @@
  * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
+
+#include "config_components.h"
+
 #include "avcodec.h"
 #include "get_bits.h"
 #include "bytestream.h"
 #include "adpcm.h"
 #include "adpcm_data.h"
+#include "codec_internal.h"
 #include "internal.h"
 
 /**
@@ -271,14 +275,15 @@ static av_cold int adpcm_decode_init(AVC
     case AV_CODEC_ID_ADPCM_MTAF:
         min_channels = 2;
         max_channels = 8;
-        if (avctx->channels & 1) {
-            avpriv_request_sample(avctx, "channel count %d", avctx->channels);
+        if (avctx->ch_layout.nb_channels & 1) {
+            avpriv_request_sample(avctx, "channel count %d", avctx->ch_layout.nb_channels);
             return AVERROR_PATCHWELCOME;
         }
         break;
     case AV_CODEC_ID_ADPCM_PSX:
         max_channels = 8;
-        if (avctx->channels <= 0 || avctx->block_align % (16 * avctx->channels))
+        if (avctx->ch_layout.nb_channels <= 0 ||
+            avctx->block_align % (16 * avctx->ch_layout.nb_channels))
             return AVERROR_INVALIDDATA;
         break;
     case AV_CODEC_ID_ADPCM_IMA_DAT4:
@@ -287,7 +292,8 @@ static av_cold int adpcm_decode_init(AVC
         max_channels = 14;
         break;
     }
-    if (avctx->channels < min_channels || avctx->channels > max_channels) {
+    if (avctx->ch_layout.nb_channels < min_channels ||
+        avctx->ch_layout.nb_channels > max_channels) {
         av_log(avctx, AV_LOG_ERROR, "Invalid number of channels\n");
         return AVERROR(EINVAL);
     }
@@ -298,7 +304,8 @@ static av_cold int adpcm_decode_init(AVC
             return AVERROR_INVALIDDATA;
         break;
     case AV_CODEC_ID_ADPCM_ARGO:
-        if (avctx->bits_per_coded_sample != 4 || avctx->block_align != 17 * avctx->channels)
+        if (avctx->bits_per_coded_sample != 4 ||
+            avctx->block_align != 17 * avctx->ch_layout.nb_channels)
             return AVERROR_INVALIDDATA;
         break;
     case AV_CODEC_ID_ADPCM_ZORK:
@@ -336,7 +343,7 @@ static av_cold int adpcm_decode_init(AVC
                                                   AV_SAMPLE_FMT_S16;
         break;
     case AV_CODEC_ID_ADPCM_MS:
-        avctx->sample_fmt = avctx->channels > 2 ? AV_SAMPLE_FMT_S16P :
+        avctx->sample_fmt = avctx->ch_layout.nb_channels > 2 ? AV_SAMPLE_FMT_S16P :
                                                   AV_SAMPLE_FMT_S16;
         break;
     default:
@@ -755,6 +762,7 @@ static void adpcm_swf_decode(AVCodecCont
     ADPCMDecodeContext *c = avctx->priv_data;
     GetBitContext gb;
     const int8_t *table;
+    int channels = avctx->ch_layout.nb_channels;
     int k0, signmask, nb_bits, count;
     int size = buf_size*8;
     int i;
@@ -767,16 +775,16 @@ static void adpcm_swf_decode(AVCodecCont
     k0 = 1 << (nb_bits-2);
     signmask = 1 << (nb_bits-1);
 
-    while (get_bits_count(&gb) <= size - 22*avctx->channels) {
-        for (i = 0; i < avctx->channels; i++) {
+    while (get_bits_count(&gb) <= size - 22 * channels) {
+        for (i = 0; i < channels; i++) {
             *samples++ = c->status[i].predictor = get_sbits(&gb, 16);
             c->status[i].step_index = get_bits(&gb, 6);
         }
 
-        for (count = 0; get_bits_count(&gb) <= size - nb_bits*avctx->channels && count < 4095; count++) {
+        for (count = 0; get_bits_count(&gb) <= size - nb_bits * channels && count < 4095; count++) {
             int i;
 
-            for (i = 0; i < avctx->channels; i++) {
+            for (i = 0; i < channels; i++) {
                 // similar to IMA adpcm
                 int delta = get_bits(&gb, nb_bits);
                 int step = ff_adpcm_step_table[c->status[i].step_index];
@@ -840,7 +848,7 @@ static int get_nb_samples(AVCodecContext
 {
     ADPCMDecodeContext *s = avctx->priv_data;
     int nb_samples        = 0;
-    int ch                = avctx->channels;
+    int ch                = avctx->ch_layout.nb_channels;
     int has_coded_samples = 0;
     int header_size;
 
@@ -1054,13 +1062,13 @@ static int get_nb_samples(AVCodecContext
     return nb_samples;
 }
 
-static int adpcm_decode_frame(AVCodecContext *avctx, void *data,
+static int adpcm_decode_frame(AVCodecContext *avctx, AVFrame *frame,
                               int *got_frame_ptr, AVPacket *avpkt)
 {
-    AVFrame *frame     = data;
     const uint8_t *buf = avpkt->data;
     int buf_size = avpkt->size;
     ADPCMDecodeContext *c = avctx->priv_data;
+    int channels = avctx->ch_layout.nb_channels;
     int16_t *samples;
     int16_t **samples_p;
     int st; /* stereo */
@@ -1089,13 +1097,13 @@ static int adpcm_decode_frame(AVCodecCon
         frame->nb_samples = nb_samples = coded_samples;
     }
 
-    st = avctx->channels == 2 ? 1 : 0;
+    st = channels == 2 ? 1 : 0;
 
     switch(avctx->codec->id) {
     CASE(ADPCM_IMA_QT,
         /* In QuickTime, IMA is encoded by chunks of 34 bytes (=64 samples).
            Channel data is interleaved per-chunk. */
-        for (int channel = 0; channel < avctx->channels; channel++) {
+        for (int channel = 0; channel < channels; channel++) {
             ADPCMChannelStatus *cs = &c->status[channel];
             int predictor;
             int step_index;
@@ -1134,7 +1142,7 @@ static int adpcm_decode_frame(AVCodecCon
         }
         ) /* End of CASE */
     CASE(ADPCM_IMA_WAV,
-        for (int i = 0; i < avctx->channels; i++) {
+        for (int i = 0; i < channels; i++) {
             ADPCMChannelStatus *cs = &c->status[i];
             cs->predictor = samples_p[i][0] = sign_extend(bytestream2_get_le16u(&gb), 16);
 
@@ -1153,12 +1161,12 @@ static int adpcm_decode_frame(AVCodecCon
             GetBitContext g;
 
             for (int n = 0; n < (nb_samples - 1) / samples_per_block; n++) {
-                for (int i = 0; i < avctx->channels; i++) {
+                for (int i = 0; i < channels; i++) {
                     ADPCMChannelStatus *cs = &c->status[i];
                     samples = &samples_p[i][1 + n * samples_per_block];
                     for (int j = 0; j < block_size; j++) {
-                        temp[j] = buf[4 * avctx->channels + block_size * n * avctx->channels +
-                                        (j % 4) + (j / 4) * (avctx->channels * 4) + i * 4];
+                        temp[j] = buf[4 * channels + block_size * n * channels +
+                                        (j % 4) + (j / 4) * (channels * 4) + i * 4];
                     }
                     ret = init_get_bits8(&g, (const uint8_t *)&temp, block_size);
                     if (ret < 0)
@@ -1169,10 +1177,10 @@ static int adpcm_decode_frame(AVCodecCon
                     }
                 }
             }
-            bytestream2_skip(&gb, avctx->block_align - avctx->channels * 4);
+            bytestream2_skip(&gb, avctx->block_align - channels * 4);
         } else {
             for (int n = 0; n < (nb_samples - 1) / 8; n++) {
-                for (int i = 0; i < avctx->channels; i++) {
+                for (int i = 0; i < channels; i++) {
                     ADPCMChannelStatus *cs = &c->status[i];
                     samples = &samples_p[i][1 + n * 8];
                     for (int m = 0; m < 8; m += 2) {
@@ -1185,10 +1193,10 @@ static int adpcm_decode_frame(AVCodecCon
         }
         ) /* End of CASE */
     CASE(ADPCM_4XM,
-        for (int i = 0; i < avctx->channels; i++)
+        for (int i = 0; i < channels; i++)
             c->status[i].predictor = sign_extend(bytestream2_get_le16u(&gb), 16);
 
-        for (int i = 0; i < avctx->channels; i++) {
+        for (int i = 0; i < channels; i++) {
             c->status[i].step_index = sign_extend(bytestream2_get_le16u(&gb), 16);
             if (c->status[i].step_index > 88u) {
                 av_log(avctx, AV_LOG_ERROR, "ERROR: step_index[%d] = %i\n",
@@ -1197,7 +1205,7 @@ static int adpcm_decode_frame(AVCodecCon
             }
         }
 
-        for (int i = 0; i < avctx->channels; i++) {
+        for (int i = 0; i < channels; i++) {
             ADPCMChannelStatus *cs = &c->status[i];
             samples = (int16_t *)frame->data[i];
             for (int n = nb_samples >> 1; n > 0; n--) {
@@ -1208,9 +1216,9 @@ static int adpcm_decode_frame(AVCodecCon
         }
         ) /* End of CASE */
     CASE(ADPCM_AGM,
-        for (int i = 0; i < avctx->channels; i++)
+        for (int i = 0; i < channels; i++)
             c->status[i].predictor = sign_extend(bytestream2_get_le16u(&gb), 16);
-        for (int i = 0; i < avctx->channels; i++)
+        for (int i = 0; i < channels; i++)
             c->status[i].step = sign_extend(bytestream2_get_le16u(&gb), 16);
 
         for (int n = 0; n < nb_samples >> (1 - st); n++) {
@@ -1222,8 +1230,8 @@ static int adpcm_decode_frame(AVCodecCon
     CASE(ADPCM_MS,
         int block_predictor;
 
-        if (avctx->channels > 2) {
-            for (int channel = 0; channel < avctx->channels; channel++) {
+        if (avctx->ch_layout.nb_channels > 2) {
+            for (int channel = 0; channel < avctx->ch_layout.nb_channels; channel++) {
                 samples = samples_p[channel];
                 block_predictor = bytestream2_get_byteu(&gb);
                 if (block_predictor > 6) {
@@ -1285,7 +1293,7 @@ static int adpcm_decode_frame(AVCodecCon
         }
         ) /* End of CASE */
     CASE(ADPCM_MTAF,
-        for (int channel = 0; channel < avctx->channels; channel += 2) {
+        for (int channel = 0; channel < channels; channel += 2) {
             bytestream2_skipu(&gb, 4);
             c->status[channel    ].step      = bytestream2_get_le16u(&gb) & 0x1f;
             c->status[channel + 1].step      = bytestream2_get_le16u(&gb) & 0x1f;
@@ -1306,7 +1314,7 @@ static int adpcm_decode_frame(AVCodecCon
         }
         ) /* End of CASE */
     CASE(ADPCM_IMA_DK4,
-        for (int channel = 0; channel < avctx->channels; channel++) {
+        for (int channel = 0; channel < channels; channel++) {
             ADPCMChannelStatus *cs = &c->status[channel];
             cs->predictor  = *samples++ = sign_extend(bytestream2_get_le16u(&gb), 16);
             cs->step_index = sign_extend(bytestream2_get_le16u(&gb), 16);
@@ -1338,7 +1346,7 @@ static int adpcm_decode_frame(AVCodecCon
         int nibble;
         int decode_top_nibble_next = 0;
         int diff_channel;
-        const int16_t *samples_end = samples + avctx->channels * nb_samples;
+        const int16_t *samples_end = samples + channels * nb_samples;
 
         bytestream2_skipu(&gb, 10);
         c->status[0].predictor  = sign_extend(bytestream2_get_le16u(&gb), 16);
@@ -1385,7 +1393,7 @@ static int adpcm_decode_frame(AVCodecCon
             bytestream2_skip(&gb, 1);
         ) /* End of CASE */
     CASE(ADPCM_IMA_ISS,
-        for (int channel = 0; channel < avctx->channels; channel++) {
+        for (int channel = 0; channel < channels; channel++) {
             ADPCMChannelStatus *cs = &c->status[channel];
             cs->predictor  = sign_extend(bytestream2_get_le16u(&gb), 16);
             cs->step_index = sign_extend(bytestream2_get_le16u(&gb), 16);
@@ -1412,7 +1420,7 @@ static int adpcm_decode_frame(AVCodecCon
         }
         ) /* End of CASE */
     CASE(ADPCM_IMA_MOFLEX,
-        for (int channel = 0; channel < avctx->channels; channel++) {
+        for (int channel = 0; channel < channels; channel++) {
             ADPCMChannelStatus *cs = &c->status[channel];
             cs->step_index = sign_extend(bytestream2_get_le16u(&gb), 16);
             cs->predictor  = sign_extend(bytestream2_get_le16u(&gb), 16);
@@ -1424,7 +1432,7 @@ static int adpcm_decode_frame(AVCodecCon
         }
 
         for (int subframe = 0; subframe < nb_samples / 256; subframe++) {
-            for (int channel = 0; channel < avctx->channels; channel++) {
+            for (int channel = 0; channel < channels; channel++) {
                 samples = samples_p[channel] + 256 * subframe;
                 for (int n = 0; n < 256; n += 2) {
                     int v = bytestream2_get_byteu(&gb);
@@ -1435,7 +1443,7 @@ static int adpcm_decode_frame(AVCodecCon
         }
         ) /* End of CASE */
     CASE(ADPCM_IMA_DAT4,
-        for (int channel = 0; channel < avctx->channels; channel++) {
+        for (int channel = 0; channel < channels; channel++) {
             ADPCMChannelStatus *cs = &c->status[channel];
             samples = samples_p[channel];
             bytestream2_skip(&gb, 4);
@@ -1462,26 +1470,26 @@ static int adpcm_decode_frame(AVCodecCon
         ) /* End of CASE */
     CASE(ADPCM_IMA_APM,
         for (int n = nb_samples / 2; n > 0; n--) {
-            for (int channel = 0; channel < avctx->channels; channel++) {
+            for (int channel = 0; channel < channels; channel++) {
                 int v = bytestream2_get_byteu(&gb);
                 *samples++  = adpcm_ima_qt_expand_nibble(&c->status[channel], v >> 4  );
                 samples[st] = adpcm_ima_qt_expand_nibble(&c->status[channel], v & 0x0F);
             }
-            samples += avctx->channels;
+            samples += channels;
         }
         ) /* End of CASE */
     CASE(ADPCM_IMA_ALP,
         for (int n = nb_samples / 2; n > 0; n--) {
-            for (int channel = 0; channel < avctx->channels; channel++) {
+            for (int channel = 0; channel < channels; channel++) {
                 int v = bytestream2_get_byteu(&gb);
                 *samples++  = adpcm_ima_alp_expand_nibble(&c->status[channel], v >> 4  , 2);
                 samples[st] = adpcm_ima_alp_expand_nibble(&c->status[channel], v & 0x0F, 2);
             }
-            samples += avctx->channels;
+            samples += channels;
         }
         ) /* End of CASE */
     CASE(ADPCM_IMA_CUNNING,
-        for (int channel = 0; channel < avctx->channels; channel++) {
+        for (int channel = 0; channel < channels; channel++) {
             int16_t *smp = samples_p[channel];
             for (int n = 0; n < nb_samples / 2; n++) {
                 int v = bytestream2_get_byteu(&gb);
@@ -1498,7 +1506,7 @@ static int adpcm_decode_frame(AVCodecCon
         }
         ) /* End of CASE */
     CASE(ADPCM_IMA_RAD,
-        for (int channel = 0; channel < avctx->channels; channel++) {
+        for (int channel = 0; channel < channels; channel++) {
             ADPCMChannelStatus *cs = &c->status[channel];
             cs->step_index = sign_extend(bytestream2_get_le16u(&gb), 16);
             cs->predictor  = sign_extend(bytestream2_get_le16u(&gb), 16);
@@ -1514,17 +1522,17 @@ static int adpcm_decode_frame(AVCodecCon
             byte[0] = bytestream2_get_byteu(&gb);
             if (st)
                 byte[1] = bytestream2_get_byteu(&gb);
-            for (int channel = 0; channel < avctx->channels; channel++) {
+            for (int channel = 0; channel < channels; channel++) {
                 *samples++ = adpcm_ima_expand_nibble(&c->status[channel], byte[channel] & 0x0F, 3);
             }
-            for (int channel = 0; channel < avctx->channels; channel++) {
+            for (int channel = 0; channel < channels; channel++) {
                 *samples++ = adpcm_ima_expand_nibble(&c->status[channel], byte[channel] >> 4  , 3);
             }
         }
         ) /* End of CASE */
     CASE(ADPCM_IMA_WS,
         if (c->vqa_version == 3) {
-            for (int channel = 0; channel < avctx->channels; channel++) {
+            for (int channel = 0; channel < channels; channel++) {
                 int16_t *smp = samples_p[channel];
 
                 for (int n = nb_samples / 2; n > 0; n--) {
@@ -1535,12 +1543,12 @@ static int adpcm_decode_frame(AVCodecCon
             }
         } else {
             for (int n = nb_samples / 2; n > 0; n--) {
-                for (int channel = 0; channel < avctx->channels; channel++) {
+                for (int channel = 0; channel < channels; channel++) {
                     int v = bytestream2_get_byteu(&gb);
                     *samples++  = adpcm_ima_expand_nibble(&c->status[channel], v & 0x0F, 3);
                     samples[st] = adpcm_ima_expand_nibble(&c->status[channel], v >> 4  , 3);
                 }
-                samples += avctx->channels;
+                samples += channels;
             }
         }
         bytestream2_seek(&gb, 0, SEEK_END);
@@ -1548,13 +1556,13 @@ static int adpcm_decode_frame(AVCodecCon
     CASE(ADPCM_XA,
         int16_t *out0 = samples_p[0];
         int16_t *out1 = samples_p[1];
-        int samples_per_block = 28 * (3 - avctx->channels) * 4;
+        int samples_per_block = 28 * (3 - channels) * 4;
         int sample_offset = 0;
         int bytes_remaining;
         while (bytestream2_get_bytes_left(&gb) >= 128) {
             if ((ret = xa_decode(avctx, out0, out1, buf + bytestream2_tell(&gb),
                                  &c->status[0], &c->status[1],
-                                 avctx->channels, sample_offset)) < 0)
+                                 channels, sample_offset)) < 0)
                 return ret;
             bytestream2_skipu(&gb, 128);
             sample_offset += samples_per_block;
@@ -1604,7 +1612,7 @@ static int adpcm_decode_frame(AVCodecCon
         /* Each EA ADPCM frame has a 12-byte header followed by 30-byte pieces,
            each coding 28 stereo samples. */
 
-        if(avctx->channels != 2)
+        if (channels != 2)
             return AVERROR_INVALIDDATA;
 
         current_left_sample   = sign_extend(bytestream2_get_le16u(&gb), 16);
@@ -1649,7 +1657,7 @@ static int adpcm_decode_frame(AVCodecCon
     CASE(ADPCM_EA_MAXIS_XA,
         int coeff[2][2], shift[2];
 
-        for (int channel = 0; channel < avctx->channels; channel++) {
+        for (int channel = 0; channel < channels; channel++) {
             int byte = bytestream2_get_byteu(&gb);
             for (int i = 0; i < 2; i++)
                 coeff[channel][i] = ea_adpcm_table[(byte >> 4) + 4*i];
@@ -1661,7 +1669,7 @@ static int adpcm_decode_frame(AVCodecCon
             byte[0] = bytestream2_get_byteu(&gb);
             if (st) byte[1] = bytestream2_get_byteu(&gb);
             for (int i = 4; i >= 0; i-=4) { /* Pairwise samples LL RR (st) or LL LL (mono) */
-                for (int channel = 0; channel < avctx->channels; channel++) {
+                for (int channel = 0; channel < channels; channel++) {
                     int sample = sign_extend(byte[channel] >> i, 4) * (1 << shift[channel]);
                     sample = (sample +
                              c->status[channel].sample1 * coeff[channel][0] +
@@ -1690,12 +1698,12 @@ static int adpcm_decode_frame(AVCodecCon
         int count = 0;
         int offsets[6];
 
-        for (unsigned channel = 0; channel < avctx->channels; channel++)
+        for (unsigned channel = 0; channel < channels; channel++)
             offsets[channel] = (big_endian ? bytestream2_get_be32(&gb) :
                                              bytestream2_get_le32(&gb)) +
-                               (avctx->channels + 1) * 4;
+                               (channels + 1) * 4;
 
-        for (unsigned channel = 0; channel < avctx->channels; channel++) {
+        for (unsigned channel = 0; channel < channels; channel++) {
             int count1;
 
             bytestream2_seek(&gb, offsets[channel], SEEK_SET);
@@ -1759,7 +1767,7 @@ static int adpcm_decode_frame(AVCodecCon
     }
 #endif /* CONFIG_ADPCM_EA_Rx_DECODER */
     CASE(ADPCM_EA_XAS,
-        for (int channel=0; channel < avctx->channels; channel++) {
+        for (int channel=0; channel < channels; channel++) {
             int coeff[2][4], shift[4];
             int16_t *s = samples_p[channel];
             for (int n = 0; n < 4; n++, s += 32) {
@@ -1791,7 +1799,7 @@ static int adpcm_decode_frame(AVCodecCon
         }
         ) /* End of CASE */
     CASE(ADPCM_IMA_ACORN,
-        for (int channel = 0; channel < avctx->channels; channel++) {
+        for (int channel = 0; channel < channels; channel++) {
             ADPCMChannelStatus *cs = &c->status[channel];
             cs->predictor  = sign_extend(bytestream2_get_le16u(&gb), 16);
             cs->step_index = bytestream2_get_le16u(&gb) & 0xFF;
@@ -1808,7 +1816,7 @@ static int adpcm_decode_frame(AVCodecCon
         }
         ) /* End of CASE */
     CASE(ADPCM_IMA_AMV,
-        av_assert0(avctx->channels == 1);
+        av_assert0(channels == 1);
 
         /*
          * Header format:
@@ -1848,7 +1856,7 @@ static int adpcm_decode_frame(AVCodecCon
         }
         ) /* End of CASE */
     CASE(ADPCM_IMA_SMJPEG,
-        for (int i = 0; i < avctx->channels; i++) {
+        for (int i = 0; i < channels; i++) {
             c->status[i].predictor = sign_extend(bytestream2_get_be16u(&gb), 16);
             c->status[i].step_index = bytestream2_get_byteu(&gb);
             bytestream2_skipu(&gb, 1);
@@ -1931,7 +1939,7 @@ static int adpcm_decode_frame(AVCodecCon
         }
         ) /* End of CASE */
     CASE(ADPCM_AICA,
-        for (int channel = 0; channel < avctx->channels; channel++) {
+        for (int channel = 0; channel < channels; channel++) {
             samples = samples_p[channel];
             for (int n = nb_samples >> 1; n > 0; n--) {
                 int v = bytestream2_get_byteu(&gb);
@@ -1953,7 +1961,7 @@ static int adpcm_decode_frame(AVCodecCon
         }
 
         for (int m = 0; m < blocks; m++) {
-            for (int channel = 0; channel < avctx->channels; channel++) {
+            for (int channel = 0; channel < channels; channel++) {
                 int prev1 = c->status[channel].sample1;
                 int prev2 = c->status[channel].sample2;
 
@@ -2005,33 +2013,33 @@ static int adpcm_decode_frame(AVCodecCon
 
         if (avctx->extradata) {
             GetByteContext tb;
-            if (avctx->extradata_size < 32 * avctx->channels) {
+            if (avctx->extradata_size < 32 * channels) {
                 av_log(avctx, AV_LOG_ERROR, "Missing coeff table\n");
                 return AVERROR_INVALIDDATA;
             }
 
             bytestream2_init(&tb, avctx->extradata, avctx->extradata_size);
-            for (int i = 0; i < avctx->channels; i++)
+            for (int i = 0; i < channels; i++)
                 for (int n = 0; n < 16; n++)
                     table[i][n] = THP_GET16(tb);
         } else {
-            for (int i = 0; i < avctx->channels; i++)
+            for (int i = 0; i < channels; i++)
                 for (int n = 0; n < 16; n++)
                     table[i][n] = THP_GET16(gb);
 
             if (!c->has_status) {
                 /* Initialize the previous sample.  */
-                for (int i = 0; i < avctx->channels; i++) {
+                for (int i = 0; i < channels; i++) {
                     c->status[i].sample1 = THP_GET16(gb);
                     c->status[i].sample2 = THP_GET16(gb);
                 }
                 c->has_status = 1;
             } else {
-                bytestream2_skip(&gb, avctx->channels * 4);
+                bytestream2_skip(&gb, channels * 4);
             }
         }
 
-        for (int ch = 0; ch < avctx->channels; ch++) {
+        for (int ch = 0; ch < channels; ch++) {
             samples = samples_p[ch];
 
             /* Read in every sample for this channel.  */
@@ -2065,7 +2073,7 @@ static int adpcm_decode_frame(AVCodecCon
     }
 #endif /* CONFIG_ADPCM_THP(_LE)_DECODER */
     CASE(ADPCM_DTK,
-        for (int channel = 0; channel < avctx->channels; channel++) {
+        for (int channel = 0; channel < channels; channel++) {
             samples = samples_p[channel];
 
             /* Read in every sample for this channel.  */
@@ -2113,9 +2121,9 @@ static int adpcm_decode_frame(AVCodecCon
         }
         ) /* End of CASE */
     CASE(ADPCM_PSX,
-        for (int block = 0; block < avpkt->size / FFMAX(avctx->block_align, 16 * avctx->channels); block++) {
-            int nb_samples_per_block = 28 * FFMAX(avctx->block_align, 16 * avctx->channels) / (16 * avctx->channels);
-            for (int channel = 0; channel < avctx->channels; channel++) {
+        for (int block = 0; block < avpkt->size / FFMAX(avctx->block_align, 16 * channels); block++) {
+            int nb_samples_per_block = 28 * FFMAX(avctx->block_align, 16 * channels) / (16 * channels);
+            for (int channel = 0; channel < channels; channel++) {
                 samples = samples_p[channel] + block * nb_samples_per_block;
                 av_assert0((block + 1) * nb_samples_per_block <= nb_samples);
 
@@ -2172,7 +2180,7 @@ static int adpcm_decode_frame(AVCodecCon
          * They should be 0 initially.
          */
         for (int block = 0; block < avpkt->size / avctx->block_align; block++) {
-            for (int channel = 0; channel < avctx->channels; channel++) {
+            for (int channel = 0; channel < avctx->ch_layout.nb_channels; channel++) {
                 ADPCMChannelStatus *cs = c->status + channel;
                 int control, shift;
 
@@ -2191,19 +2199,19 @@ static int adpcm_decode_frame(AVCodecCon
         }
         ) /* End of CASE */
     CASE(ADPCM_ZORK,
-        for (int n = 0; n < nb_samples * avctx->channels; n++) {
+        for (int n = 0; n < nb_samples * channels; n++) {
             int v = bytestream2_get_byteu(&gb);
-            *samples++ = adpcm_zork_expand_nibble(&c->status[n % avctx->channels], v);
+            *samples++ = adpcm_zork_expand_nibble(&c->status[n % channels], v);
         }
         ) /* End of CASE */
     CASE(ADPCM_IMA_MTF,
         for (int n = nb_samples / 2; n > 0; n--) {
-            for (int channel = 0; channel < avctx->channels; channel++) {
+            for (int channel = 0; channel < channels; channel++) {
                 int v = bytestream2_get_byteu(&gb);
                 *samples++  = adpcm_ima_mtf_expand_nibble(&c->status[channel], v >> 4);
                 samples[st] = adpcm_ima_mtf_expand_nibble(&c->status[channel], v & 0x0F);
             }
-            samples += avctx->channels;
+            samples += channels;
         }
         ) /* End of CASE */
     default:
@@ -2277,17 +2285,17 @@ static const enum AVSampleFormat sample_
 
 #define ADPCM_DECODER_0(id_, sample_fmts_, name_, long_name_)
 #define ADPCM_DECODER_1(id_, sample_fmts_, name_, long_name_) \
-const AVCodec ff_ ## name_ ## _decoder = {                  \
-    .name           = #name_,                               \
-    .long_name      = NULL_IF_CONFIG_SMALL(long_name_),     \
-    .type           = AVMEDIA_TYPE_AUDIO,                   \
-    .id             = id_,                                  \
+const FFCodec ff_ ## name_ ## _decoder = {                  \
+    .p.name         = #name_,                               \
+    .p.long_name    = NULL_IF_CONFIG_SMALL(long_name_),     \
+    .p.type         = AVMEDIA_TYPE_AUDIO,                   \
+    .p.id           = id_,                                  \
+    .p.capabilities = AV_CODEC_CAP_DR1,                     \
+    .p.sample_fmts  = sample_fmts_,                         \
     .priv_data_size = sizeof(ADPCMDecodeContext),           \
     .init           = adpcm_decode_init,                    \
-    .decode         = adpcm_decode_frame,                   \
+    FF_CODEC_DECODE_CB(adpcm_decode_frame),                 \
     .flush          = adpcm_flush,                          \
-    .capabilities   = AV_CODEC_CAP_DR1,                     \
-    .sample_fmts    = sample_fmts_,                         \
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,         \
 };
 #define ADPCM_DECODER_2(enabled, codec_id, name, sample_fmts, long_name) \
diff -pruN 7:5.0.1-3/libavcodec/adpcmenc.c 7:5.1-1/libavcodec/adpcmenc.c
--- 7:5.0.1-3/libavcodec/adpcmenc.c	2022-01-14 18:45:39.000000000 +0000
+++ 7:5.1-1/libavcodec/adpcmenc.c	2022-07-22 17:58:38.000000000 +0000
@@ -22,6 +22,8 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "config_components.h"
+
 #include "libavutil/opt.h"
 
 #include "avcodec.h"
@@ -29,8 +31,8 @@
 #include "bytestream.h"
 #include "adpcm.h"
 #include "adpcm_data.h"
+#include "codec_internal.h"
 #include "encode.h"
-#include "internal.h"
 
 /**
  * @file
@@ -79,11 +81,7 @@ typedef struct ADPCMEncodeContext {
 static av_cold int adpcm_encode_init(AVCodecContext *avctx)
 {
     ADPCMEncodeContext *s = avctx->priv_data;
-
-    if (avctx->channels > 2) {
-        av_log(avctx, AV_LOG_ERROR, "only stereo or mono is supported\n");
-        return AVERROR(EINVAL);
-    }
+    int channels = avctx->ch_layout.nb_channels;
 
     /*
      * AMV's block size has to match that of the corresponding video
@@ -130,8 +128,8 @@ static av_cold int adpcm_encode_init(AVC
     CASE(ADPCM_IMA_WAV,
         /* each 16 bits sample gives one nibble
            and we have 4 bytes per channel overhead */
-        avctx->frame_size = (s->block_size - 4 * avctx->channels) * 8 /
-                            (4 * avctx->channels) + 1;
+        avctx->frame_size = (s->block_size - 4 * channels) * 8 /
+                            (4 * channels) + 1;
         /* seems frame_size isn't taken into account...
            have to buffer the samples :-( */
         avctx->block_align = s->block_size;
@@ -139,13 +137,13 @@ static av_cold int adpcm_encode_init(AVC
         ) /* End of CASE */
     CASE(ADPCM_IMA_QT,
         avctx->frame_size  = 64;
-        avctx->block_align = 34 * avctx->channels;
+        avctx->block_align = 34 * channels;
         ) /* End of CASE */
     CASE(ADPCM_MS,
         uint8_t *extradata;
         /* each 16 bits sample gives one nibble
            and we have 7 bytes per channel overhead */
-        avctx->frame_size = (s->block_size - 7 * avctx->channels) * 2 / avctx->channels + 2;
+        avctx->frame_size = (s->block_size - 7 * channels) * 2 / channels + 2;
         avctx->bits_per_coded_sample = 4;
         avctx->block_align     = s->block_size;
         if (!(avctx->extradata = av_malloc(32 + AV_INPUT_BUFFER_PADDING_SIZE)))
@@ -160,7 +158,7 @@ static av_cold int adpcm_encode_init(AVC
         }
         ) /* End of CASE */
     CASE(ADPCM_YAMAHA,
-        avctx->frame_size  = s->block_size * 2 / avctx->channels;
+        avctx->frame_size  = s->block_size * 2 / channels;
         avctx->block_align = s->block_size;
         ) /* End of CASE */
     CASE(ADPCM_SWF,
@@ -172,11 +170,11 @@ static av_cold int adpcm_encode_init(AVC
             return AVERROR(EINVAL);
         }
         avctx->frame_size  = 4096; /* Hardcoded according to the SWF spec. */
-        avctx->block_align = (2 + avctx->channels * (22 + 4 * (avctx->frame_size - 1)) + 7) / 8;
+        avctx->block_align = (2 + channels * (22 + 4 * (avctx->frame_size - 1)) + 7) / 8;
         ) /* End of CASE */
     case AV_CODEC_ID_ADPCM_IMA_SSI:
     case AV_CODEC_ID_ADPCM_IMA_ALP:
-        avctx->frame_size  = s->block_size * 2 / avctx->channels;
+        avctx->frame_size  = s->block_size * 2 / channels;
         avctx->block_align = s->block_size;
         break;
     CASE(ADPCM_IMA_AMV,
@@ -185,7 +183,7 @@ static av_cold int adpcm_encode_init(AVC
             return AVERROR(EINVAL);
         }
 
-        if (avctx->channels != 1) {
+        if (channels != 1) {
             av_log(avctx, AV_LOG_ERROR, "Only mono is supported\n");
             return AVERROR(EINVAL);
         }
@@ -194,7 +192,7 @@ static av_cold int adpcm_encode_init(AVC
         avctx->block_align = 8 + (FFALIGN(avctx->frame_size, 2) / 2);
         ) /* End of CASE */
     CASE(ADPCM_IMA_APM,
-        avctx->frame_size  = s->block_size * 2 / avctx->channels;
+        avctx->frame_size  = s->block_size * 2 / channels;
         avctx->block_align = s->block_size;
 
         if (!(avctx->extradata = av_mallocz(28 + AV_INPUT_BUFFER_PADDING_SIZE)))
@@ -203,11 +201,11 @@ static av_cold int adpcm_encode_init(AVC
         ) /* End of CASE */
     CASE(ADPCM_ARGO,
         avctx->frame_size = 32;
-        avctx->block_align = 17 * avctx->channels;
+        avctx->block_align = 17 * channels;
         ) /* End of CASE */
     CASE(ADPCM_IMA_WS,
         /* each 16 bits sample gives one nibble */
-        avctx->frame_size = s->block_size * 2 / avctx->channels;
+        avctx->frame_size = s->block_size * 2 / channels;
         avctx->block_align = s->block_size;
         ) /* End of CASE */
     default:
@@ -606,16 +604,17 @@ static int adpcm_encode_frame(AVCodecCon
     int16_t **samples_p;
     uint8_t *dst;
     ADPCMEncodeContext *c = avctx->priv_data;
+    int channels = avctx->ch_layout.nb_channels;
 
     samples = (const int16_t *)frame->data[0];
     samples_p = (int16_t **)frame->extended_data;
-    st = avctx->channels == 2;
+    st = channels == 2;
 
     if (avctx->codec_id == AV_CODEC_ID_ADPCM_IMA_SSI ||
         avctx->codec_id == AV_CODEC_ID_ADPCM_IMA_ALP ||
         avctx->codec_id == AV_CODEC_ID_ADPCM_IMA_APM ||
         avctx->codec_id == AV_CODEC_ID_ADPCM_IMA_WS)
-        pkt_size = (frame->nb_samples * avctx->channels) / 2;
+        pkt_size = (frame->nb_samples * channels) / 2;
     else
         pkt_size = avctx->block_align;
     if ((ret = ff_get_encode_buffer(avctx, avpkt, pkt_size, 0)) < 0)
@@ -626,7 +625,7 @@ static int adpcm_encode_frame(AVCodecCon
     CASE(ADPCM_IMA_WAV,
         int blocks = (frame->nb_samples - 1) / 8;
 
-        for (int ch = 0; ch < avctx->channels; ch++) {
+        for (int ch = 0; ch < channels; ch++) {
             ADPCMChannelStatus *status = &c->status[ch];
             status->prev_sample = samples_p[ch][0];
             /* status->step_index = 0;
@@ -639,15 +638,15 @@ static int adpcm_encode_frame(AVCodecCon
         /* stereo: 4 bytes (8 samples) for left, 4 bytes for right */
         if (avctx->trellis > 0) {
             uint8_t *buf;
-            if (!FF_ALLOC_TYPED_ARRAY(buf, avctx->channels * blocks * 8))
+            if (!FF_ALLOC_TYPED_ARRAY(buf, channels * blocks * 8))
                 return AVERROR(ENOMEM);
-            for (int ch = 0; ch < avctx->channels; ch++) {
+            for (int ch = 0; ch < channels; ch++) {
                 adpcm_compress_trellis(avctx, &samples_p[ch][1],
                                        buf + ch * blocks * 8, &c->status[ch],
                                        blocks * 8, 1);
             }
             for (int i = 0; i < blocks; i++) {
-                for (int ch = 0; ch < avctx->channels; ch++) {
+                for (int ch = 0; ch < channels; ch++) {
                     uint8_t *buf1 = buf + ch * blocks * 8 + i * 8;
                     for (int j = 0; j < 8; j += 2)
                         *dst++ = buf1[j] | (buf1[j + 1] << 4);
@@ -656,7 +655,7 @@ static int adpcm_encode_frame(AVCodecCon
             av_free(buf);
         } else {
             for (int i = 0; i < blocks; i++) {
-                for (int ch = 0; ch < avctx->channels; ch++) {
+                for (int ch = 0; ch < channels; ch++) {
                     ADPCMChannelStatus *status = &c->status[ch];
                     const int16_t *smp = &samples_p[ch][1 + i * 8];
                     for (int j = 0; j < 8; j += 2) {
@@ -672,7 +671,7 @@ static int adpcm_encode_frame(AVCodecCon
         PutBitContext pb;
         init_put_bits(&pb, dst, pkt_size);
 
-        for (int ch = 0; ch < avctx->channels; ch++) {
+        for (int ch = 0; ch < channels; ch++) {
             ADPCMChannelStatus *status = &c->status[ch];
             put_bits(&pb, 9, (status->prev_sample & 0xFFFF) >> 7);
             put_bits(&pb, 7,  status->step_index);
@@ -703,7 +702,7 @@ static int adpcm_encode_frame(AVCodecCon
         av_assert0(avctx->trellis == 0);
 
         for (int i = 0; i < frame->nb_samples; i++) {
-            for (int ch = 0; ch < avctx->channels; ch++) {
+            for (int ch = 0; ch < channels; ch++) {
                 put_bits(&pb, 4, adpcm_ima_qt_compress_sample(c->status + ch, *samples++));
             }
         }
@@ -717,11 +716,11 @@ static int adpcm_encode_frame(AVCodecCon
         av_assert0(avctx->trellis == 0);
 
         for (int n = frame->nb_samples / 2; n > 0; n--) {
-            for (int ch = 0; ch < avctx->channels; ch++) {
+            for (int ch = 0; ch < channels; ch++) {
                 put_bits(&pb, 4, adpcm_ima_alp_compress_sample(c->status + ch, *samples++));
                 put_bits(&pb, 4, adpcm_ima_alp_compress_sample(c->status + ch, samples[st]));
             }
-            samples += avctx->channels;
+            samples += channels;
         }
 
         flush_put_bits(&pb);
@@ -738,7 +737,7 @@ static int adpcm_encode_frame(AVCodecCon
         put_bits(&pb, 2, 2);    // set 4-bit flash adpcm format
 
         // init the encoder state
-        for (int i = 0; i < avctx->channels; i++) {
+        for (int i = 0; i < channels; i++) {
             // clip step so it fits 6 bits
             c->status[i].step_index = av_clip_uintp2(c->status[i].step_index, 6);
             put_sbits(&pb, 16, samples[i]);
@@ -748,22 +747,22 @@ static int adpcm_encode_frame(AVCodecCon
 
         if (avctx->trellis > 0) {
             uint8_t buf[8190 /* = 2 * n */];
-            adpcm_compress_trellis(avctx, samples + avctx->channels, buf,
-                                   &c->status[0], n, avctx->channels);
-            if (avctx->channels == 2)
-                adpcm_compress_trellis(avctx, samples + avctx->channels + 1,
+            adpcm_compress_trellis(avctx, samples + channels, buf,
+                                   &c->status[0], n, channels);
+            if (channels == 2)
+                adpcm_compress_trellis(avctx, samples + channels + 1,
                                        buf + n, &c->status[1], n,
-                                       avctx->channels);
+                                       channels);
             for (int i = 0; i < n; i++) {
                 put_bits(&pb, 4, buf[i]);
-                if (avctx->channels == 2)
+                if (channels == 2)
                     put_bits(&pb, 4, buf[n + i]);
             }
         } else {
             for (int i = 1; i < frame->nb_samples; i++) {
                 put_bits(&pb, 4, adpcm_ima_compress_sample(&c->status[0],
-                         samples[avctx->channels * i]));
-                if (avctx->channels == 2)
+                         samples[channels * i]));
+                if (channels == 2)
                     put_bits(&pb, 4, adpcm_ima_compress_sample(&c->status[1],
                              samples[2 * i + 1]));
             }
@@ -771,47 +770,47 @@ static int adpcm_encode_frame(AVCodecCon
         flush_put_bits(&pb);
         ) /* End of CASE */
     CASE(ADPCM_MS,
-        for (int i = 0; i < avctx->channels; i++) {
+        for (int i = 0; i < channels; i++) {
             int predictor = 0;
             *dst++ = predictor;
             c->status[i].coeff1 = ff_adpcm_AdaptCoeff1[predictor];
             c->status[i].coeff2 = ff_adpcm_AdaptCoeff2[predictor];
         }
-        for (int i = 0; i < avctx->channels; i++) {
+        for (int i = 0; i < channels; i++) {
             if (c->status[i].idelta < 16)
                 c->status[i].idelta = 16;
             bytestream_put_le16(&dst, c->status[i].idelta);
         }
-        for (int i = 0; i < avctx->channels; i++)
+        for (int i = 0; i < channels; i++)
             c->status[i].sample2= *samples++;
-        for (int i = 0; i < avctx->channels; i++) {
+        for (int i = 0; i < channels; i++) {
             c->status[i].sample1 = *samples++;
             bytestream_put_le16(&dst, c->status[i].sample1);
         }
-        for (int i = 0; i < avctx->channels; i++)
+        for (int i = 0; i < channels; i++)
             bytestream_put_le16(&dst, c->status[i].sample2);
 
         if (avctx->trellis > 0) {
-            const int n  = avctx->block_align - 7 * avctx->channels;
+            const int n  = avctx->block_align - 7 * channels;
             uint8_t *buf = av_malloc(2 * n);
             if (!buf)
                 return AVERROR(ENOMEM);
-            if (avctx->channels == 1) {
+            if (channels == 1) {
                 adpcm_compress_trellis(avctx, samples, buf, &c->status[0], n,
-                                       avctx->channels);
+                                       channels);
                 for (int i = 0; i < n; i += 2)
                     *dst++ = (buf[i] << 4) | buf[i + 1];
             } else {
                 adpcm_compress_trellis(avctx, samples,     buf,
-                                       &c->status[0], n, avctx->channels);
+                                       &c->status[0], n, channels);
                 adpcm_compress_trellis(avctx, samples + 1, buf + n,
-                                       &c->status[1], n, avctx->channels);
+                                       &c->status[1], n, channels);
                 for (int i = 0; i < n; i++)
                     *dst++ = (buf[i] << 4) | buf[n + i];
             }
             av_free(buf);
         } else {
-            for (int i = 7 * avctx->channels; i < avctx->block_align; i++) {
+            for (int i = 7 * channels; i < avctx->block_align; i++) {
                 int nibble;
                 nibble  = adpcm_ms_compress_sample(&c->status[ 0], *samples++) << 4;
                 nibble |= adpcm_ms_compress_sample(&c->status[st], *samples++);
@@ -826,22 +825,22 @@ static int adpcm_encode_frame(AVCodecCon
             if (!buf)
                 return AVERROR(ENOMEM);
             n *= 2;
-            if (avctx->channels == 1) {
+            if (channels == 1) {
                 adpcm_compress_trellis(avctx, samples, buf, &c->status[0], n,
-                                       avctx->channels);
+                                       channels);
                 for (int i = 0; i < n; i += 2)
                     *dst++ = buf[i] | (buf[i + 1] << 4);
             } else {
                 adpcm_compress_trellis(avctx, samples,     buf,
-                                       &c->status[0], n, avctx->channels);
+                                       &c->status[0], n, channels);
                 adpcm_compress_trellis(avctx, samples + 1, buf + n,
-                                       &c->status[1], n, avctx->channels);
+                                       &c->status[1], n, channels);
                 for (int i = 0; i < n; i++)
                     *dst++ = buf[i] | (buf[n + i] << 4);
             }
             av_free(buf);
         } else
-            for (n *= avctx->channels; n > 0; n--) {
+            for (n *= channels; n > 0; n--) {
                 int nibble;
                 nibble  = adpcm_yamaha_compress_sample(&c->status[ 0], *samples++);
                 nibble |= adpcm_yamaha_compress_sample(&c->status[st], *samples++) << 4;
@@ -855,17 +854,17 @@ static int adpcm_encode_frame(AVCodecCon
         av_assert0(avctx->trellis == 0);
 
         for (int n = frame->nb_samples / 2; n > 0; n--) {
-            for (int ch = 0; ch < avctx->channels; ch++) {
+            for (int ch = 0; ch < channels; ch++) {
                 put_bits(&pb, 4, adpcm_ima_qt_compress_sample(c->status + ch, *samples++));
                 put_bits(&pb, 4, adpcm_ima_qt_compress_sample(c->status + ch, samples[st]));
             }
-            samples += avctx->channels;
+            samples += channels;
         }
 
         flush_put_bits(&pb);
         ) /* End of CASE */
     CASE(ADPCM_IMA_AMV,
-        av_assert0(avctx->channels == 1);
+        av_assert0(channels == 1);
 
         c->status[0].prev_sample = *samples;
         bytestream_put_le16(&dst, c->status[0].prev_sample);
@@ -880,7 +879,7 @@ static int adpcm_encode_frame(AVCodecCon
             if (!buf)
                 return AVERROR(ENOMEM);
 
-            adpcm_compress_trellis(avctx, samples, buf, &c->status[0], 2 * n, avctx->channels);
+            adpcm_compress_trellis(avctx, samples, buf, &c->status[0], 2 * n, channels);
             for (int i = 0; i < n; i++)
                 bytestream_put_byte(&dst, (buf[2 * i] << 4) | buf[2 * i + 1]);
 
@@ -904,7 +903,7 @@ static int adpcm_encode_frame(AVCodecCon
 
         av_assert0(frame->nb_samples == 32);
 
-        for (int ch = 0; ch < avctx->channels; ch++) {
+        for (int ch = 0; ch < channels; ch++) {
             int64_t error  = INT64_MAX, tmperr = INT64_MAX;
             int     shift  = 2, flag = 0;
             int     saved1 = c->status[ch].sample1;
@@ -941,14 +940,14 @@ static int adpcm_encode_frame(AVCodecCon
         av_assert0(avctx->trellis == 0);
         for (int n = frame->nb_samples / 2; n > 0; n--) {
             /* stereo: 1 byte (2 samples) for left, 1 byte for right */
-            for (int ch = 0; ch < avctx->channels; ch++) {
+            for (int ch = 0; ch < channels; ch++) {
                 int t1, t2;
                 t1 = adpcm_ima_compress_sample(&c->status[ch], *samples++);
                 t2 = adpcm_ima_compress_sample(&c->status[ch], samples[st]);
                 put_bits(&pb, 4, t2);
                 put_bits(&pb, 4, t1);
             }
-            samples += avctx->channels;
+            samples += channels;
         }
         flush_put_bits(&pb);
         ) /* End of CASE */
@@ -968,6 +967,12 @@ static const enum AVSampleFormat sample_
     AV_SAMPLE_FMT_S16P, AV_SAMPLE_FMT_NONE
 };
 
+static const AVChannelLayout ch_layouts[] = {
+    AV_CHANNEL_LAYOUT_MONO,
+    AV_CHANNEL_LAYOUT_STEREO,
+    { 0 },
+};
+
 static const AVOption options[] = {
     {
         .name        = "block_size",
@@ -991,19 +996,20 @@ static const AVClass adpcm_encoder_class
 
 #define ADPCM_ENCODER_0(id_, name_, sample_fmts_, capabilities_, long_name_)
 #define ADPCM_ENCODER_1(id_, name_, sample_fmts_, capabilities_, long_name_) \
-const AVCodec ff_ ## name_ ## _encoder = {                                 \
-    .name           = #name_,                                              \
-    .long_name      = NULL_IF_CONFIG_SMALL(long_name_),                    \
-    .type           = AVMEDIA_TYPE_AUDIO,                                  \
-    .id             = id_,                                                 \
+const FFCodec ff_ ## name_ ## _encoder = {                                 \
+    .p.name         = #name_,                                              \
+    .p.long_name    = NULL_IF_CONFIG_SMALL(long_name_),                    \
+    .p.type         = AVMEDIA_TYPE_AUDIO,                                  \
+    .p.id           = id_,                                                 \
+    .p.sample_fmts  = sample_fmts_,                                        \
+    .p.ch_layouts   = ch_layouts,                                          \
+    .p.capabilities = capabilities_ | AV_CODEC_CAP_DR1,                    \
+    .p.priv_class   = &adpcm_encoder_class,                                \
     .priv_data_size = sizeof(ADPCMEncodeContext),                          \
     .init           = adpcm_encode_init,                                   \
-    .encode2        = adpcm_encode_frame,                                  \
+    FF_CODEC_ENCODE_CB(adpcm_encode_frame),                                \
     .close          = adpcm_encode_close,                                  \
-    .sample_fmts    = sample_fmts_,                                        \
-    .capabilities   = capabilities_ | AV_CODEC_CAP_DR1,                    \
     .caps_internal  = FF_CODEC_CAP_INIT_CLEANUP | FF_CODEC_CAP_INIT_THREADSAFE, \
-    .priv_class     = &adpcm_encoder_class,                                \
 };
 #define ADPCM_ENCODER_2(enabled, codec_id, name, sample_fmts, capabilities, long_name) \
     ADPCM_ENCODER_ ## enabled(codec_id, name, sample_fmts, capabilities, long_name)
diff -pruN 7:5.0.1-3/libavcodec/adx.c 7:5.1-1/libavcodec/adx.c
--- 7:5.0.1-3/libavcodec/adx.c	2020-04-27 21:48:15.000000000 +0000
+++ 7:5.1-1/libavcodec/adx.c	2022-07-22 17:58:38.000000000 +0000
@@ -38,7 +38,7 @@ void ff_adx_calculate_coeffs(int cutoff,
 int ff_adx_decode_header(AVCodecContext *avctx, const uint8_t *buf,
                          int bufsize, int *header_size, int *coeff)
 {
-    int offset, cutoff;
+    int offset, cutoff, channels;
 
     if (bufsize < 24)
         return AVERROR_INVALIDDATA;
@@ -58,18 +58,24 @@ int ff_adx_decode_header(AVCodecContext
     }
 
     /* channels */
-    avctx->channels = buf[7];
-    if (avctx->channels <= 0 || avctx->channels > 2)
+    channels = buf[7];
+    if (channels <= 0 || channels > 2)
         return AVERROR_INVALIDDATA;
 
+    if (avctx->ch_layout.nb_channels != channels) {
+        av_channel_layout_uninit(&avctx->ch_layout);
+        avctx->ch_layout.order = AV_CHANNEL_ORDER_UNSPEC;
+        avctx->ch_layout.nb_channels = channels;
+    }
+
     /* sample rate */
     avctx->sample_rate = AV_RB32(buf + 8);
     if (avctx->sample_rate < 1 ||
-        avctx->sample_rate > INT_MAX / (avctx->channels * BLOCK_SIZE * 8))
+        avctx->sample_rate > INT_MAX / (channels * BLOCK_SIZE * 8))
         return AVERROR_INVALIDDATA;
 
     /* bit rate */
-    avctx->bit_rate = avctx->sample_rate * avctx->channels * BLOCK_SIZE * 8 / BLOCK_SAMPLES;
+    avctx->bit_rate = avctx->sample_rate * channels * BLOCK_SIZE * 8 / BLOCK_SAMPLES;
 
     /* LPC coefficients */
     if (coeff) {
diff -pruN 7:5.0.1-3/libavcodec/adxdec.c 7:5.1-1/libavcodec/adxdec.c
--- 7:5.0.1-3/libavcodec/adxdec.c	2022-01-14 18:45:39.000000000 +0000
+++ 7:5.1-1/libavcodec/adxdec.c	2022-07-22 17:58:38.000000000 +0000
@@ -22,6 +22,7 @@
 #include "libavutil/intreadwrite.h"
 #include "avcodec.h"
 #include "adx.h"
+#include "codec_internal.h"
 #include "get_bits.h"
 #include "internal.h"
 
@@ -46,7 +47,7 @@ static av_cold int adx_decode_init(AVCod
             av_log(avctx, AV_LOG_ERROR, "error parsing ADX header\n");
             return AVERROR_INVALIDDATA;
         }
-        c->channels      = avctx->channels;
+        c->channels      = avctx->ch_layout.nb_channels;
         c->header_parsed = 1;
     }
 
@@ -92,10 +93,9 @@ static int adx_decode(ADXContext *c, int
     return 0;
 }
 
-static int adx_decode_frame(AVCodecContext *avctx, void *data,
+static int adx_decode_frame(AVCodecContext *avctx, AVFrame *frame,
                             int *got_frame_ptr, AVPacket *avpkt)
 {
-    AVFrame *frame      = data;
     int buf_size        = avpkt->size;
     ADXContext *c       = avctx->priv_data;
     int16_t **samples;
@@ -132,7 +132,7 @@ static int adx_decode_frame(AVCodecConte
             av_log(avctx, AV_LOG_ERROR, "error parsing ADX header\n");
             return AVERROR_INVALIDDATA;
         }
-        c->channels      = avctx->channels;
+        c->channels      = avctx->ch_layout.nb_channels;
         c->header_parsed = 1;
         if (buf_size < header_size)
             return AVERROR_INVALIDDATA;
@@ -147,7 +147,7 @@ static int adx_decode_frame(AVCodecConte
 
     /* if the packet is not an even multiple of BLOCK_SIZE, check for an EOF
        packet */
-    if (!num_blocks || buf_size % (BLOCK_SIZE * avctx->channels)) {
+    if (!num_blocks || buf_size % (BLOCK_SIZE * c->channels)) {
         if (buf_size >= 4 && (AV_RB16(buf) & 0x8000)) {
             c->eof = 1;
             *got_frame_ptr = 0;
@@ -190,18 +190,18 @@ static void adx_decode_flush(AVCodecCont
     c->eof = 0;
 }
 
-const AVCodec ff_adpcm_adx_decoder = {
-    .name           = "adpcm_adx",
-    .long_name      = NULL_IF_CONFIG_SMALL("SEGA CRI ADX ADPCM"),
-    .type           = AVMEDIA_TYPE_AUDIO,
-    .id             = AV_CODEC_ID_ADPCM_ADX,
+const FFCodec ff_adpcm_adx_decoder = {
+    .p.name         = "adpcm_adx",
+    .p.long_name    = NULL_IF_CONFIG_SMALL("SEGA CRI ADX ADPCM"),
+    .p.type         = AVMEDIA_TYPE_AUDIO,
+    .p.id           = AV_CODEC_ID_ADPCM_ADX,
     .priv_data_size = sizeof(ADXContext),
     .init           = adx_decode_init,
-    .decode         = adx_decode_frame,
+    FF_CODEC_DECODE_CB(adx_decode_frame),
     .flush          = adx_decode_flush,
-    .capabilities   = AV_CODEC_CAP_CHANNEL_CONF |
+    .p.capabilities = AV_CODEC_CAP_CHANNEL_CONF |
                       AV_CODEC_CAP_DR1,
-    .sample_fmts    = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16P,
+    .p.sample_fmts  = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16P,
                                                       AV_SAMPLE_FMT_NONE },
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff -pruN 7:5.0.1-3/libavcodec/adxenc.c 7:5.1-1/libavcodec/adxenc.c
--- 7:5.0.1-3/libavcodec/adxenc.c	2022-01-14 18:45:39.000000000 +0000
+++ 7:5.1-1/libavcodec/adxenc.c	2022-07-22 17:58:38.000000000 +0000
@@ -22,8 +22,8 @@
 #include "avcodec.h"
 #include "adx.h"
 #include "bytestream.h"
+#include "codec_internal.h"
 #include "encode.h"
-#include "internal.h"
 #include "put_bits.h"
 
 /**
@@ -107,7 +107,7 @@ static int adx_encode_header(AVCodecCont
     bytestream_put_byte(&buf, 3);                   /* encoding */
     bytestream_put_byte(&buf, BLOCK_SIZE);          /* block size */
     bytestream_put_byte(&buf, 4);                   /* sample size */
-    bytestream_put_byte(&buf, avctx->channels);     /* channels */
+    bytestream_put_byte(&buf, avctx->ch_layout.nb_channels); /* channels */
     bytestream_put_be32(&buf, avctx->sample_rate);  /* sample rate */
     bytestream_put_be32(&buf, 0);                   /* total sample count */
     bytestream_put_be16(&buf, c->cutoff);           /* cutoff frequency */
@@ -125,7 +125,7 @@ static av_cold int adx_encode_init(AVCod
 {
     ADXContext *c = avctx->priv_data;
 
-    if (avctx->channels > 2) {
+    if (avctx->ch_layout.nb_channels > 2) {
         av_log(avctx, AV_LOG_ERROR, "Invalid number of channels\n");
         return AVERROR(EINVAL);
     }
@@ -144,6 +144,7 @@ static int adx_encode_frame(AVCodecConte
     ADXContext *c          = avctx->priv_data;
     const int16_t *samples = frame ? (const int16_t *)frame->data[0] : NULL;
     uint8_t *dst;
+    int channels = avctx->ch_layout.nb_channels;
     int ch, out_size, ret;
 
     if (!samples) {
@@ -162,7 +163,7 @@ static int adx_encode_frame(AVCodecConte
         return 0;
     }
 
-    out_size = BLOCK_SIZE * avctx->channels + !c->header_parsed * HEADER_SIZE;
+    out_size = BLOCK_SIZE * channels + !c->header_parsed * HEADER_SIZE;
     if ((ret = ff_get_encode_buffer(avctx, avpkt, out_size, 0)) < 0)
         return ret;
     dst = avpkt->data;
@@ -177,8 +178,8 @@ static int adx_encode_frame(AVCodecConte
         c->header_parsed = 1;
     }
 
-    for (ch = 0; ch < avctx->channels; ch++) {
-        adx_encode(c, dst, samples + ch, &c->prev[ch], avctx->channels);
+    for (ch = 0; ch < channels; ch++) {
+        adx_encode(c, dst, samples + ch, &c->prev[ch], channels);
         dst += BLOCK_SIZE;
     }
 
@@ -188,16 +189,16 @@ static int adx_encode_frame(AVCodecConte
     return 0;
 }
 
-const AVCodec ff_adpcm_adx_encoder = {
-    .name           = "adpcm_adx",
-    .long_name      = NULL_IF_CONFIG_SMALL("SEGA CRI ADX ADPCM"),
-    .type           = AVMEDIA_TYPE_AUDIO,
-    .id             = AV_CODEC_ID_ADPCM_ADX,
-    .capabilities   = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY,
+const FFCodec ff_adpcm_adx_encoder = {
+    .p.name         = "adpcm_adx",
+    .p.long_name    = NULL_IF_CONFIG_SMALL("SEGA CRI ADX ADPCM"),
+    .p.type         = AVMEDIA_TYPE_AUDIO,
+    .p.id           = AV_CODEC_ID_ADPCM_ADX,
+    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY,
     .priv_data_size = sizeof(ADXContext),
     .init           = adx_encode_init,
-    .encode2        = adx_encode_frame,
-    .sample_fmts    = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16,
+    FF_CODEC_ENCODE_CB(adx_encode_frame),
+    .p.sample_fmts  = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16,
                                                       AV_SAMPLE_FMT_NONE },
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff -pruN 7:5.0.1-3/libavcodec/agm.c 7:5.1-1/libavcodec/agm.c
--- 7:5.0.1-3/libavcodec/agm.c	2022-01-14 18:45:39.000000000 +0000
+++ 7:5.1-1/libavcodec/agm.c	2022-07-22 17:58:38.000000000 +0000
@@ -30,6 +30,7 @@
 
 #include "avcodec.h"
 #include "bytestream.h"
+#include "codec_internal.h"
 #include "copy_block.h"
 #include "get_bits.h"
 #include "idctdsp.h"
@@ -1093,13 +1094,12 @@ static int decode_huffman2(AVCodecContex
     return 0;
 }
 
-static int decode_frame(AVCodecContext *avctx, void *data,
+static int decode_frame(AVCodecContext *avctx, AVFrame *frame,
                         int *got_frame, AVPacket *avpkt)
 {
     AGMContext *s = avctx->priv_data;
     GetBitContext *gb = &s->gb;
     GetByteContext *gbyte = &s->gbyte;
-    AVFrame *frame = data;
     int w, h, width, height, header;
     unsigned compressed_size;
     long skip;
@@ -1285,17 +1285,17 @@ static av_cold int decode_close(AVCodecC
     return 0;
 }
 
-const AVCodec ff_agm_decoder = {
-    .name             = "agm",
-    .long_name        = NULL_IF_CONFIG_SMALL("Amuse Graphics Movie"),
-    .type             = AVMEDIA_TYPE_VIDEO,
-    .id               = AV_CODEC_ID_AGM,
+const FFCodec ff_agm_decoder = {
+    .p.name           = "agm",
+    .p.long_name      = NULL_IF_CONFIG_SMALL("Amuse Graphics Movie"),
+    .p.type           = AVMEDIA_TYPE_VIDEO,
+    .p.id             = AV_CODEC_ID_AGM,
+    .p.capabilities   = AV_CODEC_CAP_DR1,
     .priv_data_size   = sizeof(AGMContext),
     .init             = decode_init,
     .close            = decode_close,
-    .decode           = decode_frame,
+    FF_CODEC_DECODE_CB(decode_frame),
     .flush            = decode_flush,
-    .capabilities     = AV_CODEC_CAP_DR1,
     .caps_internal    = FF_CODEC_CAP_INIT_THREADSAFE |
                         FF_CODEC_CAP_INIT_CLEANUP |
                         FF_CODEC_CAP_EXPORTS_CROPPING,
diff -pruN 7:5.0.1-3/libavcodec/aic.c 7:5.1-1/libavcodec/aic.c
--- 7:5.0.1-3/libavcodec/aic.c	2022-01-14 18:45:39.000000000 +0000
+++ 7:5.1-1/libavcodec/aic.c	2022-07-22 17:58:38.000000000 +0000
@@ -26,7 +26,7 @@
 
 #include "avcodec.h"
 #include "bytestream.h"
-#include "internal.h"
+#include "codec_internal.h"
 #include "get_bits.h"
 #include "golomb.h"
 #include "idctdsp.h"
@@ -381,8 +381,8 @@ static int aic_decode_slice(AICContext *
     return 0;
 }
 
-static int aic_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
-                            AVPacket *avpkt)
+static int aic_decode_frame(AVCodecContext *avctx, AVFrame *frame,
+                            int *got_frame, AVPacket *avpkt)
 {
     AICContext *ctx    = avctx->priv_data;
     const uint8_t *buf = avpkt->data;
@@ -391,9 +391,8 @@ static int aic_decode_frame(AVCodecConte
     uint32_t off;
     int x, y, ret;
     int slice_size;
-    ThreadFrame frame = { .f = data };
 
-    ctx->frame            = data;
+    ctx->frame            = frame;
     ctx->frame->pict_type = AV_PICTURE_TYPE_I;
     ctx->frame->key_frame = 1;
 
@@ -410,7 +409,7 @@ static int aic_decode_frame(AVCodecConte
         return ret;
     }
 
-    if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0)
+    if ((ret = ff_thread_get_buffer(avctx, ctx->frame, 0)) < 0)
         return ret;
 
     bytestream2_init(&gb, buf + AIC_HDR_SIZE,
@@ -496,15 +495,15 @@ static av_cold int aic_decode_close(AVCo
     return 0;
 }
 
-const AVCodec ff_aic_decoder = {
-    .name           = "aic",
-    .long_name      = NULL_IF_CONFIG_SMALL("Apple Intermediate Codec"),
-    .type           = AVMEDIA_TYPE_VIDEO,
-    .id             = AV_CODEC_ID_AIC,
+const FFCodec ff_aic_decoder = {
+    .p.name         = "aic",
+    .p.long_name    = NULL_IF_CONFIG_SMALL("Apple Intermediate Codec"),
+    .p.type         = AVMEDIA_TYPE_VIDEO,
+    .p.id           = AV_CODEC_ID_AIC,
     .priv_data_size = sizeof(AICContext),
     .init           = aic_decode_init,
     .close          = aic_decode_close,
-    .decode         = aic_decode_frame,
-    .capabilities   = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
+    FF_CODEC_DECODE_CB(aic_decode_frame),
+    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff -pruN 7:5.0.1-3/libavcodec/alac.c 7:5.1-1/libavcodec/alac.c
--- 7:5.0.1-3/libavcodec/alac.c	2022-01-14 18:45:39.000000000 +0000
+++ 7:5.1-1/libavcodec/alac.c	2022-07-22 17:58:38.000000000 +0000
@@ -52,7 +52,7 @@
 #include "avcodec.h"
 #include "get_bits.h"
 #include "bytestream.h"
-#include "internal.h"
+#include "codec_internal.h"
 #include "thread.h"
 #include "unary.h"
 #include "mathops.h"
@@ -270,10 +270,9 @@ static int decode_element(AVCodecContext
         return AVERROR_INVALIDDATA;
     }
     if (!alac->nb_samples) {
-        ThreadFrame tframe = { .f = frame };
         /* get output buffer */
         frame->nb_samples = output_samples;
-        if ((ret = ff_thread_get_buffer(avctx, &tframe, 0)) < 0)
+        if ((ret = ff_thread_get_buffer(avctx, frame, 0)) < 0)
             return ret;
     } else if (output_samples != alac->nb_samples) {
         av_log(avctx, AV_LOG_ERROR, "sample count mismatch: %"PRIu32" != %d\n",
@@ -414,11 +413,10 @@ static int decode_element(AVCodecContext
     return 0;
 }
 
-static int alac_decode_frame(AVCodecContext *avctx, void *data,
+static int alac_decode_frame(AVCodecContext *avctx, AVFrame *frame,
                              int *got_frame_ptr, AVPacket *avpkt)
 {
     ALACContext *alac = avctx->priv_data;
-    AVFrame *frame    = data;
     enum AlacRawDataBlockType element;
     int channels;
     int ch, ret, got_end;
@@ -576,21 +574,17 @@ static av_cold int alac_decode_init(AVCo
     avctx->bits_per_raw_sample = alac->sample_size;
     avctx->sample_rate         = alac->sample_rate;
 
-    if (alac->channels < 1) {
+    if (alac->channels < 1 || alac->channels > ALAC_MAX_CHANNELS) {
         av_log(avctx, AV_LOG_WARNING, "Invalid channel count\n");
-        alac->channels = avctx->channels;
-    } else {
-        if (alac->channels > ALAC_MAX_CHANNELS)
-            alac->channels = avctx->channels;
-        else
-            avctx->channels = alac->channels;
+        alac->channels = avctx->ch_layout.nb_channels;
     }
-    if (avctx->channels > ALAC_MAX_CHANNELS || avctx->channels <= 0 ) {
+    if (avctx->ch_layout.nb_channels > ALAC_MAX_CHANNELS || avctx->ch_layout.nb_channels <= 0 ) {
         avpriv_report_missing_feature(avctx, "Channel count %d",
-                                      avctx->channels);
+                                      avctx->ch_layout.nb_channels);
         return AVERROR_PATCHWELCOME;
     }
-    avctx->channel_layout = ff_alac_channel_layouts[alac->channels - 1];
+    av_channel_layout_uninit(&avctx->ch_layout);
+    avctx->ch_layout = ff_alac_ch_layouts[alac->channels - 1];
 
     if ((ret = allocate_buffers(alac)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "Error allocating buffers\n");
@@ -616,16 +610,16 @@ static const AVClass alac_class = {
     .version    = LIBAVUTIL_VERSION_INT,
 };
 
-const AVCodec ff_alac_decoder = {
-    .name           = "alac",
-    .long_name      = NULL_IF_CONFIG_SMALL("ALAC (Apple Lossless Audio Codec)"),
-    .type           = AVMEDIA_TYPE_AUDIO,
-    .id             = AV_CODEC_ID_ALAC,
+const FFCodec ff_alac_decoder = {
+    .p.name         = "alac",
+    .p.long_name    = NULL_IF_CONFIG_SMALL("ALAC (Apple Lossless Audio Codec)"),
+    .p.type         = AVMEDIA_TYPE_AUDIO,
+    .p.id           = AV_CODEC_ID_ALAC,
     .priv_data_size = sizeof(ALACContext),
     .init           = alac_decode_init,
     .close          = alac_decode_close,
-    .decode         = alac_decode_frame,
-    .capabilities   = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS | AV_CODEC_CAP_CHANNEL_CONF,
+    FF_CODEC_DECODE_CB(alac_decode_frame),
+    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS | AV_CODEC_CAP_CHANNEL_CONF,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
-    .priv_class     = &alac_class
+    .p.priv_class   = &alac_class
 };
diff -pruN 7:5.0.1-3/libavcodec/alac_data.c 7:5.1-1/libavcodec/alac_data.c
--- 7:5.0.1-3/libavcodec/alac_data.c	2020-04-27 21:48:15.000000000 +0000
+++ 7:5.1-1/libavcodec/alac_data.c	2022-07-22 17:58:38.000000000 +0000
@@ -32,16 +32,16 @@ const uint8_t ff_alac_channel_layout_off
     { 2, 6, 7, 0, 1, 4, 5, 3 }
 };
 
-const uint64_t ff_alac_channel_layouts[ALAC_MAX_CHANNELS + 1] = {
-    AV_CH_LAYOUT_MONO,
-    AV_CH_LAYOUT_STEREO,
-    AV_CH_LAYOUT_SURROUND,
-    AV_CH_LAYOUT_4POINT0,
-    AV_CH_LAYOUT_5POINT0_BACK,
-    AV_CH_LAYOUT_5POINT1_BACK,
-    AV_CH_LAYOUT_6POINT1_BACK,
-    AV_CH_LAYOUT_7POINT1_WIDE_BACK,
-    0
+const AVChannelLayout ff_alac_ch_layouts[ALAC_MAX_CHANNELS + 1] = {
+    AV_CHANNEL_LAYOUT_MONO,
+    AV_CHANNEL_LAYOUT_STEREO,
+    AV_CHANNEL_LAYOUT_SURROUND,
+    AV_CHANNEL_LAYOUT_4POINT0,
+    AV_CHANNEL_LAYOUT_5POINT0_BACK,
+    AV_CHANNEL_LAYOUT_5POINT1_BACK,
+    AV_CHANNEL_LAYOUT_6POINT1_BACK,
+    AV_CHANNEL_LAYOUT_7POINT1_WIDE_BACK,
+    { 0 }
 };
 
 const enum AlacRawDataBlockType ff_alac_channel_elements[ALAC_MAX_CHANNELS][5] = {
diff -pruN 7:5.0.1-3/libavcodec/alac_data.h 7:5.1-1/libavcodec/alac_data.h
--- 7:5.0.1-3/libavcodec/alac_data.h	2020-04-27 21:48:15.000000000 +0000
+++ 7:5.1-1/libavcodec/alac_data.h	2022-07-22 17:58:38.000000000 +0000
@@ -23,6 +23,8 @@
 
 #include <stdint.h>
 
+#include "libavutil/channel_layout.h"
+
 enum AlacRawDataBlockType {
     /* At the moment, only SCE, CPE, LFE, and END are recognized. */
     TYPE_SCE,
@@ -39,7 +41,7 @@ enum AlacRawDataBlockType {
 
 extern const uint8_t ff_alac_channel_layout_offsets[ALAC_MAX_CHANNELS][ALAC_MAX_CHANNELS];
 
-extern const uint64_t ff_alac_channel_layouts[ALAC_MAX_CHANNELS + 1];
+extern const AVChannelLayout ff_alac_ch_layouts[ALAC_MAX_CHANNELS + 1];
 
 extern const enum AlacRawDataBlockType ff_alac_channel_elements[ALAC_MAX_CHANNELS][5];
 
diff -pruN 7:5.0.1-3/libavcodec/alacdsp.c 7:5.1-1/libavcodec/alacdsp.c
--- 7:5.0.1-3/libavcodec/alacdsp.c	2022-01-14 18:45:39.000000000 +0000
+++ 7:5.1-1/libavcodec/alacdsp.c	2022-07-22 17:58:38.000000000 +0000
@@ -29,12 +29,12 @@ static void decorrelate_stereo(int32_t *
     int i;
 
     for (i = 0; i < nb_samples; i++) {
-        int32_t a, b;
+        uint32_t a, b;
 
         a = buffer[0][i];
         b = buffer[1][i];
 
-        a -= (int)(b * (unsigned)decorr_left_weight) >> decorr_shift;
+        a -= (int)(b * decorr_left_weight) >> decorr_shift;
         b += a;
 
         buffer[0][i] = b;
@@ -58,6 +58,7 @@ av_cold void ff_alacdsp_init(ALACDSPCont
     c->append_extra_bits[0] =
     c->append_extra_bits[1] = append_extra_bits;
 
-    if (ARCH_X86)
-        ff_alacdsp_init_x86(c);
+#if ARCH_X86
+    ff_alacdsp_init_x86(c);
+#endif
 }
diff -pruN 7:5.0.1-3/libavcodec/alacenc.c 7:5.1-1/libavcodec/alacenc.c
--- 7:5.0.1-3/libavcodec/alacenc.c	2022-01-14 18:45:39.000000000 +0000
+++ 7:5.1-1/libavcodec/alacenc.c	2022-07-22 17:58:38.000000000 +0000
@@ -22,9 +22,9 @@
 #include "libavutil/opt.h"
 
 #include "avcodec.h"
+#include "codec_internal.h"
 #include "encode.h"
 #include "put_bits.h"
-#include "internal.h"
 #include "lpc.h"
 #include "mathops.h"
 #include "alac_data.h"
@@ -462,14 +462,15 @@ static int write_frame(AlacEncodeContext
                        uint8_t * const *samples)
 {
     PutBitContext *pb = &s->pbctx;
-    const enum AlacRawDataBlockType *ch_elements = ff_alac_channel_elements[s->avctx->channels - 1];
-    const uint8_t *ch_map = ff_alac_channel_layout_offsets[s->avctx->channels - 1];
+    int channels = s->avctx->ch_layout.nb_channels;
+    const enum AlacRawDataBlockType *ch_elements = ff_alac_channel_elements[channels - 1];
+    const uint8_t *ch_map = ff_alac_channel_layout_offsets[channels - 1];
     int ch, element, sce, cpe;
 
     init_put_bits(pb, avpkt->data, avpkt->size);
 
     ch = element = sce = cpe = 0;
-    while (ch < s->avctx->channels) {
+    while (ch < channels) {
         if (ch_elements[element] == TYPE_CPE) {
             write_element(s, TYPE_CPE, cpe, samples[ch_map[ch]],
                           samples[ch_map[ch + 1]]);
@@ -532,7 +533,7 @@ static av_cold int alac_encode_init(AVCo
     s->rc.rice_modifier   = 4;
 
     s->max_coded_frame_size = get_max_frame_size(avctx->frame_size,
-                                                 avctx->channels,
+                                                 avctx->ch_layout.nb_channels,
                                                  avctx->bits_per_raw_sample);
 
     avctx->extradata = av_mallocz(ALAC_EXTRADATA_SIZE + AV_INPUT_BUFFER_PADDING_SIZE);
@@ -545,10 +546,10 @@ static av_cold int alac_encode_init(AVCo
     AV_WB32(alac_extradata+4,  MKBETAG('a','l','a','c'));
     AV_WB32(alac_extradata+12, avctx->frame_size);
     AV_WB8 (alac_extradata+17, avctx->bits_per_raw_sample);
-    AV_WB8 (alac_extradata+21, avctx->channels);
+    AV_WB8 (alac_extradata+21, avctx->ch_layout.nb_channels);
     AV_WB32(alac_extradata+24, s->max_coded_frame_size);
     AV_WB32(alac_extradata+28,
-            avctx->sample_rate * avctx->channels * avctx->bits_per_raw_sample); // average bitrate
+            avctx->sample_rate * avctx->ch_layout.nb_channels * avctx->bits_per_raw_sample); // average bitrate
     AV_WB32(alac_extradata+32, avctx->sample_rate);
 
     // Set relevant extradata fields
@@ -585,7 +586,7 @@ static int alac_encode_frame(AVCodecCont
     s->frame_size = frame->nb_samples;
 
     if (frame->nb_samples < DEFAULT_FRAME_SIZE)
-        max_frame_size = get_max_frame_size(s->frame_size, avctx->channels,
+        max_frame_size = get_max_frame_size(s->frame_size, avctx->ch_layout.nb_channels,
                                             avctx->bits_per_raw_sample);
     else
         max_frame_size = s->max_coded_frame_size;
@@ -616,6 +617,21 @@ static int alac_encode_frame(AVCodecCont
     return 0;
 }
 
+#if FF_API_OLD_CHANNEL_LAYOUT
+static const uint64_t alac_channel_layouts[ALAC_MAX_CHANNELS + 1] = {
+    AV_CH_LAYOUT_MONO,
+    AV_CH_LAYOUT_STEREO,
+    AV_CH_LAYOUT_SURROUND,
+    AV_CH_LAYOUT_4POINT0,
+    AV_CH_LAYOUT_5POINT0_BACK,
+    AV_CH_LAYOUT_5POINT1_BACK,
+    AV_CH_LAYOUT_6POINT1_BACK,
+    AV_CH_LAYOUT_7POINT1_WIDE_BACK,
+    0
+};
+#endif
+
+
 #define OFFSET(x) offsetof(AlacEncodeContext, x)
 #define AE AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
 static const AVOption options[] = {
@@ -632,20 +648,25 @@ static const AVClass alacenc_class = {
     .version    = LIBAVUTIL_VERSION_INT,
 };
 
-const AVCodec ff_alac_encoder = {
-    .name           = "alac",
-    .long_name      = NULL_IF_CONFIG_SMALL("ALAC (Apple Lossless Audio Codec)"),
-    .type           = AVMEDIA_TYPE_AUDIO,
-    .id             = AV_CODEC_ID_ALAC,
+FF_DISABLE_DEPRECATION_WARNINGS
+const FFCodec ff_alac_encoder = {
+    .p.name         = "alac",
+    .p.long_name    = NULL_IF_CONFIG_SMALL("ALAC (Apple Lossless Audio Codec)"),
+    .p.type         = AVMEDIA_TYPE_AUDIO,
+    .p.id           = AV_CODEC_ID_ALAC,
     .priv_data_size = sizeof(AlacEncodeContext),
-    .priv_class     = &alacenc_class,
+    .p.priv_class   = &alacenc_class,
     .init           = alac_encode_init,
-    .encode2        = alac_encode_frame,
+    FF_CODEC_ENCODE_CB(alac_encode_frame),
     .close          = alac_encode_close,
-    .capabilities   = AV_CODEC_CAP_SMALL_LAST_FRAME,
-    .channel_layouts = ff_alac_channel_layouts,
-    .sample_fmts    = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S32P,
+    .p.capabilities = AV_CODEC_CAP_SMALL_LAST_FRAME,
+#if FF_API_OLD_CHANNEL_LAYOUT
+    .p.channel_layouts = alac_channel_layouts,
+#endif
+    .p.ch_layouts   = ff_alac_ch_layouts,
+    .p.sample_fmts  = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S32P,
                                                      AV_SAMPLE_FMT_S16P,
                                                      AV_SAMPLE_FMT_NONE },
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
+FF_ENABLE_DEPRECATION_WARNINGS
diff -pruN 7:5.0.1-3/libavcodec/aliaspixdec.c 7:5.1-1/libavcodec/aliaspixdec.c
--- 7:5.0.1-3/libavcodec/aliaspixdec.c	2022-01-14 18:45:39.000000000 +0000
+++ 7:5.1-1/libavcodec/aliaspixdec.c	2022-07-22 17:58:38.000000000 +0000
@@ -23,14 +23,14 @@
 
 #include "avcodec.h"
 #include "bytestream.h"
+#include "codec_internal.h"
 #include "internal.h"
 
 #define ALIAS_HEADER_SIZE 10
 
-static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
-                        AVPacket *avpkt)
+static int decode_frame(AVCodecContext *avctx, AVFrame *f,
+                        int *got_frame, AVPacket *avpkt)
 {
-    AVFrame *f = data;
     GetByteContext gb;
     int width, height, ret, bits_pixel, pixel;
     uint8_t *out_buf;
@@ -121,11 +121,11 @@ static int decode_frame(AVCodecContext *
     return avpkt->size;
 }
 
-const AVCodec ff_alias_pix_decoder = {
-    .name         = "alias_pix",
-    .long_name    = NULL_IF_CONFIG_SMALL("Alias/Wavefront PIX image"),
-    .type         = AVMEDIA_TYPE_VIDEO,
-    .id           = AV_CODEC_ID_ALIAS_PIX,
-    .decode       = decode_frame,
-    .capabilities = AV_CODEC_CAP_DR1,
+const FFCodec ff_alias_pix_decoder = {
+    .p.name         = "alias_pix",
+    .p.long_name    = NULL_IF_CONFIG_SMALL("Alias/Wavefront PIX image"),
+    .p.type         = AVMEDIA_TYPE_VIDEO,
+    .p.id           = AV_CODEC_ID_ALIAS_PIX,
+    .p.capabilities = AV_CODEC_CAP_DR1,
+    FF_CODEC_DECODE_CB(decode_frame),
 };
diff -pruN 7:5.0.1-3/libavcodec/aliaspixenc.c 7:5.1-1/libavcodec/aliaspixenc.c
--- 7:5.0.1-3/libavcodec/aliaspixenc.c	2022-01-14 18:45:39.000000000 +0000
+++ 7:5.1-1/libavcodec/aliaspixenc.c	2022-07-22 17:58:38.000000000 +0000
@@ -23,8 +23,8 @@
 
 #include "avcodec.h"
 #include "bytestream.h"
+#include "codec_internal.h"
 #include "encode.h"
-#include "internal.h"
 
 #define ALIAS_HEADER_SIZE 10
 
@@ -101,13 +101,13 @@ static int encode_frame(AVCodecContext *
     return 0;
 }
 
-const AVCodec ff_alias_pix_encoder = {
-    .name      = "alias_pix",
-    .long_name = NULL_IF_CONFIG_SMALL("Alias/Wavefront PIX image"),
-    .type      = AVMEDIA_TYPE_VIDEO,
-    .id        = AV_CODEC_ID_ALIAS_PIX,
-    .encode2   = encode_frame,
-    .pix_fmts  = (const enum AVPixelFormat[]) {
+const FFCodec ff_alias_pix_encoder = {
+    .p.name    = "alias_pix",
+    .p.long_name = NULL_IF_CONFIG_SMALL("Alias/Wavefront PIX image"),
+    .p.type    = AVMEDIA_TYPE_VIDEO,
+    .p.id      = AV_CODEC_ID_ALIAS_PIX,
+    FF_CODEC_ENCODE_CB(encode_frame),
+    .p.pix_fmts = (const enum AVPixelFormat[]) {
         AV_PIX_FMT_BGR24, AV_PIX_FMT_GRAY8, AV_PIX_FMT_NONE
     },
 };
diff -pruN 7:5.0.1-3/libavcodec/allcodecs.c 7:5.1-1/libavcodec/allcodecs.c
--- 7:5.0.1-3/libavcodec/allcodecs.c	2022-01-14 18:45:39.000000000 +0000
+++ 7:5.1-1/libavcodec/allcodecs.c	2022-07-22 17:58:38.000000000 +0000
@@ -28,750 +28,763 @@
 #include <string.h>
 
 #include "config.h"
+#include "config_components.h"
 #include "libavutil/thread.h"
 #include "codec.h"
 #include "codec_id.h"
+#include "codec_internal.h"
 
-extern const AVCodec ff_a64multi_encoder;
-extern const AVCodec ff_a64multi5_encoder;
-extern const AVCodec ff_aasc_decoder;
-extern const AVCodec ff_aic_decoder;
-extern const AVCodec ff_alias_pix_encoder;
-extern const AVCodec ff_alias_pix_decoder;
-extern const AVCodec ff_agm_decoder;
-extern const AVCodec ff_amv_encoder;
-extern const AVCodec ff_amv_decoder;
-extern const AVCodec ff_anm_decoder;
-extern const AVCodec ff_ansi_decoder;
-extern const AVCodec ff_apng_encoder;
-extern const AVCodec ff_apng_decoder;
-extern const AVCodec ff_arbc_decoder;
-extern const AVCodec ff_argo_decoder;
-extern const AVCodec ff_asv1_encoder;
-extern const AVCodec ff_asv1_decoder;
-extern const AVCodec ff_asv2_encoder;
-extern const AVCodec ff_asv2_decoder;
-extern const AVCodec ff_aura_decoder;
-extern const AVCodec ff_aura2_decoder;
-extern const AVCodec ff_avrp_encoder;
-extern const AVCodec ff_avrp_decoder;
-extern const AVCodec ff_avrn_decoder;
-extern const AVCodec ff_avs_decoder;
-extern const AVCodec ff_avui_encoder;
-extern const AVCodec ff_avui_decoder;
-extern const AVCodec ff_ayuv_encoder;
-extern const AVCodec ff_ayuv_decoder;
-extern const AVCodec ff_bethsoftvid_decoder;
-extern const AVCodec ff_bfi_decoder;
-extern const AVCodec ff_bink_decoder;
-extern const AVCodec ff_bitpacked_decoder;
-extern const AVCodec ff_bitpacked_encoder;
-extern const AVCodec ff_bmp_encoder;
-extern const AVCodec ff_bmp_decoder;
-extern const AVCodec ff_bmv_video_decoder;
-extern const AVCodec ff_brender_pix_decoder;
-extern const AVCodec ff_c93_decoder;
-extern const AVCodec ff_cavs_decoder;
-extern const AVCodec ff_cdgraphics_decoder;
-extern const AVCodec ff_cdtoons_decoder;
-extern const AVCodec ff_cdxl_decoder;
-extern const AVCodec ff_cfhd_encoder;
-extern const AVCodec ff_cfhd_decoder;
-extern const AVCodec ff_cinepak_encoder;
-extern const AVCodec ff_cinepak_decoder;
-extern const AVCodec ff_clearvideo_decoder;
-extern const AVCodec ff_cljr_encoder;
-extern const AVCodec ff_cljr_decoder;
-extern const AVCodec ff_cllc_decoder;
-extern const AVCodec ff_comfortnoise_encoder;
-extern const AVCodec ff_comfortnoise_decoder;
-extern const AVCodec ff_cpia_decoder;
-extern const AVCodec ff_cri_decoder;
-extern const AVCodec ff_cscd_decoder;
-extern const AVCodec ff_cyuv_decoder;
-extern const AVCodec ff_dds_decoder;
-extern const AVCodec ff_dfa_decoder;
-extern const AVCodec ff_dirac_decoder;
-extern const AVCodec ff_dnxhd_encoder;
-extern const AVCodec ff_dnxhd_decoder;
-extern const AVCodec ff_dpx_encoder;
-extern const AVCodec ff_dpx_decoder;
-extern const AVCodec ff_dsicinvideo_decoder;
-extern const AVCodec ff_dvaudio_decoder;
-extern const AVCodec ff_dvvideo_encoder;
-extern const AVCodec ff_dvvideo_decoder;
-extern const AVCodec ff_dxa_decoder;
-extern const AVCodec ff_dxtory_decoder;
-extern const AVCodec ff_dxv_decoder;
-extern const AVCodec ff_eacmv_decoder;
-extern const AVCodec ff_eamad_decoder;
-extern const AVCodec ff_eatgq_decoder;
-extern const AVCodec ff_eatgv_decoder;
-extern const AVCodec ff_eatqi_decoder;
-extern const AVCodec ff_eightbps_decoder;
-extern const AVCodec ff_eightsvx_exp_decoder;
-extern const AVCodec ff_eightsvx_fib_decoder;
-extern const AVCodec ff_escape124_decoder;
-extern const AVCodec ff_escape130_decoder;
-extern const AVCodec ff_exr_encoder;
-extern const AVCodec ff_exr_decoder;
-extern const AVCodec ff_ffv1_encoder;
-extern const AVCodec ff_ffv1_decoder;
-extern const AVCodec ff_ffvhuff_encoder;
-extern const AVCodec ff_ffvhuff_decoder;
-extern const AVCodec ff_fic_decoder;
-extern const AVCodec ff_fits_encoder;
-extern const AVCodec ff_fits_decoder;
-extern const AVCodec ff_flashsv_encoder;
-extern const AVCodec ff_flashsv_decoder;
-extern const AVCodec ff_flashsv2_encoder;
-extern const AVCodec ff_flashsv2_decoder;
-extern const AVCodec ff_flic_decoder;
-extern const AVCodec ff_flv_encoder;
-extern const AVCodec ff_flv_decoder;
-extern const AVCodec ff_fmvc_decoder;
-extern const AVCodec ff_fourxm_decoder;
-extern const AVCodec ff_fraps_decoder;
-extern const AVCodec ff_frwu_decoder;
-extern const AVCodec ff_g2m_decoder;
-extern const AVCodec ff_gdv_decoder;
-extern const AVCodec ff_gem_decoder;
-extern const AVCodec ff_gif_encoder;
-extern const AVCodec ff_gif_decoder;
-extern const AVCodec ff_h261_encoder;
-extern const AVCodec ff_h261_decoder;
-extern const AVCodec ff_h263_encoder;
-extern const AVCodec ff_h263_decoder;
-extern const AVCodec ff_h263i_decoder;
-extern const AVCodec ff_h263p_encoder;
-extern const AVCodec ff_h263p_decoder;
-extern const AVCodec ff_h263_v4l2m2m_decoder;
-extern const AVCodec ff_h264_decoder;
-extern const AVCodec ff_h264_crystalhd_decoder;
-extern const AVCodec ff_h264_v4l2m2m_decoder;
-extern const AVCodec ff_h264_mediacodec_decoder;
-extern const AVCodec ff_h264_mmal_decoder;
-extern const AVCodec ff_h264_qsv_decoder;
-extern const AVCodec ff_h264_rkmpp_decoder;
-extern const AVCodec ff_hap_encoder;
-extern const AVCodec ff_hap_decoder;
-extern const AVCodec ff_hevc_decoder;
-extern const AVCodec ff_hevc_qsv_decoder;
-extern const AVCodec ff_hevc_rkmpp_decoder;
-extern const AVCodec ff_hevc_v4l2m2m_decoder;
-extern const AVCodec ff_hnm4_video_decoder;
-extern const AVCodec ff_hq_hqa_decoder;
-extern const AVCodec ff_hqx_decoder;
-extern const AVCodec ff_huffyuv_encoder;
-extern const AVCodec ff_huffyuv_decoder;
-extern const AVCodec ff_hymt_decoder;
-extern const AVCodec ff_idcin_decoder;
-extern const AVCodec ff_iff_ilbm_decoder;
-extern const AVCodec ff_imm4_decoder;
-extern const AVCodec ff_imm5_decoder;
-extern const AVCodec ff_indeo2_decoder;
-extern const AVCodec ff_indeo3_decoder;
-extern const AVCodec ff_indeo4_decoder;
-extern const AVCodec ff_indeo5_decoder;
-extern const AVCodec ff_interplay_video_decoder;
-extern const AVCodec ff_ipu_decoder;
-extern const AVCodec ff_jpeg2000_encoder;
-extern const AVCodec ff_jpeg2000_decoder;
-extern const AVCodec ff_jpegls_encoder;
-extern const AVCodec ff_jpegls_decoder;
-extern const AVCodec ff_jv_decoder;
-extern const AVCodec ff_kgv1_decoder;
-extern const AVCodec ff_kmvc_decoder;
-extern const AVCodec ff_lagarith_decoder;
-extern const AVCodec ff_ljpeg_encoder;
-extern const AVCodec ff_loco_decoder;
-extern const AVCodec ff_lscr_decoder;
-extern const AVCodec ff_m101_decoder;
-extern const AVCodec ff_magicyuv_encoder;
-extern const AVCodec ff_magicyuv_decoder;
-extern const AVCodec ff_mdec_decoder;
-extern const AVCodec ff_mimic_decoder;
-extern const AVCodec ff_mjpeg_encoder;
-extern const AVCodec ff_mjpeg_decoder;
-extern const AVCodec ff_mjpegb_decoder;
-extern const AVCodec ff_mmvideo_decoder;
-extern const AVCodec ff_mobiclip_decoder;
-extern const AVCodec ff_motionpixels_decoder;
-extern const AVCodec ff_mpeg1video_encoder;
-extern const AVCodec ff_mpeg1video_decoder;
-extern const AVCodec ff_mpeg2video_encoder;
-extern const AVCodec ff_mpeg2video_decoder;
-extern const AVCodec ff_mpeg4_encoder;
-extern const AVCodec ff_mpeg4_decoder;
-extern const AVCodec ff_mpeg4_crystalhd_decoder;
-extern const AVCodec ff_mpeg4_v4l2m2m_decoder;
-extern const AVCodec ff_mpeg4_mmal_decoder;
-extern const AVCodec ff_mpegvideo_decoder;
-extern const AVCodec ff_mpeg1_v4l2m2m_decoder;
-extern const AVCodec ff_mpeg2_mmal_decoder;
-extern const AVCodec ff_mpeg2_crystalhd_decoder;
-extern const AVCodec ff_mpeg2_v4l2m2m_decoder;
-extern const AVCodec ff_mpeg2_qsv_decoder;
-extern const AVCodec ff_mpeg2_mediacodec_decoder;
-extern const AVCodec ff_msa1_decoder;
-extern const AVCodec ff_mscc_decoder;
-extern const AVCodec ff_msmpeg4v1_decoder;
-extern const AVCodec ff_msmpeg4v2_encoder;
-extern const AVCodec ff_msmpeg4v2_decoder;
-extern const AVCodec ff_msmpeg4v3_encoder;
-extern const AVCodec ff_msmpeg4v3_decoder;
-extern const AVCodec ff_msmpeg4_crystalhd_decoder;
-extern const AVCodec ff_msp2_decoder;
-extern const AVCodec ff_msrle_decoder;
-extern const AVCodec ff_mss1_decoder;
-extern const AVCodec ff_mss2_decoder;
-extern const AVCodec ff_msvideo1_encoder;
-extern const AVCodec ff_msvideo1_decoder;
-extern const AVCodec ff_mszh_decoder;
-extern const AVCodec ff_mts2_decoder;
-extern const AVCodec ff_mv30_decoder;
-extern const AVCodec ff_mvc1_decoder;
-extern const AVCodec ff_mvc2_decoder;
-extern const AVCodec ff_mvdv_decoder;
-extern const AVCodec ff_mvha_decoder;
-extern const AVCodec ff_mwsc_decoder;
-extern const AVCodec ff_mxpeg_decoder;
-extern const AVCodec ff_notchlc_decoder;
-extern const AVCodec ff_nuv_decoder;
-extern const AVCodec ff_paf_video_decoder;
-extern const AVCodec ff_pam_encoder;
-extern const AVCodec ff_pam_decoder;
-extern const AVCodec ff_pbm_encoder;
-extern const AVCodec ff_pbm_decoder;
-extern const AVCodec ff_pcx_encoder;
-extern const AVCodec ff_pcx_decoder;
-extern const AVCodec ff_pfm_encoder;
-extern const AVCodec ff_pfm_decoder;
-extern const AVCodec ff_pgm_encoder;
-extern const AVCodec ff_pgm_decoder;
-extern const AVCodec ff_pgmyuv_encoder;
-extern const AVCodec ff_pgmyuv_decoder;
-extern const AVCodec ff_pgx_decoder;
-extern const AVCodec ff_photocd_decoder;
-extern const AVCodec ff_pictor_decoder;
-extern const AVCodec ff_pixlet_decoder;
-extern const AVCodec ff_png_encoder;
-extern const AVCodec ff_png_decoder;
-extern const AVCodec ff_ppm_encoder;
-extern const AVCodec ff_ppm_decoder;
-extern const AVCodec ff_prores_encoder;
-extern const AVCodec ff_prores_decoder;
-extern const AVCodec ff_prores_aw_encoder;
-extern const AVCodec ff_prores_ks_encoder;
-extern const AVCodec ff_prosumer_decoder;
-extern const AVCodec ff_psd_decoder;
-extern const AVCodec ff_ptx_decoder;
-extern const AVCodec ff_qdraw_decoder;
-extern const AVCodec ff_qpeg_decoder;
-extern const AVCodec ff_qtrle_encoder;
-extern const AVCodec ff_qtrle_decoder;
-extern const AVCodec ff_r10k_encoder;
-extern const AVCodec ff_r10k_decoder;
-extern const AVCodec ff_r210_encoder;
-extern const AVCodec ff_r210_decoder;
-extern const AVCodec ff_rasc_decoder;
-extern const AVCodec ff_rawvideo_encoder;
-extern const AVCodec ff_rawvideo_decoder;
-extern const AVCodec ff_rl2_decoder;
-extern const AVCodec ff_roq_encoder;
-extern const AVCodec ff_roq_decoder;
-extern const AVCodec ff_rpza_encoder;
-extern const AVCodec ff_rpza_decoder;
-extern const AVCodec ff_rscc_decoder;
-extern const AVCodec ff_rv10_encoder;
-extern const AVCodec ff_rv10_decoder;
-extern const AVCodec ff_rv20_encoder;
-extern const AVCodec ff_rv20_decoder;
-extern const AVCodec ff_rv30_decoder;
-extern const AVCodec ff_rv40_decoder;
-extern const AVCodec ff_s302m_encoder;
-extern const AVCodec ff_s302m_decoder;
-extern const AVCodec ff_sanm_decoder;
-extern const AVCodec ff_scpr_decoder;
-extern const AVCodec ff_screenpresso_decoder;
-extern const AVCodec ff_sga_decoder;
-extern const AVCodec ff_sgi_encoder;
-extern const AVCodec ff_sgi_decoder;
-extern const AVCodec ff_sgirle_decoder;
-extern const AVCodec ff_sheervideo_decoder;
-extern const AVCodec ff_simbiosis_imx_decoder;
-extern const AVCodec ff_smacker_decoder;
-extern const AVCodec ff_smc_encoder;
-extern const AVCodec ff_smc_decoder;
-extern const AVCodec ff_smvjpeg_decoder;
-extern const AVCodec ff_snow_encoder;
-extern const AVCodec ff_snow_decoder;
-extern const AVCodec ff_sp5x_decoder;
-extern const AVCodec ff_speedhq_decoder;
-extern const AVCodec ff_speedhq_encoder;
-extern const AVCodec ff_speex_decoder;
-extern const AVCodec ff_srgc_decoder;
-extern const AVCodec ff_sunrast_encoder;
-extern const AVCodec ff_sunrast_decoder;
-extern const AVCodec ff_svq1_encoder;
-extern const AVCodec ff_svq1_decoder;
-extern const AVCodec ff_svq3_decoder;
-extern const AVCodec ff_targa_encoder;
-extern const AVCodec ff_targa_decoder;
-extern const AVCodec ff_targa_y216_decoder;
-extern const AVCodec ff_tdsc_decoder;
-extern const AVCodec ff_theora_decoder;
-extern const AVCodec ff_thp_decoder;
-extern const AVCodec ff_tiertexseqvideo_decoder;
-extern const AVCodec ff_tiff_encoder;
-extern const AVCodec ff_tiff_decoder;
-extern const AVCodec ff_tmv_decoder;
-extern const AVCodec ff_truemotion1_decoder;
-extern const AVCodec ff_truemotion2_decoder;
-extern const AVCodec ff_truemotion2rt_decoder;
-extern const AVCodec ff_tscc_decoder;
-extern const AVCodec ff_tscc2_decoder;
-extern const AVCodec ff_txd_decoder;
-extern const AVCodec ff_ulti_decoder;
-extern const AVCodec ff_utvideo_encoder;
-extern const AVCodec ff_utvideo_decoder;
-extern const AVCodec ff_v210_encoder;
-extern const AVCodec ff_v210_decoder;
-extern const AVCodec ff_v210x_decoder;
-extern const AVCodec ff_v308_encoder;
-extern const AVCodec ff_v308_decoder;
-extern const AVCodec ff_v408_encoder;
-extern const AVCodec ff_v408_decoder;
-extern const AVCodec ff_v410_encoder;
-extern const AVCodec ff_v410_decoder;
-extern const AVCodec ff_vb_decoder;
-extern const AVCodec ff_vble_decoder;
-extern const AVCodec ff_vc1_decoder;
-extern const AVCodec ff_vc1_crystalhd_decoder;
-extern const AVCodec ff_vc1image_decoder;
-extern const AVCodec ff_vc1_mmal_decoder;
-extern const AVCodec ff_vc1_qsv_decoder;
-extern const AVCodec ff_vc1_v4l2m2m_decoder;
-extern const AVCodec ff_vc2_encoder;
-extern const AVCodec ff_vcr1_decoder;
-extern const AVCodec ff_vmdvideo_decoder;
-extern const AVCodec ff_vmnc_decoder;
-extern const AVCodec ff_vp3_decoder;
-extern const AVCodec ff_vp4_decoder;
-extern const AVCodec ff_vp5_decoder;
-extern const AVCodec ff_vp6_decoder;
-extern const AVCodec ff_vp6a_decoder;
-extern const AVCodec ff_vp6f_decoder;
-extern const AVCodec ff_vp7_decoder;
-extern const AVCodec ff_vp8_decoder;
-extern const AVCodec ff_vp8_rkmpp_decoder;
-extern const AVCodec ff_vp8_v4l2m2m_decoder;
-extern const AVCodec ff_vp9_decoder;
-extern const AVCodec ff_vp9_rkmpp_decoder;
-extern const AVCodec ff_vp9_v4l2m2m_decoder;
-extern const AVCodec ff_vqa_decoder;
-extern const AVCodec ff_webp_decoder;
-extern const AVCodec ff_wcmv_decoder;
-extern const AVCodec ff_wrapped_avframe_encoder;
-extern const AVCodec ff_wrapped_avframe_decoder;
-extern const AVCodec ff_wmv1_encoder;
-extern const AVCodec ff_wmv1_decoder;
-extern const AVCodec ff_wmv2_encoder;
-extern const AVCodec ff_wmv2_decoder;
-extern const AVCodec ff_wmv3_decoder;
-extern const AVCodec ff_wmv3_crystalhd_decoder;
-extern const AVCodec ff_wmv3image_decoder;
-extern const AVCodec ff_wnv1_decoder;
-extern const AVCodec ff_xan_wc3_decoder;
-extern const AVCodec ff_xan_wc4_decoder;
-extern const AVCodec ff_xbm_encoder;
-extern const AVCodec ff_xbm_decoder;
-extern const AVCodec ff_xface_encoder;
-extern const AVCodec ff_xface_decoder;
-extern const AVCodec ff_xl_decoder;
-extern const AVCodec ff_xpm_decoder;
-extern const AVCodec ff_xwd_encoder;
-extern const AVCodec ff_xwd_decoder;
-extern const AVCodec ff_y41p_encoder;
-extern const AVCodec ff_y41p_decoder;
-extern const AVCodec ff_ylc_decoder;
-extern const AVCodec ff_yop_decoder;
-extern const AVCodec ff_yuv4_encoder;
-extern const AVCodec ff_yuv4_decoder;
-extern const AVCodec ff_zero12v_decoder;
-extern const AVCodec ff_zerocodec_decoder;
-extern const AVCodec ff_zlib_encoder;
-extern const AVCodec ff_zlib_decoder;
-extern const AVCodec ff_zmbv_encoder;
-extern const AVCodec ff_zmbv_decoder;
+extern const FFCodec ff_a64multi_encoder;
+extern const FFCodec ff_a64multi5_encoder;
+extern const FFCodec ff_aasc_decoder;
+extern const FFCodec ff_aic_decoder;
+extern const FFCodec ff_alias_pix_encoder;
+extern const FFCodec ff_alias_pix_decoder;
+extern const FFCodec ff_agm_decoder;
+extern const FFCodec ff_amv_encoder;
+extern const FFCodec ff_amv_decoder;
+extern const FFCodec ff_anm_decoder;
+extern const FFCodec ff_ansi_decoder;
+extern const FFCodec ff_apng_encoder;
+extern const FFCodec ff_apng_decoder;
+extern const FFCodec ff_arbc_decoder;
+extern const FFCodec ff_argo_decoder;
+extern const FFCodec ff_asv1_encoder;
+extern const FFCodec ff_asv1_decoder;
+extern const FFCodec ff_asv2_encoder;
+extern const FFCodec ff_asv2_decoder;
+extern const FFCodec ff_aura_decoder;
+extern const FFCodec ff_aura2_decoder;
+extern const FFCodec ff_avrp_encoder;
+extern const FFCodec ff_avrp_decoder;
+extern const FFCodec ff_avrn_decoder;
+extern const FFCodec ff_avs_decoder;
+extern const FFCodec ff_avui_encoder;
+extern const FFCodec ff_avui_decoder;
+extern const FFCodec ff_ayuv_encoder;
+extern const FFCodec ff_ayuv_decoder;
+extern const FFCodec ff_bethsoftvid_decoder;
+extern const FFCodec ff_bfi_decoder;
+extern const FFCodec ff_bink_decoder;
+extern const FFCodec ff_bitpacked_decoder;
+extern const FFCodec ff_bitpacked_encoder;
+extern const FFCodec ff_bmp_encoder;
+extern const FFCodec ff_bmp_decoder;
+extern const FFCodec ff_bmv_video_decoder;
+extern const FFCodec ff_brender_pix_decoder;
+extern const FFCodec ff_c93_decoder;
+extern const FFCodec ff_cavs_decoder;
+extern const FFCodec ff_cdgraphics_decoder;
+extern const FFCodec ff_cdtoons_decoder;
+extern const FFCodec ff_cdxl_decoder;
+extern const FFCodec ff_cfhd_encoder;
+extern const FFCodec ff_cfhd_decoder;
+extern const FFCodec ff_cinepak_encoder;
+extern const FFCodec ff_cinepak_decoder;
+extern const FFCodec ff_clearvideo_decoder;
+extern const FFCodec ff_cljr_encoder;
+extern const FFCodec ff_cljr_decoder;
+extern const FFCodec ff_cllc_decoder;
+extern const FFCodec ff_comfortnoise_encoder;
+extern const FFCodec ff_comfortnoise_decoder;
+extern const FFCodec ff_cpia_decoder;
+extern const FFCodec ff_cri_decoder;
+extern const FFCodec ff_cscd_decoder;
+extern const FFCodec ff_cyuv_decoder;
+extern const FFCodec ff_dds_decoder;
+extern const FFCodec ff_dfa_decoder;
+extern const FFCodec ff_dirac_decoder;
+extern const FFCodec ff_dnxhd_encoder;
+extern const FFCodec ff_dnxhd_decoder;
+extern const FFCodec ff_dpx_encoder;
+extern const FFCodec ff_dpx_decoder;
+extern const FFCodec ff_dsicinvideo_decoder;
+extern const FFCodec ff_dvaudio_decoder;
+extern const FFCodec ff_dvvideo_encoder;
+extern const FFCodec ff_dvvideo_decoder;
+extern const FFCodec ff_dxa_decoder;
+extern const FFCodec ff_dxtory_decoder;
+extern const FFCodec ff_dxv_decoder;
+extern const FFCodec ff_eacmv_decoder;
+extern const FFCodec ff_eamad_decoder;
+extern const FFCodec ff_eatgq_decoder;
+extern const FFCodec ff_eatgv_decoder;
+extern const FFCodec ff_eatqi_decoder;
+extern const FFCodec ff_eightbps_decoder;
+extern const FFCodec ff_eightsvx_exp_decoder;
+extern const FFCodec ff_eightsvx_fib_decoder;
+extern const FFCodec ff_escape124_decoder;
+extern const FFCodec ff_escape130_decoder;
+extern const FFCodec ff_exr_encoder;
+extern const FFCodec ff_exr_decoder;
+extern const FFCodec ff_ffv1_encoder;
+extern const FFCodec ff_ffv1_decoder;
+extern const FFCodec ff_ffvhuff_encoder;
+extern const FFCodec ff_ffvhuff_decoder;
+extern const FFCodec ff_fic_decoder;
+extern const FFCodec ff_fits_encoder;
+extern const FFCodec ff_fits_decoder;
+extern const FFCodec ff_flashsv_encoder;
+extern const FFCodec ff_flashsv_decoder;
+extern const FFCodec ff_flashsv2_encoder;
+extern const FFCodec ff_flashsv2_decoder;
+extern const FFCodec ff_flic_decoder;
+extern const FFCodec ff_flv_encoder;
+extern const FFCodec ff_flv_decoder;
+extern const FFCodec ff_fmvc_decoder;
+extern const FFCodec ff_fourxm_decoder;
+extern const FFCodec ff_fraps_decoder;
+extern const FFCodec ff_frwu_decoder;
+extern const FFCodec ff_g2m_decoder;
+extern const FFCodec ff_gdv_decoder;
+extern const FFCodec ff_gem_decoder;
+extern const FFCodec ff_gif_encoder;
+extern const FFCodec ff_gif_decoder;
+extern const FFCodec ff_h261_encoder;
+extern const FFCodec ff_h261_decoder;
+extern const FFCodec ff_h263_encoder;
+extern const FFCodec ff_h263_decoder;
+extern const FFCodec ff_h263i_decoder;
+extern const FFCodec ff_h263p_encoder;
+extern const FFCodec ff_h263p_decoder;
+extern const FFCodec ff_h263_v4l2m2m_decoder;
+extern const FFCodec ff_h264_decoder;
+extern const FFCodec ff_h264_crystalhd_decoder;
+extern const FFCodec ff_h264_v4l2m2m_decoder;
+extern const FFCodec ff_h264_mediacodec_decoder;
+extern const FFCodec ff_h264_mmal_decoder;
+extern const FFCodec ff_h264_qsv_decoder;
+extern const FFCodec ff_h264_rkmpp_decoder;
+extern const FFCodec ff_hap_encoder;
+extern const FFCodec ff_hap_decoder;
+extern const FFCodec ff_hevc_decoder;
+extern const FFCodec ff_hevc_qsv_decoder;
+extern const FFCodec ff_hevc_rkmpp_decoder;
+extern const FFCodec ff_hevc_v4l2m2m_decoder;
+extern const FFCodec ff_hnm4_video_decoder;
+extern const FFCodec ff_hq_hqa_decoder;
+extern const FFCodec ff_hqx_decoder;
+extern const FFCodec ff_huffyuv_encoder;
+extern const FFCodec ff_huffyuv_decoder;
+extern const FFCodec ff_hymt_decoder;
+extern const FFCodec ff_idcin_decoder;
+extern const FFCodec ff_iff_ilbm_decoder;
+extern const FFCodec ff_imm4_decoder;
+extern const FFCodec ff_imm5_decoder;
+extern const FFCodec ff_indeo2_decoder;
+extern const FFCodec ff_indeo3_decoder;
+extern const FFCodec ff_indeo4_decoder;
+extern const FFCodec ff_indeo5_decoder;
+extern const FFCodec ff_interplay_video_decoder;
+extern const FFCodec ff_ipu_decoder;
+extern const FFCodec ff_jpeg2000_encoder;
+extern const FFCodec ff_jpeg2000_decoder;
+extern const FFCodec ff_jpegls_encoder;
+extern const FFCodec ff_jpegls_decoder;
+extern const FFCodec ff_jv_decoder;
+extern const FFCodec ff_kgv1_decoder;
+extern const FFCodec ff_kmvc_decoder;
+extern const FFCodec ff_lagarith_decoder;
+extern const FFCodec ff_ljpeg_encoder;
+extern const FFCodec ff_loco_decoder;
+extern const FFCodec ff_lscr_decoder;
+extern const FFCodec ff_m101_decoder;
+extern const FFCodec ff_magicyuv_encoder;
+extern const FFCodec ff_magicyuv_decoder;
+extern const FFCodec ff_mdec_decoder;
+extern const FFCodec ff_mimic_decoder;
+extern const FFCodec ff_mjpeg_encoder;
+extern const FFCodec ff_mjpeg_decoder;
+extern const FFCodec ff_mjpegb_decoder;
+extern const FFCodec ff_mmvideo_decoder;
+extern const FFCodec ff_mobiclip_decoder;
+extern const FFCodec ff_motionpixels_decoder;
+extern const FFCodec ff_mpeg1video_encoder;
+extern const FFCodec ff_mpeg1video_decoder;
+extern const FFCodec ff_mpeg2video_encoder;
+extern const FFCodec ff_mpeg2video_decoder;
+extern const FFCodec ff_mpeg4_encoder;
+extern const FFCodec ff_mpeg4_decoder;
+extern const FFCodec ff_mpeg4_crystalhd_decoder;
+extern const FFCodec ff_mpeg4_v4l2m2m_decoder;
+extern const FFCodec ff_mpeg4_mmal_decoder;
+extern const FFCodec ff_mpegvideo_decoder;
+extern const FFCodec ff_mpeg1_v4l2m2m_decoder;
+extern const FFCodec ff_mpeg2_mmal_decoder;
+extern const FFCodec ff_mpeg2_crystalhd_decoder;
+extern const FFCodec ff_mpeg2_v4l2m2m_decoder;
+extern const FFCodec ff_mpeg2_qsv_decoder;
+extern const FFCodec ff_mpeg2_mediacodec_decoder;
+extern const FFCodec ff_msa1_decoder;
+extern const FFCodec ff_mscc_decoder;
+extern const FFCodec ff_msmpeg4v1_decoder;
+extern const FFCodec ff_msmpeg4v2_encoder;
+extern const FFCodec ff_msmpeg4v2_decoder;
+extern const FFCodec ff_msmpeg4v3_encoder;
+extern const FFCodec ff_msmpeg4v3_decoder;
+extern const FFCodec ff_msmpeg4_crystalhd_decoder;
+extern const FFCodec ff_msp2_decoder;
+extern const FFCodec ff_msrle_decoder;
+extern const FFCodec ff_mss1_decoder;
+extern const FFCodec ff_mss2_decoder;
+extern const FFCodec ff_msvideo1_encoder;
+extern const FFCodec ff_msvideo1_decoder;
+extern const FFCodec ff_mszh_decoder;
+extern const FFCodec ff_mts2_decoder;
+extern const FFCodec ff_mv30_decoder;
+extern const FFCodec ff_mvc1_decoder;
+extern const FFCodec ff_mvc2_decoder;
+extern const FFCodec ff_mvdv_decoder;
+extern const FFCodec ff_mvha_decoder;
+extern const FFCodec ff_mwsc_decoder;
+extern const FFCodec ff_mxpeg_decoder;
+extern const FFCodec ff_notchlc_decoder;
+extern const FFCodec ff_nuv_decoder;
+extern const FFCodec ff_paf_video_decoder;
+extern const FFCodec ff_pam_encoder;
+extern const FFCodec ff_pam_decoder;
+extern const FFCodec ff_pbm_encoder;
+extern const FFCodec ff_pbm_decoder;
+extern const FFCodec ff_pcx_encoder;
+extern const FFCodec ff_pcx_decoder;
+extern const FFCodec ff_pfm_encoder;
+extern const FFCodec ff_pfm_decoder;
+extern const FFCodec ff_pgm_encoder;
+extern const FFCodec ff_pgm_decoder;
+extern const FFCodec ff_pgmyuv_encoder;
+extern const FFCodec ff_pgmyuv_decoder;
+extern const FFCodec ff_pgx_decoder;
+extern const FFCodec ff_phm_encoder;
+extern const FFCodec ff_phm_decoder;
+extern const FFCodec ff_photocd_decoder;
+extern const FFCodec ff_pictor_decoder;
+extern const FFCodec ff_pixlet_decoder;
+extern const FFCodec ff_png_encoder;
+extern const FFCodec ff_png_decoder;
+extern const FFCodec ff_ppm_encoder;
+extern const FFCodec ff_ppm_decoder;
+extern const FFCodec ff_prores_encoder;
+extern const FFCodec ff_prores_decoder;
+extern const FFCodec ff_prores_aw_encoder;
+extern const FFCodec ff_prores_ks_encoder;
+extern const FFCodec ff_prosumer_decoder;
+extern const FFCodec ff_psd_decoder;
+extern const FFCodec ff_ptx_decoder;
+extern const FFCodec ff_qdraw_decoder;
+extern const FFCodec ff_qoi_encoder;
+extern const FFCodec ff_qoi_decoder;
+extern const FFCodec ff_qpeg_decoder;
+extern const FFCodec ff_qtrle_encoder;
+extern const FFCodec ff_qtrle_decoder;
+extern const FFCodec ff_r10k_encoder;
+extern const FFCodec ff_r10k_decoder;
+extern const FFCodec ff_r210_encoder;
+extern const FFCodec ff_r210_decoder;
+extern const FFCodec ff_rasc_decoder;
+extern const FFCodec ff_rawvideo_encoder;
+extern const FFCodec ff_rawvideo_decoder;
+extern const FFCodec ff_rl2_decoder;
+extern const FFCodec ff_roq_encoder;
+extern const FFCodec ff_roq_decoder;
+extern const FFCodec ff_rpza_encoder;
+extern const FFCodec ff_rpza_decoder;
+extern const FFCodec ff_rscc_decoder;
+extern const FFCodec ff_rv10_encoder;
+extern const FFCodec ff_rv10_decoder;
+extern const FFCodec ff_rv20_encoder;
+extern const FFCodec ff_rv20_decoder;
+extern const FFCodec ff_rv30_decoder;
+extern const FFCodec ff_rv40_decoder;
+extern const FFCodec ff_s302m_encoder;
+extern const FFCodec ff_s302m_decoder;
+extern const FFCodec ff_sanm_decoder;
+extern const FFCodec ff_scpr_decoder;
+extern const FFCodec ff_screenpresso_decoder;
+extern const FFCodec ff_sga_decoder;
+extern const FFCodec ff_sgi_encoder;
+extern const FFCodec ff_sgi_decoder;
+extern const FFCodec ff_sgirle_decoder;
+extern const FFCodec ff_sheervideo_decoder;
+extern const FFCodec ff_simbiosis_imx_decoder;
+extern const FFCodec ff_smacker_decoder;
+extern const FFCodec ff_smc_encoder;
+extern const FFCodec ff_smc_decoder;
+extern const FFCodec ff_smvjpeg_decoder;
+extern const FFCodec ff_snow_encoder;
+extern const FFCodec ff_snow_decoder;
+extern const FFCodec ff_sp5x_decoder;
+extern const FFCodec ff_speedhq_decoder;
+extern const FFCodec ff_speedhq_encoder;
+extern const FFCodec ff_speex_decoder;
+extern const FFCodec ff_srgc_decoder;
+extern const FFCodec ff_sunrast_encoder;
+extern const FFCodec ff_sunrast_decoder;
+extern const FFCodec ff_svq1_encoder;
+extern const FFCodec ff_svq1_decoder;
+extern const FFCodec ff_svq3_decoder;
+extern const FFCodec ff_targa_encoder;
+extern const FFCodec ff_targa_decoder;
+extern const FFCodec ff_targa_y216_decoder;
+extern const FFCodec ff_tdsc_decoder;
+extern const FFCodec ff_theora_decoder;
+extern const FFCodec ff_thp_decoder;
+extern const FFCodec ff_tiertexseqvideo_decoder;
+extern const FFCodec ff_tiff_encoder;
+extern const FFCodec ff_tiff_decoder;
+extern const FFCodec ff_tmv_decoder;
+extern const FFCodec ff_truemotion1_decoder;
+extern const FFCodec ff_truemotion2_decoder;
+extern const FFCodec ff_truemotion2rt_decoder;
+extern const FFCodec ff_tscc_decoder;
+extern const FFCodec ff_tscc2_decoder;
+extern const FFCodec ff_txd_decoder;
+extern const FFCodec ff_ulti_decoder;
+extern const FFCodec ff_utvideo_encoder;
+extern const FFCodec ff_utvideo_decoder;
+extern const FFCodec ff_v210_encoder;
+extern const FFCodec ff_v210_decoder;
+extern const FFCodec ff_v210x_decoder;
+extern const FFCodec ff_v308_encoder;
+extern const FFCodec ff_v308_decoder;
+extern const FFCodec ff_v408_encoder;
+extern const FFCodec ff_v408_decoder;
+extern const FFCodec ff_v410_encoder;
+extern const FFCodec ff_v410_decoder;
+extern const FFCodec ff_vb_decoder;
+extern const FFCodec ff_vbn_encoder;
+extern const FFCodec ff_vbn_decoder;
+extern const FFCodec ff_vble_decoder;
+extern const FFCodec ff_vc1_decoder;
+extern const FFCodec ff_vc1_crystalhd_decoder;
+extern const FFCodec ff_vc1image_decoder;
+extern const FFCodec ff_vc1_mmal_decoder;
+extern const FFCodec ff_vc1_qsv_decoder;
+extern const FFCodec ff_vc1_v4l2m2m_decoder;
+extern const FFCodec ff_vc2_encoder;
+extern const FFCodec ff_vcr1_decoder;
+extern const FFCodec ff_vmdvideo_decoder;
+extern const FFCodec ff_vmnc_decoder;
+extern const FFCodec ff_vp3_decoder;
+extern const FFCodec ff_vp4_decoder;
+extern const FFCodec ff_vp5_decoder;
+extern const FFCodec ff_vp6_decoder;
+extern const FFCodec ff_vp6a_decoder;
+extern const FFCodec ff_vp6f_decoder;
+extern const FFCodec ff_vp7_decoder;
+extern const FFCodec ff_vp8_decoder;
+extern const FFCodec ff_vp8_rkmpp_decoder;
+extern const FFCodec ff_vp8_v4l2m2m_decoder;
+extern const FFCodec ff_vp9_decoder;
+extern const FFCodec ff_vp9_rkmpp_decoder;
+extern const FFCodec ff_vp9_v4l2m2m_decoder;
+extern const FFCodec ff_vqa_decoder;
+extern const FFCodec ff_webp_decoder;
+extern const FFCodec ff_wcmv_decoder;
+extern const FFCodec ff_wrapped_avframe_encoder;
+extern const FFCodec ff_wrapped_avframe_decoder;
+extern const FFCodec ff_wmv1_encoder;
+extern const FFCodec ff_wmv1_decoder;
+extern const FFCodec ff_wmv2_encoder;
+extern const FFCodec ff_wmv2_decoder;
+extern const FFCodec ff_wmv3_decoder;
+extern const FFCodec ff_wmv3_crystalhd_decoder;
+extern const FFCodec ff_wmv3image_decoder;
+extern const FFCodec ff_wnv1_decoder;
+extern const FFCodec ff_xan_wc3_decoder;
+extern const FFCodec ff_xan_wc4_decoder;
+extern const FFCodec ff_xbm_encoder;
+extern const FFCodec ff_xbm_decoder;
+extern const FFCodec ff_xface_encoder;
+extern const FFCodec ff_xface_decoder;
+extern const FFCodec ff_xl_decoder;
+extern const FFCodec ff_xpm_decoder;
+extern const FFCodec ff_xwd_encoder;
+extern const FFCodec ff_xwd_decoder;
+extern const FFCodec ff_y41p_encoder;
+extern const FFCodec ff_y41p_decoder;
+extern const FFCodec ff_ylc_decoder;
+extern const FFCodec ff_yop_decoder;
+extern const FFCodec ff_yuv4_encoder;
+extern const FFCodec ff_yuv4_decoder;
+extern const FFCodec ff_zero12v_decoder;
+extern const FFCodec ff_zerocodec_decoder;
+extern const FFCodec ff_zlib_encoder;
+extern const FFCodec ff_zlib_decoder;
+extern const FFCodec ff_zmbv_encoder;
+extern const FFCodec ff_zmbv_decoder;
 
 /* audio codecs */
-extern const AVCodec ff_aac_encoder;
-extern const AVCodec ff_aac_decoder;
-extern const AVCodec ff_aac_fixed_decoder;
-extern const AVCodec ff_aac_latm_decoder;
-extern const AVCodec ff_ac3_encoder;
-extern const AVCodec ff_ac3_decoder;
-extern const AVCodec ff_ac3_fixed_encoder;
-extern const AVCodec ff_ac3_fixed_decoder;
-extern const AVCodec ff_acelp_kelvin_decoder;
-extern const AVCodec ff_alac_encoder;
-extern const AVCodec ff_alac_decoder;
-extern const AVCodec ff_als_decoder;
-extern const AVCodec ff_amrnb_decoder;
-extern const AVCodec ff_amrwb_decoder;
-extern const AVCodec ff_ape_decoder;
-extern const AVCodec ff_aptx_encoder;
-extern const AVCodec ff_aptx_decoder;
-extern const AVCodec ff_aptx_hd_encoder;
-extern const AVCodec ff_aptx_hd_decoder;
-extern const AVCodec ff_atrac1_decoder;
-extern const AVCodec ff_atrac3_decoder;
-extern const AVCodec ff_atrac3al_decoder;
-extern const AVCodec ff_atrac3p_decoder;
-extern const AVCodec ff_atrac3pal_decoder;
-extern const AVCodec ff_atrac9_decoder;
-extern const AVCodec ff_binkaudio_dct_decoder;
-extern const AVCodec ff_binkaudio_rdft_decoder;
-extern const AVCodec ff_bmv_audio_decoder;
-extern const AVCodec ff_cook_decoder;
-extern const AVCodec ff_dca_encoder;
-extern const AVCodec ff_dca_decoder;
-extern const AVCodec ff_dolby_e_decoder;
-extern const AVCodec ff_dsd_lsbf_decoder;
-extern const AVCodec ff_dsd_msbf_decoder;
-extern const AVCodec ff_dsd_lsbf_planar_decoder;
-extern const AVCodec ff_dsd_msbf_planar_decoder;
-extern const AVCodec ff_dsicinaudio_decoder;
-extern const AVCodec ff_dss_sp_decoder;
-extern const AVCodec ff_dst_decoder;
-extern const AVCodec ff_eac3_encoder;
-extern const AVCodec ff_eac3_decoder;
-extern const AVCodec ff_evrc_decoder;
-extern const AVCodec ff_fastaudio_decoder;
-extern const AVCodec ff_ffwavesynth_decoder;
-extern const AVCodec ff_flac_encoder;
-extern const AVCodec ff_flac_decoder;
-extern const AVCodec ff_g723_1_encoder;
-extern const AVCodec ff_g723_1_decoder;
-extern const AVCodec ff_g729_decoder;
-extern const AVCodec ff_gsm_decoder;
-extern const AVCodec ff_gsm_ms_decoder;
-extern const AVCodec ff_hca_decoder;
-extern const AVCodec ff_hcom_decoder;
-extern const AVCodec ff_iac_decoder;
-extern const AVCodec ff_ilbc_decoder;
-extern const AVCodec ff_imc_decoder;
-extern const AVCodec ff_interplay_acm_decoder;
-extern const AVCodec ff_mace3_decoder;
-extern const AVCodec ff_mace6_decoder;
-extern const AVCodec ff_metasound_decoder;
-extern const AVCodec ff_mlp_encoder;
-extern const AVCodec ff_mlp_decoder;
-extern const AVCodec ff_mp1_decoder;
-extern const AVCodec ff_mp1float_decoder;
-extern const AVCodec ff_mp2_encoder;
-extern const AVCodec ff_mp2_decoder;
-extern const AVCodec ff_mp2float_decoder;
-extern const AVCodec ff_mp2fixed_encoder;
-extern const AVCodec ff_mp3float_decoder;
-extern const AVCodec ff_mp3_decoder;
-extern const AVCodec ff_mp3adufloat_decoder;
-extern const AVCodec ff_mp3adu_decoder;
-extern const AVCodec ff_mp3on4float_decoder;
-extern const AVCodec ff_mp3on4_decoder;
-extern const AVCodec ff_mpc7_decoder;
-extern const AVCodec ff_mpc8_decoder;
-extern const AVCodec ff_msnsiren_decoder;
-extern const AVCodec ff_nellymoser_encoder;
-extern const AVCodec ff_nellymoser_decoder;
-extern const AVCodec ff_on2avc_decoder;
-extern const AVCodec ff_opus_encoder;
-extern const AVCodec ff_opus_decoder;
-extern const AVCodec ff_paf_audio_decoder;
-extern const AVCodec ff_qcelp_decoder;
-extern const AVCodec ff_qdm2_decoder;
-extern const AVCodec ff_qdmc_decoder;
-extern const AVCodec ff_ra_144_encoder;
-extern const AVCodec ff_ra_144_decoder;
-extern const AVCodec ff_ra_288_decoder;
-extern const AVCodec ff_ralf_decoder;
-extern const AVCodec ff_sbc_encoder;
-extern const AVCodec ff_sbc_decoder;
-extern const AVCodec ff_shorten_decoder;
-extern const AVCodec ff_sipr_decoder;
-extern const AVCodec ff_siren_decoder;
-extern const AVCodec ff_smackaud_decoder;
-extern const AVCodec ff_sonic_encoder;
-extern const AVCodec ff_sonic_decoder;
-extern const AVCodec ff_sonic_ls_encoder;
-extern const AVCodec ff_tak_decoder;
-extern const AVCodec ff_truehd_encoder;
-extern const AVCodec ff_truehd_decoder;
-extern const AVCodec ff_truespeech_decoder;
-extern const AVCodec ff_tta_encoder;
-extern const AVCodec ff_tta_decoder;
-extern const AVCodec ff_twinvq_decoder;
-extern const AVCodec ff_vmdaudio_decoder;
-extern const AVCodec ff_vorbis_encoder;
-extern const AVCodec ff_vorbis_decoder;
-extern const AVCodec ff_wavpack_encoder;
-extern const AVCodec ff_wavpack_decoder;
-extern const AVCodec ff_wmalossless_decoder;
-extern const AVCodec ff_wmapro_decoder;
-extern const AVCodec ff_wmav1_encoder;
-extern const AVCodec ff_wmav1_decoder;
-extern const AVCodec ff_wmav2_encoder;
-extern const AVCodec ff_wmav2_decoder;
-extern const AVCodec ff_wmavoice_decoder;
-extern const AVCodec ff_ws_snd1_decoder;
-extern const AVCodec ff_xma1_decoder;
-extern const AVCodec ff_xma2_decoder;
+extern const FFCodec ff_aac_encoder;
+extern const FFCodec ff_aac_decoder;
+extern const FFCodec ff_aac_fixed_decoder;
+extern const FFCodec ff_aac_latm_decoder;
+extern const FFCodec ff_ac3_encoder;
+extern const FFCodec ff_ac3_decoder;
+extern const FFCodec ff_ac3_fixed_encoder;
+extern const FFCodec ff_ac3_fixed_decoder;
+extern const FFCodec ff_acelp_kelvin_decoder;
+extern const FFCodec ff_alac_encoder;
+extern const FFCodec ff_alac_decoder;
+extern const FFCodec ff_als_decoder;
+extern const FFCodec ff_amrnb_decoder;
+extern const FFCodec ff_amrwb_decoder;
+extern const FFCodec ff_ape_decoder;
+extern const FFCodec ff_aptx_encoder;
+extern const FFCodec ff_aptx_decoder;
+extern const FFCodec ff_aptx_hd_encoder;
+extern const FFCodec ff_aptx_hd_decoder;
+extern const FFCodec ff_atrac1_decoder;
+extern const FFCodec ff_atrac3_decoder;
+extern const FFCodec ff_atrac3al_decoder;
+extern const FFCodec ff_atrac3p_decoder;
+extern const FFCodec ff_atrac3pal_decoder;
+extern const FFCodec ff_atrac9_decoder;
+extern const FFCodec ff_binkaudio_dct_decoder;
+extern const FFCodec ff_binkaudio_rdft_decoder;
+extern const FFCodec ff_bmv_audio_decoder;
+extern const FFCodec ff_cook_decoder;
+extern const FFCodec ff_dca_encoder;
+extern const FFCodec ff_dca_decoder;
+extern const FFCodec ff_dfpwm_encoder;
+extern const FFCodec ff_dfpwm_decoder;
+extern const FFCodec ff_dolby_e_decoder;
+extern const FFCodec ff_dsd_lsbf_decoder;
+extern const FFCodec ff_dsd_msbf_decoder;
+extern const FFCodec ff_dsd_lsbf_planar_decoder;
+extern const FFCodec ff_dsd_msbf_planar_decoder;
+extern const FFCodec ff_dsicinaudio_decoder;
+extern const FFCodec ff_dss_sp_decoder;
+extern const FFCodec ff_dst_decoder;
+extern const FFCodec ff_eac3_encoder;
+extern const FFCodec ff_eac3_decoder;
+extern const FFCodec ff_evrc_decoder;
+extern const FFCodec ff_fastaudio_decoder;
+extern const FFCodec ff_ffwavesynth_decoder;
+extern const FFCodec ff_flac_encoder;
+extern const FFCodec ff_flac_decoder;
+extern const FFCodec ff_g723_1_encoder;
+extern const FFCodec ff_g723_1_decoder;
+extern const FFCodec ff_g729_decoder;
+extern const FFCodec ff_gsm_decoder;
+extern const FFCodec ff_gsm_ms_decoder;
+extern const FFCodec ff_hca_decoder;
+extern const FFCodec ff_hcom_decoder;
+extern const FFCodec ff_iac_decoder;
+extern const FFCodec ff_ilbc_decoder;
+extern const FFCodec ff_imc_decoder;
+extern const FFCodec ff_interplay_acm_decoder;
+extern const FFCodec ff_mace3_decoder;
+extern const FFCodec ff_mace6_decoder;
+extern const FFCodec ff_metasound_decoder;
+extern const FFCodec ff_mlp_encoder;
+extern const FFCodec ff_mlp_decoder;
+extern const FFCodec ff_mp1_decoder;
+extern const FFCodec ff_mp1float_decoder;
+extern const FFCodec ff_mp2_encoder;
+extern const FFCodec ff_mp2_decoder;
+extern const FFCodec ff_mp2float_decoder;
+extern const FFCodec ff_mp2fixed_encoder;
+extern const FFCodec ff_mp3float_decoder;
+extern const FFCodec ff_mp3_decoder;
+extern const FFCodec ff_mp3adufloat_decoder;
+extern const FFCodec ff_mp3adu_decoder;
+extern const FFCodec ff_mp3on4float_decoder;
+extern const FFCodec ff_mp3on4_decoder;
+extern const FFCodec ff_mpc7_decoder;
+extern const FFCodec ff_mpc8_decoder;
+extern const FFCodec ff_msnsiren_decoder;
+extern const FFCodec ff_nellymoser_encoder;
+extern const FFCodec ff_nellymoser_decoder;
+extern const FFCodec ff_on2avc_decoder;
+extern const FFCodec ff_opus_encoder;
+extern const FFCodec ff_opus_decoder;
+extern const FFCodec ff_paf_audio_decoder;
+extern const FFCodec ff_qcelp_decoder;
+extern const FFCodec ff_qdm2_decoder;
+extern const FFCodec ff_qdmc_decoder;
+extern const FFCodec ff_ra_144_encoder;
+extern const FFCodec ff_ra_144_decoder;
+extern const FFCodec ff_ra_288_decoder;
+extern const FFCodec ff_ralf_decoder;
+extern const FFCodec ff_sbc_encoder;
+extern const FFCodec ff_sbc_decoder;
+extern const FFCodec ff_shorten_decoder;
+extern const FFCodec ff_sipr_decoder;
+extern const FFCodec ff_siren_decoder;
+extern const FFCodec ff_smackaud_decoder;
+extern const FFCodec ff_sonic_encoder;
+extern const FFCodec ff_sonic_decoder;
+extern const FFCodec ff_sonic_ls_encoder;
+extern const FFCodec ff_tak_decoder;
+extern const FFCodec ff_truehd_encoder;
+extern const FFCodec ff_truehd_decoder;
+extern const FFCodec ff_truespeech_decoder;
+extern const FFCodec ff_tta_encoder;
+extern const FFCodec ff_tta_decoder;
+extern const FFCodec ff_twinvq_decoder;
+extern const FFCodec ff_vmdaudio_decoder;
+extern const FFCodec ff_vorbis_encoder;
+extern const FFCodec ff_vorbis_decoder;
+extern const FFCodec ff_wavpack_encoder;
+extern const FFCodec ff_wavpack_decoder;
+extern const FFCodec ff_wmalossless_decoder;
+extern const FFCodec ff_wmapro_decoder;
+extern const FFCodec ff_wmav1_encoder;
+extern const FFCodec ff_wmav1_decoder;
+extern const FFCodec ff_wmav2_encoder;
+extern const FFCodec ff_wmav2_decoder;
+extern const FFCodec ff_wmavoice_decoder;
+extern const FFCodec ff_ws_snd1_decoder;
+extern const FFCodec ff_xma1_decoder;
+extern const FFCodec ff_xma2_decoder;
 
 /* PCM codecs */
-extern const AVCodec ff_pcm_alaw_encoder;
-extern const AVCodec ff_pcm_alaw_decoder;
-extern const AVCodec ff_pcm_bluray_decoder;
-extern const AVCodec ff_pcm_dvd_encoder;
-extern const AVCodec ff_pcm_dvd_decoder;
-extern const AVCodec ff_pcm_f16le_decoder;
-extern const AVCodec ff_pcm_f24le_decoder;
-extern const AVCodec ff_pcm_f32be_encoder;
-extern const AVCodec ff_pcm_f32be_decoder;
-extern const AVCodec ff_pcm_f32le_encoder;
-extern const AVCodec ff_pcm_f32le_decoder;
-extern const AVCodec ff_pcm_f64be_encoder;
-extern const AVCodec ff_pcm_f64be_decoder;
-extern const AVCodec ff_pcm_f64le_encoder;
-extern const AVCodec ff_pcm_f64le_decoder;
-extern const AVCodec ff_pcm_lxf_decoder;
-extern const AVCodec ff_pcm_mulaw_encoder;
-extern const AVCodec ff_pcm_mulaw_decoder;
-extern const AVCodec ff_pcm_s8_encoder;
-extern const AVCodec ff_pcm_s8_decoder;
-extern const AVCodec ff_pcm_s8_planar_encoder;
-extern const AVCodec ff_pcm_s8_planar_decoder;
-extern const AVCodec ff_pcm_s16be_encoder;
-extern const AVCodec ff_pcm_s16be_decoder;
-extern const AVCodec ff_pcm_s16be_planar_encoder;
-extern const AVCodec ff_pcm_s16be_planar_decoder;
-extern const AVCodec ff_pcm_s16le_encoder;
-extern const AVCodec ff_pcm_s16le_decoder;
-extern const AVCodec ff_pcm_s16le_planar_encoder;
-extern const AVCodec ff_pcm_s16le_planar_decoder;
-extern const AVCodec ff_pcm_s24be_encoder;
-extern const AVCodec ff_pcm_s24be_decoder;
-extern const AVCodec ff_pcm_s24daud_encoder;
-extern const AVCodec ff_pcm_s24daud_decoder;
-extern const AVCodec ff_pcm_s24le_encoder;
-extern const AVCodec ff_pcm_s24le_decoder;
-extern const AVCodec ff_pcm_s24le_planar_encoder;
-extern const AVCodec ff_pcm_s24le_planar_decoder;
-extern const AVCodec ff_pcm_s32be_encoder;
-extern const AVCodec ff_pcm_s32be_decoder;
-extern const AVCodec ff_pcm_s32le_encoder;
-extern const AVCodec ff_pcm_s32le_decoder;
-extern const AVCodec ff_pcm_s32le_planar_encoder;
-extern const AVCodec ff_pcm_s32le_planar_decoder;
-extern const AVCodec ff_pcm_s64be_encoder;
-extern const AVCodec ff_pcm_s64be_decoder;
-extern const AVCodec ff_pcm_s64le_encoder;
-extern const AVCodec ff_pcm_s64le_decoder;
-extern const AVCodec ff_pcm_sga_decoder;
-extern const AVCodec ff_pcm_u8_encoder;
-extern const AVCodec ff_pcm_u8_decoder;
-extern const AVCodec ff_pcm_u16be_encoder;
-extern const AVCodec ff_pcm_u16be_decoder;
-extern const AVCodec ff_pcm_u16le_encoder;
-extern const AVCodec ff_pcm_u16le_decoder;
-extern const AVCodec ff_pcm_u24be_encoder;
-extern const AVCodec ff_pcm_u24be_decoder;
-extern const AVCodec ff_pcm_u24le_encoder;
-extern const AVCodec ff_pcm_u24le_decoder;
-extern const AVCodec ff_pcm_u32be_encoder;
-extern const AVCodec ff_pcm_u32be_decoder;
-extern const AVCodec ff_pcm_u32le_encoder;
-extern const AVCodec ff_pcm_u32le_decoder;
-extern const AVCodec ff_pcm_vidc_encoder;
-extern const AVCodec ff_pcm_vidc_decoder;
+extern const FFCodec ff_pcm_alaw_encoder;
+extern const FFCodec ff_pcm_alaw_decoder;
+extern const FFCodec ff_pcm_bluray_encoder;
+extern const FFCodec ff_pcm_bluray_decoder;
+extern const FFCodec ff_pcm_dvd_encoder;
+extern const FFCodec ff_pcm_dvd_decoder;
+extern const FFCodec ff_pcm_f16le_decoder;
+extern const FFCodec ff_pcm_f24le_decoder;
+extern const FFCodec ff_pcm_f32be_encoder;
+extern const FFCodec ff_pcm_f32be_decoder;
+extern const FFCodec ff_pcm_f32le_encoder;
+extern const FFCodec ff_pcm_f32le_decoder;
+extern const FFCodec ff_pcm_f64be_encoder;
+extern const FFCodec ff_pcm_f64be_decoder;
+extern const FFCodec ff_pcm_f64le_encoder;
+extern const FFCodec ff_pcm_f64le_decoder;
+extern const FFCodec ff_pcm_lxf_decoder;
+extern const FFCodec ff_pcm_mulaw_encoder;
+extern const FFCodec ff_pcm_mulaw_decoder;
+extern const FFCodec ff_pcm_s8_encoder;
+extern const FFCodec ff_pcm_s8_decoder;
+extern const FFCodec ff_pcm_s8_planar_encoder;
+extern const FFCodec ff_pcm_s8_planar_decoder;
+extern const FFCodec ff_pcm_s16be_encoder;
+extern const FFCodec ff_pcm_s16be_decoder;
+extern const FFCodec ff_pcm_s16be_planar_encoder;
+extern const FFCodec ff_pcm_s16be_planar_decoder;
+extern const FFCodec ff_pcm_s16le_encoder;
+extern const FFCodec ff_pcm_s16le_decoder;
+extern const FFCodec ff_pcm_s16le_planar_encoder;
+extern const FFCodec ff_pcm_s16le_planar_decoder;
+extern const FFCodec ff_pcm_s24be_encoder;
+extern const FFCodec ff_pcm_s24be_decoder;
+extern const FFCodec ff_pcm_s24daud_encoder;
+extern const FFCodec ff_pcm_s24daud_decoder;
+extern const FFCodec ff_pcm_s24le_encoder;
+extern const FFCodec ff_pcm_s24le_decoder;
+extern const FFCodec ff_pcm_s24le_planar_encoder;
+extern const FFCodec ff_pcm_s24le_planar_decoder;
+extern const FFCodec ff_pcm_s32be_encoder;
+extern const FFCodec ff_pcm_s32be_decoder;
+extern const FFCodec ff_pcm_s32le_encoder;
+extern const FFCodec ff_pcm_s32le_decoder;
+extern const FFCodec ff_pcm_s32le_planar_encoder;
+extern const FFCodec ff_pcm_s32le_planar_decoder;
+extern const FFCodec ff_pcm_s64be_encoder;
+extern const FFCodec ff_pcm_s64be_decoder;
+extern const FFCodec ff_pcm_s64le_encoder;
+extern const FFCodec ff_pcm_s64le_decoder;
+extern const FFCodec ff_pcm_sga_decoder;
+extern const FFCodec ff_pcm_u8_encoder;
+extern const FFCodec ff_pcm_u8_decoder;
+extern const FFCodec ff_pcm_u16be_encoder;
+extern const FFCodec ff_pcm_u16be_decoder;
+extern const FFCodec ff_pcm_u16le_encoder;
+extern const FFCodec ff_pcm_u16le_decoder;
+extern const FFCodec ff_pcm_u24be_encoder;
+extern const FFCodec ff_pcm_u24be_decoder;
+extern const FFCodec ff_pcm_u24le_encoder;
+extern const FFCodec ff_pcm_u24le_decoder;
+extern const FFCodec ff_pcm_u32be_encoder;
+extern const FFCodec ff_pcm_u32be_decoder;
+extern const FFCodec ff_pcm_u32le_encoder;
+extern const FFCodec ff_pcm_u32le_decoder;
+extern const FFCodec ff_pcm_vidc_encoder;
+extern const FFCodec ff_pcm_vidc_decoder;
 
 /* DPCM codecs */
-extern const AVCodec ff_derf_dpcm_decoder;
-extern const AVCodec ff_gremlin_dpcm_decoder;
-extern const AVCodec ff_interplay_dpcm_decoder;
-extern const AVCodec ff_roq_dpcm_encoder;
-extern const AVCodec ff_roq_dpcm_decoder;
-extern const AVCodec ff_sdx2_dpcm_decoder;
-extern const AVCodec ff_sol_dpcm_decoder;
-extern const AVCodec ff_xan_dpcm_decoder;
+extern const FFCodec ff_derf_dpcm_decoder;
+extern const FFCodec ff_gremlin_dpcm_decoder;
+extern const FFCodec ff_interplay_dpcm_decoder;
+extern const FFCodec ff_roq_dpcm_encoder;
+extern const FFCodec ff_roq_dpcm_decoder;
+extern const FFCodec ff_sdx2_dpcm_decoder;
+extern const FFCodec ff_sol_dpcm_decoder;
+extern const FFCodec ff_xan_dpcm_decoder;
 
 /* ADPCM codecs */
-extern const AVCodec ff_adpcm_4xm_decoder;
-extern const AVCodec ff_adpcm_adx_encoder;
-extern const AVCodec ff_adpcm_adx_decoder;
-extern const AVCodec ff_adpcm_afc_decoder;
-extern const AVCodec ff_adpcm_agm_decoder;
-extern const AVCodec ff_adpcm_aica_decoder;
-extern const AVCodec ff_adpcm_argo_decoder;
-extern const AVCodec ff_adpcm_argo_encoder;
-extern const AVCodec ff_adpcm_ct_decoder;
-extern const AVCodec ff_adpcm_dtk_decoder;
-extern const AVCodec ff_adpcm_ea_decoder;
-extern const AVCodec ff_adpcm_ea_maxis_xa_decoder;
-extern const AVCodec ff_adpcm_ea_r1_decoder;
-extern const AVCodec ff_adpcm_ea_r2_decoder;
-extern const AVCodec ff_adpcm_ea_r3_decoder;
-extern const AVCodec ff_adpcm_ea_xas_decoder;
-extern const AVCodec ff_adpcm_g722_encoder;
-extern const AVCodec ff_adpcm_g722_decoder;
-extern const AVCodec ff_adpcm_g726_encoder;
-extern const AVCodec ff_adpcm_g726_decoder;
-extern const AVCodec ff_adpcm_g726le_encoder;
-extern const AVCodec ff_adpcm_g726le_decoder;
-extern const AVCodec ff_adpcm_ima_acorn_decoder;
-extern const AVCodec ff_adpcm_ima_amv_decoder;
-extern const AVCodec ff_adpcm_ima_amv_encoder;
-extern const AVCodec ff_adpcm_ima_alp_decoder;
-extern const AVCodec ff_adpcm_ima_alp_encoder;
-extern const AVCodec ff_adpcm_ima_apc_decoder;
-extern const AVCodec ff_adpcm_ima_apm_decoder;
-extern const AVCodec ff_adpcm_ima_apm_encoder;
-extern const AVCodec ff_adpcm_ima_cunning_decoder;
-extern const AVCodec ff_adpcm_ima_dat4_decoder;
-extern const AVCodec ff_adpcm_ima_dk3_decoder;
-extern const AVCodec ff_adpcm_ima_dk4_decoder;
-extern const AVCodec ff_adpcm_ima_ea_eacs_decoder;
-extern const AVCodec ff_adpcm_ima_ea_sead_decoder;
-extern const AVCodec ff_adpcm_ima_iss_decoder;
-extern const AVCodec ff_adpcm_ima_moflex_decoder;
-extern const AVCodec ff_adpcm_ima_mtf_decoder;
-extern const AVCodec ff_adpcm_ima_oki_decoder;
-extern const AVCodec ff_adpcm_ima_qt_encoder;
-extern const AVCodec ff_adpcm_ima_qt_decoder;
-extern const AVCodec ff_adpcm_ima_rad_decoder;
-extern const AVCodec ff_adpcm_ima_ssi_decoder;
-extern const AVCodec ff_adpcm_ima_ssi_encoder;
-extern const AVCodec ff_adpcm_ima_smjpeg_decoder;
-extern const AVCodec ff_adpcm_ima_wav_encoder;
-extern const AVCodec ff_adpcm_ima_wav_decoder;
-extern const AVCodec ff_adpcm_ima_ws_encoder;
-extern const AVCodec ff_adpcm_ima_ws_decoder;
-extern const AVCodec ff_adpcm_ms_encoder;
-extern const AVCodec ff_adpcm_ms_decoder;
-extern const AVCodec ff_adpcm_mtaf_decoder;
-extern const AVCodec ff_adpcm_psx_decoder;
-extern const AVCodec ff_adpcm_sbpro_2_decoder;
-extern const AVCodec ff_adpcm_sbpro_3_decoder;
-extern const AVCodec ff_adpcm_sbpro_4_decoder;
-extern const AVCodec ff_adpcm_swf_encoder;
-extern const AVCodec ff_adpcm_swf_decoder;
-extern const AVCodec ff_adpcm_thp_decoder;
-extern const AVCodec ff_adpcm_thp_le_decoder;
-extern const AVCodec ff_adpcm_vima_decoder;
-extern const AVCodec ff_adpcm_xa_decoder;
-extern const AVCodec ff_adpcm_yamaha_encoder;
-extern const AVCodec ff_adpcm_yamaha_decoder;
-extern const AVCodec ff_adpcm_zork_decoder;
+extern const FFCodec ff_adpcm_4xm_decoder;
+extern const FFCodec ff_adpcm_adx_encoder;
+extern const FFCodec ff_adpcm_adx_decoder;
+extern const FFCodec ff_adpcm_afc_decoder;
+extern const FFCodec ff_adpcm_agm_decoder;
+extern const FFCodec ff_adpcm_aica_decoder;
+extern const FFCodec ff_adpcm_argo_decoder;
+extern const FFCodec ff_adpcm_argo_encoder;
+extern const FFCodec ff_adpcm_ct_decoder;
+extern const FFCodec ff_adpcm_dtk_decoder;
+extern const FFCodec ff_adpcm_ea_decoder;
+extern const FFCodec ff_adpcm_ea_maxis_xa_decoder;
+extern const FFCodec ff_adpcm_ea_r1_decoder;
+extern const FFCodec ff_adpcm_ea_r2_decoder;
+extern const FFCodec ff_adpcm_ea_r3_decoder;
+extern const FFCodec ff_adpcm_ea_xas_decoder;
+extern const FFCodec ff_adpcm_g722_encoder;
+extern const FFCodec ff_adpcm_g722_decoder;
+extern const FFCodec ff_adpcm_g726_encoder;
+extern const FFCodec ff_adpcm_g726_decoder;
+extern const FFCodec ff_adpcm_g726le_encoder;
+extern const FFCodec ff_adpcm_g726le_decoder;
+extern const FFCodec ff_adpcm_ima_acorn_decoder;
+extern const FFCodec ff_adpcm_ima_amv_decoder;
+extern const FFCodec ff_adpcm_ima_amv_encoder;
+extern const FFCodec ff_adpcm_ima_alp_decoder;
+extern const FFCodec ff_adpcm_ima_alp_encoder;
+extern const FFCodec ff_adpcm_ima_apc_decoder;
+extern const FFCodec ff_adpcm_ima_apm_decoder;
+extern const FFCodec ff_adpcm_ima_apm_encoder;
+extern const FFCodec ff_adpcm_ima_cunning_decoder;
+extern const FFCodec ff_adpcm_ima_dat4_decoder;
+extern const FFCodec ff_adpcm_ima_dk3_decoder;
+extern const FFCodec ff_adpcm_ima_dk4_decoder;
+extern const FFCodec ff_adpcm_ima_ea_eacs_decoder;
+extern const FFCodec ff_adpcm_ima_ea_sead_decoder;
+extern const FFCodec ff_adpcm_ima_iss_decoder;
+extern const FFCodec ff_adpcm_ima_moflex_decoder;
+extern const FFCodec ff_adpcm_ima_mtf_decoder;
+extern const FFCodec ff_adpcm_ima_oki_decoder;
+extern const FFCodec ff_adpcm_ima_qt_encoder;
+extern const FFCodec ff_adpcm_ima_qt_decoder;
+extern const FFCodec ff_adpcm_ima_rad_decoder;
+extern const FFCodec ff_adpcm_ima_ssi_decoder;
+extern const FFCodec ff_adpcm_ima_ssi_encoder;
+extern const FFCodec ff_adpcm_ima_smjpeg_decoder;
+extern const FFCodec ff_adpcm_ima_wav_encoder;
+extern const FFCodec ff_adpcm_ima_wav_decoder;
+extern const FFCodec ff_adpcm_ima_ws_encoder;
+extern const FFCodec ff_adpcm_ima_ws_decoder;
+extern const FFCodec ff_adpcm_ms_encoder;
+extern const FFCodec ff_adpcm_ms_decoder;
+extern const FFCodec ff_adpcm_mtaf_decoder;
+extern const FFCodec ff_adpcm_psx_decoder;
+extern const FFCodec ff_adpcm_sbpro_2_decoder;
+extern const FFCodec ff_adpcm_sbpro_3_decoder;
+extern const FFCodec ff_adpcm_sbpro_4_decoder;
+extern const FFCodec ff_adpcm_swf_encoder;
+extern const FFCodec ff_adpcm_swf_decoder;
+extern const FFCodec ff_adpcm_thp_decoder;
+extern const FFCodec ff_adpcm_thp_le_decoder;
+extern const FFCodec ff_adpcm_vima_decoder;
+extern const FFCodec ff_adpcm_xa_decoder;
+extern const FFCodec ff_adpcm_yamaha_encoder;
+extern const FFCodec ff_adpcm_yamaha_decoder;
+extern const FFCodec ff_adpcm_zork_decoder;
 
 /* subtitles */
-extern const AVCodec ff_ssa_encoder;
-extern const AVCodec ff_ssa_decoder;
-extern const AVCodec ff_ass_encoder;
-extern const AVCodec ff_ass_decoder;
-extern const AVCodec ff_ccaption_decoder;
-extern const AVCodec ff_dvbsub_encoder;
-extern const AVCodec ff_dvbsub_decoder;
-extern const AVCodec ff_dvdsub_encoder;
-extern const AVCodec ff_dvdsub_decoder;
-extern const AVCodec ff_jacosub_decoder;
-extern const AVCodec ff_microdvd_decoder;
-extern const AVCodec ff_movtext_encoder;
-extern const AVCodec ff_movtext_decoder;
-extern const AVCodec ff_mpl2_decoder;
-extern const AVCodec ff_pgssub_decoder;
-extern const AVCodec ff_pjs_decoder;
-extern const AVCodec ff_realtext_decoder;
-extern const AVCodec ff_sami_decoder;
-extern const AVCodec ff_srt_encoder;
-extern const AVCodec ff_srt_decoder;
-extern const AVCodec ff_stl_decoder;
-extern const AVCodec ff_subrip_encoder;
-extern const AVCodec ff_subrip_decoder;
-extern const AVCodec ff_subviewer_decoder;
-extern const AVCodec ff_subviewer1_decoder;
-extern const AVCodec ff_text_encoder;
-extern const AVCodec ff_text_decoder;
-extern const AVCodec ff_ttml_encoder;
-extern const AVCodec ff_vplayer_decoder;
-extern const AVCodec ff_webvtt_encoder;
-extern const AVCodec ff_webvtt_decoder;
-extern const AVCodec ff_xsub_encoder;
-extern const AVCodec ff_xsub_decoder;
+extern const FFCodec ff_ssa_encoder;
+extern const FFCodec ff_ssa_decoder;
+extern const FFCodec ff_ass_encoder;
+extern const FFCodec ff_ass_decoder;
+extern const FFCodec ff_ccaption_decoder;
+extern const FFCodec ff_dvbsub_encoder;
+extern const FFCodec ff_dvbsub_decoder;
+extern const FFCodec ff_dvdsub_encoder;
+extern const FFCodec ff_dvdsub_decoder;
+extern const FFCodec ff_jacosub_decoder;
+extern const FFCodec ff_microdvd_decoder;
+extern const FFCodec ff_movtext_encoder;
+extern const FFCodec ff_movtext_decoder;
+extern const FFCodec ff_mpl2_decoder;
+extern const FFCodec ff_pgssub_decoder;
+extern const FFCodec ff_pjs_decoder;
+extern const FFCodec ff_realtext_decoder;
+extern const FFCodec ff_sami_decoder;
+extern const FFCodec ff_srt_encoder;
+extern const FFCodec ff_srt_decoder;
+extern const FFCodec ff_stl_decoder;
+extern const FFCodec ff_subrip_encoder;
+extern const FFCodec ff_subrip_decoder;
+extern const FFCodec ff_subviewer_decoder;
+extern const FFCodec ff_subviewer1_decoder;
+extern const FFCodec ff_text_encoder;
+extern const FFCodec ff_text_decoder;
+extern const FFCodec ff_ttml_encoder;
+extern const FFCodec ff_vplayer_decoder;
+extern const FFCodec ff_webvtt_encoder;
+extern const FFCodec ff_webvtt_decoder;
+extern const FFCodec ff_xsub_encoder;
+extern const FFCodec ff_xsub_decoder;
 
 /* external libraries */
-extern const AVCodec ff_aac_at_encoder;
-extern const AVCodec ff_aac_at_decoder;
-extern const AVCodec ff_ac3_at_decoder;
-extern const AVCodec ff_adpcm_ima_qt_at_decoder;
-extern const AVCodec ff_alac_at_encoder;
-extern const AVCodec ff_alac_at_decoder;
-extern const AVCodec ff_amr_nb_at_decoder;
-extern const AVCodec ff_eac3_at_decoder;
-extern const AVCodec ff_gsm_ms_at_decoder;
-extern const AVCodec ff_ilbc_at_encoder;
-extern const AVCodec ff_ilbc_at_decoder;
-extern const AVCodec ff_mp1_at_decoder;
-extern const AVCodec ff_mp2_at_decoder;
-extern const AVCodec ff_mp3_at_decoder;
-extern const AVCodec ff_pcm_alaw_at_encoder;
-extern const AVCodec ff_pcm_alaw_at_decoder;
-extern const AVCodec ff_pcm_mulaw_at_encoder;
-extern const AVCodec ff_pcm_mulaw_at_decoder;
-extern const AVCodec ff_qdmc_at_decoder;
-extern const AVCodec ff_qdm2_at_decoder;
-extern AVCodec ff_libaom_av1_encoder;
-extern const AVCodec ff_libaribb24_decoder;
-extern const AVCodec ff_libcelt_decoder;
-extern const AVCodec ff_libcodec2_encoder;
-extern const AVCodec ff_libcodec2_decoder;
-extern const AVCodec ff_libdav1d_decoder;
-extern const AVCodec ff_libdavs2_decoder;
-extern const AVCodec ff_libfdk_aac_encoder;
-extern const AVCodec ff_libfdk_aac_decoder;
-extern const AVCodec ff_libgsm_encoder;
-extern const AVCodec ff_libgsm_decoder;
-extern const AVCodec ff_libgsm_ms_encoder;
-extern const AVCodec ff_libgsm_ms_decoder;
-extern const AVCodec ff_libilbc_encoder;
-extern const AVCodec ff_libilbc_decoder;
-extern const AVCodec ff_libmp3lame_encoder;
-extern const AVCodec ff_libopencore_amrnb_encoder;
-extern const AVCodec ff_libopencore_amrnb_decoder;
-extern const AVCodec ff_libopencore_amrwb_decoder;
-extern const AVCodec ff_libopenjpeg_encoder;
-extern const AVCodec ff_libopenjpeg_decoder;
-extern const AVCodec ff_libopus_encoder;
-extern const AVCodec ff_libopus_decoder;
-extern const AVCodec ff_librav1e_encoder;
-extern const AVCodec ff_librsvg_decoder;
-extern const AVCodec ff_libshine_encoder;
-extern const AVCodec ff_libspeex_encoder;
-extern const AVCodec ff_libspeex_decoder;
-extern const AVCodec ff_libsvtav1_encoder;
-extern const AVCodec ff_libtheora_encoder;
-extern const AVCodec ff_libtwolame_encoder;
-extern const AVCodec ff_libuavs3d_decoder;
-extern const AVCodec ff_libvo_amrwbenc_encoder;
-extern const AVCodec ff_libvorbis_encoder;
-extern const AVCodec ff_libvorbis_decoder;
-extern const AVCodec ff_libvpx_vp8_encoder;
-extern const AVCodec ff_libvpx_vp8_decoder;
-extern AVCodec ff_libvpx_vp9_encoder;
-extern AVCodec ff_libvpx_vp9_decoder;
+extern const FFCodec ff_aac_at_encoder;
+extern const FFCodec ff_aac_at_decoder;
+extern const FFCodec ff_ac3_at_decoder;
+extern const FFCodec ff_adpcm_ima_qt_at_decoder;
+extern const FFCodec ff_alac_at_encoder;
+extern const FFCodec ff_alac_at_decoder;
+extern const FFCodec ff_amr_nb_at_decoder;
+extern const FFCodec ff_eac3_at_decoder;
+extern const FFCodec ff_gsm_ms_at_decoder;
+extern const FFCodec ff_ilbc_at_encoder;
+extern const FFCodec ff_ilbc_at_decoder;
+extern const FFCodec ff_mp1_at_decoder;
+extern const FFCodec ff_mp2_at_decoder;
+extern const FFCodec ff_mp3_at_decoder;
+extern const FFCodec ff_pcm_alaw_at_encoder;
+extern const FFCodec ff_pcm_alaw_at_decoder;
+extern const FFCodec ff_pcm_mulaw_at_encoder;
+extern const FFCodec ff_pcm_mulaw_at_decoder;
+extern const FFCodec ff_qdmc_at_decoder;
+extern const FFCodec ff_qdm2_at_decoder;
+extern FFCodec ff_libaom_av1_encoder;
+extern const FFCodec ff_libaribb24_decoder;
+extern const FFCodec ff_libcelt_decoder;
+extern const FFCodec ff_libcodec2_encoder;
+extern const FFCodec ff_libcodec2_decoder;
+extern const FFCodec ff_libdav1d_decoder;
+extern const FFCodec ff_libdavs2_decoder;
+extern const FFCodec ff_libfdk_aac_encoder;
+extern const FFCodec ff_libfdk_aac_decoder;
+extern const FFCodec ff_libgsm_encoder;
+extern const FFCodec ff_libgsm_decoder;
+extern const FFCodec ff_libgsm_ms_encoder;
+extern const FFCodec ff_libgsm_ms_decoder;
+extern const FFCodec ff_libilbc_encoder;
+extern const FFCodec ff_libilbc_decoder;
+extern const FFCodec ff_libjxl_decoder;
+extern const FFCodec ff_libjxl_encoder;
+extern const FFCodec ff_libmp3lame_encoder;
+extern const FFCodec ff_libopencore_amrnb_encoder;
+extern const FFCodec ff_libopencore_amrnb_decoder;
+extern const FFCodec ff_libopencore_amrwb_decoder;
+extern const FFCodec ff_libopenjpeg_encoder;
+extern const FFCodec ff_libopenjpeg_decoder;
+extern const FFCodec ff_libopus_encoder;
+extern const FFCodec ff_libopus_decoder;
+extern const FFCodec ff_librav1e_encoder;
+extern const FFCodec ff_librsvg_decoder;
+extern const FFCodec ff_libshine_encoder;
+extern const FFCodec ff_libspeex_encoder;
+extern const FFCodec ff_libspeex_decoder;
+extern const FFCodec ff_libsvtav1_encoder;
+extern const FFCodec ff_libtheora_encoder;
+extern const FFCodec ff_libtwolame_encoder;
+extern const FFCodec ff_libuavs3d_decoder;
+extern const FFCodec ff_libvo_amrwbenc_encoder;
+extern const FFCodec ff_libvorbis_encoder;
+extern const FFCodec ff_libvorbis_decoder;
+extern const FFCodec ff_libvpx_vp8_encoder;
+extern const FFCodec ff_libvpx_vp8_decoder;
+extern FFCodec ff_libvpx_vp9_encoder;
+extern FFCodec ff_libvpx_vp9_decoder;
 /* preferred over libwebp */
-extern const AVCodec ff_libwebp_anim_encoder;
-extern const AVCodec ff_libwebp_encoder;
-extern const AVCodec ff_libx262_encoder;
+extern const FFCodec ff_libwebp_anim_encoder;
+extern const FFCodec ff_libwebp_encoder;
+extern const FFCodec ff_libx262_encoder;
 #if CONFIG_LIBX264_ENCODER
 #include <x264.h>
 #if X264_BUILD < 153
@@ -779,80 +792,80 @@ extern const AVCodec ff_libx262_encoder;
 #else
 #define LIBX264_CONST const
 #endif
-extern LIBX264_CONST AVCodec ff_libx264_encoder;
+extern LIBX264_CONST FFCodec ff_libx264_encoder;
 #endif
-extern const AVCodec ff_libx264rgb_encoder;
-extern AVCodec ff_libx265_encoder;
-extern const AVCodec ff_libxavs_encoder;
-extern const AVCodec ff_libxavs2_encoder;
-extern const AVCodec ff_libxvid_encoder;
-extern const AVCodec ff_libzvbi_teletext_decoder;
+extern const FFCodec ff_libx264rgb_encoder;
+extern FFCodec ff_libx265_encoder;
+extern const FFCodec ff_libxavs_encoder;
+extern const FFCodec ff_libxavs2_encoder;
+extern const FFCodec ff_libxvid_encoder;
+extern const FFCodec ff_libzvbi_teletext_decoder;
 
 /* text */
-extern const AVCodec ff_bintext_decoder;
-extern const AVCodec ff_xbin_decoder;
-extern const AVCodec ff_idf_decoder;
+extern const FFCodec ff_bintext_decoder;
+extern const FFCodec ff_xbin_decoder;
+extern const FFCodec ff_idf_decoder;
 
 /* external libraries, that shouldn't be used by default if one of the
  * above is available */
-extern const AVCodec ff_aac_mf_encoder;
-extern const AVCodec ff_ac3_mf_encoder;
-extern const AVCodec ff_h263_v4l2m2m_encoder;
-extern const AVCodec ff_libaom_av1_decoder;
+extern const FFCodec ff_aac_mf_encoder;
+extern const FFCodec ff_ac3_mf_encoder;
+extern const FFCodec ff_h263_v4l2m2m_encoder;
+extern const FFCodec ff_libaom_av1_decoder;
 /* hwaccel hooks only, so prefer external decoders */
-extern const AVCodec ff_av1_decoder;
-extern const AVCodec ff_av1_cuvid_decoder;
-extern const AVCodec ff_av1_qsv_decoder;
-extern const AVCodec ff_libopenh264_encoder;
-extern const AVCodec ff_libopenh264_decoder;
-extern const AVCodec ff_h264_amf_encoder;
-extern const AVCodec ff_h264_cuvid_decoder;
-extern const AVCodec ff_h264_mf_encoder;
-extern const AVCodec ff_h264_nvenc_encoder;
-extern const AVCodec ff_h264_omx_encoder;
-extern const AVCodec ff_h264_qsv_encoder;
-extern const AVCodec ff_h264_v4l2m2m_encoder;
-extern const AVCodec ff_h264_vaapi_encoder;
-extern const AVCodec ff_h264_videotoolbox_encoder;
-extern const AVCodec ff_hevc_amf_encoder;
-extern const AVCodec ff_hevc_cuvid_decoder;
-extern const AVCodec ff_hevc_mediacodec_decoder;
-extern const AVCodec ff_hevc_mf_encoder;
-extern const AVCodec ff_hevc_nvenc_encoder;
-extern const AVCodec ff_hevc_qsv_encoder;
-extern const AVCodec ff_hevc_v4l2m2m_encoder;
-extern const AVCodec ff_hevc_vaapi_encoder;
-extern const AVCodec ff_hevc_videotoolbox_encoder;
-extern const AVCodec ff_libkvazaar_encoder;
-extern const AVCodec ff_mjpeg_cuvid_decoder;
-extern const AVCodec ff_mjpeg_qsv_encoder;
-extern const AVCodec ff_mjpeg_qsv_decoder;
-extern const AVCodec ff_mjpeg_vaapi_encoder;
-extern const AVCodec ff_mp3_mf_encoder;
-extern const AVCodec ff_mpeg1_cuvid_decoder;
-extern const AVCodec ff_mpeg2_cuvid_decoder;
-extern const AVCodec ff_mpeg2_qsv_encoder;
-extern const AVCodec ff_mpeg2_vaapi_encoder;
-extern const AVCodec ff_mpeg4_cuvid_decoder;
-extern const AVCodec ff_mpeg4_mediacodec_decoder;
-extern const AVCodec ff_mpeg4_omx_encoder;
-extern const AVCodec ff_mpeg4_v4l2m2m_encoder;
-extern const AVCodec ff_prores_videotoolbox_encoder;
-extern const AVCodec ff_vc1_cuvid_decoder;
-extern const AVCodec ff_vp8_cuvid_decoder;
-extern const AVCodec ff_vp8_mediacodec_decoder;
-extern const AVCodec ff_vp8_qsv_decoder;
-extern const AVCodec ff_vp8_v4l2m2m_encoder;
-extern const AVCodec ff_vp8_vaapi_encoder;
-extern const AVCodec ff_vp9_cuvid_decoder;
-extern const AVCodec ff_vp9_mediacodec_decoder;
-extern const AVCodec ff_vp9_qsv_decoder;
-extern const AVCodec ff_vp9_vaapi_encoder;
-extern const AVCodec ff_vp9_qsv_encoder;
+extern const FFCodec ff_av1_decoder;
+extern const FFCodec ff_av1_cuvid_decoder;
+extern const FFCodec ff_av1_qsv_decoder;
+extern const FFCodec ff_libopenh264_encoder;
+extern const FFCodec ff_libopenh264_decoder;
+extern const FFCodec ff_h264_amf_encoder;
+extern const FFCodec ff_h264_cuvid_decoder;
+extern const FFCodec ff_h264_mf_encoder;
+extern const FFCodec ff_h264_nvenc_encoder;
+extern const FFCodec ff_h264_omx_encoder;
+extern const FFCodec ff_h264_qsv_encoder;
+extern const FFCodec ff_h264_v4l2m2m_encoder;
+extern const FFCodec ff_h264_vaapi_encoder;
+extern const FFCodec ff_h264_videotoolbox_encoder;
+extern const FFCodec ff_hevc_amf_encoder;
+extern const FFCodec ff_hevc_cuvid_decoder;
+extern const FFCodec ff_hevc_mediacodec_decoder;
+extern const FFCodec ff_hevc_mf_encoder;
+extern const FFCodec ff_hevc_nvenc_encoder;
+extern const FFCodec ff_hevc_qsv_encoder;
+extern const FFCodec ff_hevc_v4l2m2m_encoder;
+extern const FFCodec ff_hevc_vaapi_encoder;
+extern const FFCodec ff_hevc_videotoolbox_encoder;
+extern const FFCodec ff_libkvazaar_encoder;
+extern const FFCodec ff_mjpeg_cuvid_decoder;
+extern const FFCodec ff_mjpeg_qsv_encoder;
+extern const FFCodec ff_mjpeg_qsv_decoder;
+extern const FFCodec ff_mjpeg_vaapi_encoder;
+extern const FFCodec ff_mp3_mf_encoder;
+extern const FFCodec ff_mpeg1_cuvid_decoder;
+extern const FFCodec ff_mpeg2_cuvid_decoder;
+extern const FFCodec ff_mpeg2_qsv_encoder;
+extern const FFCodec ff_mpeg2_vaapi_encoder;
+extern const FFCodec ff_mpeg4_cuvid_decoder;
+extern const FFCodec ff_mpeg4_mediacodec_decoder;
+extern const FFCodec ff_mpeg4_omx_encoder;
+extern const FFCodec ff_mpeg4_v4l2m2m_encoder;
+extern const FFCodec ff_prores_videotoolbox_encoder;
+extern const FFCodec ff_vc1_cuvid_decoder;
+extern const FFCodec ff_vp8_cuvid_decoder;
+extern const FFCodec ff_vp8_mediacodec_decoder;
+extern const FFCodec ff_vp8_qsv_decoder;
+extern const FFCodec ff_vp8_v4l2m2m_encoder;
+extern const FFCodec ff_vp8_vaapi_encoder;
+extern const FFCodec ff_vp9_cuvid_decoder;
+extern const FFCodec ff_vp9_mediacodec_decoder;
+extern const FFCodec ff_vp9_qsv_decoder;
+extern const FFCodec ff_vp9_vaapi_encoder;
+extern const FFCodec ff_vp9_qsv_encoder;
 
 // The iterate API is not usable with ossfuzz due to the excessive size of binaries created
 #if CONFIG_OSSFUZZ
-const AVCodec * codec_list[] = {
+const FFCodec * codec_list[] = {
     NULL,
     NULL,
     NULL
@@ -866,21 +879,22 @@ static void av_codec_init_static(void)
 {
     for (int i = 0; codec_list[i]; i++) {
         if (codec_list[i]->init_static_data)
-            codec_list[i]->init_static_data((AVCodec*)codec_list[i]);
+            codec_list[i]->init_static_data((FFCodec*)codec_list[i]);
     }
 }
 
 const AVCodec *av_codec_iterate(void **opaque)
 {
     uintptr_t i = (uintptr_t)*opaque;
-    const AVCodec *c = codec_list[i];
+    const FFCodec *c = codec_list[i];
 
     ff_thread_once(&av_codec_static_init, av_codec_init_static);
 
-    if (c)
+    if (c) {
         *opaque = (void*)(i + 1);
-
-    return c;
+        return &c->p;
+    }
+    return NULL;
 }
 
 static enum AVCodecID remap_deprecated_codec_id(enum AVCodecID id)
diff -pruN 7:5.0.1-3/libavcodec/alsdec.c 7:5.1-1/libavcodec/alsdec.c
--- 7:5.0.1-3/libavcodec/alsdec.c	2022-01-14 18:45:39.000000000 +0000
+++ 7:5.1-1/libavcodec/alsdec.c	2022-07-22 17:58:38.000000000 +0000
@@ -33,6 +33,7 @@
 #include "mpeg4audio.h"
 #include "bgmc.h"
 #include "bswapdsp.h"
+#include "codec_internal.h"
 #include "internal.h"
 #include "mlz.h"
 #include "libavutil/samplefmt.h"
@@ -319,7 +320,13 @@ static av_cold int read_specific_config(
     avctx->sample_rate          = m4ac.sample_rate;
     skip_bits_long(&gb, 32); // sample rate already known
     sconf->samples              = get_bits_long(&gb, 32);
-    avctx->channels             = m4ac.channels;
+
+    if (avctx->ch_layout.nb_channels != m4ac.channels) {
+        av_channel_layout_uninit(&avctx->ch_layout);
+        avctx->ch_layout.order = AV_CHANNEL_ORDER_UNSPEC;
+        avctx->ch_layout.nb_channels = m4ac.channels;
+    }
+
     skip_bits(&gb, 16);      // number of channels already known
     skip_bits(&gb, 3);       // skip file_type
     sconf->resolution           = get_bits(&gb, 3);
@@ -349,11 +356,14 @@ static av_cold int read_specific_config(
     if (als_id != MKBETAG('A','L','S','\0'))
         return AVERROR_INVALIDDATA;
 
-    if (avctx->channels > FF_SANE_NB_CHANNELS) {
+    if (avctx->ch_layout.nb_channels > FF_SANE_NB_CHANNELS) {
         avpriv_request_sample(avctx, "Huge number of channels");
         return AVERROR_PATCHWELCOME;
     }
 
+    if (avctx->ch_layout.nb_channels == 0)
+        return AVERROR_INVALIDDATA;
+
     ctx->cur_frame_length = sconf->frame_length;
 
     // read channel config
@@ -363,26 +373,26 @@ static av_cold int read_specific_config(
 
 
     // read channel sorting
-    if (sconf->chan_sort && avctx->channels > 1) {
-        int chan_pos_bits = av_ceil_log2(avctx->channels);
-        int bits_needed  = avctx->channels * chan_pos_bits + 7;
+    if (sconf->chan_sort && avctx->ch_layout.nb_channels > 1) {
+        int chan_pos_bits = av_ceil_log2(avctx->ch_layout.nb_channels);
+        int bits_needed  = avctx->ch_layout.nb_channels * chan_pos_bits + 7;
         if (get_bits_left(&gb) < bits_needed)
             return AVERROR_INVALIDDATA;
 
-        if (!(sconf->chan_pos = av_malloc_array(avctx->channels, sizeof(*sconf->chan_pos))))
+        if (!(sconf->chan_pos = av_malloc_array(avctx->ch_layout.nb_channels, sizeof(*sconf->chan_pos))))
             return AVERROR(ENOMEM);
 
         ctx->cs_switch = 1;
 
-        for (i = 0; i < avctx->channels; i++) {
+        for (i = 0; i < avctx->ch_layout.nb_channels; i++) {
             sconf->chan_pos[i] = -1;
         }
 
-        for (i = 0; i < avctx->channels; i++) {
+        for (i = 0; i < avctx->ch_layout.nb_channels; i++) {
             int idx;
 
             idx = get_bits(&gb, chan_pos_bits);
-            if (idx >= avctx->channels || sconf->chan_pos[idx] != -1) {
+            if (idx >= avctx->ch_layout.nb_channels || sconf->chan_pos[idx] != -1) {
                 av_log(avctx, AV_LOG_WARNING, "Invalid channel reordering.\n");
                 ctx->cs_switch = 0;
                 break;
@@ -1228,7 +1238,7 @@ static int read_channel_data(ALSDecConte
 {
     GetBitContext *gb       = &ctx->gb;
     ALSChannelData *current = cd;
-    unsigned int channels   = ctx->avctx->channels;
+    unsigned int channels   = ctx->avctx->ch_layout.nb_channels;
     int entries             = 0;
 
     while (entries < channels && !(current->stop_flag = get_bits1(gb))) {
@@ -1277,7 +1287,7 @@ static int revert_channel_correlation(AL
 {
     ALSChannelData *ch = cd[c];
     unsigned int   dep = 0;
-    unsigned int channels = ctx->avctx->channels;
+    unsigned int channels = ctx->avctx->ch_layout.nb_channels;
     unsigned int channel_size = ctx->sconf.frame_length + ctx->sconf.max_order;
 
     if (reverted[c])
@@ -1475,15 +1485,15 @@ static int read_diff_float_data(ALSDecCo
     use_acf = get_bits1(gb);
 
     if (ra_frame) {
-        memset(last_acf_mantissa, 0, avctx->channels * sizeof(*last_acf_mantissa));
-        memset(last_shift_value,  0, avctx->channels * sizeof(*last_shift_value) );
+        memset(last_acf_mantissa, 0, avctx->ch_layout.nb_channels * sizeof(*last_acf_mantissa));
+        memset(last_shift_value,  0, avctx->ch_layout.nb_channels * sizeof(*last_shift_value) );
         ff_mlz_flush_dict(ctx->mlz);
     }
 
-    if (avctx->channels * 8 > get_bits_left(gb))
+    if (avctx->ch_layout.nb_channels * 8 > get_bits_left(gb))
         return AVERROR_INVALIDDATA;
 
-    for (c = 0; c < avctx->channels; ++c) {
+    for (c = 0; c < avctx->ch_layout.nb_channels; ++c) {
         if (use_acf) {
             //acf_flag
             if (get_bits1(gb)) {
@@ -1634,6 +1644,7 @@ static int read_frame_data(ALSDecContext
     unsigned int div_blocks[32];                ///< block sizes.
     int c;
     unsigned int js_blocks[2];
+    int channels = avctx->ch_layout.nb_channels;
     uint32_t bs_info = 0;
     int ret;
 
@@ -1649,7 +1660,7 @@ static int read_frame_data(ALSDecContext
     if (!sconf->mc_coding || ctx->js_switch) {
         int independent_bs = !sconf->joint_stereo;
 
-        for (c = 0; c < avctx->channels; c++) {
+        for (c = 0; c < channels; c++) {
             js_blocks[0] = 0;
             js_blocks[1] = 0;
 
@@ -1662,7 +1673,7 @@ static int read_frame_data(ALSDecContext
                     independent_bs = 2;
 
             // if this is the last channel, it has to be decoded independently
-            if (c == avctx->channels - 1 || (c & 1))
+            if (c == channels - 1 || (c & 1))
                 independent_bs = 1;
 
             if (independent_bs) {
@@ -1691,13 +1702,13 @@ static int read_frame_data(ALSDecContext
         int            *reverted_channels = ctx->reverted_channels;
         unsigned int   offset             = 0;
 
-        for (c = 0; c < avctx->channels; c++)
+        for (c = 0; c < channels; c++)
             if (ctx->chan_data[c] < ctx->chan_data_buffer) {
                 av_log(ctx->avctx, AV_LOG_ERROR, "Invalid channel data.\n");
                 return AVERROR_INVALIDDATA;
             }
 
-        memset(reverted_channels, 0, sizeof(*reverted_channels) * avctx->channels);
+        memset(reverted_channels, 0, sizeof(*reverted_channels) * channels);
 
         bd.ra_block         = ra_frame;
         bd.prev_raw_samples = ctx->prev_raw_samples;
@@ -1713,7 +1724,7 @@ static int read_frame_data(ALSDecContext
                 continue;
             }
 
-            for (c = 0; c < avctx->channels; c++) {
+            for (c = 0; c < channels; c++) {
                 bd.const_block = ctx->const_block + c;
                 bd.shift_lsbs  = ctx->shift_lsbs + c;
                 bd.opt_order   = ctx->opt_order + c;
@@ -1732,13 +1743,13 @@ static int read_frame_data(ALSDecContext
                     return ret;
             }
 
-            for (c = 0; c < avctx->channels; c++) {
+            for (c = 0; c < channels; c++) {
                 ret = revert_channel_correlation(ctx, &bd, ctx->chan_data,
                                                  reverted_channels, offset, c);
                 if (ret < 0)
                     return ret;
             }
-            for (c = 0; c < avctx->channels; c++) {
+            for (c = 0; c < channels; c++) {
                 bd.const_block = ctx->const_block + c;
                 bd.shift_lsbs  = ctx->shift_lsbs + c;
                 bd.opt_order   = ctx->opt_order + c;
@@ -1756,13 +1767,13 @@ static int read_frame_data(ALSDecContext
                 ctx->highest_decoded_channel = FFMAX(ctx->highest_decoded_channel, c);
             }
 
-            memset(reverted_channels, 0, avctx->channels * sizeof(*reverted_channels));
+            memset(reverted_channels, 0, channels * sizeof(*reverted_channels));
             offset      += div_blocks[b];
             bd.ra_block  = 0;
         }
 
         // store carryover raw samples
-        for (c = 0; c < avctx->channels; c++)
+        for (c = 0; c < channels; c++)
             memmove(ctx->raw_samples[c] - sconf->max_order,
                     ctx->raw_samples[c] - sconf->max_order + sconf->frame_length,
                     sizeof(*ctx->raw_samples[c]) * sconf->max_order);
@@ -1783,15 +1794,15 @@ static int read_frame_data(ALSDecContext
 
 /** Decode an ALS frame.
  */
-static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame_ptr,
-                        AVPacket *avpkt)
+static int decode_frame(AVCodecContext *avctx, AVFrame *frame,
+                        int *got_frame_ptr, AVPacket *avpkt)
 {
     ALSDecContext *ctx       = avctx->priv_data;
-    AVFrame *frame           = data;
     ALSSpecificConfig *sconf = &ctx->sconf;
     const uint8_t *buffer    = avpkt->data;
     int buffer_size          = avpkt->size;
     int invalid_frame, ret;
+    int channels = avctx->ch_layout.nb_channels;
     unsigned int c, sample, ra_frame, bytes_read, shift;
 
     if ((ret = init_get_bits8(&ctx->gb, buffer, buffer_size)) < 0)
@@ -1833,7 +1844,6 @@ static int decode_frame(AVCodecContext *
     #define INTERLEAVE_OUTPUT(bps)                                                   \
     {                                                                                \
         int##bps##_t *dest = (int##bps##_t*)frame->data[0];                          \
-        int channels = avctx->channels;                                              \
         int32_t *raw_samples = ctx->raw_samples[0];                                  \
         int raw_step = channels > 1 ? ctx->raw_samples[1] - raw_samples : 1;         \
         shift = bps - ctx->avctx->bits_per_raw_sample;                               \
@@ -1862,7 +1872,7 @@ static int decode_frame(AVCodecContext *
             int32_t *src = (int32_t *)frame->data[0];
 
             for (sample = 0;
-                 sample < ctx->cur_frame_length * avctx->channels;
+                 sample < ctx->cur_frame_length * channels;
                  sample++) {
                 int32_t v;
 
@@ -1883,13 +1893,13 @@ static int decode_frame(AVCodecContext *
                     int16_t *src  = (int16_t*) frame->data[0];
                     int16_t *dest = (int16_t*) ctx->crc_buffer;
                     for (sample = 0;
-                         sample < ctx->cur_frame_length * avctx->channels;
+                         sample < ctx->cur_frame_length * channels;
                          sample++)
                         *dest++ = av_bswap16(src[sample]);
                 } else {
                     ctx->bdsp.bswap_buf((uint32_t *) ctx->crc_buffer,
                                         (uint32_t *) frame->data[0],
-                                        ctx->cur_frame_length * avctx->channels);
+                                        ctx->cur_frame_length * channels);
                 }
                 crc_source = ctx->crc_buffer;
             } else {
@@ -1897,7 +1907,7 @@ static int decode_frame(AVCodecContext *
             }
 
             ctx->crc = av_crc(ctx->crc_table, ctx->crc, crc_source,
-                              ctx->cur_frame_length * avctx->channels *
+                              ctx->cur_frame_length * channels *
                               av_get_bytes_per_sample(avctx->sample_fmt));
         }
 
@@ -1960,7 +1970,7 @@ static av_cold int decode_end(AVCodecCon
     av_freep(&ctx->shift_value);
     av_freep(&ctx->last_shift_value);
     if (ctx->raw_mantissa) {
-        for (i = 0; i < avctx->channels; i++) {
+        for (i = 0; i < avctx->ch_layout.nb_channels; i++) {
             av_freep(&ctx->raw_mantissa[i]);
         }
         av_freep(&ctx->raw_mantissa);
@@ -1979,6 +1989,7 @@ static av_cold int decode_init(AVCodecCo
     unsigned int c;
     unsigned int channel_size;
     int num_buffers, ret;
+    int channels;
     ALSDecContext *ctx = avctx->priv_data;
     ALSSpecificConfig *sconf = &ctx->sconf;
     ctx->avctx = avctx;
@@ -1990,17 +2001,18 @@ static av_cold int decode_init(AVCodecCo
 
     if ((ret = read_specific_config(ctx)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "Reading ALSSpecificConfig failed.\n");
-        goto fail;
+        return ret;
     }
+    channels = avctx->ch_layout.nb_channels;
 
     if ((ret = check_specific_config(ctx)) < 0) {
-        goto fail;
+        return ret;
     }
 
     if (sconf->bgmc) {
         ret = ff_bgmc_init(avctx, &ctx->bgmc_lut, &ctx->bgmc_lut_status);
         if (ret < 0)
-            goto fail;
+            return ret;
     }
     if (sconf->floating) {
         avctx->sample_fmt          = AV_SAMPLE_FMT_FLT;
@@ -2012,8 +2024,7 @@ static av_cold int decode_init(AVCodecCo
         if (avctx->bits_per_raw_sample > 32) {
             av_log(avctx, AV_LOG_ERROR, "Bits per raw sample %d larger than 32.\n",
                    avctx->bits_per_raw_sample);
-            ret = AVERROR_INVALIDDATA;
-            goto fail;
+            return AVERROR_INVALIDDATA;
         }
     }
 
@@ -2027,7 +2038,7 @@ static av_cold int decode_init(AVCodecCo
                               (avctx->sample_rate >= 192000);
 
     // allocate quantized parcor coefficient buffer
-    num_buffers = sconf->mc_coding ? avctx->channels : 1;
+    num_buffers = sconf->mc_coding ? channels : 1;
     if (num_buffers * (uint64_t)num_buffers > INT_MAX) // protect chan_data_buffer allocation
         return AVERROR_INVALIDDATA;
 
@@ -2044,8 +2055,7 @@ static av_cold int decode_init(AVCodecCo
         !ctx->quant_cof_buffer       || !ctx->lpc_cof_buffer ||
         !ctx->lpc_cof_reversed_buffer) {
         av_log(avctx, AV_LOG_ERROR, "Allocating buffer memory failed.\n");
-        ret = AVERROR(ENOMEM);
-        goto fail;
+        return AVERROR(ENOMEM);
     }
 
     // assign quantized parcor coefficient buffers
@@ -2069,8 +2079,7 @@ static av_cold int decode_init(AVCodecCo
         !ctx->use_ltp  || !ctx->ltp_lag ||
         !ctx->ltp_gain || !ctx->ltp_gain_buffer) {
         av_log(avctx, AV_LOG_ERROR, "Allocating buffer memory failed.\n");
-        ret = AVERROR(ENOMEM);
-        goto fail;
+        return AVERROR(ENOMEM);
     }
 
     for (c = 0; c < num_buffers; c++)
@@ -2086,8 +2095,7 @@ static av_cold int decode_init(AVCodecCo
 
         if (!ctx->chan_data_buffer || !ctx->chan_data || !ctx->reverted_channels) {
             av_log(avctx, AV_LOG_ERROR, "Allocating buffer memory failed.\n");
-            ret = AVERROR(ENOMEM);
-            goto fail;
+            return AVERROR(ENOMEM);
         }
 
         for (c = 0; c < num_buffers; c++)
@@ -2098,18 +2106,12 @@ static av_cold int decode_init(AVCodecCo
         ctx->reverted_channels = NULL;
     }
 
-    channel_size      = sconf->frame_length + sconf->max_order;
-
-    ctx->prev_raw_samples = av_malloc_array(sconf->max_order, sizeof(*ctx->prev_raw_samples));
-    ctx->raw_buffer       = av_calloc(avctx->channels * channel_size, sizeof(*ctx->raw_buffer));
-    ctx->raw_samples      = av_malloc_array(avctx->channels, sizeof(*ctx->raw_samples));
-
     if (sconf->floating) {
-        ctx->acf               = av_malloc_array(avctx->channels, sizeof(*ctx->acf));
-        ctx->shift_value       = av_malloc_array(avctx->channels, sizeof(*ctx->shift_value));
-        ctx->last_shift_value  = av_malloc_array(avctx->channels, sizeof(*ctx->last_shift_value));
-        ctx->last_acf_mantissa = av_malloc_array(avctx->channels, sizeof(*ctx->last_acf_mantissa));
-        ctx->raw_mantissa      = av_calloc(avctx->channels, sizeof(*ctx->raw_mantissa));
+        ctx->acf               = av_malloc_array(channels, sizeof(*ctx->acf));
+        ctx->shift_value       = av_malloc_array(channels, sizeof(*ctx->shift_value));
+        ctx->last_shift_value  = av_malloc_array(channels, sizeof(*ctx->last_shift_value));
+        ctx->last_acf_mantissa = av_malloc_array(channels, sizeof(*ctx->last_acf_mantissa));
+        ctx->raw_mantissa      = av_calloc(channels, sizeof(*ctx->raw_mantissa));
 
         ctx->larray = av_malloc_array(ctx->cur_frame_length * 4, sizeof(*ctx->larray));
         ctx->nbits  = av_malloc_array(ctx->cur_frame_length, sizeof(*ctx->nbits));
@@ -2118,50 +2120,51 @@ static av_cold int decode_init(AVCodecCo
         if (!ctx->mlz || !ctx->acf || !ctx->shift_value || !ctx->last_shift_value
             || !ctx->last_acf_mantissa || !ctx->raw_mantissa) {
             av_log(avctx, AV_LOG_ERROR, "Allocating buffer memory failed.\n");
-            ret = AVERROR(ENOMEM);
-            goto fail;
+            return AVERROR(ENOMEM);
         }
 
-        ff_mlz_init_dict(avctx, ctx->mlz);
+        ret = ff_mlz_init_dict(avctx, ctx->mlz);
+        if (ret < 0)
+            return ret;
         ff_mlz_flush_dict(ctx->mlz);
 
-        for (c = 0; c < avctx->channels; ++c) {
+        for (c = 0; c < channels; ++c) {
             ctx->raw_mantissa[c] = av_calloc(ctx->cur_frame_length, sizeof(**ctx->raw_mantissa));
         }
     }
 
+    channel_size      = sconf->frame_length + sconf->max_order;
+
     // allocate previous raw sample buffer
+    ctx->prev_raw_samples = av_malloc_array(sconf->max_order, sizeof(*ctx->prev_raw_samples));
+    ctx->raw_buffer       = av_calloc(channels * channel_size, sizeof(*ctx->raw_buffer));
+    ctx->raw_samples      = av_malloc_array(channels, sizeof(*ctx->raw_samples));
     if (!ctx->prev_raw_samples || !ctx->raw_buffer|| !ctx->raw_samples) {
         av_log(avctx, AV_LOG_ERROR, "Allocating buffer memory failed.\n");
-        ret = AVERROR(ENOMEM);
-        goto fail;
+        return AVERROR(ENOMEM);
     }
 
     // assign raw samples buffers
     ctx->raw_samples[0] = ctx->raw_buffer + sconf->max_order;
-    for (c = 1; c < avctx->channels; c++)
+    for (c = 1; c < channels; c++)
         ctx->raw_samples[c] = ctx->raw_samples[c - 1] + channel_size;
 
     // allocate crc buffer
     if (HAVE_BIGENDIAN != sconf->msb_first && sconf->crc_enabled &&
         (avctx->err_recognition & (AV_EF_CRCCHECK|AV_EF_CAREFUL))) {
         ctx->crc_buffer = av_malloc_array(ctx->cur_frame_length *
-                                          avctx->channels *
+                                          channels *
                                           av_get_bytes_per_sample(avctx->sample_fmt),
                                           sizeof(*ctx->crc_buffer));
         if (!ctx->crc_buffer) {
             av_log(avctx, AV_LOG_ERROR, "Allocating buffer memory failed.\n");
-            ret = AVERROR(ENOMEM);
-            goto fail;
+            return AVERROR(ENOMEM);
         }
     }
 
     ff_bswapdsp_init(&ctx->bdsp);
 
     return 0;
-
-fail:
-    return ret;
 }
 
 
@@ -2175,16 +2178,16 @@ static av_cold void flush(AVCodecContext
 }
 
 
-const AVCodec ff_als_decoder = {
-    .name           = "als",
-    .long_name      = NULL_IF_CONFIG_SMALL("MPEG-4 Audio Lossless Coding (ALS)"),
-    .type           = AVMEDIA_TYPE_AUDIO,
-    .id             = AV_CODEC_ID_MP4ALS,
+const FFCodec ff_als_decoder = {
+    .p.name         = "als",
+    .p.long_name    = NULL_IF_CONFIG_SMALL("MPEG-4 Audio Lossless Coding (ALS)"),
+    .p.type         = AVMEDIA_TYPE_AUDIO,
+    .p.id           = AV_CODEC_ID_MP4ALS,
     .priv_data_size = sizeof(ALSDecContext),
     .init           = decode_init,
     .close          = decode_end,
-    .decode         = decode_frame,
+    FF_CODEC_DECODE_CB(decode_frame),
     .flush          = flush,
-    .capabilities   = AV_CODEC_CAP_SUBFRAMES | AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF,
-    .caps_internal  = FF_CODEC_CAP_INIT_CLEANUP,
+    .p.capabilities = AV_CODEC_CAP_SUBFRAMES | AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF,
+    .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
 };
diff -pruN 7:5.0.1-3/libavcodec/amfenc.c 7:5.1-1/libavcodec/amfenc.c
--- 7:5.0.1-3/libavcodec/amfenc.c	2021-10-24 20:47:07.000000000 +0000
+++ 7:5.1-1/libavcodec/amfenc.c	2022-07-22 17:58:38.000000000 +0000
@@ -17,6 +17,7 @@
  */
 
 #include "config.h"
+#include "config_components.h"
 
 #include "libavutil/avassert.h"
 #include "libavutil/imgutils.h"
@@ -117,8 +118,9 @@ static int amf_load_library(AVCodecConte
     if (!ctx->delayed_frame) {
         return AVERROR(ENOMEM);
     }
-    // hardcoded to current HW queue size - will realloc in timestamp_queue_enqueue() if too small
-    ctx->timestamp_list = av_fifo_alloc((avctx->max_b_frames + 16) * sizeof(int64_t));
+    // hardcoded to current HW queue size - will auto-realloc if too small
+    ctx->timestamp_list = av_fifo_alloc2(avctx->max_b_frames + 16, sizeof(int64_t),
+                                         AV_FIFO_FLAG_AUTO_GROW);
     if (!ctx->timestamp_list) {
         return AVERROR(ENOMEM);
     }
@@ -403,7 +405,7 @@ int av_cold ff_amf_encode_close(AVCodecC
     ctx->version = 0;
     ctx->delayed_drain = 0;
     av_frame_free(&ctx->delayed_frame);
-    av_fifo_freep(&ctx->timestamp_list);
+    av_fifo_freep2(&ctx->timestamp_list);
 
     return 0;
 }
@@ -432,18 +434,6 @@ static int amf_copy_surface(AVCodecConte
     return 0;
 }
 
-static inline int timestamp_queue_enqueue(AVCodecContext *avctx, int64_t timestamp)
-{
-    AmfContext         *ctx = avctx->priv_data;
-    if (av_fifo_space(ctx->timestamp_list) < sizeof(timestamp)) {
-        if (av_fifo_grow(ctx->timestamp_list, sizeof(timestamp)) < 0) {
-            return AVERROR(ENOMEM);
-        }
-    }
-    av_fifo_generic_write(ctx->timestamp_list, &timestamp, sizeof(timestamp), NULL);
-    return 0;
-}
-
 static int amf_copy_buffer(AVCodecContext *avctx, AVPacket *pkt, AMFBuffer *buffer)
 {
     AmfContext      *ctx = avctx->priv_data;
@@ -479,21 +469,17 @@ static int amf_copy_buffer(AVCodecContex
     pkt->pts = var.int64Value; // original pts
 
 
-    AMF_RETURN_IF_FALSE(ctx, av_fifo_size(ctx->timestamp_list) > 0, AVERROR_UNKNOWN, "timestamp_list is empty\n");
-
-    av_fifo_generic_read(ctx->timestamp_list, &timestamp, sizeof(timestamp), NULL);
+    AMF_RETURN_IF_FALSE(ctx, av_fifo_read(ctx->timestamp_list, &timestamp, 1) >= 0,
+                        AVERROR_UNKNOWN, "timestamp_list is empty\n");
 
     // calc dts shift if max_b_frames > 0
     if (avctx->max_b_frames > 0 && ctx->dts_delay == 0) {
         int64_t timestamp_last = AV_NOPTS_VALUE;
-        AMF_RETURN_IF_FALSE(ctx, av_fifo_size(ctx->timestamp_list) > 0, AVERROR_UNKNOWN,
+        size_t can_read = av_fifo_can_read(ctx->timestamp_list);
+
+        AMF_RETURN_IF_FALSE(ctx, can_read > 0, AVERROR_UNKNOWN,
             "timestamp_list is empty while max_b_frames = %d\n", avctx->max_b_frames);
-        av_fifo_generic_peek_at(
-            ctx->timestamp_list,
-            &timestamp_last,
-            (av_fifo_size(ctx->timestamp_list) / sizeof(timestamp) - 1) * sizeof(timestamp_last),
-            sizeof(timestamp_last),
-            NULL);
+        av_fifo_peek(ctx->timestamp_list, &timestamp_last, 1, can_read - 1);
         if (timestamp < 0 || timestamp_last < AV_NOPTS_VALUE) {
             return AVERROR(ERANGE);
         }
@@ -710,9 +696,9 @@ int ff_amf_receive_packet(AVCodecContext
             AMF_RETURN_IF_FALSE(ctx, res == AMF_OK, AVERROR_UNKNOWN, "SubmitInput() failed with error %d\n", res);
 
             av_frame_unref(frame);
-            if ((ret = timestamp_queue_enqueue(avctx, pts)) < 0) {
+            ret = av_fifo_write(ctx->timestamp_list, &pts, 1);
+            if (ret < 0)
                 return ret;
-            }
         }
     }
 
@@ -751,9 +737,9 @@ int ff_amf_receive_packet(AVCodecContext
                     av_frame_unref(ctx->delayed_frame);
                     AMF_RETURN_IF_FALSE(ctx, res == AMF_OK, AVERROR_UNKNOWN, "Repeated SubmitInput() failed with error %d\n", res);
 
-                    if ((ret = timestamp_queue_enqueue(avctx, pts)) < 0) {
+                    ret = av_fifo_write(ctx->timestamp_list, &pts, 1);
+                    if (ret < 0)
                         return ret;
-                    }
                 } else {
                     av_log(avctx, AV_LOG_WARNING, "Data acquired but delayed frame submission got AMF_INPUT_FULL- should not happen\n");
                 }
diff -pruN 7:5.0.1-3/libavcodec/amfenc.h 7:5.1-1/libavcodec/amfenc.h
--- 7:5.0.1-3/libavcodec/amfenc.h	2021-10-24 20:47:07.000000000 +0000
+++ 7:5.1-1/libavcodec/amfenc.h	2022-07-22 17:58:38.000000000 +0000
@@ -72,7 +72,7 @@ typedef struct AmfContext {
     AVFrame            *delayed_frame;
 
     // shift dts back by max_b_frames in timing
-    AVFifoBuffer       *timestamp_list;
+    AVFifo             *timestamp_list;
     int64_t             dts_delay;
 
     // common encoder option options
diff -pruN 7:5.0.1-3/libavcodec/amfenc_h264.c 7:5.1-1/libavcodec/amfenc_h264.c
--- 7:5.0.1-3/libavcodec/amfenc_h264.c	2022-01-14 18:45:39.000000000 +0000
+++ 7:5.1-1/libavcodec/amfenc_h264.c	2022-07-22 17:58:38.000000000 +0000
@@ -20,6 +20,7 @@
 #include "libavutil/internal.h"
 #include "libavutil/opt.h"
 #include "amfenc.h"
+#include "codec_internal.h"
 #include "internal.h"
 
 #define OFFSET(x) offsetof(AmfContext, x)
@@ -358,7 +359,7 @@ static av_cold int amf_encode_init_h264(
     return 0;
 }
 
-static const AVCodecDefault defaults[] = {
+static const FFCodecDefault defaults[] = {
     { "refs",       "-1"  },
     { "aspect",     "0"   },
     { "qmin",       "-1"  },
@@ -377,21 +378,21 @@ static const AVClass h264_amf_class = {
     .version = LIBAVUTIL_VERSION_INT,
 };
 
-const AVCodec ff_h264_amf_encoder = {
-    .name           = "h264_amf",
-    .long_name      = NULL_IF_CONFIG_SMALL("AMD AMF H.264 Encoder"),
-    .type           = AVMEDIA_TYPE_VIDEO,
-    .id             = AV_CODEC_ID_H264,
+const FFCodec ff_h264_amf_encoder = {
+    .p.name         = "h264_amf",
+    .p.long_name    = NULL_IF_CONFIG_SMALL("AMD AMF H.264 Encoder"),
+    .p.type         = AVMEDIA_TYPE_VIDEO,
+    .p.id           = AV_CODEC_ID_H264,
     .init           = amf_encode_init_h264,
-    .receive_packet = ff_amf_receive_packet,
+    FF_CODEC_RECEIVE_PACKET_CB(ff_amf_receive_packet),
     .close          = ff_amf_encode_close,
     .priv_data_size = sizeof(AmfContext),
-    .priv_class     = &h264_amf_class,
+    .p.priv_class   = &h264_amf_class,
     .defaults       = defaults,
-    .capabilities   = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE |
+    .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE |
                       AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_CLEANUP,
-    .pix_fmts       = ff_amf_pix_fmts,
-    .wrapper_name   = "amf",
+    .p.pix_fmts     = ff_amf_pix_fmts,
+    .p.wrapper_name = "amf",
     .hw_configs     = ff_amfenc_hw_configs,
 };
diff -pruN 7:5.0.1-3/libavcodec/amfenc_hevc.c 7:5.1-1/libavcodec/amfenc_hevc.c
--- 7:5.0.1-3/libavcodec/amfenc_hevc.c	2022-01-14 18:45:39.000000000 +0000
+++ 7:5.1-1/libavcodec/amfenc_hevc.c	2022-07-22 17:58:38.000000000 +0000
@@ -19,6 +19,7 @@
 #include "libavutil/internal.h"
 #include "libavutil/opt.h"
 #include "amfenc.h"
+#include "codec_internal.h"
 #include "internal.h"
 
 #define OFFSET(x) offsetof(AmfContext, x)
@@ -292,7 +293,7 @@ static av_cold int amf_encode_init_hevc(
 
     return 0;
 }
-static const AVCodecDefault defaults[] = {
+static const FFCodecDefault defaults[] = {
     { "refs",       "-1"  },
     { "aspect",     "0"   },
     { "b",          "2M"  },
@@ -309,21 +310,21 @@ static const AVClass hevc_amf_class = {
     .version = LIBAVUTIL_VERSION_INT,
 };
 
-const AVCodec ff_hevc_amf_encoder = {
-    .name           = "hevc_amf",
-    .long_name      = NULL_IF_CONFIG_SMALL("AMD AMF HEVC encoder"),
-    .type           = AVMEDIA_TYPE_VIDEO,
-    .id             = AV_CODEC_ID_HEVC,
+const FFCodec ff_hevc_amf_encoder = {
+    .p.name         = "hevc_amf",
+    .p.long_name    = NULL_IF_CONFIG_SMALL("AMD AMF HEVC encoder"),
+    .p.type         = AVMEDIA_TYPE_VIDEO,
+    .p.id           = AV_CODEC_ID_HEVC,
     .init           = amf_encode_init_hevc,
-    .receive_packet = ff_amf_receive_packet,
+    FF_CODEC_RECEIVE_PACKET_CB(ff_amf_receive_packet),
     .close          = ff_amf_encode_close,
     .priv_data_size = sizeof(AmfContext),
-    .priv_class     = &hevc_amf_class,
+    .p.priv_class   = &hevc_amf_class,
     .defaults       = defaults,
-    .capabilities   = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE |
+    .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE |
                       AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_CLEANUP,
-    .pix_fmts       = ff_amf_pix_fmts,
-    .wrapper_name   = "amf",
+    .p.pix_fmts     = ff_amf_pix_fmts,
+    .p.wrapper_name = "amf",
     .hw_configs     = ff_amfenc_hw_configs,
 };
diff -pruN 7:5.0.1-3/libavcodec/amrnbdec.c 7:5.1-1/libavcodec/amrnbdec.c
--- 7:5.0.1-3/libavcodec/amrnbdec.c	2022-01-14 18:45:39.000000000 +0000
+++ 7:5.1-1/libavcodec/amrnbdec.c	2022-07-22 17:58:38.000000000 +0000
@@ -55,6 +55,7 @@
 #include "acelp_pitch_delay.h"
 #include "lsp.h"
 #include "amr.h"
+#include "codec_internal.h"
 #include "internal.h"
 
 #include "amrnbdata.h"
@@ -166,20 +167,20 @@ static av_cold int amrnb_decode_init(AVC
     AMRChannelsContext *s = avctx->priv_data;
     int i;
 
-    if (avctx->channels > 2) {
+    if (avctx->ch_layout.nb_channels > 2) {
         avpriv_report_missing_feature(avctx, ">2 channel AMR");
         return AVERROR_PATCHWELCOME;
     }
 
-    if (!avctx->channels) {
-        avctx->channels       = 1;
-        avctx->channel_layout = AV_CH_LAYOUT_MONO;
+    if (!avctx->ch_layout.nb_channels) {
+        av_channel_layout_uninit(&avctx->ch_layout);
+        avctx->ch_layout      = (AVChannelLayout)AV_CHANNEL_LAYOUT_MONO;
     }
     if (!avctx->sample_rate)
         avctx->sample_rate = 8000;
     avctx->sample_fmt     = AV_SAMPLE_FMT_FLTP;
 
-    for (int ch = 0; ch < avctx->channels; ch++) {
+    for (int ch = 0; ch < avctx->ch_layout.nb_channels; ch++) {
         AMRContext *p = &s->ch[ch];
         // p->excitation always points to the same position in p->excitation_buf
         p->excitation = &p->excitation_buf[PITCH_DELAY_MAX + LP_FILTER_ORDER + 1];
@@ -954,12 +955,11 @@ static void postfilter(AMRContext *p, fl
 
 /// @}
 
-static int amrnb_decode_frame(AVCodecContext *avctx, void *data,
+static int amrnb_decode_frame(AVCodecContext *avctx, AVFrame *frame,
                               int *got_frame_ptr, AVPacket *avpkt)
 {
 
     AMRChannelsContext *s = avctx->priv_data;        // pointer to private data
-    AVFrame *frame     = data;
     const uint8_t *buf = avpkt->data;
     int buf_size       = avpkt->size;
     int ret;
@@ -969,7 +969,7 @@ static int amrnb_decode_frame(AVCodecCon
     if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
         return ret;
 
-    for (int ch = 0; ch < avctx->channels; ch++) {
+    for (int ch = 0; ch < avctx->ch_layout.nb_channels; ch++) {
         AMRContext *p = &s->ch[ch];
         float fixed_gain_factor;
         AMRFixed fixed_sparse = {0};             // fixed vector up to anti-sparseness processing
@@ -1096,15 +1096,16 @@ static int amrnb_decode_frame(AVCodecCon
 }
 
 
-const AVCodec ff_amrnb_decoder = {
-    .name           = "amrnb",
-    .long_name      = NULL_IF_CONFIG_SMALL("AMR-NB (Adaptive Multi-Rate NarrowBand)"),
-    .type           = AVMEDIA_TYPE_AUDIO,
-    .id             = AV_CODEC_ID_AMR_NB,
+const FFCodec ff_amrnb_decoder = {
+    .p.name         = "amrnb",
+    .p.long_name    = NULL_IF_CONFIG_SMALL("AMR-NB (Adaptive Multi-Rate NarrowBand)"),
+    .p.type         = AVMEDIA_TYPE_AUDIO,
+    .p.id           = AV_CODEC_ID_AMR_NB,
     .priv_data_size = sizeof(AMRChannelsContext),
     .init           = amrnb_decode_init,
-    .decode         = amrnb_decode_frame,
-    .capabilities   = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF,
-    .sample_fmts    = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_FLTP,
+    FF_CODEC_DECODE_CB(amrnb_decode_frame),
+    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF,
+    .p.sample_fmts  = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_FLTP,
                                                      AV_SAMPLE_FMT_NONE },
+    .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff -pruN 7:5.0.1-3/libavcodec/amr_parser.c 7:5.1-1/libavcodec/amr_parser.c
--- 7:5.0.1-3/libavcodec/amr_parser.c	2022-01-14 18:45:39.000000000 +0000
+++ 7:5.1-1/libavcodec/amr_parser.c	2022-07-22 17:58:38.000000000 +0000
@@ -63,9 +63,9 @@ static int amr_parse(AVCodecParserContex
     *poutbuf_size = 0;
     *poutbuf = NULL;
 
-    if (!avctx->channels) {
-        avctx->channels       = 1;
-        avctx->channel_layout = AV_CH_LAYOUT_MONO;
+    if (!avctx->ch_layout.nb_channels) {
+        av_channel_layout_uninit(&avctx->ch_layout);
+        avctx->ch_layout      = (AVChannelLayout)AV_CHANNEL_LAYOUT_MONO;
     }
 
     if (s1->flags & PARSER_FLAG_COMPLETE_FRAMES) {
@@ -73,7 +73,7 @@ static int amr_parse(AVCodecParserContex
     } else {
         int ch, offset = 0;
 
-        for (ch = s->current_channel; ch < avctx->channels; ch++) {
+        for (ch = s->current_channel; ch < avctx->ch_layout.nb_channels; ch++) {
             if (s->remaining >= 0) {
                 next = s->remaining;
             } else {
@@ -96,7 +96,7 @@ static int amr_parse(AVCodecParserContex
             }
         }
 
-        s->current_channel = ch % avctx->channels;
+        s->current_channel = ch % avctx->ch_layout.nb_channels;
         if (s->remaining < 0)
             next = offset;
 
diff -pruN 7:5.0.1-3/libavcodec/amrwbdec.c 7:5.1-1/libavcodec/amrwbdec.c
--- 7:5.0.1-3/libavcodec/amrwbdec.c	2022-01-14 18:45:39.000000000 +0000
+++ 7:5.1-1/libavcodec/amrwbdec.c	2022-07-22 17:58:38.000000000 +0000
@@ -36,6 +36,7 @@
 #include "acelp_filters.h"
 #include "acelp_vectors.h"
 #include "acelp_pitch_delay.h"
+#include "codec_internal.h"
 #include "internal.h"
 
 #define AMR_USE_16BIT_TABLES
@@ -102,20 +103,20 @@ static av_cold int amrwb_decode_init(AVC
     AMRWBChannelsContext *s = avctx->priv_data;
     int i;
 
-    if (avctx->channels > 2) {
+    if (avctx->ch_layout.nb_channels > 2) {
         avpriv_report_missing_feature(avctx, ">2 channel AMR");
         return AVERROR_PATCHWELCOME;
     }
 
-    if (!avctx->channels) {
-        avctx->channels       = 1;
-        avctx->channel_layout = AV_CH_LAYOUT_MONO;
+    if (!avctx->ch_layout.nb_channels) {
+        av_channel_layout_uninit(&avctx->ch_layout);
+        avctx->ch_layout      = (AVChannelLayout)AV_CHANNEL_LAYOUT_MONO;
     }
     if (!avctx->sample_rate)
         avctx->sample_rate = 16000;
     avctx->sample_fmt     = AV_SAMPLE_FMT_FLTP;
 
-    for (int ch = 0; ch < avctx->channels; ch++) {
+    for (int ch = 0; ch < avctx->ch_layout.nb_channels; ch++) {
         AMRWBContext *ctx = &s->ch[ch];
 
         av_lfg_init(&ctx->prng, 1);
@@ -1101,11 +1102,10 @@ static void update_sub_state(AMRWBContex
             LP_ORDER_16k * sizeof(float));
 }
 
-static int amrwb_decode_frame(AVCodecContext *avctx, void *data,
+static int amrwb_decode_frame(AVCodecContext *avctx, AVFrame *frame,
                               int *got_frame_ptr, AVPacket *avpkt)
 {
     AMRWBChannelsContext *s  = avctx->priv_data;
-    AVFrame *frame     = data;
     const uint8_t *buf = avpkt->data;
     int buf_size       = avpkt->size;
     int sub, i, ret;
@@ -1115,7 +1115,7 @@ static int amrwb_decode_frame(AVCodecCon
     if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
         return ret;
 
-    for (int ch = 0; ch < avctx->channels; ch++) {
+    for (int ch = 0; ch < avctx->ch_layout.nb_channels; ch++) {
         AMRWBContext *ctx  = &s->ch[ch];
         AMRWBFrame   *cf   = &ctx->frame;
         int expected_fr_size, header_size;
@@ -1292,15 +1292,16 @@ static int amrwb_decode_frame(AVCodecCon
     return avpkt->size;
 }
 
-const AVCodec ff_amrwb_decoder = {
-    .name           = "amrwb",
-    .long_name      = NULL_IF_CONFIG_SMALL("AMR-WB (Adaptive Multi-Rate WideBand)"),
-    .type           = AVMEDIA_TYPE_AUDIO,
-    .id             = AV_CODEC_ID_AMR_WB,
+const FFCodec ff_amrwb_decoder = {
+    .p.name         = "amrwb",
+    .p.long_name    = NULL_IF_CONFIG_SMALL("AMR-WB (Adaptive Multi-Rate WideBand)"),
+    .p.type         = AVMEDIA_TYPE_AUDIO,
+    .p.id           = AV_CODEC_ID_AMR_WB,
     .priv_data_size = sizeof(AMRWBChannelsContext),
     .init           = amrwb_decode_init,
-    .decode         = amrwb_decode_frame,
-    .capabilities   = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF,
-    .sample_fmts    = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_FLT,
+    FF_CODEC_DECODE_CB(amrwb_decode_frame),
+    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF,
+    .p.sample_fmts  = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_FLT,
                                                      AV_SAMPLE_FMT_NONE },
+    .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff -pruN 7:5.0.1-3/libavcodec/anm.c 7:5.1-1/libavcodec/anm.c
--- 7:5.0.1-3/libavcodec/anm.c	2022-01-14 18:45:39.000000000 +0000
+++ 7:5.1-1/libavcodec/anm.c	2022-07-22 17:58:38.000000000 +0000
@@ -26,6 +26,7 @@
 
 #include "avcodec.h"
 #include "bytestream.h"
+#include "codec_internal.h"
 #include "internal.h"
 
 typedef struct AnmContext {
@@ -107,9 +108,8 @@ exhausted:
     return 1;
 }
 
-static int decode_frame(AVCodecContext *avctx,
-                        void *data, int *got_frame,
-                        AVPacket *avpkt)
+static int decode_frame(AVCodecContext *avctx, AVFrame *rframe,
+                        int *got_frame, AVPacket *avpkt)
 {
     AnmContext *s = avctx->priv_data;
     const int buf_size = avpkt->size;
@@ -175,7 +175,7 @@ static int decode_frame(AVCodecContext *
     memcpy(s->frame->data[1], s->palette, AVPALETTE_SIZE);
 
     *got_frame = 1;
-    if ((ret = av_frame_ref(data, s->frame)) < 0)
+    if ((ret = av_frame_ref(rframe, s->frame)) < 0)
         return ret;
 
     return buf_size;
@@ -189,15 +189,15 @@ static av_cold int decode_end(AVCodecCon
     return 0;
 }
 
-const AVCodec ff_anm_decoder = {
-    .name           = "anm",
-    .long_name      = NULL_IF_CONFIG_SMALL("Deluxe Paint Animation"),
-    .type           = AVMEDIA_TYPE_VIDEO,
-    .id             = AV_CODEC_ID_ANM,
+const FFCodec ff_anm_decoder = {
+    .p.name         = "anm",
+    .p.long_name    = NULL_IF_CONFIG_SMALL("Deluxe Paint Animation"),
+    .p.type         = AVMEDIA_TYPE_VIDEO,
+    .p.id           = AV_CODEC_ID_ANM,
     .priv_data_size = sizeof(AnmContext),
     .init           = decode_init,
     .close          = decode_end,
-    .decode         = decode_frame,
-    .capabilities   = AV_CODEC_CAP_DR1,
+    FF_CODEC_DECODE_CB(decode_frame),
+    .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff -pruN 7:5.0.1-3/libavcodec/ansi.c 7:5.1-1/libavcodec/ansi.c
--- 7:5.0.1-3/libavcodec/ansi.c	2022-01-14 18:45:39.000000000 +0000
+++ 7:5.1-1/libavcodec/ansi.c	2022-07-22 17:58:38.000000000 +0000
@@ -30,6 +30,7 @@
 #include "libavutil/xga_font_data.h"
 #include "avcodec.h"
 #include "cga_data.h"
+#include "codec_internal.h"
 #include "internal.h"
 
 #define ATTR_BOLD         0x01  /**< Bold/Bright-foreground (mode 1) */
@@ -353,12 +354,11 @@ static int execute_code(AVCodecContext *
     return 0;
 }
 
-static int decode_frame(AVCodecContext *avctx,
-                            void *data, int *got_frame,
-                            AVPacket *avpkt)
+static int decode_frame(AVCodecContext *avctx, AVFrame *rframe,
+                        int *got_frame, AVPacket *avpkt)
 {
     AnsiContext *s = avctx->priv_data;
-    uint8_t *buf = avpkt->data;
+    const uint8_t *buf = avpkt->data;
     int buf_size = avpkt->size;
     const uint8_t *buf_end   = buf+buf_size;
     int ret, i, count;
@@ -462,7 +462,7 @@ static int decode_frame(AVCodecContext *
     }
 
     *got_frame = 1;
-    if ((ret = av_frame_ref(data, s->frame)) < 0)
+    if ((ret = av_frame_ref(rframe, s->frame)) < 0)
         return ret;
     return buf_size;
 }
@@ -475,21 +475,21 @@ static av_cold int decode_close(AVCodecC
     return 0;
 }
 
-static const AVCodecDefault ansi_defaults[] = {
+static const FFCodecDefault ansi_defaults[] = {
     { "max_pixels", "640*480" },
     { NULL },
 };
 
-const AVCodec ff_ansi_decoder = {
-    .name           = "ansi",
-    .long_name      = NULL_IF_CONFIG_SMALL("ASCII/ANSI art"),
-    .type           = AVMEDIA_TYPE_VIDEO,
-    .id             = AV_CODEC_ID_ANSI,
+const FFCodec ff_ansi_decoder = {
+    .p.name         = "ansi",
+    .p.long_name    = NULL_IF_CONFIG_SMALL("ASCII/ANSI art"),
+    .p.type         = AVMEDIA_TYPE_VIDEO,
+    .p.id           = AV_CODEC_ID_ANSI,
     .priv_data_size = sizeof(AnsiContext),
     .init           = decode_init,
     .close          = decode_close,
-    .decode         = decode_frame,
-    .capabilities   = AV_CODEC_CAP_DR1,
+    FF_CODEC_DECODE_CB(decode_frame),
+    .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
     .defaults       = ansi_defaults,
 };
diff -pruN 7:5.0.1-3/libavcodec/apedec.c 7:5.1-1/libavcodec/apedec.c
--- 7:5.0.1-3/libavcodec/apedec.c	2022-04-04 14:40:22.000000000 +0000
+++ 7:5.1-1/libavcodec/apedec.c	2022-07-22 17:58:38.000000000 +0000
@@ -30,6 +30,7 @@
 #include "avcodec.h"
 #include "bswapdsp.h"
 #include "bytestream.h"
+#include "codec_internal.h"
 #include "internal.h"
 #include "get_bits.h"
 #include "unary.h"
@@ -233,13 +234,14 @@ static av_cold int ape_decode_close(AVCo
 static av_cold int ape_decode_init(AVCodecContext *avctx)
 {
     APEContext *s = avctx->priv_data;
+    int channels = avctx->ch_layout.nb_channels;
     int i;
 
     if (avctx->extradata_size != 6) {
         av_log(avctx, AV_LOG_ERROR, "Incorrect extradata\n");
         return AVERROR(EINVAL);
     }
-    if (avctx->channels > 2) {
+    if (channels > 2) {
         av_log(avctx, AV_LOG_ERROR, "Only mono and stereo is supported\n");
         return AVERROR(EINVAL);
     }
@@ -261,7 +263,7 @@ static av_cold int ape_decode_init(AVCod
         return AVERROR_PATCHWELCOME;
     }
     s->avctx             = avctx;
-    s->channels          = avctx->channels;
+    s->channels          = channels;
     s->fileversion       = AV_RL16(avctx->extradata);
     s->compression_level = AV_RL16(avctx->extradata + 2);
     s->flags             = AV_RL16(avctx->extradata + 4);
@@ -313,7 +315,9 @@ static av_cold int ape_decode_init(AVCod
 
     ff_bswapdsp_init(&s->bdsp);
     ff_llauddsp_init(&s->adsp);
-    avctx->channel_layout = (avctx->channels==2) ? AV_CH_LAYOUT_STEREO : AV_CH_LAYOUT_MONO;
+    av_channel_layout_uninit(&avctx->ch_layout);
+    avctx->ch_layout = (channels == 2) ? (AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO
+                                       : (AVChannelLayout)AV_CHANNEL_LAYOUT_MONO;
 
     return 0;
 }
@@ -1457,10 +1461,9 @@ static void ape_unpack_stereo(APEContext
     }
 }
 
-static int ape_decode_frame(AVCodecContext *avctx, void *data,
+static int ape_decode_frame(AVCodecContext *avctx, AVFrame *frame,
                             int *got_frame_ptr, AVPacket *avpkt)
 {
-    AVFrame *frame     = data;
     const uint8_t *buf = avpkt->data;
     APEContext *s = avctx->priv_data;
     uint8_t *sample8;
@@ -1655,22 +1658,22 @@ static const AVClass ape_decoder_class =
     .version    = LIBAVUTIL_VERSION_INT,
 };
 
-const AVCodec ff_ape_decoder = {
-    .name           = "ape",
-    .long_name      = NULL_IF_CONFIG_SMALL("Monkey's Audio"),
-    .type           = AVMEDIA_TYPE_AUDIO,
-    .id             = AV_CODEC_ID_APE,
+const FFCodec ff_ape_decoder = {
+    .p.name         = "ape",
+    .p.long_name    = NULL_IF_CONFIG_SMALL("Monkey's Audio"),
+    .p.type         = AVMEDIA_TYPE_AUDIO,
+    .p.id           = AV_CODEC_ID_APE,
     .priv_data_size = sizeof(APEContext),
     .init           = ape_decode_init,
     .close          = ape_decode_close,
-    .decode         = ape_decode_frame,
-    .capabilities   = AV_CODEC_CAP_SUBFRAMES | AV_CODEC_CAP_DELAY |
+    FF_CODEC_DECODE_CB(ape_decode_frame),
+    .p.capabilities = AV_CODEC_CAP_SUBFRAMES | AV_CODEC_CAP_DELAY |
                       AV_CODEC_CAP_DR1,
-    .caps_internal  = FF_CODEC_CAP_INIT_CLEANUP,
+    .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
     .flush          = ape_flush,
-    .sample_fmts    = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_U8P,
+    .p.sample_fmts  = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_U8P,
                                                       AV_SAMPLE_FMT_S16P,
                                                       AV_SAMPLE_FMT_S32P,
                                                       AV_SAMPLE_FMT_NONE },
-    .priv_class     = &ape_decoder_class,
+    .p.priv_class   = &ape_decoder_class,
 };
diff -pruN 7:5.0.1-3/libavcodec/apng.h 7:5.1-1/libavcodec/apng.h
--- 7:5.0.1-3/libavcodec/apng.h	2020-04-27 21:48:15.000000000 +0000
+++ 7:5.1-1/libavcodec/apng.h	2022-07-22 17:58:38.000000000 +0000
@@ -38,4 +38,7 @@ enum {
     APNG_BLEND_OP_OVER   = 1,
 };
 
+/* Only the payload data, not including length, fourcc and CRC-32. */
+#define APNG_FCTL_CHUNK_SIZE    26
+
 #endif /* AVCODEC_APNG_H */
diff -pruN 7:5.0.1-3/libavcodec/aptx.c 7:5.1-1/libavcodec/aptx.c
--- 7:5.0.1-3/libavcodec/aptx.c	2021-10-21 17:06:35.000000000 +0000
+++ 7:5.1-1/libavcodec/aptx.c	2022-07-22 17:58:38.000000000 +0000
@@ -21,6 +21,7 @@
  */
 
 #include "aptx.h"
+#include "mathops.h"
 
 
 static const int32_t quantize_intervals_LF[65] = {
@@ -509,7 +510,7 @@ av_cold int ff_aptx_init(AVCodecContext
     AptXContext *s = avctx->priv_data;
     int chan, subband;
 
-    if (avctx->channels != 2)
+    if (avctx->ch_layout.nb_channels != 2)
         return AVERROR_INVALIDDATA;
 
     s->hd = avctx->codec->id == AV_CODEC_ID_APTX_HD;
diff -pruN 7:5.0.1-3/libavcodec/aptxdec.c 7:5.1-1/libavcodec/aptxdec.c
--- 7:5.0.1-3/libavcodec/aptxdec.c	2022-01-14 18:45:39.000000000 +0000
+++ 7:5.1-1/libavcodec/aptxdec.c	2022-07-22 17:58:38.000000000 +0000
@@ -20,8 +20,12 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "config_components.h"
+
 #include "libavutil/channel_layout.h"
 #include "aptx.h"
+#include "codec_internal.h"
+#include "internal.h"
 
 /*
  * Half-band QMF synthesis filter realized with a polyphase FIR filter.
@@ -133,11 +137,10 @@ static int aptx_decode_samples(AptXConte
     return ret;
 }
 
-static int aptx_decode_frame(AVCodecContext *avctx, void *data,
+static int aptx_decode_frame(AVCodecContext *avctx, AVFrame *frame,
                              int *got_frame_ptr, AVPacket *avpkt)
 {
     AptXContext *s = avctx->priv_data;
-    AVFrame *frame = data;
     int pos, opos, channel, sample, ret;
 
     if (avpkt->size < s->block_size) {
@@ -146,7 +149,7 @@ static int aptx_decode_frame(AVCodecCont
     }
 
     /* get output buffer */
-    frame->channels = NB_CHANNELS;
+    frame->ch_layout.nb_channels = NB_CHANNELS;
     frame->format = AV_SAMPLE_FMT_S32P;
     frame->nb_samples = 4 * avpkt->size / s->block_size;
     if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
@@ -171,35 +174,41 @@ static int aptx_decode_frame(AVCodecCont
 }
 
 #if CONFIG_APTX_DECODER
-const AVCodec ff_aptx_decoder = {
-    .name                  = "aptx",
-    .long_name             = NULL_IF_CONFIG_SMALL("aptX (Audio Processing Technology for Bluetooth)"),
-    .type                  = AVMEDIA_TYPE_AUDIO,
-    .id                    = AV_CODEC_ID_APTX,
+const FFCodec ff_aptx_decoder = {
+    .p.name                = "aptx",
+    .p.long_name           = NULL_IF_CONFIG_SMALL("aptX (Audio Processing Technology for Bluetooth)"),
+    .p.type                = AVMEDIA_TYPE_AUDIO,
+    .p.id                  = AV_CODEC_ID_APTX,
     .priv_data_size        = sizeof(AptXContext),
     .init                  = ff_aptx_init,
-    .decode                = aptx_decode_frame,
-    .capabilities          = AV_CODEC_CAP_DR1,
+    FF_CODEC_DECODE_CB(aptx_decode_frame),
+    .p.capabilities        = AV_CODEC_CAP_DR1,
     .caps_internal         = FF_CODEC_CAP_INIT_THREADSAFE,
-    .channel_layouts       = (const uint64_t[]) { AV_CH_LAYOUT_STEREO, 0},
-    .sample_fmts           = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S32P,
+#if FF_API_OLD_CHANNEL_LAYOUT
+    .p.channel_layouts     = (const uint64_t[]) { AV_CH_LAYOUT_STEREO, 0},
+#endif
+    .p.ch_layouts          = (const AVChannelLayout[]) { AV_CHANNEL_LAYOUT_STEREO, { 0 } },
+    .p.sample_fmts         = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S32P,
                                                              AV_SAMPLE_FMT_NONE },
 };
 #endif
 
 #if CONFIG_APTX_HD_DECODER
-const AVCodec ff_aptx_hd_decoder = {
-    .name                  = "aptx_hd",
-    .long_name             = NULL_IF_CONFIG_SMALL("aptX HD (Audio Processing Technology for Bluetooth)"),
-    .type                  = AVMEDIA_TYPE_AUDIO,
-    .id                    = AV_CODEC_ID_APTX_HD,
+const FFCodec ff_aptx_hd_decoder = {
+    .p.name                = "aptx_hd",
+    .p.long_name           = NULL_IF_CONFIG_SMALL("aptX HD (Audio Processing Technology for Bluetooth)"),
+    .p.type                = AVMEDIA_TYPE_AUDIO,
+    .p.id                  = AV_CODEC_ID_APTX_HD,
     .priv_data_size        = sizeof(AptXContext),
     .init                  = ff_aptx_init,
-    .decode                = aptx_decode_frame,
-    .capabilities          = AV_CODEC_CAP_DR1,
+    FF_CODEC_DECODE_CB(aptx_decode_frame),
+    .p.capabilities        = AV_CODEC_CAP_DR1,
     .caps_internal         = FF_CODEC_CAP_INIT_THREADSAFE,
-    .channel_layouts       = (const uint64_t[]) { AV_CH_LAYOUT_STEREO, 0},
-    .sample_fmts           = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S32P,
+#if FF_API_OLD_CHANNEL_LAYOUT
+    .p.channel_layouts     = (const uint64_t[]) { AV_CH_LAYOUT_STEREO, 0},
+#endif
+    .p.ch_layouts          = (const AVChannelLayout[]) { AV_CHANNEL_LAYOUT_STEREO, { 0 } },
+    .p.sample_fmts         = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S32P,
                                                              AV_SAMPLE_FMT_NONE },
 };
 #endif
diff -pruN 7:5.0.1-3/libavcodec/aptxenc.c 7:5.1-1/libavcodec/aptxenc.c
--- 7:5.0.1-3/libavcodec/aptxenc.c	2022-01-14 18:45:39.000000000 +0000
+++ 7:5.1-1/libavcodec/aptxenc.c	2022-07-22 17:58:38.000000000 +0000
@@ -20,8 +20,11 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "config_components.h"
+
 #include "libavutil/channel_layout.h"
 #include "aptx.h"
+#include "codec_internal.h"
 #include "encode.h"
 
 /*
@@ -242,39 +245,45 @@ static av_cold int aptx_close(AVCodecCon
 }
 
 #if CONFIG_APTX_ENCODER
-const AVCodec ff_aptx_encoder = {
-    .name                  = "aptx",
-    .long_name             = NULL_IF_CONFIG_SMALL("aptX (Audio Processing Technology for Bluetooth)"),
-    .type                  = AVMEDIA_TYPE_AUDIO,
-    .id                    = AV_CODEC_ID_APTX,
-    .capabilities          = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_SMALL_LAST_FRAME,
+const FFCodec ff_aptx_encoder = {
+    .p.name                = "aptx",
+    .p.long_name           = NULL_IF_CONFIG_SMALL("aptX (Audio Processing Technology for Bluetooth)"),
+    .p.type                = AVMEDIA_TYPE_AUDIO,
+    .p.id                  = AV_CODEC_ID_APTX,
+    .p.capabilities        = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_SMALL_LAST_FRAME,
     .priv_data_size        = sizeof(AptXContext),
     .init                  = ff_aptx_init,
-    .encode2               = aptx_encode_frame,
+    FF_CODEC_ENCODE_CB(aptx_encode_frame),
     .close                 = aptx_close,
     .caps_internal         = FF_CODEC_CAP_INIT_THREADSAFE,
-    .channel_layouts       = (const uint64_t[]) { AV_CH_LAYOUT_STEREO, 0},
-    .sample_fmts           = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S32P,
+#if FF_API_OLD_CHANNEL_LAYOUT
+    .p.channel_layouts     = (const uint64_t[]) { AV_CH_LAYOUT_STEREO, 0},
+#endif
+    .p.ch_layouts          = (const AVChannelLayout[]) { AV_CHANNEL_LAYOUT_STEREO, { 0 } },
+    .p.sample_fmts         = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S32P,
                                                              AV_SAMPLE_FMT_NONE },
-    .supported_samplerates = (const int[]) {8000, 16000, 24000, 32000, 44100, 48000, 0},
+    .p.supported_samplerates = (const int[]) {8000, 16000, 24000, 32000, 44100, 48000, 0},
 };
 #endif
 
 #if CONFIG_APTX_HD_ENCODER
-const AVCodec ff_aptx_hd_encoder = {
-    .name                  = "aptx_hd",
-    .long_name             = NULL_IF_CONFIG_SMALL("aptX HD (Audio Processing Technology for Bluetooth)"),
-    .type                  = AVMEDIA_TYPE_AUDIO,
-    .id                    = AV_CODEC_ID_APTX_HD,
-    .capabilities          = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_SMALL_LAST_FRAME,
+const FFCodec ff_aptx_hd_encoder = {
+    .p.name                = "aptx_hd",
+    .p.long_name           = NULL_IF_CONFIG_SMALL("aptX HD (Audio Processing Technology for Bluetooth)"),
+    .p.type                = AVMEDIA_TYPE_AUDIO,
+    .p.id                  = AV_CODEC_ID_APTX_HD,
+    .p.capabilities        = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_SMALL_LAST_FRAME,
     .priv_data_size        = sizeof(AptXContext),
     .init                  = ff_aptx_init,
-    .encode2               = aptx_encode_frame,
+    FF_CODEC_ENCODE_CB(aptx_encode_frame),
     .close                 = aptx_close,
     .caps_internal         = FF_CODEC_CAP_INIT_THREADSAFE,
-    .channel_layouts       = (const uint64_t[]) { AV_CH_LAYOUT_STEREO, 0},
-    .sample_fmts           = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S32P,
+#if FF_API_OLD_CHANNEL_LAYOUT
+    .p.channel_layouts     = (const uint64_t[]) { AV_CH_LAYOUT_STEREO, 0},
+#endif
+    .p.ch_layouts          = (const AVChannelLayout[]) { AV_CHANNEL_LAYOUT_STEREO, { 0 } },
+    .p.sample_fmts         = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S32P,
                                                              AV_SAMPLE_FMT_NONE },
-    .supported_samplerates = (const int[]) {8000, 16000, 24000, 32000, 44100, 48000, 0},
+    .p.supported_samplerates = (const int[]) {8000, 16000, 24000, 32000, 44100, 48000, 0},
 };
 #endif
diff -pruN 7:5.0.1-3/libavcodec/aptx.h 7:5.1-1/libavcodec/aptx.h
--- 7:5.0.1-3/libavcodec/aptx.h	2021-10-21 17:06:35.000000000 +0000
+++ 7:5.1-1/libavcodec/aptx.h	2022-07-22 17:58:38.000000000 +0000
@@ -25,7 +25,6 @@
 
 #include "libavutil/intreadwrite.h"
 #include "avcodec.h"
-#include "internal.h"
 #include "mathops.h"
 #include "audio_frame_queue.h"
 
diff -pruN 7:5.0.1-3/libavcodec/arbc.c 7:5.1-1/libavcodec/arbc.c
--- 7:5.0.1-3/libavcodec/arbc.c	2022-01-14 18:45:39.000000000 +0000
+++ 7:5.1-1/libavcodec/arbc.c	2022-07-22 17:58:38.000000000 +0000
@@ -29,6 +29,7 @@
 
 #include "avcodec.h"
 #include "bytestream.h"
+#include "codec_internal.h"
 #include "internal.h"
 
 typedef struct ARBCContext {
@@ -115,11 +116,10 @@ static int fill_tileX(AVCodecContext *av
     return pixels_overwritten;
 }
 
-static int decode_frame(AVCodecContext *avctx, void *data,
+static int decode_frame(AVCodecContext *avctx, AVFrame *frame,
                         int *got_frame, AVPacket *avpkt)
 {
     ARBCContext *s = avctx->priv_data;
-    AVFrame *frame = data;
     int ret, nb_segments;
     int prev_pixels = avctx->width * avctx->height;
 
@@ -211,16 +211,16 @@ static av_cold int decode_close(AVCodecC
     return 0;
 }
 
-const AVCodec ff_arbc_decoder = {
-    .name           = "arbc",
-    .long_name      = NULL_IF_CONFIG_SMALL("Gryphon's Anim Compressor"),
-    .type           = AVMEDIA_TYPE_VIDEO,
-    .id             = AV_CODEC_ID_ARBC,
+const FFCodec ff_arbc_decoder = {
+    .p.name         = "arbc",
+    .p.long_name    = NULL_IF_CONFIG_SMALL("Gryphon's Anim Compressor"),
+    .p.type         = AVMEDIA_TYPE_VIDEO,
+    .p.id           = AV_CODEC_ID_ARBC,
     .priv_data_size = sizeof(ARBCContext),
     .init           = decode_init,
-    .decode         = decode_frame,
+    FF_CODEC_DECODE_CB(decode_frame),
     .flush          = decode_flush,
     .close          = decode_close,
-    .capabilities   = AV_CODEC_CAP_DR1,
+    .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
 };
diff -pruN 7:5.0.1-3/libavcodec/argo.c 7:5.1-1/libavcodec/argo.c
--- 7:5.0.1-3/libavcodec/argo.c	2022-04-04 14:40:22.000000000 +0000
+++ 7:5.1-1/libavcodec/argo.c	2022-07-22 17:58:38.000000000 +0000
@@ -29,6 +29,7 @@
 
 #include "avcodec.h"
 #include "bytestream.h"
+#include "codec_internal.h"
 #include "internal.h"
 
 typedef struct ArgoContext {
@@ -598,7 +599,7 @@ static int decode_rle(AVCodecContext *av
     return 0;
 }
 
-static int decode_frame(AVCodecContext *avctx, void *data,
+static int decode_frame(AVCodecContext *avctx, AVFrame *rframe,
                         int *got_frame, AVPacket *avpkt)
 {
     ArgoContext *s = avctx->priv_data;
@@ -664,7 +665,7 @@ static int decode_frame(AVCodecContext *
     if (avctx->pix_fmt == AV_PIX_FMT_PAL8)
         memcpy(frame->data[1], s->pal, AVPALETTE_SIZE);
 
-    if ((ret = av_frame_ref(data, s->frame)) < 0)
+    if ((ret = av_frame_ref(rframe, s->frame)) < 0)
         return ret;
 
     frame->pict_type = s->key ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P;
@@ -732,16 +733,16 @@ static av_cold int decode_close(AVCodecC
     return 0;
 }
 
-const AVCodec ff_argo_decoder = {
-    .name           = "argo",
-    .long_name      = NULL_IF_CONFIG_SMALL("Argonaut Games Video"),
-    .type           = AVMEDIA_TYPE_VIDEO,
-    .id             = AV_CODEC_ID_ARGO,
+const FFCodec ff_argo_decoder = {
+    .p.name         = "argo",
+    .p.long_name    = NULL_IF_CONFIG_SMALL("Argonaut Games Video"),
+    .p.type         = AVMEDIA_TYPE_VIDEO,
+    .p.id           = AV_CODEC_ID_ARGO,
     .priv_data_size = sizeof(ArgoContext),
     .init           = decode_init,
-    .decode         = decode_frame,
+    FF_CODEC_DECODE_CB(decode_frame),
     .flush          = decode_flush,
     .close          = decode_close,
-    .capabilities   = AV_CODEC_CAP_DR1,
+    .p.capabilities = AV_CODEC_CAP_DR1,
     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
 };
diff -pruN 7:5.0.1-3/libavcodec/arm/flacdsp_init_arm.c 7:5.1-1/libavcodec/arm/flacdsp_init_arm.c
--- 7:5.0.1-3/libavcodec/arm/flacdsp_init_arm.c	2022-01-14 18:45:39.000000000 +0000
+++ 7:5.1-1/libavcodec/arm/flacdsp_init_arm.c	2022-07-22 17:58:38.000000000 +0000
@@ -21,6 +21,7 @@
 #include "libavutil/attributes.h"
 #include "libavcodec/flacdsp.h"
 #include "config.h"
+#include "config_components.h"
 
 void ff_flac_lpc_16_arm(int32_t *samples, const int coeffs[32], int order,
                         int qlevel, int len);
diff -pruN 7:5.0.1-3/libavcodec/arm/h264cmc_neon.S 7:5.1-1/libavcodec/arm/h264cmc_neon.S
--- 7:5.0.1-3/libavcodec/arm/h264cmc_neon.S	2021-10-21 17:06:35.000000000 +0000
+++ 7:5.1-1/libavcodec/arm/h264cmc_neon.S	2022-07-22 17:58:38.000000000 +0000
@@ -18,6 +18,8 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "config_components.h"
+
 #include "libavutil/arm/asm.S"
 
 /* chroma_mc8(uint8_t *dst, uint8_t *src, ptrdiff_t stride, int h, int x, int y) */
diff -pruN 7:5.0.1-3/libavcodec/arm/hevcdsp_init_neon.c 7:5.1-1/libavcodec/arm/hevcdsp_init_neon.c
--- 7:5.0.1-3/libavcodec/arm/hevcdsp_init_neon.c	2021-10-21 17:06:35.000000000 +0000
+++ 7:5.1-1/libavcodec/arm/hevcdsp_init_neon.c	2022-07-22 17:58:38.000000000 +0000
@@ -270,7 +270,8 @@ av_cold void ff_hevc_dsp_init_neon(HEVCD
         put_hevc_qpel_uw_neon[3][1]      = ff_hevc_put_qpel_uw_h1v3_neon_8;
         put_hevc_qpel_uw_neon[3][2]      = ff_hevc_put_qpel_uw_h2v3_neon_8;
         put_hevc_qpel_uw_neon[3][3]      = ff_hevc_put_qpel_uw_h3v3_neon_8;
-        for (x = 0; x < 10; x++) {
+        for (x = 3; x < 10; x++) {
+            if (x == 4) continue;
             c->put_hevc_qpel[x][1][0]         = ff_hevc_put_qpel_neon_wrapper;
             c->put_hevc_qpel[x][0][1]         = ff_hevc_put_qpel_neon_wrapper;
             c->put_hevc_qpel[x][1][1]         = ff_hevc_put_qpel_neon_wrapper;
diff -pruN 7:5.0.1-3/libavcodec/arm/hevcdsp_qpel_neon.S 7:5.1-1/libavcodec/arm/hevcdsp_qpel_neon.S
--- 7:5.0.1-3/libavcodec/arm/hevcdsp_qpel_neon.S	2022-01-14 18:45:39.000000000 +0000
+++ 7:5.1-1/libavcodec/arm/hevcdsp_qpel_neon.S	2022-07-22 17:58:38.000000000 +0000
@@ -237,7 +237,7 @@
         vld1.8    {d23}, [r2], r3
         bne 8b
         subs  r5, #8
-        ble       99f
+        beq       99f
         mov r4, r12
         add r6, #16
         mov r0, r6
@@ -280,7 +280,7 @@
         vld1.8    {d23}, [r2], r3
         bne 8b
         subs  r5, #8
-        ble       99f
+        beq       99f
         mov r4, r12
         add r6, #8
         mov r0, r6
@@ -310,7 +310,7 @@
         vld1.8    {d23}, [r2], r3
         bne 8b
         subs  r5, #8
-        ble       99f
+        beq       99f
         mov r4, r12
         add r6, #8
         mov r0, r6
@@ -377,7 +377,7 @@ endfunc
         vst1.16   {q7}, [r0], r1
         bne       8b
         subs      r5, #8
-        ble       99f
+        beq      99f
         mov       r4, r12
         add       r6, #16
         mov       r0, r6
@@ -417,7 +417,7 @@ endfunc
         vst1.8    d0, [r0], r1
         bne       8b
         subs      r5, #8
-        ble       99f
+        beq      99f
         mov       r4, r12
         add       r6, #8
         mov       r0, r6
@@ -446,7 +446,7 @@ endfunc
         vst1.8         d0, [r0], r1
         bne       8b
         subs      r5, #8
-        ble       99f
+        beq      99f
         mov       r4, r12
         add       r6, #8
         add       r10, #16
@@ -533,7 +533,7 @@ endfunc
         \filterh q7
         bne 8b
         subs  r5, #8
-        ble 99f
+        beq 99f
         mov r4, r12
         add r6, #16
         mov r0, r6
@@ -594,7 +594,7 @@ endfunc
         \filterh q7
         bne 8b
         subs  r5, #8
-        ble 99f
+        beq 99f
         mov r4, r12
         add r6, #8
         mov r0, r6
@@ -641,7 +641,7 @@ endfunc
         \filterh q7
         bne 8b
         subs  r5, #8
-        ble 99f
+        beq 99f
         mov r4, r12
         add r6, #8
         mov r0, r6
diff -pruN 7:5.0.1-3/libavcodec/arm/vc1dsp_init_neon.c 7:5.1-1/libavcodec/arm/vc1dsp_init_neon.c
--- 7:5.0.1-3/libavcodec/arm/vc1dsp_init_neon.c	2021-10-21 17:06:35.000000000 +0000
+++ 7:5.1-1/libavcodec/arm/vc1dsp_init_neon.c	2022-07-22 17:58:38.000000000 +0000
@@ -19,6 +19,7 @@
 #include <stdint.h>
 
 #include "libavutil/attributes.h"
+#include "libavutil/intreadwrite.h"
 #include "libavcodec/vc1dsp.h"
 #include "vc1dsp.h"
 
@@ -32,6 +33,13 @@ void ff_vc1_inv_trans_4x8_dc_neon(uint8_
 void ff_vc1_inv_trans_8x4_dc_neon(uint8_t *dest, ptrdiff_t stride, int16_t *block);
 void ff_vc1_inv_trans_4x4_dc_neon(uint8_t *dest, ptrdiff_t stride, int16_t *block);
 
+void ff_vc1_v_loop_filter4_neon(uint8_t *src, int stride, int pq);
+void ff_vc1_h_loop_filter4_neon(uint8_t *src, int stride, int pq);
+void ff_vc1_v_loop_filter8_neon(uint8_t *src, int stride, int pq);
+void ff_vc1_h_loop_filter8_neon(uint8_t *src, int stride, int pq);
+void ff_vc1_v_loop_filter16_neon(uint8_t *src, int stride, int pq);
+void ff_vc1_h_loop_filter16_neon(uint8_t *src, int stride, int pq);
+
 void ff_put_pixels8x8_neon(uint8_t *block, const uint8_t *pixels,
                            ptrdiff_t line_size, int rnd);
 
@@ -77,6 +85,64 @@ void ff_put_vc1_chroma_mc4_neon(uint8_t
 void ff_avg_vc1_chroma_mc4_neon(uint8_t *dst, uint8_t *src, ptrdiff_t stride,
                                 int h, int x, int y);
 
+int ff_vc1_unescape_buffer_helper_neon(const uint8_t *src, int size, uint8_t *dst);
+
+static int vc1_unescape_buffer_neon(const uint8_t *src, int size, uint8_t *dst)
+{
+    /* Dealing with starting and stopping, and removing escape bytes, are
+     * comparatively less time-sensitive, so are more clearly expressed using
+     * a C wrapper around the assembly inner loop. Note that we assume a
+     * little-endian machine that supports unaligned loads. */
+    int dsize = 0;
+    while (size >= 4)
+    {
+        int found = 0;
+        while (!found && (((uintptr_t) dst) & 7) && size >= 4)
+        {
+            found = (AV_RL32(src) &~ 0x03000000) == 0x00030000;
+            if (!found)
+            {
+                *dst++ = *src++;
+                --size;
+                ++dsize;
+            }
+        }
+        if (!found)
+        {
+            int skip = size - ff_vc1_unescape_buffer_helper_neon(src, size, dst);
+            dst += skip;
+            src += skip;
+            size -= skip;
+            dsize += skip;
+            while (!found && size >= 4)
+            {
+                found = (AV_RL32(src) &~ 0x03000000) == 0x00030000;
+                if (!found)
+                {
+                    *dst++ = *src++;
+                    --size;
+                    ++dsize;
+                }
+            }
+        }
+        if (found)
+        {
+            *dst++ = *src++;
+            *dst++ = *src++;
+            ++src;
+            size -= 3;
+            dsize += 2;
+        }
+    }
+    while (size > 0)
+    {
+        *dst++ = *src++;
+        --size;
+        ++dsize;
+    }
+    return dsize;
+}
+
 #define FN_ASSIGN(X, Y) \
     dsp->put_vc1_mspel_pixels_tab[0][X+4*Y] = ff_put_vc1_mspel_mc##X##Y##_16_neon; \
     dsp->put_vc1_mspel_pixels_tab[1][X+4*Y] = ff_put_vc1_mspel_mc##X##Y##_neon
@@ -92,6 +158,13 @@ av_cold void ff_vc1dsp_init_neon(VC1DSPC
     dsp->vc1_inv_trans_8x4_dc = ff_vc1_inv_trans_8x4_dc_neon;
     dsp->vc1_inv_trans_4x4_dc = ff_vc1_inv_trans_4x4_dc_neon;
 
+    dsp->vc1_v_loop_filter4  = ff_vc1_v_loop_filter4_neon;
+    dsp->vc1_h_loop_filter4  = ff_vc1_h_loop_filter4_neon;
+    dsp->vc1_v_loop_filter8  = ff_vc1_v_loop_filter8_neon;
+    dsp->vc1_h_loop_filter8  = ff_vc1_h_loop_filter8_neon;
+    dsp->vc1_v_loop_filter16 = ff_vc1_v_loop_filter16_neon;
+    dsp->vc1_h_loop_filter16 = ff_vc1_h_loop_filter16_neon;
+
     dsp->put_vc1_mspel_pixels_tab[1][ 0] = ff_put_pixels8x8_neon;
     FN_ASSIGN(1, 0);
     FN_ASSIGN(2, 0);
@@ -116,4 +189,6 @@ av_cold void ff_vc1dsp_init_neon(VC1DSPC
     dsp->avg_no_rnd_vc1_chroma_pixels_tab[0] = ff_avg_vc1_chroma_mc8_neon;
     dsp->put_no_rnd_vc1_chroma_pixels_tab[1] = ff_put_vc1_chroma_mc4_neon;
     dsp->avg_no_rnd_vc1_chroma_pixels_tab[1] = ff_avg_vc1_chroma_mc4_neon;
+
+    dsp->vc1_unescape_buffer = vc1_unescape_buffer_neon;
 }
diff -pruN 7:5.0.1-3/libavcodec/arm/vc1dsp_neon.S 7:5.1-1/libavcodec/arm/vc1dsp_neon.S
--- 7:5.0.1-3/libavcodec/arm/vc1dsp_neon.S	2021-10-21 17:06:35.000000000 +0000
+++ 7:5.1-1/libavcodec/arm/vc1dsp_neon.S	2022-07-22 17:58:38.000000000 +0000
@@ -1161,3 +1161,764 @@ function ff_vc1_inv_trans_4x4_dc_neon, e
         vst1.32         {d1[1]},  [r0,:32]
         bx              lr
 endfunc
+
+@ VC-1 in-loop deblocking filter for 4 pixel pairs at boundary of vertically-neighbouring blocks
+@ On entry:
+@   r0 -> top-left pel of lower block
+@   r1 = row stride, bytes
+@   r2 = PQUANT bitstream parameter
+function ff_vc1_v_loop_filter4_neon, export=1
+        sub             r3, r0, r1, lsl #2
+        vldr            d0, .Lcoeffs
+        vld1.32         {d1[0]}, [r0], r1       @ P5
+        vld1.32         {d2[0]}, [r3], r1       @ P1
+        vld1.32         {d3[0]}, [r3], r1       @ P2
+        vld1.32         {d4[0]}, [r0], r1       @ P6
+        vld1.32         {d5[0]}, [r3], r1       @ P3
+        vld1.32         {d6[0]}, [r0], r1       @ P7
+        vld1.32         {d7[0]}, [r3]           @ P4
+        vld1.32         {d16[0]}, [r0]          @ P8
+        vshll.u8        q9, d1, #1              @ 2*P5
+        vdup.16         d17, r2                 @ pq
+        vshll.u8        q10, d2, #1             @ 2*P1
+        vmovl.u8        q11, d3                 @ P2
+        vmovl.u8        q1, d4                  @ P6
+        vmovl.u8        q12, d5                 @ P3
+        vmls.i16        d20, d22, d0[1]         @ 2*P1-5*P2
+        vmovl.u8        q11, d6                 @ P7
+        vmls.i16        d18, d2, d0[1]          @ 2*P5-5*P6
+        vshll.u8        q2, d5, #1              @ 2*P3
+        vmovl.u8        q3, d7                  @ P4
+        vmla.i16        d18, d22, d0[1]         @ 2*P5-5*P6+5*P7
+        vmovl.u8        q11, d16                @ P8
+        vmla.u16        d20, d24, d0[1]         @ 2*P1-5*P2+5*P3
+        vmovl.u8        q12, d1                 @ P5
+        vmls.u16        d4, d6, d0[1]           @ 2*P3-5*P4
+        vmls.u16        d18, d22, d0[0]         @ 2*P5-5*P6+5*P7-2*P8
+        vsub.i16        d1, d6, d24             @ P4-P5
+        vmls.i16        d20, d6, d0[0]          @ 2*P1-5*P2+5*P3-2*P4
+        vmla.i16        d4, d24, d0[1]          @ 2*P3-5*P4+5*P5
+        vmls.i16        d4, d2, d0[0]           @ 2*P3-5*P4+5*P5-2*P6
+        vabs.s16        d2, d1
+        vrshr.s16       d3, d18, #3
+        vrshr.s16       d5, d20, #3
+        vshr.s16        d2, d2, #1              @ clip
+        vrshr.s16       d4, d4, #3
+        vabs.s16        d3, d3                  @ a2
+        vshr.s16        d1, d1, #8              @ clip_sign
+        vabs.s16        d5, d5                  @ a1
+        vceq.i16        d7, d2, #0              @ test clip == 0
+        vabs.s16        d16, d4                 @ a0
+        vshr.s16        d4, d4, #8              @ a0_sign
+        vcge.s16        d18, d5, d3             @ test a1 >= a2
+        vcge.s16        d17, d16, d17           @ test a0 >= pq
+        vbsl            d18, d3, d5             @ a3
+        vsub.i16        d1, d1, d4              @ clip_sign - a0_sign
+        vorr            d3, d7, d17             @ test clip == 0 || a0 >= pq
+        vqsub.u16       d4, d16, d18            @ a0 >= a3 ? a0-a3 : 0  (a0 > a3 in all cases where filtering is enabled, so makes more sense to subtract this way round than the opposite and then taking the abs)
+        vcge.s16        d5, d18, d16            @ test a3 >= a0
+        vmul.i16        d0, d4, d0[1]           @ a0 >= a3 ? 5*(a0-a3) : 0
+        vorr            d4, d3, d5              @ test clip == 0 || a0 >= pq || a3 >= a0
+        vmov.32         r0, d4[1]               @ move to gp reg
+        vshr.u16        d0, d0, #3              @ a0 >= a3 ? (5*(a0-a3))>>3 : 0
+        vcge.s16        d4, d0, d2
+        tst             r0, #1
+        bne             1f                      @ none of the 4 pixel pairs should be updated if this one is not filtered
+        vbsl            d4, d2, d0              @ FFMIN(d, clip)
+        vbic            d0, d4, d3              @ set each d to zero if it should not be filtered because clip == 0 || a0 >= pq (a3 > a0 case already zeroed by saturating sub)
+        vmls.i16        d6, d0, d1              @ invert d depending on clip_sign & a0_sign, or zero it if they match, and accumulate into P4
+        vmla.i16        d24, d0, d1             @ invert d depending on clip_sign & a0_sign, or zero it if they match, and accumulate into P5
+        vqmovun.s16     d0, q3
+        vqmovun.s16     d1, q12
+        vst1.32         {d0[0]}, [r3], r1
+        vst1.32         {d1[0]}, [r3]
+1:      bx              lr
+endfunc
+
+@ VC-1 in-loop deblocking filter for 4 pixel pairs at boundary of horizontally-neighbouring blocks
+@ On entry:
+@   r0 -> top-left pel of right block
+@   r1 = row stride, bytes
+@   r2 = PQUANT bitstream parameter
+function ff_vc1_h_loop_filter4_neon, export=1
+        sub             r3, r0, #4              @ where to start reading
+        vldr            d0, .Lcoeffs
+        vld1.32         {d2}, [r3], r1
+        sub             r0, r0, #1              @ where to start writing
+        vld1.32         {d4}, [r3], r1
+        vld1.32         {d3}, [r3], r1
+        vld1.32         {d5}, [r3]
+        vdup.16         d1, r2                  @ pq
+        vtrn.8          q1, q2
+        vtrn.16         d2, d3                  @ P1, P5, P3, P7
+        vtrn.16         d4, d5                  @ P2, P6, P4, P8
+        vshll.u8        q3, d2, #1              @ 2*P1, 2*P5
+        vmovl.u8        q8, d4                  @ P2, P6
+        vmovl.u8        q9, d3                  @ P3, P7
+        vmovl.u8        q2, d5                  @ P4, P8
+        vmls.i16        q3, q8, d0[1]           @ 2*P1-5*P2, 2*P5-5*P6
+        vshll.u8        q10, d3, #1             @ 2*P3, 2*P7
+        vmovl.u8        q1, d2                  @ P1, P5
+        vmla.i16        q3, q9, d0[1]           @ 2*P1-5*P2+5*P3, 2*P5-5*P6+5*P7
+        vmls.i16        q3, q2, d0[0]           @ 2*P1-5*P2+5*P3-2*P4, 2*P5-5*P6+5*P7-2*P8
+        vmov            d2, d3                  @ needs to be in an even-numbered vector for when we come to narrow it later
+        vmls.i16        d20, d4, d0[1]          @ 2*P3-5*P4
+        vmla.i16        d20, d3, d0[1]          @ 2*P3-5*P4+5*P5
+        vsub.i16        d3, d4, d2              @ P4-P5
+        vmls.i16        d20, d17, d0[0]         @ 2*P3-5*P4+5*P5-2*P6
+        vrshr.s16       q3, q3, #3
+        vabs.s16        d5, d3
+        vshr.s16        d3, d3, #8              @ clip_sign
+        vrshr.s16       d16, d20, #3
+        vabs.s16        q3, q3                  @ a1, a2
+        vshr.s16        d5, d5, #1              @ clip
+        vabs.s16        d17, d16                @ a0
+        vceq.i16        d18, d5, #0             @ test clip == 0
+        vshr.s16        d16, d16, #8            @ a0_sign
+        vcge.s16        d19, d6, d7             @ test a1 >= a2
+        vcge.s16        d1, d17, d1             @ test a0 >= pq
+        vsub.i16        d16, d3, d16            @ clip_sign - a0_sign
+        vbsl            d19, d7, d6             @ a3
+        vorr            d1, d18, d1             @ test clip == 0 || a0 >= pq
+        vqsub.u16       d3, d17, d19            @ a0 >= a3 ? a0-a3 : 0  (a0 > a3 in all cases where filtering is enabled, so makes more sense to subtract this way round than the opposite and then taking the abs)
+        vcge.s16        d6, d19, d17            @ test a3 >= a0    @
+        vmul.i16        d0, d3, d0[1]           @ a0 >= a3 ? 5*(a0-a3) : 0
+        vorr            d3, d1, d6              @ test clip == 0 || a0 >= pq || a3 >= a0
+        vmov.32         r2, d3[1]               @ move to gp reg
+        vshr.u16        d0, d0, #3              @ a0 >= a3 ? (5*(a0-a3))>>3 : 0
+        vcge.s16        d3, d0, d5
+        tst             r2, #1
+        bne             1f                      @ none of the 4 pixel pairs should be updated if this one is not filtered
+        vbsl            d3, d5, d0              @ FFMIN(d, clip)
+        vbic            d0, d3, d1              @ set each d to zero if it should not be filtered because clip == 0 || a0 >= pq (a3 > a0 case already zeroed by saturating sub)
+        vmla.i16        d2, d0, d16             @ invert d depending on clip_sign & a0_sign, or zero it if they match, and accumulate into P5
+        vmls.i16        d4, d0, d16             @ invert d depending on clip_sign & a0_sign, or zero it if they match, and accumulate into P4
+        vqmovun.s16     d1, q1
+        vqmovun.s16     d0, q2
+        vst2.8          {d0[0], d1[0]}, [r0], r1
+        vst2.8          {d0[1], d1[1]}, [r0], r1
+        vst2.8          {d0[2], d1[2]}, [r0], r1
+        vst2.8          {d0[3], d1[3]}, [r0]
+1:      bx              lr
+endfunc
+
+@ VC-1 in-loop deblocking filter for 8 pixel pairs at boundary of vertically-neighbouring blocks
+@ On entry:
+@   r0 -> top-left pel of lower block
+@   r1 = row stride, bytes
+@   r2 = PQUANT bitstream parameter
+function ff_vc1_v_loop_filter8_neon, export=1
+        sub             r3, r0, r1, lsl #2
+        vldr            d0, .Lcoeffs
+        vld1.32         {d1}, [r0 :64], r1      @ P5
+        vld1.32         {d2}, [r3 :64], r1      @ P1
+        vld1.32         {d3}, [r3 :64], r1      @ P2
+        vld1.32         {d4}, [r0 :64], r1      @ P6
+        vld1.32         {d5}, [r3 :64], r1      @ P3
+        vld1.32         {d6}, [r0 :64], r1      @ P7
+        vshll.u8        q8, d1, #1              @ 2*P5
+        vshll.u8        q9, d2, #1              @ 2*P1
+        vld1.32         {d7}, [r3 :64]          @ P4
+        vmovl.u8        q1, d3                  @ P2
+        vld1.32         {d20}, [r0 :64]         @ P8
+        vmovl.u8        q11, d4                 @ P6
+        vdup.16         q12, r2                 @ pq
+        vmovl.u8        q13, d5                 @ P3
+        vmls.i16        q9, q1, d0[1]           @ 2*P1-5*P2
+        vmovl.u8        q1, d6                  @ P7
+        vshll.u8        q2, d5, #1              @ 2*P3
+        vmls.i16        q8, q11, d0[1]          @ 2*P5-5*P6
+        vmovl.u8        q3, d7                  @ P4
+        vmovl.u8        q10, d20                @ P8
+        vmla.i16        q8, q1, d0[1]           @ 2*P5-5*P6+5*P7
+        vmovl.u8        q1, d1                  @ P5
+        vmla.i16        q9, q13, d0[1]          @ 2*P1-5*P2+5*P3
+        vsub.i16        q13, q3, q1             @ P4-P5
+        vmls.i16        q2, q3, d0[1]           @ 2*P3-5*P4
+        vmls.i16        q8, q10, d0[0]          @ 2*P5-5*P6+5*P7-2*P8
+        vabs.s16        q10, q13
+        vshr.s16        q13, q13, #8            @ clip_sign
+        vmls.i16        q9, q3, d0[0]           @ 2*P1-5*P2+5*P3-2*P4
+        vshr.s16        q10, q10, #1            @ clip
+        vmla.i16        q2, q1, d0[1]           @ 2*P3-5*P4+5*P5
+        vrshr.s16       q8, q8, #3
+        vmls.i16        q2, q11, d0[0]          @ 2*P3-5*P4+5*P5-2*P6
+        vceq.i16        q11, q10, #0            @ test clip == 0
+        vrshr.s16       q9, q9, #3
+        vabs.s16        q8, q8                  @ a2
+        vabs.s16        q9, q9                  @ a1
+        vrshr.s16       q2, q2, #3
+        vcge.s16        q14, q9, q8             @ test a1 >= a2
+        vabs.s16        q15, q2                 @ a0
+        vshr.s16        q2, q2, #8              @ a0_sign
+        vbsl            q14, q8, q9             @ a3
+        vcge.s16        q8, q15, q12            @ test a0 >= pq
+        vsub.i16        q2, q13, q2             @ clip_sign - a0_sign
+        vqsub.u16       q9, q15, q14            @ a0 >= a3 ? a0-a3 : 0  (a0 > a3 in all cases where filtering is enabled, so makes more sense to subtract this way round than the opposite and then taking the abs)
+        vcge.s16        q12, q14, q15           @ test a3 >= a0
+        vorr            q8, q11, q8             @ test clip == 0 || a0 >= pq
+        vmul.i16        q0, q9, d0[1]           @ a0 >= a3 ? 5*(a0-a3) : 0
+        vorr            q9, q8, q12             @ test clip == 0 || a0 >= pq || a3 >= a0
+        vshl.i64        q11, q9, #16
+        vmov.32         r0, d18[1]              @ move to gp reg
+        vshr.u16        q0, q0, #3              @ a0 >= a3 ? (5*(a0-a3))>>3 : 0
+        vmov.32         r2, d19[1]
+        vshr.s64        q9, q11, #48
+        vcge.s16        q11, q0, q10
+        vorr            q8, q8, q9
+        and             r0, r0, r2
+        vbsl            q11, q10, q0            @ FFMIN(d, clip)
+        tst             r0, #1
+        bne             1f                      @ none of the 8 pixel pairs should be updated in this case
+        vbic            q0, q11, q8             @ set each d to zero if it should not be filtered
+        vmls.i16        q3, q0, q2              @ invert d depending on clip_sign & a0_sign, or zero it if they match, and accumulate into P4
+        vmla.i16        q1, q0, q2              @ invert d depending on clip_sign & a0_sign, or zero it if they match, and accumulate into P5
+        vqmovun.s16     d0, q3
+        vqmovun.s16     d1, q1
+        vst1.32         {d0}, [r3 :64], r1
+        vst1.32         {d1}, [r3 :64]
+1:      bx              lr
+endfunc
+
+.align  5
+.Lcoeffs:
+.quad   0x00050002
+
+@ VC-1 in-loop deblocking filter for 8 pixel pairs at boundary of horizontally-neighbouring blocks
+@ On entry:
+@   r0 -> top-left pel of right block
+@   r1 = row stride, bytes
+@   r2 = PQUANT bitstream parameter
+function ff_vc1_h_loop_filter8_neon, export=1
+        push            {lr}
+        sub             r3, r0, #4              @ where to start reading
+        vldr            d0, .Lcoeffs
+        vld1.32         {d2}, [r3], r1          @ P1[0], P2[0]...
+        sub             r0, r0, #1              @ where to start writing
+        vld1.32         {d4}, [r3], r1
+        add             r12, r0, r1, lsl #2
+        vld1.32         {d3}, [r3], r1
+        vld1.32         {d5}, [r3], r1
+        vld1.32         {d6}, [r3], r1
+        vld1.32         {d16}, [r3], r1
+        vld1.32         {d7}, [r3], r1
+        vld1.32         {d17}, [r3]
+        vtrn.8          q1, q2                  @ P1[0], P1[1], P3[0]... P1[2], P1[3], P3[2]... P2[0], P2[1], P4[0]... P2[2], P2[3], P4[2]...
+        vdup.16         q9, r2                  @ pq
+        vtrn.16         d2, d3                  @ P1[0], P1[1], P1[2], P1[3], P5[0]... P3[0], P3[1], P3[2], P3[3], P7[0]...
+        vtrn.16         d4, d5                  @ P2[0], P2[1], P2[2], P2[3], P6[0]... P4[0], P4[1], P4[2], P4[3], P8[0]...
+        vtrn.8          q3, q8                  @ P1[4], P1[5], P3[4]... P1[6], P1[7], P3[6]... P2[4], P2[5], P4[4]... P2[6], P2[7], P4[6]...
+        vtrn.16         d6, d7                  @ P1[4], P1[5], P1[6], P1[7], P5[4]... P3[4], P3[5], P3[5], P3[7], P7[4]...
+        vtrn.16         d16, d17                @ P2[4], P2[5], P2[6], P2[7], P6[4]... P4[4], P4[5], P4[6], P4[7], P8[4]...
+        vtrn.32         d2, d6                  @ P1, P5
+        vtrn.32         d4, d16                 @ P2, P6
+        vtrn.32         d3, d7                  @ P3, P7
+        vtrn.32         d5, d17                 @ P4, P8
+        vshll.u8        q10, d2, #1             @ 2*P1
+        vshll.u8        q11, d6, #1             @ 2*P5
+        vmovl.u8        q12, d4                 @ P2
+        vmovl.u8        q13, d16                @ P6
+        vmovl.u8        q14, d3                 @ P3
+        vmls.i16        q10, q12, d0[1]         @ 2*P1-5*P2
+        vmovl.u8        q12, d7                 @ P7
+        vshll.u8        q1, d3, #1              @ 2*P3
+        vmls.i16        q11, q13, d0[1]         @ 2*P5-5*P6
+        vmovl.u8        q2, d5                  @ P4
+        vmovl.u8        q8, d17                 @ P8
+        vmla.i16        q11, q12, d0[1]         @ 2*P5-5*P6+5*P7
+        vmovl.u8        q3, d6                  @ P5
+        vmla.i16        q10, q14, d0[1]         @ 2*P1-5*P2+5*P3
+        vsub.i16        q12, q2, q3             @ P4-P5
+        vmls.i16        q1, q2, d0[1]           @ 2*P3-5*P4
+        vmls.i16        q11, q8, d0[0]          @ 2*P5-5*P6+5*P7-2*P8
+        vabs.s16        q8, q12
+        vshr.s16        q12, q12, #8            @ clip_sign
+        vmls.i16        q10, q2, d0[0]          @ 2*P1-5*P2+5*P3-2*P4
+        vshr.s16        q8, q8, #1              @ clip
+        vmla.i16        q1, q3, d0[1]           @ 2*P3-5*P4+5*P5
+        vrshr.s16       q11, q11, #3
+        vmls.i16        q1, q13, d0[0]          @ 2*P3-5*P4+5*P5-2*P6
+        vceq.i16        q13, q8, #0             @ test clip == 0
+        vrshr.s16       q10, q10, #3
+        vabs.s16        q11, q11                @ a2
+        vabs.s16        q10, q10                @ a1
+        vrshr.s16       q1, q1, #3
+        vcge.s16        q14, q10, q11           @ test a1 >= a2
+        vabs.s16        q15, q1                 @ a0
+        vshr.s16        q1, q1, #8              @ a0_sign
+        vbsl            q14, q11, q10           @ a3
+        vcge.s16        q9, q15, q9             @ test a0 >= pq
+        vsub.i16        q1, q12, q1             @ clip_sign - a0_sign
+        vqsub.u16       q10, q15, q14           @ a0 >= a3 ? a0-a3 : 0  (a0 > a3 in all cases where filtering is enabled, so makes more sense to subtract this way round than the opposite and then taking the abs)
+        vcge.s16        q11, q14, q15           @ test a3 >= a0
+        vorr            q9, q13, q9             @ test clip == 0 || a0 >= pq
+        vmul.i16        q0, q10, d0[1]          @ a0 >= a3 ? 5*(a0-a3) : 0
+        vorr            q10, q9, q11            @ test clip == 0 || a0 >= pq || a3 >= a0
+        vmov.32         r2, d20[1]              @ move to gp reg
+        vshr.u16        q0, q0, #3              @ a0 >= a3 ? (5*(a0-a3))>>3 : 0
+        vmov.32         r3, d21[1]
+        vcge.s16        q10, q0, q8
+        and             r14, r2, r3
+        vbsl            q10, q8, q0             @ FFMIN(d, clip)
+        tst             r14, #1
+        bne             2f                      @ none of the 8 pixel pairs should be updated in this case
+        vbic            q0, q10, q9             @ set each d to zero if it should not be filtered because clip == 0 || a0 >= pq (a3 > a0 case already zeroed by saturating sub)
+        vmla.i16        q3, q0, q1              @ invert d depending on clip_sign & a0_sign, or zero it if they match, and accumulate into P5
+        vmls.i16        q2, q0, q1              @ invert d depending on clip_sign & a0_sign, or zero it if they match, and accumulate into P4
+        vqmovun.s16     d1, q3
+        vqmovun.s16     d0, q2
+        tst             r2, #1
+        bne             1f                      @ none of the first 4 pixel pairs should be updated if so
+        vst2.8          {d0[0], d1[0]}, [r0], r1
+        vst2.8          {d0[1], d1[1]}, [r0], r1
+        vst2.8          {d0[2], d1[2]}, [r0], r1
+        vst2.8          {d0[3], d1[3]}, [r0]
+1:      tst             r3, #1
+        bne             2f                      @ none of the second 4 pixel pairs should be updated if so
+        vst2.8          {d0[4], d1[4]}, [r12], r1
+        vst2.8          {d0[5], d1[5]}, [r12], r1
+        vst2.8          {d0[6], d1[6]}, [r12], r1
+        vst2.8          {d0[7], d1[7]}, [r12]
+2:      pop             {pc}
+endfunc
+
+@ VC-1 in-loop deblocking filter for 16 pixel pairs at boundary of vertically-neighbouring blocks
+@ On entry:
+@   r0 -> top-left pel of lower block
+@   r1 = row stride, bytes
+@   r2 = PQUANT bitstream parameter
+function ff_vc1_v_loop_filter16_neon, export=1
+        vpush           {d8-d15}
+        sub             r3, r0, r1, lsl #2
+        vldr            d0, .Lcoeffs
+        vld1.64         {q1}, [r0 :128], r1     @ P5
+        vld1.64         {q2}, [r3 :128], r1     @ P1
+        vld1.64         {q3}, [r3 :128], r1     @ P2
+        vld1.64         {q4}, [r0 :128], r1     @ P6
+        vld1.64         {q5}, [r3 :128], r1     @ P3
+        vld1.64         {q6}, [r0 :128], r1     @ P7
+        vshll.u8        q7, d2, #1              @ 2*P5[0..7]
+        vshll.u8        q8, d4, #1              @ 2*P1[0..7]
+        vld1.64         {q9}, [r3 :128]         @ P4
+        vmovl.u8        q10, d6                 @ P2[0..7]
+        vld1.64         {q11}, [r0 :128]        @ P8
+        vmovl.u8        q12, d8                 @ P6[0..7]
+        vdup.16         q13, r2                 @ pq
+        vshll.u8        q2, d5, #1              @ 2*P1[8..15]
+        vmls.i16        q8, q10, d0[1]          @ 2*P1[0..7]-5*P2[0..7]
+        vshll.u8        q10, d3, #1             @ 2*P5[8..15]
+        vmovl.u8        q3, d7                  @ P2[8..15]
+        vmls.i16        q7, q12, d0[1]          @ 2*P5[0..7]-5*P6[0..7]
+        vmovl.u8        q4, d9                  @ P6[8..15]
+        vmovl.u8        q14, d10                @ P3[0..7]
+        vmovl.u8        q15, d12                @ P7[0..7]
+        vmls.i16        q2, q3, d0[1]           @ 2*P1[8..15]-5*P2[8..15]
+        vshll.u8        q3, d10, #1             @ 2*P3[0..7]
+        vmls.i16        q10, q4, d0[1]          @ 2*P5[8..15]-5*P6[8..15]
+        vmovl.u8        q6, d13                 @ P7[8..15]
+        vmla.i16        q8, q14, d0[1]          @ 2*P1[0..7]-5*P2[0..7]+5*P3[0..7]
+        vmovl.u8        q14, d18                @ P4[0..7]
+        vmovl.u8        q9, d19                 @ P4[8..15]
+        vmla.i16        q7, q15, d0[1]          @ 2*P5[0..7]-5*P6[0..7]+5*P7[0..7]
+        vmovl.u8        q15, d11                @ P3[8..15]
+        vshll.u8        q5, d11, #1             @ 2*P3[8..15]
+        vmls.i16        q3, q14, d0[1]          @ 2*P3[0..7]-5*P4[0..7]
+        vmla.i16        q2, q15, d0[1]          @ 2*P1[8..15]-5*P2[8..15]+5*P3[8..15]
+        vmovl.u8        q15, d22                @ P8[0..7]
+        vmovl.u8        q11, d23                @ P8[8..15]
+        vmla.i16        q10, q6, d0[1]          @ 2*P5[8..15]-5*P6[8..15]+5*P7[8..15]
+        vmovl.u8        q6, d2                  @ P5[0..7]
+        vmovl.u8        q1, d3                  @ P5[8..15]
+        vmls.i16        q5, q9, d0[1]           @ 2*P3[8..15]-5*P4[8..15]
+        vmls.i16        q8, q14, d0[0]          @ 2*P1[0..7]-5*P2[0..7]+5*P3[0..7]-2*P4[0..7]
+        vmls.i16        q7, q15, d0[0]          @ 2*P5[0..7]-5*P6[0..7]+5*P7[0..7]-2*P8[0..7]
+        vsub.i16        q15, q14, q6            @ P4[0..7]-P5[0..7]
+        vmla.i16        q3, q6, d0[1]           @ 2*P3[0..7]-5*P4[0..7]+5*P5[0..7]
+        vrshr.s16       q8, q8, #3
+        vmls.i16        q2, q9, d0[0]           @ 2*P1[8..15]-5*P2[8..15]+5*P3[8..15]-2*P4[8..15]
+        vrshr.s16       q7, q7, #3
+        vmls.i16        q10, q11, d0[0]         @ 2*P5[8..15]-5*P6[8..15]+5*P7[8..15]-2*P8[8..15]
+        vabs.s16        q11, q15
+        vabs.s16        q8, q8                  @ a1[0..7]
+        vmla.i16        q5, q1, d0[1]           @ 2*P3[8..15]-5*P4[8..15]+5*P5[8..15]
+        vshr.s16        q15, q15, #8            @ clip_sign[0..7]
+        vrshr.s16       q2, q2, #3
+        vmls.i16        q3, q12, d0[0]          @ 2*P3[0..7]-5*P4[0..7]+5*P5[0..7]-2*P6[0..7]
+        vabs.s16        q7, q7                  @ a2[0..7]
+        vrshr.s16       q10, q10, #3
+        vsub.i16        q12, q9, q1             @ P4[8..15]-P5[8..15]
+        vshr.s16        q11, q11, #1            @ clip[0..7]
+        vmls.i16        q5, q4, d0[0]           @ 2*P3[8..15]-5*P4[8..15]+5*P5[8..15]-2*P6[8..15]
+        vcge.s16        q4, q8, q7              @ test a1[0..7] >= a2[0..7]
+        vabs.s16        q2, q2                  @ a1[8..15]
+        vrshr.s16       q3, q3, #3
+        vabs.s16        q10, q10                @ a2[8..15]
+        vbsl            q4, q7, q8              @ a3[0..7]
+        vabs.s16        q7, q12
+        vshr.s16        q8, q12, #8             @ clip_sign[8..15]
+        vrshr.s16       q5, q5, #3
+        vcge.s16        q12, q2, q10            @ test a1[8..15] >= a2[8.15]
+        vshr.s16        q7, q7, #1              @ clip[8..15]
+        vbsl            q12, q10, q2            @ a3[8..15]
+        vabs.s16        q2, q3                  @ a0[0..7]
+        vceq.i16        q10, q11, #0            @ test clip[0..7] == 0
+        vshr.s16        q3, q3, #8              @ a0_sign[0..7]
+        vsub.i16        q3, q15, q3             @ clip_sign[0..7] - a0_sign[0..7]
+        vcge.s16        q15, q2, q13            @ test a0[0..7] >= pq
+        vorr            q10, q10, q15           @ test clip[0..7] == 0 || a0[0..7] >= pq
+        vqsub.u16       q15, q2, q4             @ a0[0..7] >= a3[0..7] ? a0[0..7]-a3[0..7] : 0  (a0 > a3 in all cases where filtering is enabled, so makes more sense to subtract this way round than the opposite and then taking the abs)
+        vcge.s16        q2, q4, q2              @ test a3[0..7] >= a0[0..7]
+        vabs.s16        q4, q5                  @ a0[8..15]
+        vshr.s16        q5, q5, #8              @ a0_sign[8..15]
+        vmul.i16        q15, q15, d0[1]         @ a0[0..7] >= a3[0..7] ? 5*(a0[0..7]-a3[0..7]) : 0
+        vcge.s16        q13, q4, q13            @ test a0[8..15] >= pq
+        vorr            q2, q10, q2             @ test clip[0..7] == 0 || a0[0..7] >= pq || a3[0..7] >= a0[0..7]
+        vsub.i16        q5, q8, q5              @ clip_sign[8..15] - a0_sign[8..15]
+        vceq.i16        q8, q7, #0              @ test clip[8..15] == 0
+        vshr.u16        q15, q15, #3            @ a0[0..7] >= a3[0..7] ? (5*(a0[0..7]-a3[0..7]))>>3 : 0
+        vmov.32         r0, d4[1]               @ move to gp reg
+        vorr            q8, q8, q13             @ test clip[8..15] == 0 || a0[8..15] >= pq
+        vqsub.u16       q13, q4, q12            @ a0[8..15] >= a3[8..15] ? a0[8..15]-a3[8..15] : 0  (a0 > a3 in all cases where filtering is enabled, so makes more sense to subtract this way round than the opposite and then taking the abs)
+        vmov.32         r2, d5[1]
+        vcge.s16        q4, q12, q4             @ test a3[8..15] >= a0[8..15]
+        vshl.i64        q2, q2, #16
+        vcge.s16        q12, q15, q11
+        vmul.i16        q0, q13, d0[1]          @ a0[8..15] >= a3[8..15] ? 5*(a0[8..15]-a3[8..15]) : 0
+        vorr            q4, q8, q4              @ test clip[8..15] == 0 || a0[8..15] >= pq || a3[8..15] >= a0[8..15]
+        vshr.s64        q2, q2, #48
+        and             r0, r0, r2
+        vbsl            q12, q11, q15           @ FFMIN(d[0..7], clip[0..7])
+        vshl.i64        q11, q4, #16
+        vmov.32         r2, d8[1]
+        vshr.u16        q0, q0, #3              @ a0[8..15] >= a3[8..15] ? (5*(a0[8..15]-a3[8..15]))>>3 : 0
+        vorr            q2, q10, q2
+        vmov.32         r12, d9[1]
+        vshr.s64        q4, q11, #48
+        vcge.s16        q10, q0, q7
+        vbic            q2, q12, q2             @ set each d[0..7] to zero if it should not be filtered because clip[0..7] == 0 || a0[0..7] >= pq (a3 > a0 case already zeroed by saturating sub)
+        vorr            q4, q8, q4
+        and             r2, r2, r12
+        vbsl            q10, q7, q0             @ FFMIN(d[8..15], clip[8..15])
+        vmls.i16        q14, q2, q3             @ invert d[0..7] depending on clip_sign[0..7] & a0_sign[0..7], or zero it if they match, and accumulate into P4[0..7]
+        and             r0, r0, r2
+        vbic            q0, q10, q4             @ set each d[8..15] to zero if it should not be filtered because clip[8..15] == 0 || a0[8..15] >= pq (a3 > a0 case already zeroed by saturating sub)
+        tst             r0, #1
+        bne             1f                      @ none of the 16 pixel pairs should be updated in this case
+        vmla.i16        q6, q2, q3              @ invert d[0..7] depending on clip_sign[0..7] & a0_sign[0..7], or zero it if they match, and accumulate into P5[0..7]
+        vmls.i16        q9, q0, q5              @ invert d[8..15] depending on clip_sign[8..15] & a0_sign[8..15], or zero it if they match, and accumulate into P4[8..15]
+        vqmovun.s16     d4, q14
+        vmla.i16        q1, q0, q5              @ invert d[8..15] depending on clip_sign[8..15] & a0_sign[8..15], or zero it if they match, and accumulate into P5[8..15]
+        vqmovun.s16     d0, q6
+        vqmovun.s16     d5, q9
+        vqmovun.s16     d1, q1
+        vst1.64         {q2}, [r3 :128], r1
+        vst1.64         {q0}, [r3 :128]
+1:      vpop            {d8-d15}
+        bx              lr
+endfunc
+
+@ VC-1 in-loop deblocking filter for 16 pixel pairs at boundary of horizontally-neighbouring blocks
+@ On entry:
+@   r0 -> top-left pel of right block
+@   r1 = row stride, bytes
+@   r2 = PQUANT bitstream parameter
+function ff_vc1_h_loop_filter16_neon, export=1
+        push            {r4-r6,lr}
+        vpush           {d8-d15}
+        sub             r3, r0, #4              @ where to start reading
+        vldr            d0, .Lcoeffs
+        vld1.32         {d2}, [r3], r1          @ P1[0], P2[0]...
+        sub             r0, r0, #1              @ where to start writing
+        vld1.32         {d3}, [r3], r1
+        add             r4, r0, r1, lsl #2
+        vld1.32         {d10}, [r3], r1
+        vld1.32         {d11}, [r3], r1
+        vld1.32         {d16}, [r3], r1
+        vld1.32         {d4}, [r3], r1
+        vld1.32         {d8}, [r3], r1
+        vtrn.8          d2, d3                  @ P1[0], P1[1], P3[0]... P2[0], P2[1], P4[0]...
+        vld1.32         {d14}, [r3], r1
+        vld1.32         {d5}, [r3], r1
+        vtrn.8          d10, d11                @ P1[2], P1[3], P3[2]... P2[2], P2[3], P4[2]...
+        vld1.32         {d6}, [r3], r1
+        vld1.32         {d12}, [r3], r1
+        vtrn.8          d16, d4                 @ P1[4], P1[5], P3[4]... P2[4], P2[5], P4[4]...
+        vld1.32         {d13}, [r3], r1
+        vtrn.16         d2, d10                 @ P1[0], P1[1], P1[2], P1[3], P5[0]... P3[0], P3[1], P3[2], P3[3], P7[0]...
+        vld1.32         {d1}, [r3], r1
+        vtrn.8          d8, d14                 @ P1[6], P1[7], P3[6]... P2[6], P2[7], P4[6]...
+        vld1.32         {d7}, [r3], r1
+        vtrn.16         d3, d11                 @ P2[0], P2[1], P2[2], P2[3], P6[0]... P4[0], P4[1], P4[2], P4[3], P8[0]...
+        vld1.32         {d9}, [r3], r1
+        vtrn.8          d5, d6                  @ P1[8], P1[9], P3[8]... P2[8], P2[9], P4[8]...
+        vld1.32         {d15}, [r3]
+        vtrn.16         d16, d8                 @ P1[4], P1[5], P1[6], P1[7], P5[4]... P3[4], P3[5], P3[6], P3[7], P7[4]...
+        vtrn.16         d4, d14                 @ P2[4], P2[5], P2[6], P2[7], P6[4]... P4[4], P4[5], P4[6], P4[7], P8[4]...
+        vtrn.8          d12, d13                @ P1[10], P1[11], P3[10]... P2[10], P2[11], P4[10]...
+        vdup.16         q9, r2                  @ pq
+        vtrn.8          d1, d7                  @ P1[12], P1[13], P3[12]... P2[12], P2[13], P4[12]...
+        vtrn.32         d2, d16                 @ P1[0..7], P5[0..7]
+        vtrn.16         d5, d12                 @ P1[8], P1[7], P1[10], P1[11], P5[8]... P3[8], P3[9], P3[10], P3[11], P7[8]...
+        vtrn.16         d6, d13                 @ P2[8], P2[7], P2[10], P2[11], P6[8]... P4[8], P4[9], P4[10], P4[11], P8[8]...
+        vtrn.8          d9, d15                 @ P1[14], P1[15], P3[14]... P2[14], P2[15], P4[14]...
+        vtrn.32         d3, d4                  @ P2[0..7], P6[0..7]
+        vshll.u8        q10, d2, #1             @ 2*P1[0..7]
+        vtrn.32         d10, d8                 @ P3[0..7], P7[0..7]
+        vshll.u8        q11, d16, #1            @ 2*P5[0..7]
+        vtrn.32         d11, d14                @ P4[0..7], P8[0..7]
+        vtrn.16         d1, d9                  @ P1[12], P1[13], P1[14], P1[15], P5[12]... P3[12], P3[13], P3[14], P3[15], P7[12]...
+        vtrn.16         d7, d15                 @ P2[12], P2[13], P2[14], P2[15], P6[12]... P4[12], P4[13], P4[14], P4[15], P8[12]...
+        vmovl.u8        q1, d3                  @ P2[0..7]
+        vmovl.u8        q12, d4                 @ P6[0..7]
+        vtrn.32         d5, d1                  @ P1[8..15], P5[8..15]
+        vtrn.32         d6, d7                  @ P2[8..15], P6[8..15]
+        vtrn.32         d12, d9                 @ P3[8..15], P7[8..15]
+        vtrn.32         d13, d15                @ P4[8..15], P8[8..15]
+        vmls.i16        q10, q1, d0[1]          @ 2*P1[0..7]-5*P2[0..7]
+        vmovl.u8        q1, d10                 @ P3[0..7]
+        vshll.u8        q2, d5, #1              @ 2*P1[8..15]
+        vshll.u8        q13, d1, #1             @ 2*P5[8..15]
+        vmls.i16        q11, q12, d0[1]         @ 2*P5[0..7]-5*P6[0..7]
+        vmovl.u8        q14, d6                 @ P2[8..15]
+        vmovl.u8        q3, d7                  @ P6[8..15]
+        vmovl.u8        q15, d8                 @ P7[0..7]
+        vmla.i16        q10, q1, d0[1]          @ 2*P1[0..7]-5*P2[0..7]+5*P3[0..7]
+        vmovl.u8        q1, d12                 @ P3[8..15]
+        vmls.i16        q2, q14, d0[1]          @ 2*P1[8..15]-5*P2[8..15]
+        vmovl.u8        q4, d9                  @ P7[8..15]
+        vshll.u8        q14, d10, #1            @ 2*P3[0..7]
+        vmls.i16        q13, q3, d0[1]          @ 2*P5[8..15]-5*P6[8..15]
+        vmovl.u8        q5, d11                 @ P4[0..7]
+        vmla.i16        q11, q15, d0[1]         @ 2*P5[0..7]-5*P6[0..7]+5*P7[0..7]
+        vshll.u8        q15, d12, #1            @ 2*P3[8..15]
+        vmovl.u8        q6, d13                 @ P4[8..15]
+        vmla.i16        q2, q1, d0[1]           @ 2*P1[8..15]-5*P2[8..15]+5*P3[8..15]
+        vmovl.u8        q1, d14                 @ P8[0..7]
+        vmovl.u8        q7, d15                 @ P8[8..15]
+        vmla.i16        q13, q4, d0[1]          @ 2*P5[8..15]-5*P6[8..15]+5*P7[8..15]
+        vmovl.u8        q4, d16                 @ P5[0..7]
+        vmovl.u8        q8, d1                  @ P5[8..15]
+        vmls.i16        q14, q5, d0[1]          @ 2*P3[0..7]-5*P4[0..7]
+        vmls.i16        q15, q6, d0[1]          @ 2*P3[8..15]-5*P4[8..15]
+        vmls.i16        q10, q5, d0[0]          @ 2*P1[0..7]-5*P2[0..7]+5*P3[0..7]-2*P4[0..7]
+        vmls.i16        q11, q1, d0[0]          @ 2*P5[0..7]-5*P6[0..7]+5*P7[0..7]-2*P8[0..7]
+        vsub.i16        q1, q5, q4              @ P4[0..7]-P5[0..7]
+        vmls.i16        q2, q6, d0[0]           @ 2*P1[8..15]-5*P2[8..15]+5*P3[8..15]-2*P4[8..15]
+        vrshr.s16       q10, q10, #3
+        vmls.i16        q13, q7, d0[0]          @ 2*P5[8..15]-5*P6[8..15]+5*P7[8..15]-2*P8[8..15]
+        vsub.i16        q7, q6, q8              @ P4[8..15]-P5[8..15]
+        vrshr.s16       q11, q11, #3
+        vmla.s16        q14, q4, d0[1]          @ 2*P3[0..7]-5*P4[0..7]+5*P5[0..7]
+        vrshr.s16       q2, q2, #3
+        vmla.i16        q15, q8, d0[1]          @ 2*P3[8..15]-5*P4[8..15]+5*P5[8..15]
+        vabs.s16        q10, q10                @ a1[0..7]
+        vrshr.s16       q13, q13, #3
+        vmls.i16        q15, q3, d0[0]          @ 2*P3[8..15]-5*P4[8..15]+5*P5[8..15]-2*P6[8..15]
+        vabs.s16        q3, q11                 @ a2[0..7]
+        vabs.s16        q2, q2                  @ a1[8..15]
+        vmls.i16        q14, q12, d0[0]         @ 2*P3[0..7]-5*P4[0..7]+5*P5[0..7]-2*P6[0..7]
+        vabs.s16        q11, q1
+        vabs.s16        q12, q13                @ a2[8..15]
+        vcge.s16        q13, q10, q3            @ test a1[0..7] >= a2[0..7]
+        vshr.s16        q1, q1, #8              @ clip_sign[0..7]
+        vrshr.s16       q15, q15, #3
+        vshr.s16        q11, q11, #1            @ clip[0..7]
+        vrshr.s16       q14, q14, #3
+        vbsl            q13, q3, q10            @ a3[0..7]
+        vcge.s16        q3, q2, q12             @ test a1[8..15] >= a2[8.15]
+        vabs.s16        q10, q15                @ a0[8..15]
+        vshr.s16        q15, q15, #8            @ a0_sign[8..15]
+        vbsl            q3, q12, q2             @ a3[8..15]
+        vabs.s16        q2, q14                 @ a0[0..7]
+        vabs.s16        q12, q7
+        vshr.s16        q7, q7, #8              @ clip_sign[8..15]
+        vshr.s16        q14, q14, #8            @ a0_sign[0..7]
+        vshr.s16        q12, q12, #1            @ clip[8..15]
+        vsub.i16        q7, q7, q15             @ clip_sign[8..15] - a0_sign[8..15]
+        vqsub.u16       q15, q10, q3            @ a0[8..15] >= a3[8..15] ? a0[8..15]-a3[8..15] : 0  (a0 > a3 in all cases where filtering is enabled, so makes more sense to subtract this way round than the opposite and then taking the abs)
+        vcge.s16        q3, q3, q10             @ test a3[8..15] >= a0[8..15]
+        vcge.s16        q10, q10, q9            @ test a0[8..15] >= pq
+        vcge.s16        q9, q2, q9              @ test a0[0..7] >= pq
+        vsub.i16        q1, q1, q14             @ clip_sign[0..7] - a0_sign[0..7]
+        vqsub.u16       q14, q2, q13            @ a0[0..7] >= a3[0..7] ? a0[0..7]-a3[0..7] : 0  (a0 > a3 in all cases where filtering is enabled, so makes more sense to subtract this way round than the opposite and then taking the abs)
+        vcge.s16        q2, q13, q2             @ test a3[0..7] >= a0[0..7]
+        vmul.i16        q13, q15, d0[1]         @ a0[8..15] >= a3[8..15] ? 5*(a0[8..15]-a3[8..15]) : 0
+        vceq.i16        q15, q11, #0            @ test clip[0..7] == 0
+        vmul.i16        q0, q14, d0[1]          @ a0[0..7] >= a3[0..7] ? 5*(a0[0..7]-a3[0..7]) : 0
+        vorr            q9, q15, q9             @ test clip[0..7] == 0 || a0[0..7] >= pq
+        vceq.i16        q14, q12, #0            @ test clip[8..15] == 0
+        vshr.u16        q13, q13, #3            @ a0[8..15] >= a3[8..15] ? (5*(a0[8..15]-a3[8..15]))>>3 : 0
+        vorr            q2, q9, q2              @ test clip[0..7] == 0 || a0[0..7] >= pq || a3[0..7] >= a0[0..7]
+        vshr.u16        q0, q0, #3              @ a0[0..7] >= a3[0..7] ? (5*(a0[0..7]-a3[0..7]))>>3 : 0
+        vorr            q10, q14, q10           @ test clip[8..15] == 0 || a0[8..15] >= pq
+        vcge.s16        q14, q13, q12
+        vmov.32         r2, d4[1]               @ move to gp reg
+        vorr            q3, q10, q3             @ test clip[8..15] == 0 || a0[8..15] >= pq || a3[8..15] >= a0[8..15]
+        vmov.32         r3, d5[1]
+        vcge.s16        q2, q0, q11
+        vbsl            q14, q12, q13           @ FFMIN(d[8..15], clip[8..15])
+        vbsl            q2, q11, q0             @ FFMIN(d[0..7], clip[0..7])
+        vmov.32         r5, d6[1]
+        vbic            q0, q14, q10            @ set each d[8..15] to zero if it should not be filtered because clip[8..15] == 0 || a0[8..15] >= pq (a3 > a0 case already zeroed by saturating sub)
+        vmov.32         r6, d7[1]
+        and             r12, r2, r3
+        vbic            q2, q2, q9              @ set each d[0..7] to zero if it should not be filtered because clip[0..7] == 0 || a0[0..7] >= pq (a3 > a0 case already zeroed by saturating sub)
+        vmls.i16        q6, q0, q7              @ invert d[8..15] depending on clip_sign[8..15] & a0_sign[8..15], or zero it if they match, and accumulate into P4
+        vmls.i16        q5, q2, q1              @ invert d[0..7] depending on clip_sign[0..7] & a0_sign[0..7], or zero it if they match, and accumulate into P4
+        and             r14, r5, r6
+        vmla.i16        q4, q2, q1              @ invert d[0..7] depending on clip_sign[0..7] & a0_sign[0..7], or zero it if they match, and accumulate into P5
+        and             r12, r12, r14
+        vqmovun.s16     d4, q6
+        vmla.i16        q8, q0, q7              @ invert d[8..15] depending on clip_sign[8..15] & a0_sign[8..15], or zero it if they match, and accumulate into P5
+        tst             r12, #1
+        bne             4f                      @ none of the 16 pixel pairs should be updated in this case
+        vqmovun.s16     d2, q5
+        vqmovun.s16     d3, q4
+        vqmovun.s16     d5, q8
+        tst             r2, #1
+        bne             1f
+        vst2.8          {d2[0], d3[0]}, [r0], r1
+        vst2.8          {d2[1], d3[1]}, [r0], r1
+        vst2.8          {d2[2], d3[2]}, [r0], r1
+        vst2.8          {d2[3], d3[3]}, [r0]
+1:      add             r0, r4, r1, lsl #2
+        tst             r3, #1
+        bne             2f
+        vst2.8          {d2[4], d3[4]}, [r4], r1
+        vst2.8          {d2[5], d3[5]}, [r4], r1
+        vst2.8          {d2[6], d3[6]}, [r4], r1
+        vst2.8          {d2[7], d3[7]}, [r4]
+2:      add             r4, r0, r1, lsl #2
+        tst             r5, #1
+        bne             3f
+        vst2.8          {d4[0], d5[0]}, [r0], r1
+        vst2.8          {d4[1], d5[1]}, [r0], r1
+        vst2.8          {d4[2], d5[2]}, [r0], r1
+        vst2.8          {d4[3], d5[3]}, [r0]
+3:      tst             r6, #1
+        bne             4f
+        vst2.8          {d4[4], d5[4]}, [r4], r1
+        vst2.8          {d4[5], d5[5]}, [r4], r1
+        vst2.8          {d4[6], d5[6]}, [r4], r1
+        vst2.8          {d4[7], d5[7]}, [r4]
+4:      vpop            {d8-d15}
+        pop             {r4-r6,pc}
+endfunc
+
+@ Copy at most the specified number of bytes from source to destination buffer,
+@ stopping at a multiple of 16 bytes, none of which are the start of an escape sequence
+@ On entry:
+@   r0 -> source buffer
+@   r1 = max number of bytes to copy
+@   r2 -> destination buffer, optimally 8-byte aligned
+@ On exit:
+@   r0 = number of bytes not copied
+function ff_vc1_unescape_buffer_helper_neon, export=1
+        @ Offset by 48 to screen out cases that are too short for us to handle,
+        @ and also make it easy to test for loop termination, or to determine
+        @ whether we need an odd number of half-iterations of the loop.
+        subs    r1, r1, #48
+        bmi     90f
+
+        @ Set up useful constants
+        vmov.i32        q0, #0x3000000
+        vmov.i32        q1, #0x30000
+
+        tst             r1, #16
+        bne             1f
+
+          vld1.8          {q8, q9}, [r0]!
+          vbic            q12, q8, q0
+          vext.8          q13, q8, q9, #1
+          vext.8          q14, q8, q9, #2
+          vext.8          q15, q8, q9, #3
+          veor            q12, q12, q1
+          vbic            q13, q13, q0
+          vbic            q14, q14, q0
+          vbic            q15, q15, q0
+          vceq.i32        q12, q12, #0
+          veor            q13, q13, q1
+          veor            q14, q14, q1
+          veor            q15, q15, q1
+          vceq.i32        q13, q13, #0
+          vceq.i32        q14, q14, #0
+          vceq.i32        q15, q15, #0
+          add             r1, r1, #16
+          b               3f
+
+1:      vld1.8          {q10, q11}, [r0]!
+        vbic            q12, q10, q0
+        vext.8          q13, q10, q11, #1
+        vext.8          q14, q10, q11, #2
+        vext.8          q15, q10, q11, #3
+        veor            q12, q12, q1
+        vbic            q13, q13, q0
+        vbic            q14, q14, q0
+        vbic            q15, q15, q0
+        vceq.i32        q12, q12, #0
+        veor            q13, q13, q1
+        veor            q14, q14, q1
+        veor            q15, q15, q1
+        vceq.i32        q13, q13, #0
+        vceq.i32        q14, q14, #0
+        vceq.i32        q15, q15, #0
+        @ Drop through...
+2:        vmov            q8, q11
+          vld1.8          {q9}, [r0]!
+        vorr            q13, q12, q13
+        vorr            q15, q14, q15
+          vbic            q12, q8, q0
+        vorr            q3, q13, q15
+          vext.8          q13, q8, q9, #1
+          vext.8          q14, q8, q9, #2
+          vext.8          q15, q8, q9, #3
+          veor            q12, q12, q1
+        vorr            d6, d6, d7
+          vbic            q13, q13, q0
+          vbic            q14, q14, q0
+          vbic            q15, q15, q0
+          vceq.i32        q12, q12, #0
+        vmov            r3, r12, d6
+          veor            q13, q13, q1
+          veor            q14, q14, q1
+          veor            q15, q15, q1
+          vceq.i32        q13, q13, #0
+          vceq.i32        q14, q14, #0
+          vceq.i32        q15, q15, #0
+        orrs            r3, r3, r12
+        bne             90f
+        vst1.64         {q10}, [r2]!
+3:          vmov            q10, q9
+            vld1.8          {q11}, [r0]!
+          vorr            q13, q12, q13
+          vorr            q15, q14, q15
+            vbic            q12, q10, q0
+          vorr            q3, q13, q15
+            vext.8          q13, q10, q11, #1
+            vext.8          q14, q10, q11, #2
+            vext.8          q15, q10, q11, #3
+            veor            q12, q12, q1
+          vorr            d6, d6, d7
+            vbic            q13, q13, q0
+            vbic            q14, q14, q0
+            vbic            q15, q15, q0
+            vceq.i32        q12, q12, #0
+          vmov            r3, r12, d6
+            veor            q13, q13, q1
+            veor            q14, q14, q1
+            veor            q15, q15, q1
+            vceq.i32        q13, q13, #0
+            vceq.i32        q14, q14, #0
+            vceq.i32        q15, q15, #0
+          orrs            r3, r3, r12
+          bne             91f
+          vst1.64         {q8}, [r2]!
+        subs            r1, r1, #32
+        bpl             2b
+
+90:     add             r0, r1, #48
+        bx              lr
+
+91:     sub             r1, r1, #16
+        b               90b
+endfunc
diff -pruN 7:5.0.1-3/libavcodec/ass.c 7:5.1-1/libavcodec/ass.c
--- 7:5.0.1-3/libavcodec/ass.c	2022-01-14 18:45:39.000000000 +0000
+++ 7:5.1-1/libavcodec/ass.c	2022-07-22 17:58:38.000000000 +0000
@@ -114,17 +114,34 @@ char *ff_ass_get_dialog(int readorder, i
                        speaker ? speaker : "", text);
 }
 
-int ff_ass_add_rect(AVSubtitle *sub, const char *dialog,
+int ff_ass_add_rect2(AVSubtitle *sub, const char *dialog,
                     int readorder, int layer, const char *style,
-                    const char *speaker)
+                    const char *speaker, unsigned *nb_rect_allocated)
 {
-    AVSubtitleRect **rects, *rect;
+    AVSubtitleRect **rects = sub->rects, *rect;
     char *ass_str;
+    uint64_t new_nb = 0;
 
-    rects = av_realloc_array(sub->rects, sub->num_rects+1, sizeof(*sub->rects));
-    if (!rects)
+    if (sub->num_rects >= UINT_MAX)
         return AVERROR(ENOMEM);
-    sub->rects = rects;
+
+    if (nb_rect_allocated && *nb_rect_allocated <= sub->num_rects) {
+        if (sub->num_rects < UINT_MAX / 17 * 16) {
+            new_nb = sub->num_rects + sub->num_rects/16 + 1;
+        } else
+            new_nb = UINT_MAX;
+    } else if (!nb_rect_allocated)
+        new_nb = sub->num_rects + 1;
+
+    if (new_nb) {
+        rects = av_realloc_array(rects, new_nb, sizeof(*sub->rects));
+        if (!rects)
+            return AVERROR(ENOMEM);
+        if (nb_rect_allocated)
+            *nb_rect_allocated = new_nb;
+        sub->rects = rects;
+    }
+
     rect       = av_mallocz(sizeof(*rect));
     if (!rect)
         return AVERROR(ENOMEM);
@@ -137,6 +154,13 @@ int ff_ass_add_rect(AVSubtitle *sub, con
     return 0;
 }
 
+int ff_ass_add_rect(AVSubtitle *sub, const char *dialog,
+                    int readorder, int layer, const char *style,
+                    const char *speaker)
+{
+    return ff_ass_add_rect2(sub, dialog, readorder, layer, style, speaker, NULL);
+}
+
 void ff_ass_decoder_flush(AVCodecCo