On Sun, Apr 7, 2024 at 5:38 PM Andrea paz <[email protected]>
wrote:

> >> I tried to cp thirdparty/src/ffmpeg-6.1.patch10 as ffmpeg-7.0.patch10
> and compilation currently  progressed beyond this error.
> Success! Thank you very much, Andrew.
>
> I saw that in this edition there are few filters. In CinGG there is
> only "tiltandshift" filter; it does not give error but it does not
> work. In the terminal I have only the message:
>
> "resource temporarily unavaible"
>
> Of the other filters, there is no trace. These are:
>
> aap
> qrencode
> quirc
> fsync
> showinfo bitstream
> dnn
>
> > Ah, even if most patches apart from 3, 4 and D still apply encoding is
> busted :/
> I have tried three encodings and they work normally (h265-Hi;
> DNxHR-HQX and AV1.svt).
>

I tried default ffmpeg  mp4 profile and it was giving me errors ...

But I think I fixed it, see last patch in attached git series (modelled
after ffmpeg-7.0/doc/examples/transcode_aac.c)

not sure about ac3 encoding and bdwrite yet ...
From 92de3d25efb24607c3760da9a4aa84b07e23338b Mon Sep 17 00:00:00 2001
From: Andrew Randrianasulu <[email protected]>
Date: Sat, 6 Apr 2024 13:18:11 +0300
Subject: [PATCH 1/5] Adapt to ffmpeg 7.0, drop ffmpeg pre 5.1 support

---
 cinelerra-5.1/cinelerra/bdwrite.C       |  2 +-
 cinelerra-5.1/cinelerra/ffmpeg.C        | 56 ++++++++++++++++---------
 cinelerra-5.1/cinelerra/fileac3.C       | 15 ++++---
 cinelerra-5.1/cinelerra/fileffmpeg.C    |  2 +-
 cinelerra-5.1/cinelerra/pluginfclient.C | 14 ++++---
 5 files changed, 56 insertions(+), 33 deletions(-)

diff --git a/cinelerra-5.1/cinelerra/bdwrite.C b/cinelerra-5.1/cinelerra/bdwrite.C
index 1b864bb9..1f7f027e 100644
--- a/cinelerra-5.1/cinelerra/bdwrite.C
+++ b/cinelerra-5.1/cinelerra/bdwrite.C
@@ -2675,7 +2675,7 @@ int media_info::scan()
       break; }
     case AVMEDIA_TYPE_AUDIO: {
       s->coding_type = bd_coding_type(codec_id);
-      s->format = bd_audio_format(st->codecpar->channels);
+      s->format = bd_audio_format(st->codecpar->ch_layout.nb_channels);
       s->rate = bd_audio_rate(st->codecpar->sample_rate);
       strcpy((char*)s->lang, "eng");
       break; }
diff --git a/cinelerra-5.1/cinelerra/ffmpeg.C b/cinelerra-5.1/cinelerra/ffmpeg.C
index 8c753a35..e0e9bf62 100644
--- a/cinelerra-5.1/cinelerra/ffmpeg.C
+++ b/cinelerra-5.1/cinelerra/ffmpeg.C
@@ -880,13 +880,17 @@ void FFAudioStream::init_swr(int ichs, int ifmt, int irate)
 	swr_ichs = ichs;  swr_ifmt = ifmt;  swr_irate = irate;
 	if( ichs == channels && ifmt == AV_SAMPLE_FMT_FLT && irate == sample_rate )
 		return;
