add bluray lpcm + from Andrew
[goodguy/cinelerra.git] / cinelerra-5.1 / thirdparty / src / ffmpeg-4.4.patch_9
diff --git a/cinelerra-5.1/thirdparty/src/ffmpeg-4.4.patch_9 b/cinelerra-5.1/thirdparty/src/ffmpeg-4.4.patch_9
new file mode 100644 (file)
index 0000000..f973f2f
--- /dev/null
@@ -0,0 +1,355 @@
+--- /dev/null  2021-12-05 17:02:04.576000000 +0300
++++ ./libavcodec/pcm-bluenc.c  2021-12-08 16:22:32.519865993 +0300
+@@ -0,0 +1,332 @@
++/*
++ * LPCM codecs for PCM formats found in Blu-ray m2ts streams
++ * Copyright (c) 2018 Paul B Mahol
++ *
++ * 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 "avcodec.h"
++#include "bytestream.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;
++
++static av_cold int pcm_bd_encode_init(AVCodecContext *avctx)
++{
++    PCMBDContext *s = avctx->priv_data;
++    int quant, freq;
++    uint16_t frame_size;
++    uint8_t ch_layout = 0;
++
++    switch (avctx->sample_rate) {
++    case 48000:
++        freq = 1;
++        break;
++    case 96000:
++        freq = 4;
++        break;
++    case 192000:
++      freq = 5;
++      break;
++    }
++
++    switch (avctx->sample_fmt) {
++    case AV_SAMPLE_FMT_S16:
++        avctx->bits_per_coded_sample = 16;
++        quant = 1;
++        break;
++/*    case AV_SAMPLE_FMT_S20:
++        avctx->bits_per_coded_sample = 20;
++        quant = 2;
++        break;
++*/
++    case AV_SAMPLE_FMT_S32:
++        avctx->bits_per_coded_sample = 24;
++        quant = 3;
++        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;
++        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);
++    }
++
++    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
++
++    return 0;
++}
++
++static int pcm_bd_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;
++    const int16_t *src16;
++    const int32_t *src32;
++    PutByteContext pb;
++    int ret;
++
++    if ((ret = ff_alloc_packet2(avctx, avpkt, pkt_size, 0)) < 0)
++        return ret;
++
++    AV_WB16(s->header, pkt_size - 4);
++    memcpy(avpkt->data, s->header, 4);
++
++    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");
++        break;
++        }
++        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;
++    }
++
++    avpkt->pts      = frame->pts;
++    avpkt->size     = pkt_size;
++    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,
++};
+--- ./libavcodec/allcodecs.orig        2021-04-09 00:28:39.000000000 +0300
++++ ./libavcodec/allcodecs.c   2021-12-06 15:45:03.333762281 +0300
+@@ -523,6 +523,7 @@
+ /* PCM codecs */
+ extern AVCodec ff_pcm_alaw_encoder;
+ extern AVCodec ff_pcm_alaw_decoder;
++extern AVCodec ff_pcm_bluray_encoder;
+ extern AVCodec ff_pcm_bluray_decoder;
+ extern AVCodec ff_pcm_dvd_encoder;
+ extern AVCodec ff_pcm_dvd_decoder;
+--- ./libavcodec/Makefile.orig 2021-04-09 00:28:39.000000000 +0300
++++ ./libavcodec/Makefile      2021-12-06 21:11:19.365842066 +0300
+@@ -789,6 +789,7 @@
+ OBJS-$(CONFIG_PCM_ALAW_DECODER)           += pcm.o
+ OBJS-$(CONFIG_PCM_ALAW_ENCODER)           += pcm.o
+ OBJS-$(CONFIG_PCM_BLURAY_DECODER)         += pcm-bluray.o
++OBJS-$(CONFIG_PCM_BLURAY_ENCODER)         += pcm-bluenc.o
+ OBJS-$(CONFIG_PCM_DVD_DECODER)            += pcm-dvd.o
+ OBJS-$(CONFIG_PCM_DVD_ENCODER)            += pcm-dvdenc.o
+ OBJS-$(CONFIG_PCM_F16LE_DECODER)          += pcm.o