From: Good Guy Date: Thu, 28 Apr 2022 14:38:57 +0000 (-0600) Subject: lpcm with tsmuxer cleanup by Andrew X-Git-Tag: 2022-04~1 X-Git-Url: https://git.cinelerra-gg.org/git/?a=commitdiff_plain;h=6a349d153f1a6e7060fabf71b2856c2a5eaa4f56;p=goodguy%2Fcinelerra.git lpcm with tsmuxer cleanup by Andrew --- diff --git a/cinelerra-5.1/cinelerra/bdcreate.C b/cinelerra-5.1/cinelerra/bdcreate.C index 61362cfc..dd1dd19a 100644 --- a/cinelerra-5.1/cinelerra/bdcreate.C +++ b/cinelerra-5.1/cinelerra/bdcreate.C @@ -962,6 +962,7 @@ void CreateBD_GUI::update() need_wide_audio->set_value(thread->use_wide_audio); need_labeled->set_value(thread->use_labeled); need_farmed->set_value(thread->use_farmed); + need_tsmuxer->set_value(thread->use_tsmuxer); } int CreateBD_Thread:: @@ -1011,6 +1012,7 @@ option_presets() use_wide_audio = 0; use_labeled = 0; use_farmed = 0; + use_tsmuxer = 0; if( !mwindow->edl ) return 1; @@ -1219,6 +1221,7 @@ CreateBD_Profile::CreateBD_Profile(CreateBD_GUI *gui, int x, int y) : BC_PopupTextBox(gui, 0, 0, x, y, xS(170),yS(50)) { this->gui = gui; + strcpy(gui->thread->use_profile, "bluray.m2ts"); } CreateBD_Profile::~CreateBD_Profile() diff --git a/cinelerra-5.1/thirdparty/src/ffmpeg-4.4.patch_99 b/cinelerra-5.1/thirdparty/src/ffmpeg-4.4.patch_99 new file mode 100644 index 00000000..6a66ff20 --- /dev/null +++ b/cinelerra-5.1/thirdparty/src/ffmpeg-4.4.patch_99 @@ -0,0 +1,574 @@ +--- 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 = 120; ++ quant =1; ++ break; ++ case AV_SAMPLE_FMT_S32: ++ avctx->bits_per_coded_sample = 24; ++ frame_size = 180; ++ 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, */ ++ 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, + };