1 --- /dev/null 2021-12-05 17:02:04.576000000 +0300
2 +++ ./libavcodec/pcm-bluenc.c 2021-12-08 16:22:32.519865993 +0300
5 + * LPCM codecs for PCM formats found in Blu-ray m2ts streams
6 + * Copyright (c) 2018 Paul B Mahol
8 + * This file is part of FFmpeg.
10 + * FFmpeg is free software; you can redistribute it and/or
11 + * modify it under the terms of the GNU Lesser General Public
12 + * License as published by the Free Software Foundation; either
13 + * version 2.1 of the License, or (at your option) any later version.
15 + * FFmpeg is distributed in the hope that it will be useful,
16 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 + * Lesser General Public License for more details.
20 + * You should have received a copy of the GNU Lesser General Public
21 + * License along with FFmpeg; if not, write to the Free Software
22 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
26 +#include "bytestream.h"
27 +#include "internal.h"
29 +typedef struct PCMBDContext {
30 + uint8_t header[4]; // Header added to every frame
31 + int block_size; // Size of a block of samples in bytes
32 + int samples_per_block; // Number of samples per channel per block
33 + int groups_per_block; // Number of 20/24-bit sample groups per block
34 + uint8_t *extra_samples; // Pointer to leftover samples from a frame
35 + int extra_sample_count; // Number of leftover samples in the buffer
38 +static av_cold int pcm_bd_encode_init(AVCodecContext *avctx)
40 + PCMBDContext *s = avctx->priv_data;
42 + uint16_t frame_size;
43 + uint8_t ch_layout = 0;
45 + switch (avctx->sample_rate) {
57 + switch (avctx->sample_fmt) {
58 + case AV_SAMPLE_FMT_S16:
59 + avctx->bits_per_coded_sample = 16;
62 +/* case AV_SAMPLE_FMT_S20:
63 + avctx->bits_per_coded_sample = 20;
67 + case AV_SAMPLE_FMT_S32:
68 + avctx->bits_per_coded_sample = 24;
73 + avctx->block_align = avctx->channels * avctx->bits_per_coded_sample / 8;
74 + avctx->bit_rate = avctx->block_align * 8LL * avctx->sample_rate;
75 + if (avctx->bit_rate > 19800000) {
76 + av_log(avctx, AV_LOG_ERROR, "Too big bitrate: reduce sample rate, bitdepth or channels.\n");
77 + return AVERROR(EINVAL);
80 + if (avctx->sample_fmt == AV_SAMPLE_FMT_S16) {
81 + switch (avctx->channels) {
83 + s->block_size = avctx->channels * 4;
86 + s->block_size = avctx->channels * 2;
89 + s->samples_per_block = 1;
90 + frame_size = 2008 / s->block_size;
92 + switch (avctx->channels) {
94 + s->block_size = 2 * avctx->channels * avctx->bits_per_coded_sample / 8;
95 + s->samples_per_block = 1;
99 + /* one group has all the samples needed */
100 + s->block_size = avctx->channels * avctx->bits_per_coded_sample / 8;
101 + s->samples_per_block = 1;
102 + s->groups_per_block = 2;
106 + /* two groups have all the samples needed */
107 + s->block_size = avctx->channels * avctx->bits_per_coded_sample / 8;
108 + s->samples_per_block = 1;
109 + // s->groups_per_block = 2;
112 + /* need avctx->channels groups */
113 + s->block_size = 4 * avctx->channels *
114 + avctx->bits_per_coded_sample / 8;
115 + s->samples_per_block = 4;
116 + s->groups_per_block = avctx->channels;
120 + frame_size = FFALIGN(2008 / s->block_size, s->samples_per_block);
123 + switch(avctx->channel_layout) {
124 + case AV_CH_LAYOUT_MONO:
127 + case AV_CH_LAYOUT_STEREO:
130 + case AV_CH_LAYOUT_5POINT1:
131 + case AV_CH_LAYOUT_5POINT1_BACK:
134 + case AV_CH_LAYOUT_7POINT1:
138 + av_log(avctx, AV_LOG_ERROR, "Not yet implemented ch layout!\n");
140 +// description on the web:
141 +/* http://forum.doom9.org/showthread.php?t=152897
145 +size in bytes = 16 bits (big endian)
146 +channel assignment = 4 bits
147 +sampling frequency = 4 bits
148 +bits per sample = 2 bits
175 + s->header[2] = (ch_layout << 4) | (freq);
176 + s->header[3] = (quant << 6) | 0x1 ;
179 + avctx->frame_size = frame_size; // in num. of samples
184 +static int pcm_bd_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
185 + const AVFrame *frame, int *got_packet_ptr)
187 + PCMBDContext *s = avctx->priv_data;
188 + int samples, channels;
189 + int64_t pkt_size = (frame->nb_samples / s->samples_per_block) * s->block_size + 4;
190 + const int16_t *src16;
191 + const int32_t *src32;
195 + if ((ret = ff_alloc_packet2(avctx, avpkt, pkt_size, 0)) < 0)
198 + AV_WB16(s->header, pkt_size - 4);
199 + memcpy(avpkt->data, s->header, 4);
201 + src16 = (const int16_t *)frame->data[0];
202 + src32 = (const int32_t *)frame->data[0];
204 + bytestream2_init_writer(&pb, avpkt->data + 4, avpkt->size - 4);
206 + int num_source_channels = FFALIGN(avctx->channels, 2);
207 + // int num_source_channels = avctx->channels;
208 + // int sample_size = (num_source_channels *
209 + // (avctx->sample_fmt == AV_SAMPLE_FMT_S16 ? 16 : 24)) >> 3;
210 + samples = frame->nb_samples * num_source_channels;
212 + switch (avctx->sample_fmt) {
213 + case AV_SAMPLE_FMT_S16:
214 + switch (avctx->channels) {
218 + channels = avctx->channels;
219 + bytestream2_put_be16(&pb, *src16++);
220 + } while (--channels);
221 + bytestream2_put_be16(&pb, 0);
222 + } while (--samples);
226 + bytestream2_put_be16(&pb, *src16++);
227 + } while (--samples);
231 + bytestream2_put_be16(&pb, src16[0]);
232 + bytestream2_put_be16(&pb, src16[1]);
233 + bytestream2_put_be16(&pb, src16[2]);
234 + bytestream2_put_be16(&pb, src16[4]);
235 + bytestream2_put_be16(&pb, src16[5]);
236 + bytestream2_put_be16(&pb, src16[3]);
238 + } while (--samples);
242 + bytestream2_put_be16(&pb, src16[0]);
243 + bytestream2_put_be16(&pb, src16[1]);
244 + bytestream2_put_be16(&pb, src16[2]);
245 + bytestream2_put_be16(&pb, src16[6]);
246 + bytestream2_put_be16(&pb, src16[4]);
247 + bytestream2_put_be16(&pb, src16[5]);
248 + bytestream2_put_be16(&pb, src16[7]);
249 + bytestream2_put_be16(&pb, src16[3]);
251 + } while (--samples);
255 + av_log(avctx, AV_LOG_ERROR, "this ch config not implemented for s16!\n");
259 + case AV_SAMPLE_FMT_S32:
260 + switch (avctx->channels) {
264 + bytestream2_put_be24(&pb, (*src32++) >> 8);
265 + } while (--samples);
269 + bytestream2_put_be24(&pb, src32[0] >> 8);
270 + bytestream2_put_be24(&pb, src32[1] >> 8);
271 + bytestream2_put_be24(&pb, src32[2] >> 8);
272 + bytestream2_put_be24(&pb, src32[6] >> 8);
273 + bytestream2_put_be24(&pb, src32[4] >> 8);
274 + bytestream2_put_be24(&pb, src32[5] >> 8);
275 + bytestream2_put_be24(&pb, src32[7] >> 8);
276 + bytestream2_put_be24(&pb, src32[3] >> 8);
278 + } while (--samples);
282 + bytestream2_put_be24(&pb, src32[0] >> 8);
283 + bytestream2_put_be24(&pb, src32[1] >> 8);
284 + bytestream2_put_be24(&pb, src32[2] >> 8);
285 + bytestream2_put_be24(&pb, src32[4] >> 8);
286 + bytestream2_put_be24(&pb, src32[5] >> 8);
287 + bytestream2_put_be24(&pb, src32[3] >> 8);
289 + } while (--samples);
294 + channels = avctx->channels;
295 + bytestream2_put_be24(&pb, (*src32++) >> 8);
296 + } while (--channels);
297 + bytestream2_put_be24(&pb, 0);
298 + } while (--samples);
301 + av_log(avctx, AV_LOG_ERROR, "this bitdepth not implemented!\n");
307 + avpkt->pts = frame->pts;
308 + avpkt->size = pkt_size;
309 + avpkt->duration = ff_samples_to_time_base(avctx, frame->nb_samples);
310 + *got_packet_ptr = 1;
315 +AVCodec ff_pcm_bluray_encoder = {
316 + .name = "pcm_bluray",
317 + .long_name = NULL_IF_CONFIG_SMALL("PCM signed 16|24-bit big-endian for bluray media"),
318 + .type = AVMEDIA_TYPE_AUDIO,
319 + .id = AV_CODEC_ID_PCM_BLURAY,
320 + .priv_data_size = sizeof(PCMBDContext),
321 + .init = pcm_bd_encode_init,
322 + .encode2 = pcm_bd_encode_frame,
323 + .capabilities = AV_CODEC_CAP_SMALL_LAST_FRAME,
324 + .supported_samplerates = (const int[]) { 48000, 96000, 192000, 0},
325 + .channel_layouts = (const uint64_t[]) { AV_CH_LAYOUT_MONO,
326 + AV_CH_LAYOUT_STEREO,
327 + AV_CH_LAYOUT_5POINT1,
328 + AV_CH_LAYOUT_5POINT1_BACK,
329 + AV_CH_LAYOUT_7POINT1,
331 + .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16,
333 + AV_SAMPLE_FMT_NONE },
334 + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
336 --- ./libavcodec/allcodecs.orig 2021-04-09 00:28:39.000000000 +0300
337 +++ ./libavcodec/allcodecs.c 2021-12-06 15:45:03.333762281 +0300
340 extern AVCodec ff_pcm_alaw_encoder;
341 extern AVCodec ff_pcm_alaw_decoder;
342 +extern AVCodec ff_pcm_bluray_encoder;
343 extern AVCodec ff_pcm_bluray_decoder;
344 extern AVCodec ff_pcm_dvd_encoder;
345 extern AVCodec ff_pcm_dvd_decoder;
346 --- ./libavcodec/Makefile.orig 2021-04-09 00:28:39.000000000 +0300
347 +++ ./libavcodec/Makefile 2021-12-06 21:11:19.365842066 +0300
349 OBJS-$(CONFIG_PCM_ALAW_DECODER) += pcm.o
350 OBJS-$(CONFIG_PCM_ALAW_ENCODER) += pcm.o
351 OBJS-$(CONFIG_PCM_BLURAY_DECODER) += pcm-bluray.o
352 +OBJS-$(CONFIG_PCM_BLURAY_ENCODER) += pcm-bluenc.o
353 OBJS-$(CONFIG_PCM_DVD_DECODER) += pcm-dvd.o
354 OBJS-$(CONFIG_PCM_DVD_ENCODER) += pcm-dvdenc.o
355 OBJS-$(CONFIG_PCM_F16LE_DECODER) += pcm.o