Attempt at utilizing tsmuxer depending on checkbox in BD creation window.

(tsmuxer should avoid whole loop mounting/unmounting root requrement.. and
support more features like HEVC muxing, arbitrary delay/chapters..)
From 2fb78df84706bcb81468cade583531f170591971 Mon Sep 17 00:00:00 2001
From: Andrew Randrianasulu <randrianas...@gmail.com>
Date: Wed, 8 Dec 2021 15:50:09 +0300
Subject: [PATCH 01/24] ffmpeg 4.4 bluray lpcm encoder

---
 .../thirdparty/src/ffmpeg-4.4.patch_9         | 353 ++++++++++++++++++
 1 file changed, 353 insertions(+)
 create mode 100644 cinelerra-5.1/thirdparty/src/ffmpeg-4.4.patch_9

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..717f0bd3
--- /dev/null
+++ b/cinelerra-5.1/thirdparty/src/ffmpeg-4.4.patch_9
@@ -0,0 +1,353 @@
+--- /dev/null	2021-12-05 17:02:04.576000000 +0300
++++ ./libavcodec/pcm-bluenc.c	2021-12-08 13:28:00.778956966 +0300
+@@ -0,0 +1,330 @@
++/*
++ * 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:
++		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_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.34.1

From c30bfcc81d7ad0bd129355f33b9b8b738250454d Mon Sep 17 00:00:00 2001
From: Andrew Randrianasulu <randrianas...@gmail.com>
Date: Wed, 8 Dec 2021 16:55:22 +0300
Subject: [PATCH 03/24] Add simple m2ts lpcm profile

---
 cinelerra-5.1/ffmpeg/audio/m2ts_pcm.m2ts | 2 ++
 1 file changed, 2 insertions(+)
 create mode 100644 cinelerra-5.1/ffmpeg/audio/m2ts_pcm.m2ts

diff --git a/cinelerra-5.1/ffmpeg/audio/m2ts_pcm.m2ts b/cinelerra-5.1/ffmpeg/audio/m2ts_pcm.m2ts
new file mode 100644
index 00000000..284f433a
--- /dev/null
+++ b/cinelerra-5.1/ffmpeg/audio/m2ts_pcm.m2ts
@@ -0,0 +1,2 @@
+bluray pcm_bluray
+id 0x1100
-- 
2.34.1

From c6b41cccc2e85900ac9351c4566d51c899a68202 Mon Sep 17 00:00:00 2001
From: Andrew Randrianasulu <randrianas...@gmail.com>
Date: Wed, 8 Dec 2021 16:53:43 +0300
Subject: [PATCH 02/24] Fix ffmpeg 4.4 bluray lpcm patch for 5.1 ?

---
 cinelerra-5.1/thirdparty/src/ffmpeg-4.4.patch_9 | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/cinelerra-5.1/thirdparty/src/ffmpeg-4.4.patch_9 b/cinelerra-5.1/thirdparty/src/ffmpeg-4.4.patch_9
index 717f0bd3..f973f2fc 100644
--- a/cinelerra-5.1/thirdparty/src/ffmpeg-4.4.patch_9
+++ b/cinelerra-5.1/thirdparty/src/ffmpeg-4.4.patch_9
@@ -1,6 +1,6 @@
 --- /dev/null	2021-12-05 17:02:04.576000000 +0300
-+++ ./libavcodec/pcm-bluenc.c	2021-12-08 13:28:00.778956966 +0300
-@@ -0,0 +1,330 @@
++++ ./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
@@ -128,6 +128,7 @@
 +		ch_layout = 3;
 +		break;
 +	case AV_CH_LAYOUT_5POINT1:
++	case AV_CH_LAYOUT_5POINT1_BACK:
 +		ch_layout = 9;
 +		break;
 +	case AV_CH_LAYOUT_7POINT1:
@@ -324,6 +325,7 @@
 +    .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,
-- 
2.34.1

From d756c6fb9e44b3bd52aef91af66bcef664589b41 Mon Sep 17 00:00:00 2001
From: Andrew Randrianasulu <randrianas...@gmail.com>
Date: Fri, 17 Dec 2021 02:56:49 +0300
Subject: [PATCH 08/24] EXPERIMENTAL: add variable chapter interval to bdwrite

---
 cinelerra-5.1/cinelerra/bdwrite.C | 21 +++++++++++++++------
 1 file changed, 15 insertions(+), 6 deletions(-)

diff --git a/cinelerra-5.1/cinelerra/bdwrite.C b/cinelerra-5.1/cinelerra/bdwrite.C
index b184e0c6..a2131251 100644
--- a/cinelerra-5.1/cinelerra/bdwrite.C
+++ b/cinelerra-5.1/cinelerra/bdwrite.C
@@ -1219,7 +1219,7 @@ public:
   ArrayList<mpls_pl *> pl;
 
   void add_movie(uint32_t *ops, int n);
-  int compose();
+  int compose(int ch_interval);
   int write(char *fn);
 
   Media() { path = 0;  filename[0] = 0; }
@@ -2805,7 +2805,7 @@ Media::add_movie(uint32_t *ops, int n)
 }
 
 int
-Media::compose()
+Media::compose(int ch_interval)
 {
 // movie
   bs.init();
@@ -2978,8 +2978,11 @@ Media::compose()
       }
       pp->play_item.append(pi);
     }
-// chapter marks every ch_duration ticks
-    int64_t ch_duration = 45000 * 60*5;
+// chapter marks every ch_duration ticks, default 5 min
+    int PCR_FREQ = 45000;
+    if (ch_interval == 0)
+    ch_interval = 60*5;
+    int64_t ch_duration = PCR_FREQ * ch_interval;
     int64_t mrktm = ch_duration;
     int64_t plytm = 0;
     int pmark = 0, pitem = 0;
@@ -3156,8 +3159,14 @@ main(int ac, char **av)
   //av_log_set_level(AV_LOG_DEBUG);
   Media media;
   media_info *mp = 0;
+  int start, chapter_every_n_sec;
+  
+  if (strcmp (av[2], "c")) {
+  chapter_every_n_sec = optarg[0]; start = 3; }
+  else
+  start = 2;
 
-  for( int ii=2; ii<ac; ++ii ) {
+  for( int ii=start; ii<ac; ++ii ) {
     char *ap = av[ii];
     // any dash seq followed by number sets curr title pgm_pid
     // single dash only sets title pgm_pid
@@ -3188,7 +3197,7 @@ main(int ac, char **av)
 
   if( mp ) mp->brk = 1;
 
-  if( media.compose() ) {
+  if( media.compose(chapter_every_n_sec) ) {
     fprintf(stderr, "cant compose media\n");
     return 1;
   }
-- 
2.34.1

From cb16d676d6333a0248d0be0c9a0fa642bdbb22d9 Mon Sep 17 00:00:00 2001
From: Andrew Randrianasulu <randrianas...@gmail.com>
Date: Fri, 10 Dec 2021 17:26:40 +0300
Subject: [PATCH 04/24] Improve truehd decoder/encoder from ffmpeg.git

---
 .../thirdparty/src/ffmpeg-4.4.patch_5         | 180 ++++++++++++++++++
 .../thirdparty/src/ffmpeg-4.4.patch_6         |  24 +++
 .../thirdparty/src/ffmpeg-4.4.patch_7         |  41 ++++
 .../thirdparty/src/ffmpeg-4.4.patch_8         |  43 +++++
 4 files changed, 288 insertions(+)
 create mode 100644 cinelerra-5.1/thirdparty/src/ffmpeg-4.4.patch_5
 create mode 100644 cinelerra-5.1/thirdparty/src/ffmpeg-4.4.patch_6
 create mode 100644 cinelerra-5.1/thirdparty/src/ffmpeg-4.4.patch_7
 create mode 100644 cinelerra-5.1/thirdparty/src/ffmpeg-4.4.patch_8

diff --git a/cinelerra-5.1/thirdparty/src/ffmpeg-4.4.patch_5 b/cinelerra-5.1/thirdparty/src/ffmpeg-4.4.patch_5
new file mode 100644
index 00000000..126e51e6
--- /dev/null
+++ b/cinelerra-5.1/thirdparty/src/ffmpeg-4.4.patch_5
@@ -0,0 +1,180 @@
+X-Git-Url: http://git.ffmpeg.org/gitweb/ffmpeg.git/blobdiff_plain/fea4f953b5c6e04b84ce9c11664c9cbcac171a60..9f420163c6207b9c54badd30056974a6b3450bfd:/libavcodec/mlpenc.c
+
+diff --git a/libavcodec/mlpenc.c b/libavcodec/mlpenc.c
+index 8b61fc6b1e..37052d9e38 100644
+--- a/libavcodec/mlpenc.c
++++ b/libavcodec/mlpenc.c
+@@ -103,7 +103,7 @@ typedef struct BestOffset {
+ /** Number of possible codebooks (counting "no codebooks") */
+ #define NUM_CODEBOOKS       4
+
+-typedef struct {
++typedef struct MLPEncodeContext {
+     AVCodecContext *avctx;
+
+     int             num_substreams;         ///< Number of substreams contained within this stream.
+@@ -129,7 +129,8 @@ typedef struct {
+     int32_t        *write_buffer;           ///< Pointer to data currently being written to bitstream.
+     int32_t        *sample_buffer;          ///< Pointer to current access unit samples.
+     int32_t        *major_scratch_buffer;   ///< Scratch buffer big enough to fit all data for one entire major frame interval.
+-    int32_t        *last_frame;             ///< Pointer to last frame with data to encode.
++    int32_t        last_frames;             ///< Signal last frames.
++    int32_t        last_index;
+
+     int32_t        *lpc_sample_buffer;
+
+@@ -201,6 +202,10 @@ typedef struct {
+
+     unsigned int    max_codebook_search;
+
++    int             shorten_by;
++
++    int64_t         pts;
++
+     LPCContext      lpc_ctx;
+ } MLPEncodeContext;
+
+@@ -1116,9 +1121,13 @@ static uint8_t *write_substrs(MLPEncodeContext *ctx, uint8_t *buf, int buf_size,
+
+         rh->lossless_check_data ^= *lossless_check_data++;
+
+-        if (ctx->last_frame == ctx->inout_buffer) {
+-            /* TODO find a sample and implement shorten_by. */
+-            put_bits(&pb, 32, END_OF_STREAM);
++        if (ctx->last_frames == 0 && ctx->shorten_by) {
++            if (ctx->avctx->codec_id == AV_CODEC_ID_TRUEHD) {
++                put_bits(&pb, 16, END_OF_STREAM & 0xFFFF);
++                put_bits(&pb, 16, (ctx->shorten_by & 0x1FFF) | 0x2000);
++            } else {
++                put_bits(&pb, 32, END_OF_STREAM);
++            }
+         }
+
+         /* Data must be flushed for the checksum and parity to be correct;
+@@ -2216,42 +2225,35 @@ static int mlp_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
+     int restart_frame, ret;
+     uint8_t *data;
+
++    if (!frame && !ctx->last_frames--)
++        return 0;
++
+     if ((ret = ff_alloc_packet2(avctx, avpkt, 87500 * avctx->channels, 0)) < 0)
+         return ret;
+
+-    /* add current frame to queue */
+-    if ((ret = ff_af_queue_add(&ctx->afq, frame)) < 0)
+-        return ret;
++    if (frame) {
++        /* add current frame to queue */
++        if ((ret = ff_af_queue_add(&ctx->afq, frame)) < 0)
++            return ret;
++        ctx->last_frames = ctx->max_restart_interval;
++        ctx->last_index = ctx->frame_index;
++    }
+
+-    data = frame->data[0];
++    data = frame ? frame->data[0] : NULL;
+
+     ctx->frame_index = avctx->frame_number % ctx->max_restart_interval;
+
+     ctx->inout_buffer = ctx->major_inout_buffer
+                       + ctx->frame_index * ctx->one_sample_buffer_size;
+
+-    if (ctx->last_frame == ctx->inout_buffer) {
+-        return 0;
+-    }
+-
+     ctx->sample_buffer = ctx->major_scratch_buffer
+                        + ctx->frame_index * ctx->one_sample_buffer_size;
+
+     ctx->write_buffer = ctx->inout_buffer;
+
+     if (avctx->frame_number < ctx->max_restart_interval) {
+-        if (data) {
++        if (data)
+             goto input_and_return;
+-        } else {
+-            /* There are less frames than the requested major header interval.
+-             * Update the context to reflect this.
+-             */
+-            ctx->max_restart_interval = avctx->frame_number;
+-            ctx->frame_index = 0;
+-
+-            ctx->sample_buffer = ctx->major_scratch_buffer;
+-            ctx->inout_buffer = ctx->major_inout_buffer;
+-        }
+     }
+
+     if (ctx->frame_size[ctx->frame_index] > MAX_BLOCKSIZE) {
+@@ -2278,14 +2280,13 @@ static int mlp_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
+
+ input_and_return:
+
+-    if (data) {
+-        ctx->frame_size[ctx->frame_index] = avctx->frame_size;
+-        ctx->next_major_frame_size += avctx->frame_size;
+-        ctx->next_major_number_of_frames++;
++    if (frame)
++        ctx->shorten_by = avctx->frame_size - frame->nb_samples;
++    ctx->frame_size[ctx->frame_index] = avctx->frame_size;
++    ctx->next_major_frame_size += avctx->frame_size;
++    ctx->next_major_number_of_frames++;
++    if (data)
+         input_data(ctx, data);
+-    } else if (!ctx->last_frame) {
+-        ctx->last_frame = ctx->inout_buffer;
+-    }
+
+     restart_frame = (ctx->frame_index + 1) % ctx->min_restart_interval;
+
+@@ -2315,10 +2316,11 @@ input_and_return:
+                                        (ctx->frame_index / ctx->min_restart_interval)*(ctx->sequence_size)*(ctx->num_substreams) +
+                                        (ctx->seq_offset[seq_index])*(ctx->num_substreams);
+
+-            for (index = 0; index < ctx->number_of_frames; index++) {
++            for (index = 0; index < ctx->number_of_frames; index++)
+                 number_of_samples += ctx->frame_size[(ctx->starting_frame_index + index) % ctx->max_restart_interval];
+-            }
+             ctx->number_of_samples = number_of_samples;
++            if (!ctx->number_of_samples)
++                break;
+
+             for (index = 0; index < ctx->seq_size[seq_index]; index++) {
+                 clear_channel_params(ctx->seq_channel_params + index * ctx->avctx->channels, ctx->avctx->channels);
+@@ -2343,8 +2345,16 @@ input_and_return:
+
+ no_data_left:
+
+-    ff_af_queue_remove(&ctx->afq, avctx->frame_size, &avpkt->pts,
+-                       &avpkt->duration);
++    if (ctx->afq.frame_count > 0) {
++        ff_af_queue_remove(&ctx->afq, avctx->frame_size, &avpkt->pts,
++                           &avpkt->duration);
++        ctx->pts = avpkt->pts + avpkt->duration;
++    } else {
++        avpkt->pts = ctx->pts;
++        ctx->pts += avctx->frame_size;
++    }
++    if (!frame)
++        avctx->frame_number++;
+     avpkt->size = bytes_written;
+     *got_packet = 1;
+     return 0;
+@@ -2379,7 +2389,7 @@ const AVCodec ff_mlp_encoder = {
+     .init                   = mlp_encode_init,
+     .encode2                = mlp_encode_frame,
+     .close                  = mlp_encode_close,
+-    .capabilities           = AV_CODEC_CAP_SMALL_LAST_FRAME | AV_CODEC_CAP_EXPERIMENTAL,
++    .capabilities           = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_EXPERIMENTAL,
+     .sample_fmts            = (const enum AVSampleFormat[]) {AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE},
+     .supported_samplerates  = (const int[]) {44100, 48000, 88200, 96000, 176400, 192000, 0},
+     .channel_layouts        = ff_mlp_channel_layouts,
+@@ -2396,7 +2406,7 @@ const AVCodec ff_truehd_encoder = {
+     .init                   = mlp_encode_init,
+     .encode2                = mlp_encode_frame,
+     .close                  = mlp_encode_close,
+-    .capabilities           = AV_CODEC_CAP_SMALL_LAST_FRAME | AV_CODEC_CAP_EXPERIMENTAL,
++    .capabilities           = AV_CODEC_CAP_SMALL_LAST_FRAME | AV_CODEC_CAP_DELAY | AV_CODEC_CAP_EXPERIMENTAL,
+     .sample_fmts            = (const enum AVSampleFormat[]) {AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE},
+     .supported_samplerates  = (const int[]) {44100, 48000, 88200, 96000, 176400, 192000, 0},
+     .channel_layouts        = (const uint64_t[]) {AV_CH_LAYOUT_STEREO, AV_CH_LAYOUT_5POINT0_BACK, AV_CH_LAYOUT_5POINT1_BACK, 0},
diff --git a/cinelerra-5.1/thirdparty/src/ffmpeg-4.4.patch_6 b/cinelerra-5.1/thirdparty/src/ffmpeg-4.4.patch_6
new file mode 100644
index 00000000..3c0b4352
--- /dev/null
+++ b/cinelerra-5.1/thirdparty/src/ffmpeg-4.4.patch_6
@@ -0,0 +1,24 @@
+X-Git-Url: http://git.ffmpeg.org/gitweb/ffmpeg.git/blobdiff_plain/61c2c9ef8e66920c8ba308e8fa9f36ae602f8245..2bb9d2be5e2e1d971e5b80358098f2a7fce06e0e:/libavcodec/mlpenc.c
+
+diff --git a/libavcodec/mlpenc.c b/libavcodec/mlpenc.c
+index 37052d9e38..443cb41cf5 100644
+--- a/libavcodec/mlpenc.c
++++ b/libavcodec/mlpenc.c
+@@ -2390,7 +2390,7 @@ const AVCodec ff_mlp_encoder = {
+     .encode2                = mlp_encode_frame,
+     .close                  = mlp_encode_close,
+     .capabilities           = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_EXPERIMENTAL,
+-    .sample_fmts            = (const enum AVSampleFormat[]) {AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE},
++    .sample_fmts            = (const enum AVSampleFormat[]) {AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_NONE},
+     .supported_samplerates  = (const int[]) {44100, 48000, 88200, 96000, 176400, 192000, 0},
+     .channel_layouts        = ff_mlp_channel_layouts,
+     .caps_internal          = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
+@@ -2407,7 +2407,7 @@ const AVCodec ff_truehd_encoder = {
+     .encode2                = mlp_encode_frame,
+     .close                  = mlp_encode_close,
+     .capabilities           = AV_CODEC_CAP_SMALL_LAST_FRAME | AV_CODEC_CAP_DELAY | AV_CODEC_CAP_EXPERIMENTAL,
+-    .sample_fmts            = (const enum AVSampleFormat[]) {AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE},
++    .sample_fmts            = (const enum AVSampleFormat[]) {AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_NONE},
+     .supported_samplerates  = (const int[]) {44100, 48000, 88200, 96000, 176400, 192000, 0},
+     .channel_layouts        = (const uint64_t[]) {AV_CH_LAYOUT_STEREO, AV_CH_LAYOUT_5POINT0_BACK, AV_CH_LAYOUT_5POINT1_BACK, 0},
+     .caps_internal          = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
diff --git a/cinelerra-5.1/thirdparty/src/ffmpeg-4.4.patch_7 b/cinelerra-5.1/thirdparty/src/ffmpeg-4.4.patch_7
new file mode 100644
index 00000000..2203a3a9
--- /dev/null
+++ b/cinelerra-5.1/thirdparty/src/ffmpeg-4.4.patch_7
@@ -0,0 +1,41 @@
+X-Git-Url: http://git.ffmpeg.org/gitweb/ffmpeg.git/blobdiff_plain/a4c98c507ed3c729fc92d641b974385f8aa37b33..5673a4842556b79a92a1ede6e9696506fd4161ad:/libavcodec/mlpdec.c
+
+diff --git a/libavcodec/mlpdec.c b/libavcodec/mlpdec.c
+index e4992550ee..0fac5ad754 100644
+--- a/libavcodec/mlpdec.c
++++ b/libavcodec/mlpdec.c
+@@ -1330,6 +1330,18 @@ error:
+     return AVERROR_INVALIDDATA;
+ }
+
++static void mlp_decode_flush(AVCodecContext *avctx)
++{
++    MLPDecodeContext *m = avctx->priv_data;
++
++    m->params_valid = 0;
++    for (int substr = 0; substr <= m->max_decoded_substream; substr++){
++        SubStream *s = &m->substream[substr];
++
++        s->lossless_check_data = 0xffffffff;
++    }
++}
++
+ #if CONFIG_MLP_DECODER
+ const AVCodec ff_mlp_decoder = {
+     .name           = "mlp",
+@@ -1339,6 +1351,7 @@ const AVCodec ff_mlp_decoder = {
+     .priv_data_size = sizeof(MLPDecodeContext),
+     .init           = mlp_decode_init,
+     .decode         = read_access_unit,
++    .flush          = mlp_decode_flush,
+     .capabilities   = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF,
+     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
+ };
+@@ -1352,6 +1365,7 @@ const AVCodec ff_truehd_decoder = {
+     .priv_data_size = sizeof(MLPDecodeContext),
+     .init           = mlp_decode_init,
+     .decode         = read_access_unit,
++    .flush          = mlp_decode_flush,
+     .capabilities   = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF,
+     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
+ };
diff --git a/cinelerra-5.1/thirdparty/src/ffmpeg-4.4.patch_8 b/cinelerra-5.1/thirdparty/src/ffmpeg-4.4.patch_8
new file mode 100644
index 00000000..c59a5ee8
--- /dev/null
+++ b/cinelerra-5.1/thirdparty/src/ffmpeg-4.4.patch_8
@@ -0,0 +1,43 @@
+X-Git-Url: http://git.ffmpeg.org/gitweb/ffmpeg.git/blobdiff_plain/9f420163c6207b9c54badd30056974a6b3450bfd..034133a0df5f327aba36ee25db9452cda9e1a62b:/libavcodec/mlpdec.c
+
+diff --git a/libavcodec/mlpdec.c b/libavcodec/mlpdec.c
+index 0fac5ad754..08db5dc63c 100644
+--- a/libavcodec/mlpdec.c
++++ b/libavcodec/mlpdec.c
+@@ -53,6 +53,8 @@
+ typedef struct SubStream {
+     /// Set if a valid restart header has been read. Otherwise the substream cannot be decoded.
+     uint8_t     restart_seen;
++    /// Set if end of stream is encountered
++    uint8_t     end_of_stream;
+
+     //@{
+     /** restart header data */
+@@ -1286,8 +1288,8 @@ static int read_access_unit(AVCodecContext *avctx, void* data,
+             else if (m->avctx->codec_id == AV_CODEC_ID_MLP    && shorten_by != 0xD234)
+                 return AVERROR_INVALIDDATA;
+
+-            if (substr == m->max_decoded_substream)
+-                av_log(m->avctx, AV_LOG_INFO, "End of stream indicated.\n");
++            av_log(m->avctx, AV_LOG_DEBUG, "End of stream indicated.\n");
++            s->end_of_stream = 1;
+         }
+
+         if (substream_parity_present[substr]) {
+@@ -1319,6 +1321,16 @@ next_substr:
+     if ((ret = output_data(m, m->max_decoded_substream, data, got_frame_ptr)) < 0)
+         return ret;
+
++    for (substr = 0; substr <= m->max_decoded_substream; substr++){
++        SubStream *s = &m->substream[substr];
++
++        if (s->end_of_stream) {
++            s->lossless_check_data = 0xffffffff;
++            s->end_of_stream = 0;
++            m->params_valid = 0;
++        }
++    }
++
+     return length;
+
+ substream_length_mismatch:
-- 
2.34.1

From 21cbbdc3e70873997a553f03e019f8235f1ed203 Mon Sep 17 00:00:00 2001
From: Andrew Randrianasulu <randrianas...@gmail.com>
Date: Fri, 17 Dec 2021 04:26:11 +0300
Subject: [PATCH 10/24] EXPERIMENTAL: bdcreate: add m2ts profiles, part 1

---
 cinelerra-5.1/cinelerra/bdcreate.C   | 31 ++++++++++++++++++++++++++++
 cinelerra-5.1/cinelerra/bdcreate.h   | 14 +++++++++++++
 cinelerra-5.1/cinelerra/bdcreate.inc |  1 +
 3 files changed, 46 insertions(+)

diff --git a/cinelerra-5.1/cinelerra/bdcreate.C b/cinelerra-5.1/cinelerra/bdcreate.C
index 20a953e2..67745a8d 100644
--- a/cinelerra-5.1/cinelerra/bdcreate.C
+++ b/cinelerra-5.1/cinelerra/bdcreate.C
@@ -66,6 +66,7 @@ static struct bd_profile {
 	const char *name;
 } bd_profiles[] = {
 	{"bluray.m2ts"},
+	{"bluray_lpcm.m2ts"},
 };
 
 
@@ -211,6 +212,7 @@ CreateBD_Thread::CreateBD_Thread(MWindow *mwindow)
 	this->use_resize_tracks = 0;
 	this->use_labeled = 0;
 	this->use_farmed = 0;
+	this->use_termux = 0;
 
 	this->bd_size = BD_SIZE;
 	this->bd_width = BD_WIDTH;
@@ -453,6 +455,7 @@ BC_Window* CreateBD_Thread::new_gui()
 	use_resize_tracks = 0;
 	use_labeled = 0;
 	use_farmed = 0;
+	use_termux = 0;
 	use_standard = !strcmp(mwindow->default_std(),"NTSC") ?
 		 BD_1920x1080_2997i : BD_1920x1080_25i;
 	bd_size = BD_SIZE;
@@ -728,6 +731,7 @@ CreateBD_GUI::CreateBD_GUI(CreateBD_Thread *thread, int x, int y, int w, int h)
 	disk_space = 0;
 	standard = 0;
 	scale = 0;
+	profile = 0;
 	need_deinterlace = 0;
 	need_inverse_telecine = 0;
 	need_resize_tracks = 0;
@@ -785,6 +789,18 @@ void CreateBD_GUI::create_objects()
 	media_size->update(media_sizes[0]->get_text());
 	disk_space->update();
 	y += disk_space->get_h() + pady/2;
+	
+	title = new BC_Title(x, y, _("Profile:"), MEDIUMFONT, YELLOW);
+	add_subwindow(title);
+	y +=  title->get_h()+pady;
+	profile = new CreateBD_Profile(this, x1, y);
+	profile->create_objects();
+	profiles.append(new BC_ListBoxItem("bluray.m2ts"));
+	profiles.append(new BC_ListBoxItem("bluray_lpcm.m2ts"));
+	profile->update_list(&profiles);
+	profile->update(profiles[0]->get_text());
+	
+	
 	title = new BC_Title(x, y, _("Format:"), MEDIUMFONT, YELLOW);
 	add_subwindow(title);
 	standard = new CreateBD_Format(this, title->get_w() + padx, y);
@@ -1128,3 +1144,18 @@ int CreateBD_MediaSize::handle_event()
 	return 1;
 }
 
+CreateBD_Profile::CreateBD_Profile(CreateBD_GUI *gui, int x, int y)
+ : BC_PopupTextBox(gui, 0, 0, x, y, xS(70),yS(50))
+{
+	this->gui = gui;
+}
+
+CreateBD_Profile::~CreateBD_Profile()
+{
+}
+
+int CreateBD_Profile::handle_event()
+{
+	return 1;
+}
+
diff --git a/cinelerra-5.1/cinelerra/bdcreate.h b/cinelerra-5.1/cinelerra/bdcreate.h
index 89ee83bb..81f11120 100644
--- a/cinelerra-5.1/cinelerra/bdcreate.h
+++ b/cinelerra-5.1/cinelerra/bdcreate.h
@@ -62,6 +62,7 @@ public:
 	int use_wide_audio, use_farmed;
 	int use_histogram, use_labeled;
 	int use_standard;
+	int use_termux;
 
 	int64_t bd_size;
 	int bd_width;
@@ -232,6 +233,8 @@ public:
 	CreateBD_OK *ok;
 	int cancel_x, cancel_y, cancel_w, cancel_h;
 	CreateBD_Cancel *cancel;
+	ArrayList<BC_ListBoxItem *> profiles;
+	CreateBD_Profile *profile;
 };
 
 class CreateBD_FormatItem : public BC_MenuItem
@@ -290,4 +293,15 @@ public:
 	CreateBD_GUI *gui;
 };
 
+class CreateBD_Profile : public BC_PopupTextBox
+{
+public:
+	CreateBD_Profile(CreateBD_GUI *gui, int x, int y);
+	~CreateBD_Profile();
+	int handle_event();
+
+	CreateBD_GUI *gui;
+};
+
+
 #endif
diff --git a/cinelerra-5.1/cinelerra/bdcreate.inc b/cinelerra-5.1/cinelerra/bdcreate.inc
index d44320c6..5db9568b 100644
--- a/cinelerra-5.1/cinelerra/bdcreate.inc
+++ b/cinelerra-5.1/cinelerra/bdcreate.inc
@@ -41,5 +41,6 @@ class CreateBD_GUI;
 class CreateBD_FormatItem;
 class CreateBD_Format;
 class CreateBD_MediaSize;
+class CreateBD_Profile;
 
 #endif
-- 
2.34.1

From 72da869b22f826e26cc19b4530ee9f97e4b78ab1 Mon Sep 17 00:00:00 2001
From: Andrew Randrianasulu <randrianas...@gmail.com>
Date: Fri, 17 Dec 2021 03:16:44 +0300
Subject: [PATCH 09/24] EXPERIMENTAL: add bd_profile array to bdcreate.C (so in
 future we can diff between encoders)

---
 cinelerra-5.1/cinelerra/bdcreate.C | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/cinelerra-5.1/cinelerra/bdcreate.C b/cinelerra-5.1/cinelerra/bdcreate.C
index 150f835d..20a953e2 100644
--- a/cinelerra-5.1/cinelerra/bdcreate.C
+++ b/cinelerra-5.1/cinelerra/bdcreate.C
@@ -62,6 +62,13 @@ static struct bd_format {
 	{ "720x480   29.97p*",	 720,480,  29.97,  0, ILACE_MODE_NOTINTERLACED },
 };
 
+static struct bd_profile {
+	const char *name;
+} bd_profiles[] = {
+	{"bluray.m2ts"},
+};
+
+
 const int64_t CreateBD_Thread::BD_SIZE = 25000000000;
 const int CreateBD_Thread::BD_STREAMS = 1;
 const int CreateBD_Thread::BD_WIDTH = 1920;
@@ -316,7 +323,7 @@ int CreateBD_Thread::create_bd_jobs(ArrayList<BatchRenderJob*> *jobs, const char
 	strcpy(asset->fformat, "m2ts");
 
 	asset->audio_data = 1;
-	strcpy(asset->acodec, "bluray.m2ts");
+	strcpy(asset->acodec, bd_profiles[0].name);
 	//mwindow->defaults->get("DEFAULT_BLURAY_ACODEC", asset->acodec);
 	FFMPEG::set_option_path(option_path, "audio/%s", asset->acodec);
 	FFMPEG::load_options(option_path, asset->ff_audio_options,
@@ -324,7 +331,7 @@ int CreateBD_Thread::create_bd_jobs(ArrayList<BatchRenderJob*> *jobs, const char
 	asset->ff_audio_bitrate = bd_kaudio_rate * 1000;
 
 	asset->video_data = 1;
-	const char *vcodec = "bluray.m2ts";
+	const char *vcodec = bd_profiles[0].name;
 	switch( asset->interlace_mode ) {
 	case ILACE_MODE_TOP_FIRST:    vcodec = "bluray_tff.m2ts";  break;
 	case ILACE_MODE_BOTTOM_FIRST: vcodec = "bluray_bff.m2ts";  break;
-- 
2.34.1

From 9c32f2bb3c805d3f0a18bf96ea03da6b8a3b9edd Mon Sep 17 00:00:00 2001
From: Andrew Randrianasulu <randrianas...@gmail.com>
Date: Fri, 17 Dec 2021 01:46:40 +0300
Subject: [PATCH 07/24] EXPERIMENT: update bdwrite for lpcm/hevc

---
 cinelerra-5.1/cinelerra/bdwrite.C | 20 ++++++++++++++++----
 1 file changed, 16 insertions(+), 4 deletions(-)

diff --git a/cinelerra-5.1/cinelerra/bdwrite.C b/cinelerra-5.1/cinelerra/bdwrite.C
index 6a2b4ca3..b184e0c6 100644
--- a/cinelerra-5.1/cinelerra/bdwrite.C
+++ b/cinelerra-5.1/cinelerra/bdwrite.C
@@ -102,6 +102,7 @@ enum {
   BLURAY_STREAM_TYPE_VIDEO_VC1 = 0xea,
   BLURAY_STREAM_TYPE_VIDEO_H264 = 0x1b,
   BLURAY_STREAM_TYPE_VIDEO_H264_MVC = 0x20,
+  BLURAY_STREAM_TYPE_VIDEO_HEVC = 0x24,
   BLURAY_STREAM_TYPE_SUB_PG = 0x90,
   BLURAY_STREAM_TYPE_SUB_IG = 0x91,
   BLURAY_STREAM_TYPE_SUB_TEXT = 0x92,
@@ -122,6 +123,7 @@ enum {
   BLURAY_VIDEO_FORMAT_720P = 5,  // SMPTE 296M
   BLURAY_VIDEO_FORMAT_1080P = 6, // SMPTE 274M
   BLURAY_VIDEO_FORMAT_576P = 7,  // ITU-R BT.1358
+  BLURAY_VIDEO_FORMAT_2160P = 8,
 
   BLURAY_VIDEO_RATE_24000_1001 = 1, // 23.976
   BLURAY_VIDEO_RATE_24 = 2,
@@ -1505,6 +1507,7 @@ clpi_prog_stream::write()
   case BLURAY_STREAM_TYPE_VIDEO_MPEG2:
   case BLURAY_STREAM_TYPE_VIDEO_VC1:
   case BLURAY_STREAM_TYPE_VIDEO_H264:
+  case BLURAY_STREAM_TYPE_VIDEO_HEVC:
   case 0x20:
     bs.write(format, 4);
     bs.write(rate, 4);
@@ -1905,18 +1908,18 @@ write()
 
   bs.write(stream_type, 8);
   switch (stream_type) {
-  case 0x01:
+  case BLURAY_STREAM_TYPE_VIDEO_MPEG1:
     bs.write(pid, 16);
     break;
 
-  case 0x02:
-  case 0x04:
+  case BLURAY_STREAM_TYPE_VIDEO_MPEG2:
+  case BLURAY_STREAM_TYPE_AUDIO_MPEG2:
     bs.write(subpath_id, 8);
     bs.write(subclip_id, 8);
     bs.write(pid, 16);
     break;
 
-  case 0x03:
+  case BLURAY_STREAM_TYPE_AUDIO_MPEG1:
     bs.write(subpath_id, 8);
     bs.write(pid, 16);
     break;
@@ -1935,6 +1938,7 @@ write()
   case BLURAY_STREAM_TYPE_VIDEO_MPEG2:
   case BLURAY_STREAM_TYPE_VIDEO_VC1:
   case BLURAY_STREAM_TYPE_VIDEO_H264:
+  case BLURAY_STREAM_TYPE_VIDEO_HEVC:
     bs.write(format, 4);
     bs.write(rate, 4);
     break;
@@ -2406,6 +2410,9 @@ static int bd_stream_type(AVCodecID codec_id)
   case AV_CODEC_ID_H264:
     stream_type = BLURAY_STREAM_TYPE_VIDEO_H264;
     break;
+  case AV_CODEC_ID_HEVC:
+    stream_type = BLURAY_STREAM_TYPE_VIDEO_HEVC;
+    break;
   case AV_CODEC_ID_MP2:
     stream_type = BLURAY_STREAM_TYPE_AUDIO_MPEG1;
     break;
@@ -2424,6 +2431,9 @@ static int bd_stream_type(AVCodecID codec_id)
   case AV_CODEC_ID_TRUEHD:
     stream_type = BLURAY_STREAM_TYPE_AUDIO_TRUHD;
     break;
+  case AV_CODEC_ID_PCM_BLURAY:
+    stream_type = BLURAY_STREAM_TYPE_AUDIO_LPCM;
+    break;
   case AV_CODEC_ID_HDMV_PGS_SUBTITLE:
     stream_type = BLURAY_STREAM_TYPE_SUB_PG;
     break;
@@ -2478,6 +2488,8 @@ static int bd_video_format(int w, int h, int ilace)
   if( w == 1280 && h ==  720 /* && !ilace*/ ) return BLURAY_VIDEO_FORMAT_720P;
   if( w == 1440 && h == 1080 /* &&  ilace*/ ) return BLURAY_VIDEO_FORMAT_1080I;
   if( w == 1920 && h == 1080 /* && !ilace*/ ) return BLURAY_VIDEO_FORMAT_1080P;
+  if( w == 3840 && h == 2160 &&  !ilace ) return BLURAY_VIDEO_FORMAT_2160P;
+  
   fprintf(stderr, "unknown bluray video format %dx%d %silace\n",
     w, h, !ilace ? "not " : "");
   exit(1);
-- 
2.34.1

From aaabb762906debfed7d3e4f950e310819ab589a5 Mon Sep 17 00:00:00 2001
From: Andrew Randrianasulu <randrianas...@gmail.com>
Date: Fri, 17 Dec 2021 07:39:07 +0300
Subject: [PATCH 14/24] truehd experimental bluray profile

---
 cinelerra-5.1/ffmpeg/audio/bluray_truehd.m2ts | 3 +++
 1 file changed, 3 insertions(+)
 create mode 100644 cinelerra-5.1/ffmpeg/audio/bluray_truehd.m2ts

diff --git a/cinelerra-5.1/ffmpeg/audio/bluray_truehd.m2ts b/cinelerra-5.1/ffmpeg/audio/bluray_truehd.m2ts
new file mode 100644
index 00000000..f1e34e6d
--- /dev/null
+++ b/cinelerra-5.1/ffmpeg/audio/bluray_truehd.m2ts
@@ -0,0 +1,3 @@
+bluray truehd
+id 0x1100
+strict -2
-- 
2.34.1

From ba170cafe1034780e6501419fcdecb913cc2e9b6 Mon Sep 17 00:00:00 2001
From: Andrew Randrianasulu <randrianas...@gmail.com>
Date: Fri, 17 Dec 2021 06:25:32 +0300
Subject: [PATCH 12/24] EXPERIMENTAL: attempt to get value from popuptextbox

---
 cinelerra-5.1/cinelerra/bdcreate.C | 7 +++++--
 cinelerra-5.1/cinelerra/bdcreate.h | 1 +
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/cinelerra-5.1/cinelerra/bdcreate.C b/cinelerra-5.1/cinelerra/bdcreate.C
index 90fb8734..291f7e7e 100644
--- a/cinelerra-5.1/cinelerra/bdcreate.C
+++ b/cinelerra-5.1/cinelerra/bdcreate.C
@@ -213,6 +213,8 @@ CreateBD_Thread::CreateBD_Thread(MWindow *mwindow)
 	this->use_labeled = 0;
 	this->use_farmed = 0;
 	this->use_termux = 0;
+	
+	strcpy(use_profile,"bluray.m2ts");
 
 	this->bd_size = BD_SIZE;
 	this->bd_width = BD_WIDTH;
@@ -325,7 +327,7 @@ int CreateBD_Thread::create_bd_jobs(ArrayList<BatchRenderJob*> *jobs, const char
 	strcpy(asset->fformat, "m2ts");
 
 	asset->audio_data = 1;
-	strcpy(asset->acodec, bd_profiles[0].name);
+	strcpy(asset->acodec, use_profile);
 	//mwindow->defaults->get("DEFAULT_BLURAY_ACODEC", asset->acodec);
 	FFMPEG::set_option_path(option_path, "audio/%s", asset->acodec);
 	FFMPEG::load_options(option_path, asset->ff_audio_options,
@@ -333,7 +335,7 @@ int CreateBD_Thread::create_bd_jobs(ArrayList<BatchRenderJob*> *jobs, const char
 	asset->ff_audio_bitrate = bd_kaudio_rate * 1000;
 
 	asset->video_data = 1;
-	const char *vcodec = bd_profiles[0].name;
+	const char *vcodec = use_profile;
 	switch( asset->interlace_mode ) {
 	case ILACE_MODE_TOP_FIRST:    vcodec = "bluray_tff.m2ts";  break;
 	case ILACE_MODE_BOTTOM_FIRST: vcodec = "bluray_bff.m2ts";  break;
@@ -1157,6 +1159,7 @@ CreateBD_Profile::~CreateBD_Profile()
 
 int CreateBD_Profile::handle_event()
 {
+	strcpy(gui->thread->use_profile, get_text());
 	return 1;
 }
 
diff --git a/cinelerra-5.1/cinelerra/bdcreate.h b/cinelerra-5.1/cinelerra/bdcreate.h
index 81f11120..e91d3c0a 100644
--- a/cinelerra-5.1/cinelerra/bdcreate.h
+++ b/cinelerra-5.1/cinelerra/bdcreate.h
@@ -57,6 +57,7 @@ public:
 	CreateBD_GUI *gui;
 	char asset_title[BCTEXTLEN];
 	char tmp_path[BCTEXTLEN];
+	char use_profile[BCTEXTLEN];
 	int use_deinterlace, use_inverse_telecine;
 	int use_scale, use_resize_tracks;
 	int use_wide_audio, use_farmed;
-- 
2.34.1

From d30c1d2661bca6f034ec4c6c11d08837888b90da Mon Sep 17 00:00:00 2001
From: Andrew Randrianasulu <randrianas...@gmail.com>
Date: Fri, 17 Dec 2021 05:13:15 +0300
Subject: [PATCH 11/24] Fix bdcreate.C layout

---
 cinelerra-5.1/cinelerra/bdcreate.C | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/cinelerra-5.1/cinelerra/bdcreate.C b/cinelerra-5.1/cinelerra/bdcreate.C
index 67745a8d..90fb8734 100644
--- a/cinelerra-5.1/cinelerra/bdcreate.C
+++ b/cinelerra-5.1/cinelerra/bdcreate.C
@@ -792,16 +792,17 @@ void CreateBD_GUI::create_objects()
 	
 	title = new BC_Title(x, y, _("Profile:"), MEDIUMFONT, YELLOW);
 	add_subwindow(title);
-	y +=  title->get_h()+pady;
-	profile = new CreateBD_Profile(this, x1, y);
+	x += title->get_w()+padx;
+	int prev_title_w = title->get_w()+padx;
+	profile = new CreateBD_Profile(this, x, y);
 	profile->create_objects();
 	profiles.append(new BC_ListBoxItem("bluray.m2ts"));
 	profiles.append(new BC_ListBoxItem("bluray_lpcm.m2ts"));
 	profile->update_list(&profiles);
 	profile->update(profiles[0]->get_text());
+	y += profile->get_h() + pady;
 	
-	
-	title = new BC_Title(x, y, _("Format:"), MEDIUMFONT, YELLOW);
+	title = new BC_Title(x-prev_title_w, y, _("Format:"), MEDIUMFONT, YELLOW);
 	add_subwindow(title);
 	standard = new CreateBD_Format(this, title->get_w() + padx, y);
 	add_subwindow(standard);
@@ -1145,7 +1146,7 @@ int CreateBD_MediaSize::handle_event()
 }
 
 CreateBD_Profile::CreateBD_Profile(CreateBD_GUI *gui, int x, int y)
- : BC_PopupTextBox(gui, 0, 0, x, y, xS(70),yS(50))
+ : BC_PopupTextBox(gui, 0, 0, x, y, xS(170),yS(50))
 {
 	this->gui = gui;
 }
-- 
2.34.1

From 59763cc5f966ff90607ecf5a4e2d90771139f3fd Mon Sep 17 00:00:00 2001
From: Andrew Randrianasulu <randrianas...@gmail.com>
Date: Fri, 17 Dec 2021 06:35:25 +0300
Subject: [PATCH 13/24] Rename m2ts_pcm.m2ts to bluray_lpcm.m2ts

---
 cinelerra-5.1/ffmpeg/audio/bluray_lpcm.m2ts | 2 ++
 1 file changed, 2 insertions(+)
 create mode 100644 cinelerra-5.1/ffmpeg/audio/bluray_lpcm.m2ts

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
-- 
2.34.1

From bbc8b3af4efa5ddefc1ba85cbdda620a0e21bcd3 Mon Sep 17 00:00:00 2001
From: Andrew Randrianasulu <randrianas...@gmail.com>
Date: Fri, 17 Dec 2021 15:41:24 +0300
Subject: [PATCH 18/24] NOT YET

---
 cinelerra-5.1/cinelerra/bdcreate.C | 12 +++++++++++-
 cinelerra-5.1/cinelerra/bdcreate.h |  3 +++
 2 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/cinelerra-5.1/cinelerra/bdcreate.C b/cinelerra-5.1/cinelerra/bdcreate.C
index 6f4e9675..738026a4 100644
--- a/cinelerra-5.1/cinelerra/bdcreate.C
+++ b/cinelerra-5.1/cinelerra/bdcreate.C
@@ -152,10 +152,15 @@ int BD_BatchRenderJob::get_udfs_mount(char *udfs, char *mopts, char *mntpt)
 	return ret;
 }
 
+
+
 char *BD_BatchRenderJob::create_script(EDL *edl, ArrayList<Indexable *> *idxbls)
 {
 	char script[BCTEXTLEN];
 	strcpy(script, edl_path);
+	
+	int tsmuxer = 1;
+	
 	FILE *fp = 0;
 	char *bp = strrchr(script,'/');
 	int fd = -1;
@@ -183,6 +188,9 @@ char *BD_BatchRenderJob::create_script(EDL *edl, ArrayList<Indexable *> *idxbls)
 	fprintf(fp,"sz=`du -cb $dir/bd.m2ts* | tail -1 | sed -e 's/[ 	].*//'`\n");
 	fprintf(fp,"blks=$((sz/2048 + 4096))\n");
 	fprintf(fp,"rm -f %s\n", udfs);
+	if (tsmuxer) {
+	fprintf(fp,"tsmuxer bd.meta $dir/bd.m2ts \n");
+	} else {
 	fprintf(fp,"mkudffs -b 2048 %s $blks\n", udfs);
 	fprintf(fp,"mount %s%s\n", mopts, mntpt);
 	fprintf(fp,"bdwrite %s $dir/bd.m2ts*\n",mntpt);
@@ -193,7 +201,7 @@ char *BD_BatchRenderJob::create_script(EDL *edl, ArrayList<Indexable *> *idxbls)
 	fprintf(fp,"echo for WORM: growisofs -dvd-compat -Z /dev/bd=$dir/bd.udfs\n");
 	fprintf(fp,"echo for RW:   dd if=$dir/bd.udfs of=/dev/bd bs=2048000\n");
 	fprintf(fp,"kill $$\n");
-	fprintf(fp,"\n");
+	fprintf(fp,"\n"); }
 	fclose(fp);
 	return cstrdup(script);
 }
@@ -226,6 +234,7 @@ CreateBD_Thread::CreateBD_Thread(MWindow *mwindow)
 	this->bd_max_bitrate = BD_MAX_BITRATE;
 	this->bd_kaudio_rate = BD_KAUDIO_RATE;
 	this->max_w = this->max_h = 0;
+	this->batchrender = 0;
 }
 
 CreateBD_Thread::~CreateBD_Thread()
@@ -430,6 +439,7 @@ void CreateBD_Thread::handle_close_event(int result)
 	char asset_dir[BCTEXTLEN], jobs_path[BCTEXTLEN];
 	snprintf(asset_dir, sizeof(asset_dir), "%s/%s", tmp_path, asset_title);
 	snprintf(jobs_path, sizeof(jobs_path), "%s/bd.jobs", asset_dir);
+	//batchrender->tsmuxered = use_tsmuxer;
 	mwindow->batch_render->reset(jobs_path);
 	int ret = create_bd_jobs(&mwindow->batch_render->jobs, asset_dir);
 	mwindow->undo->update_undo_after(_("create bd"), LOAD_ALL);
diff --git a/cinelerra-5.1/cinelerra/bdcreate.h b/cinelerra-5.1/cinelerra/bdcreate.h
index 6744e027..c9bbc5f9 100644
--- a/cinelerra-5.1/cinelerra/bdcreate.h
+++ b/cinelerra-5.1/cinelerra/bdcreate.h
@@ -30,6 +30,7 @@ public:
 	static int get_udfs_mount(char *udfs, char *mopts, char *mntpt);
 	BD_BatchRenderJob(Preferences *preferences, int labeled, int farmed);
 	char *create_script(EDL *edl, ArrayList<Indexable *> *idxbls);
+	int tsmuxered;
 };
 
 
@@ -76,6 +77,8 @@ public:
 	double bd_kaudio_rate;
 	int bd_interlace_mode;
 	int max_w, max_h;
+	
+	BD_BatchRenderJob *batchrender;
 };
 
 class CreateBD_OK : public BC_OKButton
-- 
2.34.1

From 67a78b78e6b8719eb34c1c3ca58dc6338d2a2f39 Mon Sep 17 00:00:00 2001
From: Andrew Randrianasulu <randrianas...@gmail.com>
Date: Fri, 17 Dec 2021 07:39:52 +0300
Subject: [PATCH 15/24] EXPERIMENTAL: add truehd audio profile for bdcreate.C

---
 cinelerra-5.1/cinelerra/bdcreate.C | 1 +
 1 file changed, 1 insertion(+)

diff --git a/cinelerra-5.1/cinelerra/bdcreate.C b/cinelerra-5.1/cinelerra/bdcreate.C
index 291f7e7e..54d391d8 100644
--- a/cinelerra-5.1/cinelerra/bdcreate.C
+++ b/cinelerra-5.1/cinelerra/bdcreate.C
@@ -800,6 +800,7 @@ void CreateBD_GUI::create_objects()
 	profile->create_objects();
 	profiles.append(new BC_ListBoxItem("bluray.m2ts"));
 	profiles.append(new BC_ListBoxItem("bluray_lpcm.m2ts"));
+	profiles.append(new BC_ListBoxItem("bluray_truehd.m2ts"));
 	profile->update_list(&profiles);
 	profile->update(profiles[0]->get_text());
 	y += profile->get_h() + pady;
-- 
2.34.1

From 83ad135d5cbf13ff33f710e2630e729166e5ccd2 Mon Sep 17 00:00:00 2001
From: Andrew Randrianasulu <randrianas...@gmail.com>
Date: Fri, 17 Dec 2021 08:36:55 +0300
Subject: [PATCH 16/24] EXPERIMENTAL: add tsmuxer checkbox

---
 cinelerra-5.1/cinelerra/bdcreate.C   | 20 ++++++++++++++++++--
 cinelerra-5.1/cinelerra/bdcreate.h   | 14 +++++++++++++-
 cinelerra-5.1/cinelerra/bdcreate.inc |  1 +
 3 files changed, 32 insertions(+), 3 deletions(-)

diff --git a/cinelerra-5.1/cinelerra/bdcreate.C b/cinelerra-5.1/cinelerra/bdcreate.C
index 54d391d8..b47f80cb 100644
--- a/cinelerra-5.1/cinelerra/bdcreate.C
+++ b/cinelerra-5.1/cinelerra/bdcreate.C
@@ -212,7 +212,7 @@ CreateBD_Thread::CreateBD_Thread(MWindow *mwindow)
 	this->use_resize_tracks = 0;
 	this->use_labeled = 0;
 	this->use_farmed = 0;
-	this->use_termux = 0;
+	this->use_tsmuxer = 0;
 	
 	strcpy(use_profile,"bluray.m2ts");
 
@@ -457,7 +457,7 @@ BC_Window* CreateBD_Thread::new_gui()
 	use_resize_tracks = 0;
 	use_labeled = 0;
 	use_farmed = 0;
-	use_termux = 0;
+	use_tsmuxer = 0;
 	use_standard = !strcmp(mwindow->default_std(),"NTSC") ?
 		 BD_1920x1080_2997i : BD_1920x1080_25i;
 	bd_size = BD_SIZE;
@@ -719,6 +719,16 @@ CreateBD_WideAudio::~CreateBD_WideAudio()
 {
 }
 
+CreateBD_UseTsmuxer::CreateBD_UseTsmuxer(CreateBD_GUI *gui, int x, int y)
+ : BC_CheckBox(x, y, &gui->thread->use_tsmuxer, _("use tsmuxer"))
+{
+	this->gui = gui;
+}
+
+CreateBD_UseTsmuxer::~CreateBD_UseTsmuxer()
+{
+}
+
 
 CreateBD_GUI::CreateBD_GUI(CreateBD_Thread *thread, int x, int y, int w, int h)
  : BC_Window(_(PROGRAM_NAME ": Create BD"), x, y, w, h, xS(50), yS(50), 1, 0, 1)
@@ -742,6 +752,7 @@ CreateBD_GUI::CreateBD_GUI(CreateBD_Thread *thread, int x, int y, int w, int h)
 	need_wide_audio = 0;
 	need_labeled = 0;
 	need_farmed = 0;
+	need_tsmuxer = 0;
 	ok = 0;
 	cancel = 0;
 // *** CONTEXT_HELP ***
@@ -803,6 +814,11 @@ void CreateBD_GUI::create_objects()
 	profiles.append(new BC_ListBoxItem("bluray_truehd.m2ts"));
 	profile->update_list(&profiles);
 	profile->update(profiles[0]->get_text());
+	
+	x += title->get_w()+padx;
+	need_tsmuxer = new CreateBD_UseTsmuxer(this, x1, y);
+	add_subwindow(need_tsmuxer);
+	
 	y += profile->get_h() + pady;
 	
 	title = new BC_Title(x-prev_title_w, y, _("Format:"), MEDIUMFONT, YELLOW);
diff --git a/cinelerra-5.1/cinelerra/bdcreate.h b/cinelerra-5.1/cinelerra/bdcreate.h
index e91d3c0a..6744e027 100644
--- a/cinelerra-5.1/cinelerra/bdcreate.h
+++ b/cinelerra-5.1/cinelerra/bdcreate.h
@@ -63,7 +63,7 @@ public:
 	int use_wide_audio, use_farmed;
 	int use_histogram, use_labeled;
 	int use_standard;
-	int use_termux;
+	int use_tsmuxer;
 
 	int64_t bd_size;
 	int bd_width;
@@ -198,6 +198,17 @@ public:
 	CreateBD_GUI *gui;
 };
 
+
+class CreateBD_UseTsmuxer : public BC_CheckBox
+{
+public:
+	CreateBD_UseTsmuxer(CreateBD_GUI *gui, int x, int y);
+	~CreateBD_UseTsmuxer();
+
+	CreateBD_GUI *gui;
+};
+
+
 class CreateBD_GUI : public BC_Window
 {
 public:
@@ -226,6 +237,7 @@ public:
 	CreateBD_InverseTelecine *need_inverse_telecine;
 	CreateBD_ResizeTracks *need_resize_tracks;
 	CreateBD_Histogram *need_histogram;
+	CreateBD_UseTsmuxer *need_tsmuxer;
 	BC_Title *non_standard;
 	CreateBD_WideAudio *need_wide_audio;
 	CreateBD_LabelChapters *need_labeled;
diff --git a/cinelerra-5.1/cinelerra/bdcreate.inc b/cinelerra-5.1/cinelerra/bdcreate.inc
index 5db9568b..45d9fc1e 100644
--- a/cinelerra-5.1/cinelerra/bdcreate.inc
+++ b/cinelerra-5.1/cinelerra/bdcreate.inc
@@ -42,5 +42,6 @@ class CreateBD_FormatItem;
 class CreateBD_Format;
 class CreateBD_MediaSize;
 class CreateBD_Profile;
+class CreateBD_UseTsmuxer;
 
 #endif
-- 
2.34.1

From 5a29b5b99c234313d54c1beda7602370e33a2030 Mon Sep 17 00:00:00 2001
From: Andrew Randrianasulu <randrianas...@gmail.com>
Date: Sat, 18 Dec 2021 08:29:35 +0300
Subject: [PATCH 20/24] Attempt at fixing bdwrite (stream_type/coding_type
 confusion)

---
 cinelerra-5.1/cinelerra/bdwrite.C | 54 +++++++++++++++++--------------
 1 file changed, 29 insertions(+), 25 deletions(-)

diff --git a/cinelerra-5.1/cinelerra/bdwrite.C b/cinelerra-5.1/cinelerra/bdwrite.C
index a2131251..bf951b89 100644
--- a/cinelerra-5.1/cinelerra/bdwrite.C
+++ b/cinelerra-5.1/cinelerra/bdwrite.C
@@ -650,6 +650,10 @@ public:
   uint8_t subclip_id;
   uint8_t format;
   uint8_t rate;
+  uint8_t dynamic_range_type;
+  uint8_t color_space;
+  uint8_t cr_flag;
+  uint8_t hdr_plus_flag;
   uint8_t char_code;
   char lang[4];
 
@@ -1908,24 +1912,24 @@ write()
 
   bs.write(stream_type, 8);
   switch (stream_type) {
-  case BLURAY_STREAM_TYPE_VIDEO_MPEG1:
+  case 1:
     bs.write(pid, 16);
     break;
 
-  case BLURAY_STREAM_TYPE_VIDEO_MPEG2:
-  case BLURAY_STREAM_TYPE_AUDIO_MPEG2:
+  case 2:
+  case 3:
     bs.write(subpath_id, 8);
     bs.write(subclip_id, 8);
     bs.write(pid, 16);
     break;
 
-  case BLURAY_STREAM_TYPE_AUDIO_MPEG1:
+  case 4:
     bs.write(subpath_id, 8);
     bs.write(pid, 16);
     break;
 
   default:
-    fprintf(stderr, "unrecognized stream type %02x\n", stream_type);
+    fprintf(stderr, "unrecognized mpls stream type %02x\n", stream_type);
     break;
   };
   bs.padb(9 - strm.bs_posb(bs));
@@ -2397,51 +2401,51 @@ build_toc(clpi_ep_map_entry *map)
 
 const AVRational media_info::clk45k = { 1, 45000 };
 
-static int bd_stream_type(AVCodecID codec_id)
+static int bd_coding_type(AVCodecID codec_id)
 {
-  int stream_type = 0;
+  int coding_type = 0;
   switch (codec_id) {
   case AV_CODEC_ID_MPEG1VIDEO:
-    stream_type = BLURAY_STREAM_TYPE_VIDEO_MPEG1;
+    coding_type = BLURAY_STREAM_TYPE_VIDEO_MPEG1;
     break;
   case AV_CODEC_ID_MPEG2VIDEO:
-    stream_type = BLURAY_STREAM_TYPE_VIDEO_MPEG2;
+    coding_type = BLURAY_STREAM_TYPE_VIDEO_MPEG2;
     break;
   case AV_CODEC_ID_H264:
-    stream_type = BLURAY_STREAM_TYPE_VIDEO_H264;
+    coding_type = BLURAY_STREAM_TYPE_VIDEO_H264;
     break;
   case AV_CODEC_ID_HEVC:
-    stream_type = BLURAY_STREAM_TYPE_VIDEO_HEVC;
+    coding_type = BLURAY_STREAM_TYPE_VIDEO_HEVC;
     break;
   case AV_CODEC_ID_MP2:
-    stream_type = BLURAY_STREAM_TYPE_AUDIO_MPEG1;
+    coding_type = BLURAY_STREAM_TYPE_AUDIO_MPEG1;
     break;
   case AV_CODEC_ID_MP3:
-    stream_type = BLURAY_STREAM_TYPE_AUDIO_MPEG2;
+    coding_type = BLURAY_STREAM_TYPE_AUDIO_MPEG2;
     break;
   case AV_CODEC_ID_AC3:
-    stream_type = BLURAY_STREAM_TYPE_AUDIO_AC3;
+    coding_type = BLURAY_STREAM_TYPE_AUDIO_AC3;
     break;
   case AV_CODEC_ID_EAC3:
-    stream_type = BLURAY_STREAM_TYPE_AUDIO_AC3PLUS;
+    coding_type = BLURAY_STREAM_TYPE_AUDIO_AC3PLUS;
     break;
   case AV_CODEC_ID_DTS:
-    stream_type = BLURAY_STREAM_TYPE_AUDIO_DTS;
+    coding_type = BLURAY_STREAM_TYPE_AUDIO_DTS;
     break;
   case AV_CODEC_ID_TRUEHD:
-    stream_type = BLURAY_STREAM_TYPE_AUDIO_TRUHD;
+    coding_type = BLURAY_STREAM_TYPE_AUDIO_TRUHD;
     break;
   case AV_CODEC_ID_PCM_BLURAY:
-    stream_type = BLURAY_STREAM_TYPE_AUDIO_LPCM;
+    coding_type = BLURAY_STREAM_TYPE_AUDIO_LPCM;
     break;
   case AV_CODEC_ID_HDMV_PGS_SUBTITLE:
-    stream_type = BLURAY_STREAM_TYPE_SUB_PG;
+    coding_type = BLURAY_STREAM_TYPE_SUB_PG;
     break;
   default:
-    fprintf(stderr, "unknown bluray stream type %s\n", avcodec_get_name(codec_id));
+    fprintf(stderr, "unknown bluray codec type %s\n", avcodec_get_name(codec_id));
     exit(1);
   }
-  return stream_type;
+  return coding_type;
 }
 
 static int bd_audio_format(int channels)
@@ -2605,7 +2609,7 @@ int media_info::scan()
     switch( type ) {
     case AVMEDIA_TYPE_VIDEO: {
       if( ep_pid < 0 ) ep_pid = st->id;
-      s->coding_type = bd_stream_type(codec_id);
+      s->coding_type = bd_coding_type(codec_id);
       int ilace = field_probe(fmt_ctx, st);
       if( ilace < 0 ) {
         fprintf(stderr, "interlace probe failed\n");
@@ -2619,13 +2623,13 @@ int media_info::scan()
 		 (double)st->sample_aspect_ratio.num / st->sample_aspect_ratio.den);
       break; }
     case AVMEDIA_TYPE_AUDIO: {
-      s->coding_type = bd_stream_type(codec_id);
+      s->coding_type = bd_coding_type(codec_id);
       s->format = bd_audio_format(st->codecpar->channels);
       s->rate = bd_audio_rate(st->codecpar->sample_rate);
       strcpy((char*)s->lang, "eng");
       break; }
     case AVMEDIA_TYPE_SUBTITLE: {
-      s->coding_type = bd_stream_type(codec_id);
+      s->coding_type = bd_coding_type(codec_id);
       AVDictionaryEntry *lang = av_dict_get(st->metadata, "language", 0, 0);
       strncpy((char*)s->lang, lang ? lang->value : "und", sizeof(s->lang));
       break; }
@@ -2978,7 +2982,7 @@ Media::compose(int ch_interval)
       }
       pp->play_item.append(pi);
     }
-// chapter marks every ch_duration ticks, default 5 min
+// chapter marks every ch_duration seconds * 45Kticks, default 5 min
     int PCR_FREQ = 45000;
     if (ch_interval == 0)
     ch_interval = 60*5;
-- 
2.34.1

From 7db14b75024d7e29483d903a6da160fc1fb85932 Mon Sep 17 00:00:00 2001
From: Andrew Randrianasulu <randrianas...@gmail.com>
Date: Fri, 17 Dec 2021 09:32:14 +0300
Subject: [PATCH 17/24] EXPERIMENTAL: fix layout in bdcreate after tsmuxer
 checkbox

---
 cinelerra-5.1/cinelerra/bdcreate.C | 19 +++++++++----------
 1 file changed, 9 insertions(+), 10 deletions(-)

diff --git a/cinelerra-5.1/cinelerra/bdcreate.C b/cinelerra-5.1/cinelerra/bdcreate.C
index b47f80cb..6f4e9675 100644
--- a/cinelerra-5.1/cinelerra/bdcreate.C
+++ b/cinelerra-5.1/cinelerra/bdcreate.C
@@ -766,7 +766,7 @@ CreateBD_GUI::~CreateBD_GUI()
 void CreateBD_GUI::create_objects()
 {
 	int xs10 = xS(10), xs35 = xS(35);
-	int xs160 = xS(160), xs170 = xS(170);
+	int xs60 = xS(60), xs160 = xS(160), xs170 = xS(170);
 	int ys5 = yS(5), ys10 = yS(10);
 	lock_window("CreateBD_GUI::create_objects");
 	int pady = BC_TextBox::calculate_h(this, MEDIUMFONT, 0, 1) + ys5;
@@ -805,8 +805,8 @@ void CreateBD_GUI::create_objects()
 	
 	title = new BC_Title(x, y, _("Profile:"), MEDIUMFONT, YELLOW);
 	add_subwindow(title);
+	int start_x = x;
 	x += title->get_w()+padx;
-	int prev_title_w = title->get_w()+padx;
 	profile = new CreateBD_Profile(this, x, y);
 	profile->create_objects();
 	profiles.append(new BC_ListBoxItem("bluray.m2ts"));
@@ -815,13 +815,12 @@ void CreateBD_GUI::create_objects()
 	profile->update_list(&profiles);
 	profile->update(profiles[0]->get_text());
 	
-	x += title->get_w()+padx;
-	need_tsmuxer = new CreateBD_UseTsmuxer(this, x1, y);
+	x += profile->get_w()+padx;
+	need_tsmuxer = new CreateBD_UseTsmuxer(this, x, y);
 	add_subwindow(need_tsmuxer);
+	y += need_tsmuxer->get_h() + pady;
 	
-	y += profile->get_h() + pady;
-	
-	title = new BC_Title(x-prev_title_w, y, _("Format:"), MEDIUMFONT, YELLOW);
+	title = new BC_Title(start_x, y, _("Format:"), MEDIUMFONT, YELLOW);
 	add_subwindow(title);
 	standard = new CreateBD_Format(this, title->get_w() + padx, y);
 	add_subwindow(standard);
@@ -836,15 +835,15 @@ void CreateBD_GUI::create_objects()
 	scale->create_objects();
 	y += standard->get_h() + pady/2;
 	x1 = x;  int y1 = y;
-	need_deinterlace = new CreateBD_Deinterlace(this, x1, y);
+	need_deinterlace = new CreateBD_Deinterlace(this, start_x, y);
 	add_subwindow(need_deinterlace);
 	y += need_deinterlace->get_h() + pady/2;
-	need_histogram = new CreateBD_Histogram(this, x1, y);
+	need_histogram = new CreateBD_Histogram(this, start_x, y);
 	add_subwindow(need_histogram);
 	y += need_histogram->get_h() + pady/2;
 	non_standard = new BC_Title(x1, y+ys5, "", MEDIUMFONT, RED);
 	add_subwindow(non_standard);
-	x1 += xs160;  y = y1;
+	x1 -= xs60;  y = y1;
 	need_inverse_telecine = new CreateBD_InverseTelecine(this, x1, y);
 	add_subwindow(need_inverse_telecine);
 	y += need_inverse_telecine->get_h() + pady/2;
-- 
2.34.1

From ec8f83cecb13cc8fe7ad26b692514df8dbb80eab Mon Sep 17 00:00:00 2001
From: Andrew Randrianasulu <randrianas...@gmail.com>
Date: Tue, 21 Dec 2021 18:47:31 +0300
Subject: [PATCH 22/24] EXPERIMENTAL: real fix for bdwrite?

---
 cinelerra-5.1/cinelerra/bdwrite.C | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/cinelerra-5.1/cinelerra/bdwrite.C b/cinelerra-5.1/cinelerra/bdwrite.C
index b1c650ee..b7bed6db 100644
--- a/cinelerra-5.1/cinelerra/bdwrite.C
+++ b/cinelerra-5.1/cinelerra/bdwrite.C
@@ -3165,10 +3165,10 @@ main(int ac, char **av)
   media_info *mp = 0;
   int start  = 0, chapter_every_n_sec = 0;
   
-  // int opt = getopt(ac, av, "c:");
-  // if (opt = 'c') {
-  // chapter_every_n_sec = optarg[0]; start = 3; }
-  // else
+  int opt = getopt(ac, av, "c:");
+  if (opt == 'c') {
+  chapter_every_n_sec = optarg[0]; start = 3; }
+  else
   start = 2;
 
   for( int ii=start; ii<ac; ++ii ) {
-- 
2.34.1

From 4eb758e7c7743d37db9106b91f9593ee5c844ff1 Mon Sep 17 00:00:00 2001
From: Andrew Randrianasulu <randrianas...@gmail.com>
Date: Mon, 20 Dec 2021 15:20:20 +0300
Subject: [PATCH 21/24] EXPERIMENTAL: attempt at fixing bdwrite on Android 
 after my changes, still crash

---
 cinelerra-5.1/cinelerra/bdwrite.C | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/cinelerra-5.1/cinelerra/bdwrite.C b/cinelerra-5.1/cinelerra/bdwrite.C
index bf951b89..b1c650ee 100644
--- a/cinelerra-5.1/cinelerra/bdwrite.C
+++ b/cinelerra-5.1/cinelerra/bdwrite.C
@@ -3163,11 +3163,12 @@ main(int ac, char **av)
   //av_log_set_level(AV_LOG_DEBUG);
   Media media;
   media_info *mp = 0;
-  int start, chapter_every_n_sec;
+  int start  = 0, chapter_every_n_sec = 0;
   
-  if (strcmp (av[2], "c")) {
-  chapter_every_n_sec = optarg[0]; start = 3; }
-  else
+  // int opt = getopt(ac, av, "c:");
+  // if (opt = 'c') {
+  // chapter_every_n_sec = optarg[0]; start = 3; }
+  // else
   start = 2;
 
   for( int ii=start; ii<ac; ++ii ) {
-- 
2.34.1

From 4e32f0b58d7a6e97c112ff43f1ac79725f38feea Mon Sep 17 00:00:00 2001
From: Andrew Randrianasulu <randrianas...@gmail.com>
Date: Fri, 17 Dec 2021 20:42:30 +0300
Subject: [PATCH 19/24] EXPERIMENTAL: shell script run tsmuxer conditionally on
 bd.meta, bd.meta conditionally written on gui var

---
 cinelerra-5.1/cinelerra/bdcreate.C | 44 ++++++++++++++++++++++++++----
 1 file changed, 38 insertions(+), 6 deletions(-)

diff --git a/cinelerra-5.1/cinelerra/bdcreate.C b/cinelerra-5.1/cinelerra/bdcreate.C
index 738026a4..aa36cc9e 100644
--- a/cinelerra-5.1/cinelerra/bdcreate.C
+++ b/cinelerra-5.1/cinelerra/bdcreate.C
@@ -159,8 +159,6 @@ char *BD_BatchRenderJob::create_script(EDL *edl, ArrayList<Indexable *> *idxbls)
 	char script[BCTEXTLEN];
 	strcpy(script, edl_path);
 	
-	int tsmuxer = 1;
-	
 	FILE *fp = 0;
 	char *bp = strrchr(script,'/');
 	int fd = -1;
@@ -188,20 +186,22 @@ char *BD_BatchRenderJob::create_script(EDL *edl, ArrayList<Indexable *> *idxbls)
 	fprintf(fp,"sz=`du -cb $dir/bd.m2ts* | tail -1 | sed -e 's/[ 	].*//'`\n");
 	fprintf(fp,"blks=$((sz/2048 + 4096))\n");
 	fprintf(fp,"rm -f %s\n", udfs);
-	if (tsmuxer) {
-	fprintf(fp,"tsmuxer bd.meta $dir/bd.m2ts \n");
-	} else {
+	fprintf(fp,"if [ -f bd.meta ]; then\n");
+	fprintf(fp,"tsmuxer bd.meta $dir/bd.iso \n");
+	fprintf(fp,"mv $dir/bd.iso $dir/bd.udfs\n");
+	fprintf(fp,"else\n");
 	fprintf(fp,"mkudffs -b 2048 %s $blks\n", udfs);
 	fprintf(fp,"mount %s%s\n", mopts, mntpt);
 	fprintf(fp,"bdwrite %s $dir/bd.m2ts*\n",mntpt);
 	fprintf(fp,"umount %s\n",mntpt);
+	fprintf(fp,"fi\n");
 	if( is_usr_mnt )
 		fprintf(fp,"mv -f %s $dir/bd.udfs\n", udfs);
 	fprintf(fp,"echo To burn bluray, load writable media and run:\n");
 	fprintf(fp,"echo for WORM: growisofs -dvd-compat -Z /dev/bd=$dir/bd.udfs\n");
 	fprintf(fp,"echo for RW:   dd if=$dir/bd.udfs of=/dev/bd bs=2048000\n");
 	fprintf(fp,"kill $$\n");
-	fprintf(fp,"\n"); }
+	fprintf(fp,"\n"); 
 	fclose(fp);
 	return cstrdup(script);
 }
@@ -316,6 +316,38 @@ int CreateBD_Thread::create_bd_jobs(ArrayList<BatchRenderJob*> *jobs, const char
 		MainError::show_error(msg);
 		return 1;
 	}
+	
+	if (use_tsmuxer) {
+	char meta_script[BCTEXTLEN];
+	strcpy(meta_script, "/");
+	
+	FILE *fp = 0;
+	char *bp = strrchr(meta_script,'/');
+	int fd = -1;
+	if( bp ) {
+		char script_filename[BCTEXTLEN];
+		sprintf(script_filename, "%s/bd.meta", asset_dir);
+		strcpy(bp, script_filename);
+		fd = open(meta_script, O_WRONLY+O_CREAT+O_TRUNC, 0755);
+	}
+	if( fd >= 0 )
+		fp = fdopen(fd, "w");
+	if( !fp ) {
+		char err[BCTEXTLEN], msg[BCTEXTLEN];
+		strerror_r(errno, err, sizeof(err));
+		sprintf(msg, _("Unable to save: %s\n-- %s"), meta_script, err);
+		MainError::show_error(msg);
+		return 0;
+	}
+	
+
+	fprintf(fp,"MUXOPT --blu-ray --hdmv-descriptors\n");
+	fprintf(fp,"V_MPEG4/ISO/AVC, bd.m2ts, track=4113\n");
+	fprintf(fp,"A_AUDIO/AC3, bd.m2ts, track=4352\n");
+	fprintf(fp,"\n"); 
+	fclose(fp);
+	
+	}
 
 	BatchRenderJob *job = new BD_BatchRenderJob(mwindow->preferences,
 		use_labeled, use_farmed);
-- 
2.34.1

From a07bade450593042e35ac96abcc6c5996de101f1 Mon Sep 17 00:00:00 2001
From: Andrew Randrianasulu <randrianas...@gmail.com>
Date: Tue, 21 Dec 2021 19:09:30 +0300
Subject: [PATCH 24/24] EXPERIMENTAL: really fix audio names fir tsmuxer meta?

---
 cinelerra-5.1/cinelerra/bdcreate.C | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/cinelerra-5.1/cinelerra/bdcreate.C b/cinelerra-5.1/cinelerra/bdcreate.C
index b6a00dc1..a46a9efc 100644
--- a/cinelerra-5.1/cinelerra/bdcreate.C
+++ b/cinelerra-5.1/cinelerra/bdcreate.C
@@ -344,9 +344,9 @@ int CreateBD_Thread::create_bd_jobs(ArrayList<BatchRenderJob*> *jobs, const char
 	fprintf(fp,"MUXOPT --blu-ray --hdmv-descriptors\n");
 	fprintf(fp,"V_MPEG4/ISO/AVC, bd.m2ts, track=4113\n");
 	if(!strcmp(use_profile, "bluray.m2ts"))
-	fprintf(fp,"A_AUDIO/AC3, bd.m2ts, track=4352\n");
+	fprintf(fp,"A_AC3, bd.m2ts, track=4352\n");
 	if(!strcmp(use_profile, "bluray_lpcm.m2ts"))
-	fprintf(fp,"A_AUDIO/LPCM, bd.m2ts, track=4352\n"); 
+	fprintf(fp,"A_LPCM, bd.m2ts, track=4352\n"); 
 	fprintf(fp,"\n"); 
 	fclose(fp);
 	
-- 
2.34.1

From 4e552108e3c158ae10cebdc0c8278355fbc8b81b Mon Sep 17 00:00:00 2001
From: Andrew Randrianasulu <randrianas...@gmail.com>
Date: Tue, 21 Dec 2021 18:58:39 +0300
Subject: [PATCH 23/24] EXPERIMENTAL: try to add lpcm to tsmuxer meta file

---
 cinelerra-5.1/cinelerra/bdcreate.C | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/cinelerra-5.1/cinelerra/bdcreate.C b/cinelerra-5.1/cinelerra/bdcreate.C
index aa36cc9e..b6a00dc1 100644
--- a/cinelerra-5.1/cinelerra/bdcreate.C
+++ b/cinelerra-5.1/cinelerra/bdcreate.C
@@ -343,7 +343,10 @@ int CreateBD_Thread::create_bd_jobs(ArrayList<BatchRenderJob*> *jobs, const char
 
 	fprintf(fp,"MUXOPT --blu-ray --hdmv-descriptors\n");
 	fprintf(fp,"V_MPEG4/ISO/AVC, bd.m2ts, track=4113\n");
+	if(!strcmp(use_profile, "bluray.m2ts"))
 	fprintf(fp,"A_AUDIO/AC3, bd.m2ts, track=4352\n");
+	if(!strcmp(use_profile, "bluray_lpcm.m2ts"))
+	fprintf(fp,"A_AUDIO/LPCM, bd.m2ts, track=4352\n"); 
 	fprintf(fp,"\n"); 
 	fclose(fp);
 	
-- 
2.34.1

-- 
Cin mailing list
Cin@lists.cinelerra-gg.org
https://lists.cinelerra-gg.org/mailman/listinfo/cin

Reply via email to