-	uint64_t ilayout = av_get_default_channel_layout(ichs);
-	if( !ilayout ) ilayout = ((uint64_t)1<<ichs) - 1;
-	uint64_t olayout = av_get_default_channel_layout(channels);
-	if( !olayout ) olayout = ((uint64_t)1<<channels) - 1;
-	resample_context = swr_alloc_set_opts(NULL,
-		olayout, AV_SAMPLE_FMT_FLT, sample_rate,
-		ilayout, (AVSampleFormat)ifmt, irate,
+	//uint64_t ilayout = av_get_default_channel_layout(ichs);
+	AVChannelLayout ilayout, olayout;
+	av_channel_layout_default(&ilayout, ichs);
+	//if( !ilayout ) ilayout = ((uint64_t)1<<ichs) - 1;
+	//uint64_t olayout = av_get_default_channel_layout(channels);
+	av_channel_layout_default(&olayout, channels);
+	//if( !olayout ) olayout = ((uint64_t)1<<channels) - 1;
+	
+	swr_alloc_set_opts2(&resample_context,
+		&olayout, AV_SAMPLE_FMT_FLT, sample_rate,
+		&ilayout, (AVSampleFormat)ifmt, irate,
 		0, NULL);
 	if( resample_context )
 		swr_init(resample_context);
@@ -963,7 +967,11 @@ int FFAudioStream::encode_activate()
 
 int64_t FFAudioStream::load_buffer(double ** const sp, int len)
 {
+#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(61,3,100)
+	reserve(len+1, st->codecpar->ch_layout.nb_channels);
+#else
 	reserve(len+1, st->codecpar->channels);
+#endif
 	for( int ch=0; ch<nch; ++ch )
 		write(sp[ch], len, ch);
 	return put_inp(len);
@@ -983,7 +991,11 @@ int FFAudioStream::init_frame(AVFrame *frame)
 {
 	frame->nb_samples = frame_sz;
 	frame->format = avctx->sample_fmt;
+#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(61,3,100)
+	frame->ch_layout.u.mask = avctx->ch_layout.u.mask;
+#else
 	frame->channel_layout = avctx->channel_layout;
+#endif
 	frame->sample_rate = avctx->sample_rate;
 	int ret = av_frame_get_buffer(frame, 0);
 	if (ret < 0)
@@ -1004,7 +1016,7 @@ int FFAudioStream::load(int64_t pos, int len)
 	while( ret>=0 && !flushed && curr_pos<end_pos && --i>=0 ) {
 		ret = read_frame(frame);
 		if( ret > 0 && frame->nb_samples > 0 ) {
-			init_swr(frame->channels, frame->format, frame->sample_rate);
+			init_swr(frame->ch_layout.nb_channels, frame->format, frame->sample_rate);
 			load_history(&frame->extended_data[0], frame->nb_samples);
 			curr_pos += frame->nb_samples;
 		}
@@ -2780,14 +2792,14 @@ int FFMPEG::open_decoder()
 			ret = vid->create_filter(opt_video_filter);
 			break; }
 		case AVMEDIA_TYPE_AUDIO: {
-			if( avpar->channels < 1 ) continue;
+			if( avpar->ch_layout.nb_channels < 1 ) continue;
 			if( avpar->sample_rate < 1 ) continue;
 			has_audio = 1;
 			int aidx = ffaudio.size();
 			FFAudioStream *aud = new FFAudioStream(this, st, aidx, i);
 			ffaudio.append(aud);
 			aud->channel0 = astrm_index.size();
-			aud->channels = avpar->channels;
+			aud->channels = avpar->ch_layout.nb_channels;
 			for( int ch=0; ch<aud->channels; ++ch )
 				astrm_index.append(ffidx(aidx, ch));
 			aud->sample_rate = avpar->sample_rate;
@@ -2943,10 +2955,12 @@ int FFMPEG::open_encoder(const char *type, const char *spec)
 			FFAudioStream *aud = new FFAudioStream(this, st, aidx, fidx);
 			aud->avctx = ctx;  ffaudio.append(aud);  fst = aud;
 			aud->sample_rate = asset->sample_rate;
-			ctx->channels = aud->channels = asset->channels;
+			ctx->ch_layout.nb_channels = aud->channels = asset->channels;
 			for( int ch=0; ch<aud->channels; ++ch )
 				astrm_index.append(ffidx(aidx, ch));
-			ctx->channel_layout =  av_get_default_channel_layout(ctx->channels);
+			AVChannelLayout ch_layout;
+			av_channel_layout_default(&ch_layout, ctx->ch_layout.nb_channels);
+			ctx->ch_layout.u.mask =  ch_layout.u.mask;
 			ctx->sample_rate = check_sample_rate(codec, asset->sample_rate);
 			if( !ctx->sample_rate ) {
 				eprintf(_("check_sample_rate failed %s\n"), filename);
@@ -2958,10 +2972,12 @@ int FFMPEG::open_encoder(const char *type, const char *spec)
 			if( sample_fmt == AV_SAMPLE_FMT_NONE )
 				sample_fmt = codec->sample_fmts ? codec->sample_fmts[0] : AV_SAMPLE_FMT_S16;
 			ctx->sample_fmt = sample_fmt;
-			uint64_t layout = av_get_default_channel_layout(ctx->channels);
-			aud->resample_context = swr_alloc_set_opts(NULL,
-				layout, ctx->sample_fmt, aud->sample_rate,
-				layout, AV_SAMPLE_FMT_FLT, ctx->sample_rate,
+			//uint64_t layout = av_get_default_channel_layout(ctx->ch_layout.nb_channels);
+			AVChannelLayout layout;
+			av_channel_layout_default(&layout, ctx->ch_layout.nb_channels);
+			swr_alloc_set_opts2(&aud->resample_context,
+				&layout, ctx->sample_fmt, aud->sample_rate,
+				&layout, AV_SAMPLE_FMT_FLT, ctx->sample_rate,
 				0, NULL);
 			swr_init(aud->resample_context);
 			aud->writing = -1;
@@ -3929,7 +3945,7 @@ int FFAudioStream::create_filter(const char *filter_spec)
 	snprintf(args, sizeof(args),
 		"time_base=%d/%d:sample_rate=%d:sample_fmt=%s:channel_layout=0x%jx",
 		st->time_base.num, st->time_base.den, avpar->sample_rate,
-		av_get_sample_fmt_name(sample_fmt), avpar->channel_layout);
+		av_get_sample_fmt_name(sample_fmt), avpar->ch_layout.u.mask);
 	if( ret >= 0 ) {
 		filt_ctx = 0;
 		ret = insert_filter("abuffer", args, "in");
@@ -3947,8 +3963,8 @@ int FFAudioStream::create_filter(const char *filter_spec)
 			AV_OPT_SEARCH_CHILDREN);
 	if( ret >= 0 )
 		ret = av_opt_set_bin(buffersink_ctx, "channel_layouts",
-			(uint8_t*)&avpar->channel_layout,
-			sizeof(avpar->channel_layout), AV_OPT_SEARCH_CHILDREN);
+			(uint8_t*)&avpar->ch_layout.u.mask,
+			sizeof(avpar->ch_layout.u.mask), AV_OPT_SEARCH_CHILDREN);
 	if( ret >= 0 )
 		ret = av_opt_set_bin(buffersink_ctx, "sample_rates",
 			(uint8_t*)&sample_rate, sizeof(sample_rate),
@@ -4200,7 +4216,7 @@ printf("audio%d pad %jd %jd (%jd)\n", aud->idx, pos, aud->curr_pos, pos-aud->cur
 			}
 			while( (ret=aud->decode_frame(frame)) > 0 ) {
 				//if( frame->channels != nch ) break;
-				aud->init_swr(frame->channels, frame->format, frame->sample_rate);
+				aud->init_swr(frame->ch_layout.nb_channels, frame->format, frame->sample_rate);
 				float *samples;
 				int len = aud->get_samples(samples,
 					 &frame->extended_data[0], frame->nb_samples);
diff --git a/cinelerra-5.1/cinelerra/fileac3.C b/cinelerra-5.1/cinelerra/fileac3.C
index dd3b4536..1f0083f0 100644
--- a/cinelerra-5.1/cinelerra/fileac3.C
+++ b/cinelerra-5.1/cinelerra/fileac3.C
@@ -142,17 +142,20 @@ int FileAC3::open_file(int rd, int wr)
 			int channels = asset->channels;
 			int sample_rate = asset->sample_rate;
 			int64_t layout = get_channel_layout(channels);
+			AVChannelLayout ch_layout;
+			av_channel_layout_from_mask(&ch_layout, layout);
 			int bitrate = asset->ac3_bitrate * 1000;
 			av_init_packet(&avpkt);
 			codec_context = avcodec_alloc_context3(codec);
 			codec_context->bit_rate = bitrate;
 			codec_context->sample_rate = sample_rate;
-			codec_context->channels = channels;
-			codec_context->channel_layout = layout;
+			codec_context->ch_layout.nb_channels = channels;
+			codec_context->ch_layout.u.mask = layout;
 			codec_context->sample_fmt = codec->sample_fmts[0];
-			resample_context = swr_alloc_set_opts(NULL,
-					layout, codec_context->sample_fmt, sample_rate,
-					layout, AV_SAMPLE_FMT_S16, sample_rate,
+			SwrContext *resample_context = NULL;
+			swr_alloc_set_opts2(&resample_context,
+					&ch_layout, codec_context->sample_fmt, sample_rate,
+					&ch_layout, AV_SAMPLE_FMT_S16, sample_rate,
 					0, NULL);
 			swr_init(resample_context);
 			if(avcodec_open2(codec_context, codec, 0))
@@ -314,7 +317,7 @@ int FileAC3::write_samples(double **buffer, int64_t len)
 		AVFrame *frame = av_frame_alloc();
 		frame->nb_samples = frame_size;
 		frame->format = avctx->sample_fmt;
-		frame->channel_layout = avctx->channel_layout;
+		frame->ch_layout.u.mask = avctx->ch_layout.u.mask;
 		frame->sample_rate = avctx->sample_rate;
 		ret = av_frame_get_buffer(frame, 0);
 		if( ret >= 0 ) {
diff --git a/cinelerra-5.1/cinelerra/fileffmpeg.C b/cinelerra-5.1/cinelerra/fileffmpeg.C
index 2fbf6c86..abed22da 100644
--- a/cinelerra-5.1/cinelerra/fileffmpeg.C
+++ b/cinelerra-5.1/cinelerra/fileffmpeg.C
@@ -1493,7 +1493,7 @@ int FFOptions_Opt::types(char *rp)
 	case AV_OPT_TYPE_SAMPLE_FMT: cp = N_("<sample_fmt>"); break;
 	case AV_OPT_TYPE_DURATION: cp = N_("<duration>"); break;
 	case AV_OPT_TYPE_COLOR: cp = N_("<color>"); break;
-	case AV_OPT_TYPE_CHANNEL_LAYOUT: cp = N_("<channel_layout>");  break;
+	case AV_OPT_TYPE_CHLAYOUT: cp = N_("<channel_layout>");  break;
 	case AV_OPT_TYPE_BOOL: cp = N_("<bool>");  break;
 	default: cp = N_("<undef>");  break;
 	}
diff --git a/cinelerra-5.1/cinelerra/pluginfclient.C b/cinelerra-5.1/cinelerra/pluginfclient.C
index 2d57743c..5d4fb659 100644
--- a/cinelerra-5.1/cinelerra/pluginfclient.C
+++ b/cinelerra-5.1/cinelerra/pluginfclient.C
@@ -453,7 +453,7 @@ int PluginFClient_Opt::types(char *rp)
 	case AV_OPT_TYPE_SAMPLE_FMT: cp = "<sample_fmt>"; break;
 	case AV_OPT_TYPE_DURATION: cp = "<duration>"; break;
 	case AV_OPT_TYPE_COLOR: cp = "<color>"; break;
-	case AV_OPT_TYPE_CHANNEL_LAYOUT: cp = "<channel_layout>";  break;
+	case AV_OPT_TYPE_CHLAYOUT: cp = "<channel_layout>";  break;
 	default: cp = "<undef>";  break;
 	}
 	return sprintf(rp, "%s", cp);
@@ -664,7 +664,7 @@ PluginFClient::~PluginFClient()
 bool PluginFClient::is_audio(const AVFilter *fp)
 {
 	if( !fp->outputs ) return 0;
-#if LIBAVFILTER_VERSION_MINOR > 2 && LIBAVFILTER_VERSION_MAJOR > 7
+#if LIBAVFILTER_VERSION_MAJOR > 8
 	if( avfilter_filter_pad_count(fp, 1) > 1 ) return 0;
 #else
 	if( avfilter_pad_count(fp->outputs) > 1 ) return 0;
@@ -672,7 +672,7 @@ bool PluginFClient::is_audio(const AVFilter *fp)
 	if( !avfilter_pad_get_name(fp->outputs, 0) ) return 0;
 	if( avfilter_pad_get_type(fp->outputs, 0) != AVMEDIA_TYPE_AUDIO ) return 0;
 	if( !fp->inputs ) return 1;
-#if LIBAVFILTER_VERSION_MINOR > 2 && LIBAVFILTER_VERSION_MAJOR > 7
+#if  LIBAVFILTER_VERSION_MAJOR > 8
 	if( avfilter_filter_pad_count(fp, 0) > 1 ) return 0;
 #else
 	if( avfilter_pad_count(fp->inputs) > 1 ) return 0;
@@ -684,7 +684,7 @@ bool PluginFClient::is_audio(const AVFilter *fp)
 bool PluginFClient::is_video(const AVFilter *fp)
 {
 	if( !fp->outputs ) return 0;
-#if LIBAVFILTER_VERSION_MINOR > 2 && LIBAVFILTER_VERSION_MAJOR > 7
+#if  LIBAVFILTER_VERSION_MAJOR > 8 
 	if( avfilter_filter_pad_count(fp, 1) > 1 ) return 0;
 #else
 	if( avfilter_pad_count(fp->outputs) > 1 ) return 0;
@@ -692,7 +692,7 @@ bool PluginFClient::is_video(const AVFilter *fp)
 	if( !avfilter_pad_get_name(fp->outputs, 0) ) return 0;
 	if( avfilter_pad_get_type(fp->outputs, 0) != AVMEDIA_TYPE_VIDEO ) return 0;
 	if( !fp->inputs ) return 1;
-#if LIBAVFILTER_VERSION_MINOR > 2 && LIBAVFILTER_VERSION_MAJOR > 7
+#if  LIBAVFILTER_VERSION_MAJOR > 8
 	if( avfilter_filter_pad_count(fp, 0) > 1 ) return 0;
 #else
 	if( avfilter_pad_count(fp->inputs) > 1 ) return 0;
@@ -992,7 +992,11 @@ int PluginFAClient::process_buffer(int64_t size, Samples **buffer, int64_t start
 		out_channels = get_outchannels();
 		frame->nb_samples = size;
 		frame->format = AV_SAMPLE_FMT_FLTP;
+#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(61,3,100)
+		frame->ch_layout.u.mask = (1<<in_channels)-1;
+#else
 		frame->channel_layout = (1<<in_channels)-1;
+#endif
 		frame->sample_rate = sample_rate;
 		frame->pts = filter_position;
 	}
-- 
2.35.8

From 39878296bfd812b38736c7a46566afb42cff8b09 Mon Sep 17 00:00:00 2001
From: Andrew Randrianasulu <[email protected]>
Date: Sun, 7 Apr 2024 16:37:13 +0300
Subject: [PATCH 2/5] Switch configure.ac to ffmpeg 7.0

---
 cinelerra-5.1/configure.ac | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/cinelerra-5.1/configure.ac b/cinelerra-5.1/configure.ac
index 4b72a861..909ffe4b 100644
--- a/cinelerra-5.1/configure.ac
+++ b/cinelerra-5.1/configure.ac
@@ -223,7 +223,7 @@ PKG_3RD([esound],[no],
   [ . ])
 
 PKG_3RD([ffmpeg],[yes],
-  [ffmpeg-6.1],
+  [ffmpeg-7.0],
   [ libavutil/libavutil.a \
     libavcodec/libavcodec.a \
     libpostproc/libpostproc.a \
-- 
2.35.8

From a914608efedbacf105c7c33caef9dff0e0b6c2ec Mon Sep 17 00:00:00 2001
From: Andrew Randrianasulu <[email protected]>
Date: Sun, 7 Apr 2024 16:47:40 +0300
Subject: [PATCH 4/5] Four more patches for ffmpeg 7.0

---
 .../thirdparty/src/ffmpeg-7.0.patchB          | 22 +++++++++
 .../thirdparty/src/ffmpeg-7.0.patchC          | 41 ++++++++++++++++
 .../thirdparty/src/ffmpeg-7.0.patchZ1         | 49 +++++++++++++++++++
 .../thirdparty/src/ffmpeg-7.0.patchZ2         | 11 +++++
 4 files changed, 123 insertions(+)
 create mode 100644 cinelerra-5.1/thirdparty/src/ffmpeg-7.0.patchB
 create mode 100644 cinelerra-5.1/thirdparty/src/ffmpeg-7.0.patchC
 create mode 100644 cinelerra-5.1/thirdparty/src/ffmpeg-7.0.patchZ1
 create mode 100644 cinelerra-5.1/thirdparty/src/ffmpeg-7.0.patchZ2

diff --git a/cinelerra-5.1/thirdparty/src/ffmpeg-7.0.patchB b/cinelerra-5.1/thirdparty/src/ffmpeg-7.0.patchB
new file mode 100644
index 00000000..89e99896
--- /dev/null
+++ b/cinelerra-5.1/thirdparty/src/ffmpeg-7.0.patchB
@@ -0,0 +1,22 @@
+--- a/libavutil/hwcontext_vdpau.c
++++ b/libavutil/hwcontext_vdpau.c
+@@ -47,6 +47,11 @@
+     { 0,                     AV_PIX_FMT_NONE,   },
+ };
+ 
++static const VDPAUPixFmtMap pix_fmts_420j[] = {
++    { VDP_YCBCR_FORMAT_YV12, AV_PIX_FMT_YUVJ420P },
++    { 0,                     AV_PIX_FMT_NONE,   },
++};
++
+ static const VDPAUPixFmtMap pix_fmts_422[] = {
+     { VDP_YCBCR_FORMAT_NV12, AV_PIX_FMT_NV16    },
+     { VDP_YCBCR_FORMAT_YV12, AV_PIX_FMT_YUV422P },
+@@ -71,6 +76,7 @@
+     const VDPAUPixFmtMap *map;
+ } vdpau_pix_fmts[] = {
+     { VDP_CHROMA_TYPE_420, AV_PIX_FMT_YUV420P, pix_fmts_420 },
++    { VDP_CHROMA_TYPE_420, AV_PIX_FMT_YUVJ420P, pix_fmts_420j },
+     { VDP_CHROMA_TYPE_422, AV_PIX_FMT_YUV422P, pix_fmts_422 },
+     { VDP_CHROMA_TYPE_444, AV_PIX_FMT_YUV444P, pix_fmts_444 },
+ #ifdef VDP_YCBCR_FORMAT_P016
diff --git a/cinelerra-5.1/thirdparty/src/ffmpeg-7.0.patchC b/cinelerra-5.1/thirdparty/src/ffmpeg-7.0.patchC
new file mode 100644
index 00000000..56df39cc
--- /dev/null
+++ b/cinelerra-5.1/thirdparty/src/ffmpeg-7.0.patchC
@@ -0,0 +1,41 @@
+--- a/libavcodec/encode.c
++++ b/libavcodec/encode.c
+@@ -331,7 +331,7 @@
+     }
+ 
+     if (!frame->buf[0]) {
+-        if (!(avctx->codec->capabilities & AV_CODEC_CAP_DELAY ||
++        if (avci->draining && !(avctx->codec->capabilities & AV_CODEC_CAP_DELAY ||
+               avci->frame_thread_encoder))
+             return AVERROR_EOF;
+ 
+@@ -350,8 +350,10 @@
+         ret = ff_encode_encode_cb(avctx, avpkt, frame, &got_packet);
+     }
+ 
+-    if (avci->draining && !got_packet)
++    if (avci->draining && !got_packet) {
++       fflush(stderr);
+         avci->draining_done = 1;
++    }
+ 
+     return ret;
+ }
+@@ -526,10 +528,16 @@
+     if (avci->draining)
+         return AVERROR_EOF;
+ 
+-    if (avci->buffer_frame->buf[0])
++    if (avci->buffer_frame->buf[0]) {
++        if (!frame) {
++           fflush(stderr);
++            av_frame_unref(avci->buffer_frame);
++       }
+         return AVERROR(EAGAIN);
++    }
+ 
+     if (!frame) {
++       fflush(stderr);
+         avci->draining = 1;
+     } else {
+         ret = encode_send_frame_internal(avctx, frame);
diff --git a/cinelerra-5.1/thirdparty/src/ffmpeg-7.0.patchZ1 b/cinelerra-5.1/thirdparty/src/ffmpeg-7.0.patchZ1
new file mode 100644
index 00000000..29cfb628
--- /dev/null
+++ b/cinelerra-5.1/thirdparty/src/ffmpeg-7.0.patchZ1
@@ -0,0 +1,49 @@
+--- a/libavcodec/wrapped_avframe.c
++++ b/libavcodec/wrapped_avframe.c
+@@ -33,6 +33,38 @@
+ #include "libavutil/buffer.h"
+ #include "libavutil/pixdesc.h"
+ 
++
++
++static const enum AVPixelFormat pix_fmts_all[] = {
++    AV_PIX_FMT_YUV411P,
++    AV_PIX_FMT_YUV420P,
++    AV_PIX_FMT_YUVJ420P,
++    AV_PIX_FMT_YUV422P,
++    AV_PIX_FMT_YUVJ422P,
++    AV_PIX_FMT_YUV444P,
++    AV_PIX_FMT_YUVJ444P,
++    AV_PIX_FMT_YUV420P10,
++    AV_PIX_FMT_YUV422P10,
++    AV_PIX_FMT_YUV444P10,
++    AV_PIX_FMT_YUV420P12,
++    AV_PIX_FMT_YUV422P12,
++    AV_PIX_FMT_YUV444P12,
++    AV_PIX_FMT_YUV420P14,
++    AV_PIX_FMT_YUV422P14,
++    AV_PIX_FMT_YUV444P14,
++    AV_PIX_FMT_YUV420P16,
++    AV_PIX_FMT_YUV422P16,
++    AV_PIX_FMT_YUV444P16,
++    AV_PIX_FMT_GRAY8,
++    AV_PIX_FMT_GRAY9,
++    AV_PIX_FMT_GRAY10,
++    AV_PIX_FMT_GRAY12,
++    AV_PIX_FMT_GRAY16,
++    AV_PIX_FMT_NONE
++};
++
++
++
+ static void wrapped_avframe_release_buffer(void *unused, uint8_t *data)
+ {
+     AVFrame *frame = (AVFrame *)data;
+@@ -111,6 +143,7 @@
+     .p.id           = AV_CODEC_ID_WRAPPED_AVFRAME,
+     .p.capabilities = AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
+     FF_CODEC_ENCODE_CB(wrapped_avframe_encode),
++    .p.pix_fmts       = pix_fmts_all,
+ };
+ 
+ const FFCodec ff_wrapped_avframe_decoder = {
diff --git a/cinelerra-5.1/thirdparty/src/ffmpeg-7.0.patchZ2 b/cinelerra-5.1/thirdparty/src/ffmpeg-7.0.patchZ2
new file mode 100644
index 00000000..a883b14d
--- /dev/null
+++ b/cinelerra-5.1/thirdparty/src/ffmpeg-7.0.patchZ2
@@ -0,0 +1,11 @@
+--- a/libavformat/yuv4mpegenc.c
++++ b/libavformat/yuv4mpegenc.c
+@@ -268,7 +268,7 @@
+             av_log(s, AV_LOG_ERROR, "'%s' is not an official yuv4mpegpipe pixel format. "
+                    "Use '-strict -1' to encode to this pixel format.\n",
+                    av_get_pix_fmt_name(s->streams[0]->codecpar->format));
+-            return AVERROR(EINVAL);
++            //return AVERROR(EINVAL);
+         }
+         av_log(s, AV_LOG_WARNING, "Warning: generating non standard YUV stream. "
+                "Mjpegtools will not work.\n");
-- 
2.35.8

From fb56a47b515fc487125d7503767ef4e71a9e017e Mon Sep 17 00:00:00 2001
From: Andrew Randrianasulu <[email protected]>
Date: Sun, 7 Apr 2024 17:26:38 +0300
Subject: [PATCH 5/5] Fix audio encoding with ffmpeg 7.0

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

diff --git a/cinelerra-5.1/cinelerra/ffmpeg.C b/cinelerra-5.1/cinelerra/ffmpeg.C
index e0e9bf62..2fa3d85d 100644
--- a/cinelerra-5.1/cinelerra/ffmpeg.C
+++ b/cinelerra-5.1/cinelerra/ffmpeg.C
@@ -993,6 +993,7 @@ int FFAudioStream::init_frame(AVFrame *frame)
 	frame->format = avctx->sample_fmt;
 #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(61,3,100)
 	frame->ch_layout.u.mask = avctx->ch_layout.u.mask;
+	av_channel_layout_copy(&frame->ch_layout, &avctx->ch_layout);
 #else
 	frame->channel_layout = avctx->channel_layout;
 #endif
@@ -2961,6 +2962,7 @@ int FFMPEG::open_encoder(const char *type, const char *spec)
 			AVChannelLayout ch_layout;
 			av_channel_layout_default(&ch_layout, ctx->ch_layout.nb_channels);
 			ctx->ch_layout.u.mask =  ch_layout.u.mask;
+			av_channel_layout_copy(&ctx->ch_layout, &ch_layout);
 			ctx->sample_rate = check_sample_rate(codec, asset->sample_rate);
 			if( !ctx->sample_rate ) {
 				eprintf(_("check_sample_rate failed %s\n"), filename);
-- 
2.35.8

From 5821280af8521e4161f48a0f8d862245adecbb04 Mon Sep 17 00:00:00 2001
From: Andrew Randrianasulu <[email protected]>
Date: Sun, 7 Apr 2024 16:37:50 +0300
Subject: [PATCH 3/5] Add some 7.0 patches. Patch 3 and 4 need rebase

---
 .../thirdparty/src/ffmpeg-7.0.patch1          |  11 +
 .../thirdparty/src/ffmpeg-7.0.patch10         |  16 +
 .../thirdparty/src/ffmpeg-7.0.patch2          | 414 ++++++++++++++++++
 .../thirdparty/src/ffmpeg-7.0.patch5          |  25 ++
 .../thirdparty/src/ffmpeg-7.0.patch7          |  10 +
 .../thirdparty/src/ffmpeg-7.0.patch8          |  11 +
 .../thirdparty/src/ffmpeg-7.0.patch9          |  14 +
 7 files changed, 501 insertions(+)
 create mode 100644 cinelerra-5.1/thirdparty/src/ffmpeg-7.0.patch1
 create mode 100644 cinelerra-5.1/thirdparty/src/ffmpeg-7.0.patch10
 create mode 100644 cinelerra-5.1/thirdparty/src/ffmpeg-7.0.patch2
 create mode 100644 cinelerra-5.1/thirdparty/src/ffmpeg-7.0.patch5
 create mode 100644 cinelerra-5.1/thirdparty/src/ffmpeg-7.0.patch7
 create mode 100644 cinelerra-5.1/thirdparty/src/ffmpeg-7.0.patch8
 create mode 100644 cinelerra-5.1/thirdparty/src/ffmpeg-7.0.patch9

diff --git a/cinelerra-5.1/thirdparty/src/ffmpeg-7.0.patch1 b/cinelerra-5.1/thirdparty/src/ffmpeg-7.0.patch1
new file mode 100644
index 00000000..e157d3f3
--- /dev/null
+++ b/cinelerra-5.1/thirdparty/src/ffmpeg-7.0.patch1
@@ -0,0 +1,11 @@
+--- a/fftools/cmdutils.c
++++ b/fftools/cmdutils.c
+@@ -59,7 +59,7 @@
+ AVDictionary *swr_opts;
+ AVDictionary *format_opts, *codec_opts;
+ 
+-int hide_banner = 0;
++int hide_banner = 1;
+ 
+ void uninit_opts(void)
+ {
diff --git a/cinelerra-5.1/thirdparty/src/ffmpeg-7.0.patch10 b/cinelerra-5.1/thirdparty/src/ffmpeg-7.0.patch10
new file mode 100644
index 00000000..1fc3f890
--- /dev/null
+++ b/cinelerra-5.1/thirdparty/src/ffmpeg-7.0.patch10
@@ -0,0 +1,16 @@
+--- a/libavutil/hwcontext_cuda.c.orig	2023-11-11 03:25:17.000000000 +0300
++++ b/libavutil/hwcontext_cuda.c	2023-11-12 17:52:01.243063419 +0300
+@@ -361,11 +361,13 @@
+                                                     hwctx->internal->cuda_device));
+         if (ret < 0)
+             return ret;
++#if 0
+     } else if (flags & AV_CUDA_USE_CURRENT_CONTEXT) {
+         ret = CHECK_CU(cu->cuCtxGetCurrent(&hwctx->cuda_ctx));
+         if (ret < 0)
+             return ret;
+         av_log(device_ctx, AV_LOG_INFO, "Using current CUDA context.\n");
++#endif
+     } else {
+         ret = CHECK_CU(cu->cuCtxCreate(&hwctx->cuda_ctx, desired_flags,
+                                        hwctx->internal->cuda_device));
diff --git a/cinelerra-5.1/thirdparty/src/ffmpeg-7.0.patch2 b/cinelerra-5.1/thirdparty/src/ffmpeg-7.0.patch2
new file mode 100644
index 00000000..77050275
--- /dev/null
+++ b/cinelerra-5.1/thirdparty/src/ffmpeg-7.0.patch2
@@ -0,0 +1,414 @@
+--- a/libavformat/mpegtsenc.c
++++ b/libavformat/mpegtsenc.c
+@@ -87,9 +87,11 @@
+     int64_t pat_period; /* PAT/PMT period in PCR time base */
+     int64_t nit_period; /* NIT period in PCR time base */
+     int nb_services;
+-    int64_t first_pcr;
+     int first_dts_checked;
+-    int64_t next_pcr;
++    int64_t pcr_pos, pcr;
++    int64_t first_pcr, next_pcr;
++    int64_t delay;
++    int pcr_stream_pid;
+     int mux_rate; ///< set to 1 when VBR
+     int pes_payload_size;
+     int64_t total_size;
+@@ -256,7 +258,7 @@
+     int data_st_warning;
+ 
+     int64_t pcr_period; /* PCR period in PCR time base */
+-    int64_t last_pcr;
++    int64_t pcr_timer;
+ 
+     /* For Opus */
+     int opus_queued_samples;
+@@ -954,18 +956,18 @@
+     return 0;
+ }
+ 
+-static int64_t get_pcr(const MpegTSWrite *ts)
++static int64_t get_pcr(const MpegTSWrite *ts, AVIOContext *pb)
+ {
+-    return av_rescale(ts->total_size + 11, 8 * PCR_TIME_BASE, ts->mux_rate) +
+-           ts->first_pcr;
++    int64_t pos = avio_tell(pb) + 11;
++    return ts->pcr + (ts->mux_rate == 1 ? (pos - ts->pcr_pos) * 8 :
++        av_rescale(pos - ts->pcr_pos, 8 * PCR_TIME_BASE, ts->mux_rate));
+ }
+ 
+ static void write_packet(AVFormatContext *s, const uint8_t *packet)
+ {
+     MpegTSWrite *ts = s->priv_data;
+     if (ts->m2ts_mode) {
+-        int64_t pcr = get_pcr(s->priv_data);
+-        uint32_t tp_extra_header = pcr % 0x3fffffff;
++        uint32_t tp_extra_header = get_pcr(ts, s->pb) % 0x3fffffff;
+         tp_extra_header = AV_RB32(&tp_extra_header);
+         avio_write(s->pb, (unsigned char *) &tp_extra_header,
+                    sizeof(tp_extra_header));
+@@ -1051,9 +1053,6 @@
+         else
+             ts_st->pcr_period = 1;
+     }
+-
+-    // output a PCR as soon as possible
+-    ts_st->last_pcr   = ts->first_pcr - ts_st->pcr_period;
+ }
+ 
+ static void select_pcr_streams(AVFormatContext *s)
+@@ -1116,6 +1115,7 @@
+ 
+     if (s->max_delay < 0) /* Not set by the caller */
+         s->max_delay = 0;
++    ts->delay = av_rescale(s->max_delay, 90000, AV_TIME_BASE);
+ 
+     // round up to a whole number of TS packets
+     ts->pes_payload_size = (ts->pes_payload_size + 14 + 183) / 184 * 184 - 14;
+@@ -1175,7 +1175,9 @@
+         /* MPEG pid values < 16 are reserved. Applications which set st->id in
+          * this range are assigned a calculated pid. */
+         if (st->id < 16) {
+-            if (ts->m2ts_mode) {
++            if (ts->start_pid >= 0)
++                ts_st->pid = ts->start_pid + i;
++            else if (ts->m2ts_mode) {
+                 switch (st->codecpar->codec_type) {
+                 case AVMEDIA_TYPE_VIDEO:
+                     ts_st->pid = ts->m2ts_video_pid++;
+@@ -1202,9 +1204,9 @@
+                     av_log(s, AV_LOG_ERROR, "Cannot automatically assign PID for stream %d\n", st->index);
+                     return AVERROR(EINVAL);
+                 }
+-            } else {
+-                ts_st->pid = ts->start_pid + i;
+             }
++            else
++                ts_st->pid = START_PID + i;
+         } else {
+             ts_st->pid = st->id;
+         }
+@@ -1272,9 +1274,14 @@
+     ts->last_pat_ts = AV_NOPTS_VALUE;
+     ts->last_sdt_ts = AV_NOPTS_VALUE;
+     ts->last_nit_ts = AV_NOPTS_VALUE;
+-    ts->pat_period = av_rescale(ts->pat_period_us, PCR_TIME_BASE, AV_TIME_BASE);
+-    ts->sdt_period = av_rescale(ts->sdt_period_us, PCR_TIME_BASE, AV_TIME_BASE);
+-    ts->nit_period = av_rescale(ts->nit_period_us, PCR_TIME_BASE, AV_TIME_BASE);
++    ts->pat_period = ts->pat_period_us < 0 ? -1 :
++        av_rescale(ts->pat_period_us, PCR_TIME_BASE, AV_TIME_BASE);
++    ts->sdt_period = ts->sdt_period_us < 0 ? -1 :
++        av_rescale(ts->sdt_period_us, PCR_TIME_BASE, AV_TIME_BASE);
++    ts->nit_period = ts->nit_period_us < 0 ? -1 :
++        av_rescale(ts->nit_period_us, PCR_TIME_BASE, AV_TIME_BASE);
++    ts->pcr = 0;
++    ts->pcr_pos = 0;
+ 
+     /* assign provider name */
+     provider = av_dict_get(s->metadata, "service_provider", NULL, 0);
+@@ -1290,8 +1297,8 @@
+         av_log(s, AV_LOG_VERBOSE, "muxrate %d, ", ts->mux_rate);
+     av_log(s, AV_LOG_VERBOSE,
+            "sdt every %"PRId64" ms, pat/pmt every %"PRId64" ms",
+-           av_rescale(ts->sdt_period, 1000, PCR_TIME_BASE),
+-           av_rescale(ts->pat_period, 1000, PCR_TIME_BASE));
++           ts->sdt_period < 0 ? -1 : av_rescale(ts->sdt_period, 1000, PCR_TIME_BASE),
++           ts->pat_period < 0 ? -1 : av_rescale(ts->pat_period, 1000, PCR_TIME_BASE));
+     if (ts->flags & MPEGTS_FLAG_NIT)
+         av_log(s, AV_LOG_VERBOSE, ", nit every %"PRId64" ms", av_rescale(ts->nit_period, 1000, PCR_TIME_BASE));
+     av_log(s, AV_LOG_VERBOSE, "\n");
+@@ -1300,36 +1307,40 @@
+ }
+ 
+ /* send SDT, NIT, PAT and PMT tables regularly */
+-static void retransmit_si_info(AVFormatContext *s, int force_pat, int force_sdt, int force_nit, int64_t pcr)
++static void retransmit_si_info(AVFormatContext *s, int force_pat, int force_sdt, int force_nit)
+ {
+     MpegTSWrite *ts = s->priv_data;
+     int i;
+ 
+-    if ((pcr != AV_NOPTS_VALUE && ts->last_sdt_ts == AV_NOPTS_VALUE) ||
+-        (pcr != AV_NOPTS_VALUE && pcr - ts->last_sdt_ts >= ts->sdt_period) ||
+-        force_sdt
+-    ) {
+-        if (pcr != AV_NOPTS_VALUE)
+-            ts->last_sdt_ts = FFMAX(pcr, ts->last_sdt_ts);
+-        mpegts_write_sdt(s);
+-    }
+-    if ((pcr != AV_NOPTS_VALUE && ts->last_pat_ts == AV_NOPTS_VALUE) ||
+-        (pcr != AV_NOPTS_VALUE && pcr - ts->last_pat_ts >= ts->pat_period) ||
+-        force_pat) {
+-        if (pcr != AV_NOPTS_VALUE)
+-            ts->last_pat_ts = FFMAX(pcr, ts->last_pat_ts);
+-        mpegts_write_pat(s);
+-        for (i = 0; i < ts->nb_services; i++)
+-            mpegts_write_pmt(s, ts->services[i]);
+-    }
+-    if ((pcr != AV_NOPTS_VALUE && ts->last_nit_ts == AV_NOPTS_VALUE) ||
+-        (pcr != AV_NOPTS_VALUE && pcr - ts->last_nit_ts >= ts->nit_period) ||
+-        force_nit
+-    ) {
+-        if (pcr != AV_NOPTS_VALUE)
+-            ts->last_nit_ts = FFMAX(pcr, ts->last_nit_ts);
++    if (ts->sdt_period >= 0) {
++        int64_t pcr = get_pcr(ts, s->pb);
++        if (ts->last_sdt_ts == AV_NOPTS_VALUE || pcr >= ts->last_sdt_ts + ts->sdt_period)
++            force_sdt = 1;
++        if (force_sdt) {
++            ts->last_sdt_ts = pcr;
++            mpegts_write_sdt(s);
++        }
++    }
++    if (ts->pat_period >= 0) {
++        int64_t pcr = get_pcr(ts, s->pb);
++        if (ts->last_pat_ts == AV_NOPTS_VALUE || pcr >= ts->last_pat_ts + ts->pat_period)
++            force_pat = 1;
++        if (force_pat) {
++            ts->last_pat_ts = pcr;
++            mpegts_write_pat(s);
++            for (i = 0; i < ts->nb_services; i++)
++                mpegts_write_pmt(s, ts->services[i]);
++        }
++    }
++    if (ts->nit_period >= 0) {
++        int64_t pcr = get_pcr(ts, s->pb);
++        if (ts->last_nit_ts == AV_NOPTS_VALUE || pcr >= ts->last_nit_ts + ts->nit_period)
++            force_nit = 1;
++        if (force_nit) {
++            ts->last_nit_ts = pcr;
+         if (ts->flags & MPEGTS_FLAG_NIT)
+             mpegts_write_nit(s);
++        }
+     }
+ }
+ 
+@@ -1366,25 +1377,29 @@
+ static void mpegts_insert_pcr_only(AVFormatContext *s, AVStream *st)
+ {
+     MpegTSWrite *ts = s->priv_data;
+-    MpegTSWriteStream *ts_st = st->priv_data;
++    int64_t pcr = get_pcr(ts, s->pb);
++    MpegTSWriteStream *ts_st = st ? st->priv_data : 0;
++    uint32_t pcr_pid = ts_st ? ts_st->pid : ts->pcr_stream_pid;
+     uint8_t *q;
+     uint8_t buf[TS_PACKET_SIZE];
+ 
+     q    = buf;
+     *q++ = 0x47;
+-    *q++ = ts_st->pid >> 8;
+-    *q++ = ts_st->pid;
+-    *q++ = 0x20 | ts_st->cc;   /* Adaptation only */
++    *q++ = pcr_pid >> 8;
++    *q++ = pcr_pid;
++    uint32_t flags =  0x20;    /* Adaptation only */
+     /* Continuity Count field does not increment (see 13818-1 section 2.4.3.3) */
++    if(ts_st) flags |= ts_st->cc;
++    *q++ = flags;
+     *q++ = TS_PACKET_SIZE - 5; /* Adaptation Field Length */
+     *q++ = 0x10;               /* Adaptation flags: PCR present */
+-    if (ts_st->discontinuity) {
++    if (ts_st && ts_st->discontinuity) {
+         q[-1] |= 0x80;
+         ts_st->discontinuity = 0;
+     }
+ 
+     /* PCR coded into 6 bytes */
+-    q += write_pcr_bits(q, get_pcr(ts));
++    q += write_pcr_bits(q, pcr);
+ 
+     /* stuffing bytes */
+     memset(q, 0xFF, TS_PACKET_SIZE - (q - buf));
+@@ -1485,9 +1500,9 @@
+     int afc_len, stuffing_len;
+     int is_dvb_subtitle = (st->codecpar->codec_id == AV_CODEC_ID_DVB_SUBTITLE);
+     int is_dvb_teletext = (st->codecpar->codec_id == AV_CODEC_ID_DVB_TELETEXT);
+-    int64_t delay = av_rescale(s->max_delay, 90000, AV_TIME_BASE);
+     int force_pat = st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && key && !ts_st->prev_payload_key;
+     int force_sdt = 0;
++    int64_t pcr;
+     int force_nit = 0;
+ 
+     av_assert0(ts_st->payload != buf || st->codecpar->codec_type != AVMEDIA_TYPE_VIDEO);
+@@ -1504,21 +1519,19 @@
+ 
+     is_start = 1;
+     while (payload_size > 0) {
+-        int64_t pcr = AV_NOPTS_VALUE;
+-        if (ts->mux_rate > 1)
+-            pcr = get_pcr(ts);
+-        else if (dts != AV_NOPTS_VALUE)
+-            pcr = (dts - delay) * 300;
+-
+-        retransmit_si_info(s, force_pat, force_sdt, force_nit, pcr);
+-        force_pat = 0;
+-        force_sdt = 0;
+-        force_nit = 0;
++        // add 11, pcr references the last byte of program clock reference base
++        ts->pcr_pos = avio_tell(s->pb) + 11;
++        pcr = ts->pcr = ts->mux_rate != 1 ?
++            av_rescale(ts->pcr_pos, 8 * PCR_TIME_BASE, ts->mux_rate) :
++            (dts == AV_NOPTS_VALUE ? 0 : (dts - ts->delay) * 300);
++        if (force_pat || force_sdt || force_nit) {
++            retransmit_si_info(s, force_pat, force_sdt, force_nit);
++            force_pat = force_sdt = force_nit = 0;
++        }
+ 
+         write_pcr = 0;
+         if (ts->mux_rate > 1) {
+             /* Send PCR packets for all PCR streams if needed */
+-            pcr = get_pcr(ts);
+             if (pcr >= ts->next_pcr) {
+                 int64_t next_pcr = INT64_MAX;
+                 for (int i = 0; i < s->nb_streams; i++) {
+@@ -1528,36 +1541,43 @@
+                     AVStream *st2 = s->streams[st2_index];
+                     MpegTSWriteStream *ts_st2 = st2->priv_data;
+                     if (ts_st2->pcr_period) {
+-                        if (pcr - ts_st2->last_pcr >= ts_st2->pcr_period) {
+-                            ts_st2->last_pcr = FFMAX(pcr - ts_st2->pcr_period, ts_st2->last_pcr + ts_st2->pcr_period);
+-                            if (st2 != st) {
++                        if (pcr >= ts_st2->pcr_timer) {
++                            ts_st2->pcr_timer = pcr + ts_st2->pcr_period;
++                            if (st2 != st) { 
+                                 mpegts_insert_pcr_only(s, st2);
+-                                pcr = get_pcr(ts);
+                             } else {
+                                 write_pcr = 1;
+                             }
+                         }
+-                        next_pcr = FFMIN(next_pcr, ts_st2->last_pcr + ts_st2->pcr_period);
++                        next_pcr = FFMIN(next_pcr, ts_st2->pcr_timer);
+                     }
+                 }
+                 ts->next_pcr = next_pcr;
+             }
+-            if (dts != AV_NOPTS_VALUE && (dts - pcr / 300) > delay) {
+-                /* pcr insert gets priority over null packet insert */
+-                if (write_pcr)
+-                    mpegts_insert_pcr_only(s, st);
+-                else
+-                    mpegts_insert_null_packet(s);
+-                /* recalculate write_pcr and possibly retransmit si_info */
+-                continue;
+-            }
+-        } else if (ts_st->pcr_period && pcr != AV_NOPTS_VALUE) {
+-            if (pcr - ts_st->last_pcr >= ts_st->pcr_period && is_start) {
+-                ts_st->last_pcr = FFMAX(pcr - ts_st->pcr_period, ts_st->last_pcr + ts_st->pcr_period);
++        }
++        else if (ts_st->pcr_period) {
++            if (pcr >= ts_st->pcr_timer) {
++                ts_st->pcr_timer = pcr + ts_st->pcr_period;
+                 write_pcr = 1;
+             }
+         }
+ 
++        if (write_pcr && ts->pcr_stream_pid >= 0) {
++           mpegts_insert_pcr_only(s, 0);
++           continue;
++        }
++
++        if (ts->mux_rate > 1 && dts != AV_NOPTS_VALUE &&
++               (dts - pcr / 300) > ts->delay) {
++           /* pcr insert gets priority over null packet insert */
++           if (write_pcr)
++               mpegts_insert_pcr_only(s, st);
++            else
++               mpegts_insert_null_packet(s);
++            /* recalculate write_pcr and possibly retransimit si_info */
++            continue;
++        }
++
+         /* prepare packet header */
+         q    = buf;
+         *q++ = 0x47;
+@@ -1587,7 +1607,6 @@
+         if (write_pcr) {
+             set_af_flag(buf, 0x10);
+             q = get_ts_payload_start(buf);
+-            // add 11, pcr references the last byte of program clock reference base
+             if (dts != AV_NOPTS_VALUE && dts < pcr / 300)
+                 av_log(s, AV_LOG_WARNING, "dts < pcr, TS is invalid\n");
+             extend_af(buf, write_pcr_bits(q, pcr));
+@@ -1851,8 +1870,8 @@
+     uint8_t *data = NULL;
+     MpegTSWrite *ts = s->priv_data;
+     MpegTSWriteStream *ts_st = st->priv_data;
+-    const int64_t delay = av_rescale(s->max_delay, 90000, AV_TIME_BASE) * 2;
+-    const int64_t max_audio_delay = av_rescale(s->max_delay, 90000, AV_TIME_BASE) / 2;
++    const int64_t delay_ticks2 = ts->delay * 2;
++    const int64_t max_audio_delay = ts->delay / 2;
+     int64_t dts = pkt->dts, pts = pkt->pts;
+     int opus_samples = 0;
+     size_t side_data_size;
+@@ -1872,9 +1891,9 @@
+ 
+     if (ts->copyts < 1) {
+         if (pts != AV_NOPTS_VALUE)
+-            pts += delay;
++            pts += delay_ticks2;
+         if (dts != AV_NOPTS_VALUE)
+-            dts += delay;
++            dts += delay_ticks2;
+     }
+ 
+     if (!ts_st->first_timestamp_checked && (pts == AV_NOPTS_VALUE || dts == AV_NOPTS_VALUE)) {
+@@ -2305,8 +2324,10 @@
+       0, AV_OPT_TYPE_CONST, { .i64 = MPEGTS_SERVICE_TYPE_HEVC_DIGITAL_HDTV }, 0x01, 0xff, ENC, "mpegts_service_type" },
+     { "mpegts_pmt_start_pid", "Set the first pid of the PMT.",
+       OFFSET(pmt_start_pid), AV_OPT_TYPE_INT, { .i64 = 0x1000 }, FIRST_OTHER_PID, LAST_OTHER_PID, ENC },
++    { "mpegts_pcr_stream_pid", "create seperate PCR stream on this pid.",
++      OFFSET(pcr_stream_pid), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 0x1f00, ENC },
+     { "mpegts_start_pid", "Set the first pid.",
+-      OFFSET(start_pid), AV_OPT_TYPE_INT, { .i64 = 0x0100 }, FIRST_OTHER_PID, LAST_OTHER_PID, ENC },
++      OFFSET(start_pid), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, LAST_OTHER_PID, ENC },
+     { "mpegts_m2ts_mode", "Enable m2ts mode.", OFFSET(m2ts_mode), AV_OPT_TYPE_BOOL, { .i64 = -1 }, -1, 1, ENC },
+     { "muxrate", NULL, OFFSET(mux_rate), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, INT_MAX, ENC },
+     { "pes_payload_size", "Minimum PES packet payload in bytes",
+@@ -2332,10 +2353,10 @@
+       OFFSET(omit_video_pes_length), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, ENC },
+     { "pcr_period", "PCR retransmission time in milliseconds",
+       OFFSET(pcr_period_ms), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, ENC },
+-    { "pat_period", "PAT/PMT retransmission time limit in seconds",
++    { "pat_period", "PAT/PMT retransmission time limit in ms, -1 no pat",
+       OFFSET(pat_period_us), AV_OPT_TYPE_DURATION, { .i64 = PAT_RETRANS_TIME * 1000LL }, 0, INT64_MAX, ENC },
+-    { "sdt_period", "SDT retransmission time limit in seconds",
+-      OFFSET(sdt_period_us), AV_OPT_TYPE_DURATION, { .i64 = SDT_RETRANS_TIME * 1000LL }, 0, INT64_MAX, ENC },
++    { "sdt_period", "SDT retransmission time limit in ms, -1 no sdt",
++      OFFSET(sdt_period_us), AV_OPT_TYPE_INT64, { .i64 = SDT_RETRANS_TIME * 1000LL }, -1, INT64_MAX, ENC },
+     { "nit_period", "NIT retransmission time limit in seconds",
+       OFFSET(nit_period_us), AV_OPT_TYPE_DURATION, { .i64 = NIT_RETRANS_TIME * 1000LL }, 0, INT64_MAX, ENC },
+     { NULL },
+--- a/libavformat/mpegts.h
++++ b/libavformat/mpegts.h
+@@ -64,6 +64,7 @@
+ /* PID from 0x1FFC to 0x1FFE may be assigned as needed to PMT, elementary
+  * streams and other data tables */
+ #define NULL_PID        0x1FFF /* Null packet (used for fixed bandwidth padding) */
++#define START_PID	0x0400
+ 
+ /* m2ts pids */
+ #define M2TS_PMT_PID                      0x0100
+--- a/libavformat/bluray.c
++++ b/libavformat/bluray.c
+@@ -27,7 +27,7 @@
+ #include "libavutil/opt.h"
+ 
+ #define BLURAY_PROTO_PREFIX     "bluray:"
+-#define MIN_PLAYLIST_LENGTH     180     /* 3 min */
++#define MIN_PLAYLIST_LENGTH     0
+ 
+ typedef struct {
+     const AVClass *class;
+
+--- a/doc/muxers.texi
++++ b/doc/muxers.texi
+@@ -1932,7 +1932,8 @@
+ Maximum time in seconds between PAT/PMT tables. Default is @code{0.1}.
+ 
+ @item sdt_period @var{duration}
+-Maximum time in seconds between SDT tables. Default is @code{0.5}.
++Maximum time in seconds between SDT tables. Default is @code{0.5}. Regardless
++of this setting no SDT is written in m2ts mode.
+ 
+ @item nit_period @var{duration}
+ Maximum time in seconds between NIT tables. Default is @code{0.5}.
diff --git a/cinelerra-5.1/thirdparty/src/ffmpeg-7.0.patch5 b/cinelerra-5.1/thirdparty/src/ffmpeg-7.0.patch5
new file mode 100644
index 00000000..64ee262c
--- /dev/null
+++ b/cinelerra-5.1/thirdparty/src/ffmpeg-7.0.patch5
@@ -0,0 +1,25 @@
+--- a/libavfilter/formats.c
++++ b/libavfilter/formats.c
+@@ -110,11 +110,13 @@
+        possibly causing a lossy conversion elsewhere in the graph.
+        To avoid that, pretend that there are no common formats to force the
+        insertion of a conversion filter. */
+-    if (type == AVMEDIA_TYPE_VIDEO)
++    if (type == AVMEDIA_TYPE_VIDEO) {
+         for (i = 0; i < a->nb_formats; i++) {
+             const AVPixFmtDescriptor *const adesc = av_pix_fmt_desc_get(a->formats[i]);
++            if( !adesc ) continue;
+             for (j = 0; j < b->nb_formats; j++) {
+                 const AVPixFmtDescriptor *bdesc = av_pix_fmt_desc_get(b->formats[j]);
++                if( !bdesc ) continue;
+                 alpha2 |= adesc->flags & bdesc->flags & AV_PIX_FMT_FLAG_ALPHA;
+                 chroma2|= adesc->nb_components > 1 && bdesc->nb_components > 1;
+                 if (a->formats[i] == b->formats[j]) {
+@@ -123,6 +125,7 @@
+                 }
+             }
+         }
++    }
+ 
+     // If chroma or alpha can be lost through merging then do not merge
+     if (alpha2 > alpha1 || chroma2 > chroma1)
diff --git a/cinelerra-5.1/thirdparty/src/ffmpeg-7.0.patch7 b/cinelerra-5.1/thirdparty/src/ffmpeg-7.0.patch7
new file mode 100644
index 00000000..379ddb62
--- /dev/null
+++ b/cinelerra-5.1/thirdparty/src/ffmpeg-7.0.patch7
@@ -0,0 +1,10 @@
+--- a/libavcodec/vdpau_mpeg12.c
++++ b/libavcodec/vdpau_mpeg12.c
+@@ -117,6 +117,7 @@
+     .frame_priv_data_size = sizeof(struct vdpau_picture_context),
+     .init           = vdpau_mpeg1_init,
+     .uninit         = ff_vdpau_common_uninit,
++    .frame_params   = ff_vdpau_common_frame_params,
+     .priv_data_size = sizeof(VDPAUContext),
+     .caps_internal  = HWACCEL_CAP_ASYNC_SAFE,
+ };
diff --git a/cinelerra-5.1/thirdparty/src/ffmpeg-7.0.patch8 b/cinelerra-5.1/thirdparty/src/ffmpeg-7.0.patch8
new file mode 100644
index 00000000..fcafebb8
--- /dev/null
+++ b/cinelerra-5.1/thirdparty/src/ffmpeg-7.0.patch8
@@ -0,0 +1,11 @@
+--- a/libavcodec/h263dec.c
++++ b/libavcodec/h263dec.c
+@@ -623,7 +623,7 @@
+     if (CONFIG_MPEG4_DECODER && avctx->codec_id == AV_CODEC_ID_MPEG4)
+         ff_mpeg4_frame_end(avctx, buf, buf_size);
+ 
+-    if (!s->divx_packed && avctx->hwaccel)
++    if (s->divx_packed && avctx->hwaccel)
+         ff_thread_finish_setup(avctx);
+ 
+     av_assert1(s->current_picture.f->pict_type == s->current_picture_ptr->f->pict_type);
diff --git a/cinelerra-5.1/thirdparty/src/ffmpeg-7.0.patch9 b/cinelerra-5.1/thirdparty/src/ffmpeg-7.0.patch9
new file mode 100644
index 00000000..721fd09d
--- /dev/null
+++ b/cinelerra-5.1/thirdparty/src/ffmpeg-7.0.patch9
@@ -0,0 +1,14 @@
+--- a/libavformat/mpegenc.c
++++ b/libavformat/mpegenc.c
+@@ -987,9 +987,9 @@
+         PacketDesc *pkt_desc;
+ 
+         while ((pkt_desc = stream->predecode_packet) &&
++               pkt_desc != stream->premux_packet &&
+                scr > pkt_desc->dts) { // FIXME: > vs >=
+-            if (stream->buffer_index < pkt_desc->size ||
+-                stream->predecode_packet == stream->premux_packet) {
++            if (stream->buffer_index < pkt_desc->size) {
+                 av_log(ctx, AV_LOG_ERROR,
+                        "buffer underflow st=%d bufi=%d size=%d\n",
+                        i, stream->buffer_index, pkt_desc->size);
-- 
2.35.8

-- 
Cin mailing list
[email protected]
https://lists.cinelerra-gg.org/mailman/listinfo/cin

Reply via email to