---- 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 = 240;
-+ quant =1;
-+ break;
-+ case AV_SAMPLE_FMT_S32:
-+ avctx->bits_per_coded_sample = 24;
-+ frame_size = 360;
-+ 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,
- };