lpcm with tsmuxer cleanup by Andrew
authorGood Guy <[email protected]>
Thu, 28 Apr 2022 14:38:57 +0000 (08:38 -0600)
committerGood Guy <[email protected]>
Thu, 28 Apr 2022 14:38:57 +0000 (08:38 -0600)
cinelerra-5.1/cinelerra/bdcreate.C
cinelerra-5.1/thirdparty/src/ffmpeg-4.4.patch_99 [new file with mode: 0644]

index 61362cfc26be5fad4ccc28931ad76bb861b9f4f6..dd1dd19a619103d666fe0ff2e6575983b8d9a87c 100644 (file)
@@ -962,6 +962,7 @@ void CreateBD_GUI::update()
        need_wide_audio->set_value(thread->use_wide_audio);
        need_labeled->set_value(thread->use_labeled);
        need_farmed->set_value(thread->use_farmed);
+       need_tsmuxer->set_value(thread->use_tsmuxer);
 }
 
 int CreateBD_Thread::
@@ -1011,6 +1012,7 @@ option_presets()
        use_wide_audio = 0;
        use_labeled = 0;
        use_farmed = 0;
+       use_tsmuxer = 0;
 
        if( !mwindow->edl ) return 1;
 
@@ -1219,6 +1221,7 @@ CreateBD_Profile::CreateBD_Profile(CreateBD_GUI *gui, int x, int y)
  : BC_PopupTextBox(gui, 0, 0, x, y, xS(170),yS(50))
 {
        this->gui = gui;
+       strcpy(gui->thread->use_profile, "bluray.m2ts");
 }
 
 CreateBD_Profile::~CreateBD_Profile()
