From 66e7bfbe53eba53997f1121027394b64ffecdace Mon Sep 17 00:00:00 2001 From: Good Guy Date: Tue, 12 Apr 2022 17:04:12 -0600 Subject: [PATCH] add bluray lpcm + from Andrew --- cinelerra-5.1/ffmpeg/audio/bluray_lpcm.m2ts | 2 + cinelerra-5.1/guicast/thread.C | 4 +- .../thirdparty/src/ffmpeg-4.4.patch_9 | 355 ++++++++++++++++++ 3 files changed, 360 insertions(+), 1 deletion(-) create mode 100644 cinelerra-5.1/ffmpeg/audio/bluray_lpcm.m2ts create mode 100644 cinelerra-5.1/thirdparty/src/ffmpeg-4.4.patch_9 diff --git a/cinelerra-5.1/ffmpeg/audio/bluray_lpcm.m2ts b/cinelerra-5.1/ffmpeg/audio/bluray_lpcm.m2ts new file mode 100644 index 00000000..284f433a --- /dev/null +++ b/cinelerra-5.1/ffmpeg/audio/bluray_lpcm.m2ts @@ -0,0 +1,2 @@ +bluray pcm_bluray +id 0x1100 diff --git a/cinelerra-5.1/guicast/thread.C b/cinelerra-5.1/guicast/thread.C index 9908a628..edac1451 100644 --- a/cinelerra-5.1/guicast/thread.C +++ b/cinelerra-5.1/guicast/thread.C @@ -58,13 +58,15 @@ void* Thread::entrypoint(void *parameters) pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); thread->cancel_enabled = false; +// not on bsd +#if defined (__linux__) || defined (__TERMUX__) // Set realtime here since it doesn't work in start if( thread->realtime && getuid() == 0 ) { struct sched_param param = { sched_priority : 1 }; if(pthread_setschedparam(thread->tid, SCHED_RR, ¶m) < 0) perror("Thread::entrypoint pthread_attr_setschedpolicy"); } - +#endif thread->run(); thread->finished = true; if( !thread->synchronous ) { 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 index 00000000..f973f2fc --- /dev/null +++ b/cinelerra-5.1/thirdparty/src/ffmpeg-4.4.patch_9 @@ -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 -- 2.26.2