+++ /dev/null
---- /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