diff --git a/cinelerra-5.1/thirdparty/src/ffmpeg-4.4.patch_99 b/cinelerra-5.1/thirdparty/src/ffmpeg-4.4.patch_99
new file mode 100644 (file)
index 0000000..6a66ff2
--- /dev/null
@@ -0,0 +1,574 @@
+--- ffmpeg-4.4/libavcodec/pcm-bluenc.c 2022-04-24 09:45:43.921091116 +0300
++++ ffmpeg-4.4/libavcodec/pcm-bluenc.c 2022-04-24 16:07:28.537982120 +0300
+@@ -1,6 +1,5 @@
+ /*
+  * LPCM codecs for PCM formats found in Blu-ray m2ts streams
+- * Copyright (c) 2018 Paul B Mahol
+  *
+  * This file is part of FFmpeg.
+  *
+@@ -19,314 +18,305 @@
+  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+  */
++#include "libavutil/channel_layout.h"
+ #include "avcodec.h"
+ #include "bytestream.h"
++//#include "codec_internal.h"
++#include "encode.h"
+ #include "internal.h"
+-typedef struct PCMBDContext {
+-    uint8_t header[4];       // Header added to every frame
+-    int block_size;          // Size of a block of samples in bytes
+-    int samples_per_block;   // Number of samples per channel per block
+-    int groups_per_block;    // Number of 20/24-bit sample groups per block
+-    uint8_t *extra_samples;  // Pointer to leftover samples from a frame
+-    int extra_sample_count;  // Number of leftover samples in the buffer
+-} PCMBDContext;
++typedef struct BlurayPCMEncContext {
++    uint16_t header;      // Header added to every frame
++} BlurayPCMEncContext;
+-static av_cold int pcm_bd_encode_init(AVCodecContext *avctx)
++static av_cold int pcm_bluray_encode_init(AVCodecContext *avctx)
+ {
+-    PCMBDContext *s = avctx->priv_data;
+-    int quant, freq;
+-    uint16_t frame_size;
+-    uint8_t ch_layout = 0;
+-
++    BlurayPCMEncContext *s = avctx->priv_data;
++    uint8_t ch_layout;
++    int quant, freq, frame_size;
++    
++    switch(avctx->sample_fmt) {
++    case AV_SAMPLE_FMT_S16:
++       avctx->bits_per_coded_sample = 16;
++       frame_size = 120;
++       quant =1;
++       break;
++    case AV_SAMPLE_FMT_S32:
++       avctx->bits_per_coded_sample = 24;
++       frame_size = 180;
++       quant =3;
++       break;
++    default:
++    return AVERROR_BUG;
++    }
++    
+     switch (avctx->sample_rate) {
+     case 48000:
+         freq = 1;
+         break;
+     case 96000:
++        frame_size *= 2;
+         freq = 4;
+         break;
+     case 192000:
+-      freq = 5;
+-      break;
++      frame_size *= 4;
++        freq = 5;
++        break;
++    default:
++        return AVERROR_BUG;
+     }
+-    switch (avctx->sample_fmt) {
+-    case AV_SAMPLE_FMT_S16:
+-        avctx->bits_per_coded_sample = 16;
+-        quant = 1;
++    frame_size *= avctx->channels;
++    
++    switch (avctx->channel_layout) {
++    case AV_CH_LAYOUT_MONO:
++        ch_layout = 1;
+         break;
+-/*    case AV_SAMPLE_FMT_S20:
+-        avctx->bits_per_coded_sample = 20;
+-        quant = 2;
++    case AV_CH_LAYOUT_STEREO:
++        ch_layout = 3;
+         break;
+-*/
+-    case AV_SAMPLE_FMT_S32:
+-        avctx->bits_per_coded_sample = 24;
+-        quant = 3;
++    case AV_CH_LAYOUT_SURROUND:
++        ch_layout = 4;
+         break;
+-    }
+-
+-    avctx->block_align           = avctx->channels * avctx->bits_per_coded_sample / 8;
+-    avctx->bit_rate              = avctx->block_align * 8LL * avctx->sample_rate;
+-    if (avctx->bit_rate > 19800000) {
+-        av_log(avctx, AV_LOG_ERROR, "Too big bitrate: reduce sample rate, bitdepth or channels.\n");
+-        return AVERROR(EINVAL);
+-    }
+-
+-    if (avctx->sample_fmt == AV_SAMPLE_FMT_S16) {
+-      switch (avctx->channels) {
+-      case 1:
+-          s->block_size = avctx->channels * 4;
+-          break;
+-      default:
+-        s->block_size        = avctx->channels * 2;
++    case AV_CH_LAYOUT_2_1:
++        ch_layout = 5;
+         break;
+-        }
+-        s->samples_per_block = 1;
+-        frame_size           = 2008 / s->block_size;
+-    } else {
+-        switch (avctx->channels) {
+-        case 1:
+-            s->block_size        = 2 * avctx->channels * avctx->bits_per_coded_sample / 8;
+-          s->samples_per_block = 1;
+-        break;
+-        case 2:
+-        case 4:
+-            /* one group has all the samples needed */
+-            s->block_size        = avctx->channels * avctx->bits_per_coded_sample / 8;
+-            s->samples_per_block = 1;
+-            s->groups_per_block  = 2;
+-            break;
+-        case 8:
+-        case 6:
+-            /* two groups have all the samples needed */
+-            s->block_size        = avctx->channels * avctx->bits_per_coded_sample / 8;
+-            s->samples_per_block = 1;
+-            // s->groups_per_block  = 2;
+-            break;
+-        default:
+-            /* need avctx->channels groups */
+-            s->block_size        = 4 * avctx->channels *
+-                                   avctx->bits_per_coded_sample / 8;
+-            s->samples_per_block = 4;
+-            s->groups_per_block  = avctx->channels;
+-            break;
+-        }
+-
+-        frame_size = FFALIGN(2008 / s->block_size, s->samples_per_block);
++    case AV_CH_LAYOUT_4POINT0:
++        ch_layout = 6;
++        break;
++    case AV_CH_LAYOUT_2_2:
++        ch_layout = 7;
++        break;
++    case AV_CH_LAYOUT_5POINT0:
++        ch_layout = 8;
++        break;
++    case AV_CH_LAYOUT_5POINT1_BACK:
++        ch_layout = 9;
++        break;
++    case AV_CH_LAYOUT_7POINT0:
++        ch_layout = 10;
++        break;
++    case AV_CH_LAYOUT_7POINT1:
++        ch_layout = 11;
++        break;
++    default:
++        return AVERROR_BUG;
+     }
+-    switch(avctx->channel_layout) {
+-      case AV_CH_LAYOUT_MONO:
+-              ch_layout = 1;
+-              break;
+-      case AV_CH_LAYOUT_STEREO:
+-              ch_layout = 3;
+-              break;
+-      case AV_CH_LAYOUT_5POINT1:
+-      case AV_CH_LAYOUT_5POINT1_BACK:
+-              ch_layout = 9;
+-              break;
+-      case AV_CH_LAYOUT_7POINT1:
+-              ch_layout = 11;
+-              break;
+-      default:
+-              av_log(avctx, AV_LOG_ERROR, "Not yet implemented ch layout!\n");
+-      }
+-// description on the web:
+-/* http://forum.doom9.org/showthread.php?t=152897
+-
+-It's a header.
+-
+-size in bytes = 16 bits (big endian)
+-channel assignment = 4 bits
+-sampling frequency = 4 bits
+-bits per sample = 2 bits
+-start flag = 1 bit
+-reserved = 5 bits
+-
+-channel assignment
+-1 = mono
+-3 = stereo
+-4 = 3/0
+-5 = 2/1
+-6 = 3/1
+-7 = 2/2
+-8 = 3/2
+-9 = 3/2+lfe
+-10 = 3/4
+-11 = 3/4+lfe
+-
+-sampling frequency
+-1 = 48 kHz
+-4 = 96 kHz
+-5 = 192 kHz
+-
+-bits per sample
+-1 = 16
+-2 = 20
+-3 = 24
+-*/
+-
+-    s->header[2] = (ch_layout << 4) | (freq);
+-    s->header[3] = (quant << 6) | 0x1 ;
+-
+-
+-        avctx->frame_size = frame_size; // in num. of samples
++    s->header = (((ch_layout << 4) | freq) << 8) | (quant << 6);
++    avctx->frame_size = frame_size;
+     return 0;
+ }
+-static int pcm_bd_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
+-                                const AVFrame *frame, int *got_packet_ptr)
++static int pcm_bluray_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
++                                   const AVFrame *frame, int *got_packet_ptr)
+ {
+-    PCMBDContext *s = avctx->priv_data;
+-    int samples, channels;
+-    int64_t pkt_size = (frame->nb_samples / s->samples_per_block) * s->block_size + 4;
++    BlurayPCMEncContext *s = avctx->priv_data;
++    int sample_size, samples, channel, num_dest_channels;
+     const int16_t *src16;
+     const int32_t *src32;
++    unsigned pkt_size;
+     PutByteContext pb;
+     int ret;
+-    if ((ret = ff_alloc_packet2(avctx, avpkt, pkt_size, 0)) < 0)
++    num_dest_channels = FFALIGN(avctx->channels, 2);
++    sample_size = (num_dest_channels *
++                   (avctx->sample_fmt == AV_SAMPLE_FMT_S16 ? 16 : 24)) >> 3;
++    samples = frame->nb_samples;
++
++    pkt_size = sample_size * samples + 4;
++
++    if ((ret = ff_get_encode_buffer(avctx, avpkt, pkt_size, 0)) < 0)
+         return ret;
+-    AV_WB16(s->header, pkt_size - 4);
+-    memcpy(avpkt->data, s->header, 4);
++    AV_WB16(avpkt->data, pkt_size - 4);
++    AV_WB16(avpkt->data + 2, s->header);
+     src16 = (const int16_t *)frame->data[0];
+     src32 = (const int32_t *)frame->data[0];
+     bytestream2_init_writer(&pb, avpkt->data + 4, avpkt->size - 4);
+-    int num_source_channels = FFALIGN(avctx->channels, 2);
+-    // int num_source_channels = avctx->channels;
+-    // int sample_size = (num_source_channels *
+-    //               (avctx->sample_fmt == AV_SAMPLE_FMT_S16 ? 16 : 24)) >> 3;
+-    samples = frame->nb_samples * num_source_channels;
+-
+-    switch (avctx->sample_fmt) {
+-    case AV_SAMPLE_FMT_S16:
+-    switch (avctx->channels) {
+-      case 1:
+-          do {
+-                   do {
+-                      channels = avctx->channels;
+-                          bytestream2_put_be16(&pb, *src16++);
+-              } while (--channels);
+-              bytestream2_put_be16(&pb, 0);
+-              } while (--samples);
+-        break;
+-      case 2:
+-      do {
+-            bytestream2_put_be16(&pb, *src16++);
+-        } while (--samples);
+-        break;
+-      case 6:
+-      do {
+-          bytestream2_put_be16(&pb, src16[0]);
+-          bytestream2_put_be16(&pb, src16[1]);
+-          bytestream2_put_be16(&pb, src16[2]);
+-          bytestream2_put_be16(&pb, src16[4]);
+-          bytestream2_put_be16(&pb, src16[5]);
+-          bytestream2_put_be16(&pb, src16[3]);
+-          src16+=6;
+-        } while (--samples);
+-      break;
+-      case 8:
+-      do {
+-          bytestream2_put_be16(&pb, src16[0]);
+-          bytestream2_put_be16(&pb, src16[1]);
+-          bytestream2_put_be16(&pb, src16[2]);
+-          bytestream2_put_be16(&pb, src16[6]);
+-          bytestream2_put_be16(&pb, src16[4]);
+-          bytestream2_put_be16(&pb, src16[5]);
+-          bytestream2_put_be16(&pb, src16[7]);
+-          bytestream2_put_be16(&pb, src16[3]);
+-          src16+=8;
+-        } while (--samples);
+-      break;
+-
+-      default:
+-      av_log(avctx, AV_LOG_ERROR, "this ch config not implemented for s16!\n");
++    switch (avctx->channel_layout) {
++    /* cases with same number of source and coded channels */
++    case AV_CH_LAYOUT_STEREO:
++    case AV_CH_LAYOUT_4POINT0:
++    case AV_CH_LAYOUT_2_2:
++        samples *= num_dest_channels;
++        if (AV_SAMPLE_FMT_S16 == avctx->sample_fmt) {
++#if HAVE_BIGENDIAN
++            bytestream2_put_bufferu(&pb, frame->data[0], samples * 2);
++#else
++            do {
++                bytestream2_put_be16u(&pb, *src16++);
++            } while (--samples);
++#endif
++        } else {
++            do {
++                bytestream2_put_be24u(&pb, (*src32++) >> 8);
++            } while (--samples);
++        }
+         break;
++    /* cases where number of source channels = coded channels + 1 */
++    case AV_CH_LAYOUT_MONO:
++    case AV_CH_LAYOUT_SURROUND:
++    case AV_CH_LAYOUT_2_1:
++    case AV_CH_LAYOUT_5POINT0:
++        if (AV_SAMPLE_FMT_S16 == avctx->sample_fmt) {
++            do {
++#if HAVE_BIGENDIAN
++                bytestream2_put_bufferu(&pb, (const uint8_t *)src16, avctx->ch_layout.nb_channels * 2);
++                src16 += avctx->channels;
++#else
++                channel = avctx->channels;
++                do {
++                    bytestream2_put_be16u(&pb, *src16++);
++                } while (--channel);
++#endif
++                bytestream2_put_ne16(&pb, 0);
++            } while (--samples);
++        } else {
++            do {
++                channel = avctx->channels;
++                do {
++                    bytestream2_put_be24u(&pb, (*src32++) >> 8);
++                } while (--channel);
++                bytestream2_put_ne24(&pb, 0);
++            } while (--samples);
+         }
+         break;
+-    case AV_SAMPLE_FMT_S32:
+-              switch (avctx->channels) {
+-                      case 2:
+-                      case 4:
+-                          do {
+-                              bytestream2_put_be24(&pb, (*src32++) >> 8);
+-                          } while (--samples);
+-                    break;
+-                        case 8:
+-                            do {
+-                          bytestream2_put_be24(&pb, src32[0] >> 8);
+-                          bytestream2_put_be24(&pb, src32[1] >> 8);
+-                          bytestream2_put_be24(&pb, src32[2] >> 8);
+-                          bytestream2_put_be24(&pb, src32[6] >> 8);
+-                          bytestream2_put_be24(&pb, src32[4] >> 8);
+-                          bytestream2_put_be24(&pb, src32[5] >> 8);
+-                          bytestream2_put_be24(&pb, src32[7] >> 8);
+-                          bytestream2_put_be24(&pb, src32[3] >> 8);
+-                          src32+=8;
+-                          } while (--samples);
+-                  break;
+-                      case 6:
+-                      do {
+-                          bytestream2_put_be24(&pb, src32[0] >> 8);
+-                          bytestream2_put_be24(&pb, src32[1] >> 8);
+-                          bytestream2_put_be24(&pb, src32[2] >> 8);
+-                          bytestream2_put_be24(&pb, src32[4] >> 8);
+-                          bytestream2_put_be24(&pb, src32[5] >> 8);
+-                          bytestream2_put_be24(&pb, src32[3] >> 8);
+-                          src32+=6;
+-                          } while (--samples);
+-                  break;
+-                      case 1:
+-                          do {
+-                             do {
+-                                  channels = avctx->channels;
+-                              bytestream2_put_be24(&pb, (*src32++) >> 8);
+-                              } while (--channels);
+-                          bytestream2_put_be24(&pb, 0);
+-                          } while (--samples);
+-                    break;
+-                      default:
+-                      av_log(avctx, AV_LOG_ERROR, "this bitdepth not implemented!\n");
+-                    break;
+-                }
+-    break;
++        /* remapping: L, R, C, LBack, RBack, LF */
++    case AV_CH_LAYOUT_5POINT1_BACK:
++        if (AV_SAMPLE_FMT_S16 == avctx->sample_fmt) {
++            do {
++                bytestream2_put_be16u(&pb, src16[0]);
++                bytestream2_put_be16u(&pb, src16[1]);
++                bytestream2_put_be16u(&pb, src16[2]);
++                bytestream2_put_be16u(&pb, src16[4]);
++                bytestream2_put_be16u(&pb, src16[5]);
++                bytestream2_put_be16u(&pb, src16[3]);
++                src16 += 6;
++            } while (--samples);
++        } else {
++            do {
++                bytestream2_put_be24u(&pb, src32[0] >> 8);
++                bytestream2_put_be24u(&pb, src32[1] >> 8);
++                bytestream2_put_be24u(&pb, src32[2] >> 8);
++                bytestream2_put_be24u(&pb, src32[4] >> 8);
++                bytestream2_put_be24u(&pb, src32[5] >> 8);
++                bytestream2_put_be24u(&pb, src32[3] >> 8);
++                src32 += 6;
++            } while (--samples);
++        }
++        break;
++        /* remapping: L, R, C, LSide, LBack, RBack, RSide, <unused> */
++    case AV_CH_LAYOUT_7POINT0:
++        if (AV_SAMPLE_FMT_S16 == avctx->sample_fmt) {
++            do {
++                bytestream2_put_be16u(&pb, src16[0]);
++                bytestream2_put_be16u(&pb, src16[1]);
++                bytestream2_put_be16u(&pb, src16[2]);
++                bytestream2_put_be16u(&pb, src16[5]);
++                bytestream2_put_be16u(&pb, src16[3]);
++                bytestream2_put_be16u(&pb, src16[4]);
++                bytestream2_put_be16u(&pb, src16[6]);
++                src16 += 7;
++                bytestream2_put_ne16(&pb, 0);
++            } while (--samples);
++        } else {
++            do {
++                bytestream2_put_be24u(&pb, src32[0] >> 8);
++                bytestream2_put_be24u(&pb, src32[1] >> 8);
++                bytestream2_put_be24u(&pb, src32[2] >> 8);
++                bytestream2_put_be24u(&pb, src32[5] >> 8);
++                bytestream2_put_be24u(&pb, src32[3] >> 8);
++                bytestream2_put_be24u(&pb, src32[4] >> 8);
++                bytestream2_put_be24u(&pb, src32[6] >> 8);
++                src32 += 7;
++                bytestream2_put_ne24(&pb, 0);
++            } while (--samples);
++        }
++        break;
++        /* remapping: L, R, C, LSide, LBack, RBack, RSide, LF */
++    case AV_CH_LAYOUT_7POINT1:
++        if (AV_SAMPLE_FMT_S16 == avctx->sample_fmt) {
++            do {
++                bytestream2_put_be16u(&pb, src16[0]);
++                bytestream2_put_be16u(&pb, src16[1]);
++                bytestream2_put_be16u(&pb, src16[2]);
++                bytestream2_put_be16u(&pb, src16[6]);
++                bytestream2_put_be16u(&pb, src16[4]);
++                bytestream2_put_be16u(&pb, src16[5]);
++                bytestream2_put_be16u(&pb, src16[7]);
++                bytestream2_put_be16u(&pb, src16[3]);
++                src16 += 8;
++            } while (--samples);
++        } else {
++            do {
++                bytestream2_put_be24u(&pb, src32[0]);
++                bytestream2_put_be24u(&pb, src32[1]);
++                bytestream2_put_be24u(&pb, src32[2]);
++                bytestream2_put_be24u(&pb, src32[6]);
++                bytestream2_put_be24u(&pb, src32[4]);
++                bytestream2_put_be24u(&pb, src32[5]);
++                bytestream2_put_be24u(&pb, src32[7]);
++                bytestream2_put_be24u(&pb, src32[3]);
++                src32 += 8;
++            } while (--samples);
++        }
++        break;
++    default:
++        return AVERROR_BUG;
+     }
+-    avpkt->pts      = frame->pts;
+-    avpkt->size     = pkt_size;
++    avpkt->pts = frame->pts;
+     avpkt->duration = ff_samples_to_time_base(avctx, frame->nb_samples);
+     *got_packet_ptr = 1;
+     return 0;
+ }
+-AVCodec ff_pcm_bluray_encoder = {
+-    .name           = "pcm_bluray",
+-    .long_name      = NULL_IF_CONFIG_SMALL("PCM signed 16|24-bit big-endian for bluray media"),
+-    .type           = AVMEDIA_TYPE_AUDIO,
+-    .id             = AV_CODEC_ID_PCM_BLURAY,
+-    .priv_data_size = sizeof(PCMBDContext),
+-    .init           = pcm_bd_encode_init,
+-    .encode2        = pcm_bd_encode_frame,
+-    .capabilities   = AV_CODEC_CAP_SMALL_LAST_FRAME,
+-    .supported_samplerates = (const int[]) { 48000, 96000, 192000, 0},
+-    .channel_layouts = (const uint64_t[]) { AV_CH_LAYOUT_MONO,
+-                                            AV_CH_LAYOUT_STEREO,
+-                                            AV_CH_LAYOUT_5POINT1,
+-                                            AV_CH_LAYOUT_5POINT1_BACK,
+-                                            AV_CH_LAYOUT_7POINT1,
+-                                            0 },
+-    .sample_fmts    = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16,
+-                                                     AV_SAMPLE_FMT_S32,
+-                                                     AV_SAMPLE_FMT_NONE },
+-    .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
++const AVCodec ff_pcm_bluray_encoder = {
++    .name               = "pcm_bluray",
++    .long_name          = NULL_IF_CONFIG_SMALL("PCM signed 16|20|24-bit big-endian for Blu-ray media"),
++    .type               = AVMEDIA_TYPE_AUDIO,
++    .id                 = AV_CODEC_ID_PCM_BLURAY,
++    .priv_data_size     = sizeof(BlurayPCMEncContext),
++    .init               = pcm_bluray_encode_init,
++    .encode2          = pcm_bluray_encode_frame,
++    .supported_samplerates = (const int[]) { 48000, 96000, 192000, 0 },
++//#define FF_API_OLD_CHANNEL_LAYOUT 1
++#if 1
++    .channel_layouts = (const uint64_t[]) {
++        AV_CH_LAYOUT_MONO,
++        AV_CH_LAYOUT_STEREO,
++        AV_CH_LAYOUT_SURROUND,
++        AV_CH_LAYOUT_2_1,
++        AV_CH_LAYOUT_4POINT0,
++        AV_CH_LAYOUT_2_2,
++        AV_CH_LAYOUT_5POINT0,
++        AV_CH_LAYOUT_5POINT1_BACK,
++        AV_CH_LAYOUT_7POINT0,
++        AV_CH_LAYOUT_7POINT1,
++        0 },
++#endif
++#if 0
++    .p.ch_layouts   = (const AVChannelLayout[]) {
++        AV_CHANNEL_LAYOUT_MONO,
++        AV_CHANNEL_LAYOUT_STEREO,
++        AV_CHANNEL_LAYOUT_SURROUND,
++        AV_CHANNEL_LAYOUT_2_1,
++        AV_CHANNEL_LAYOUT_4POINT0,
++        AV_CHANNEL_LAYOUT_2_2,
++        AV_CHANNEL_LAYOUT_5POINT0,
++        AV_CHANNEL_LAYOUT_5POINT1,
++        AV_CHANNEL_LAYOUT_7POINT0,
++        AV_CHANNEL_LAYOUT_7POINT1,
++        { 0 } },
++#endif
++    .sample_fmts         = (const enum AVSampleFormat[]) {
++        AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_NONE },
++    .caps_internal         = FF_CODEC_CAP_INIT_THREADSAFE,
++    .capabilities        = AV_CODEC_CAP_DR1,
+ };