Credit FFmpeg team with Andrew-R mods for version 8.0 master
authorGood Guy <good1.2guy@gmail.com>
Wed, 19 Nov 2025 18:26:28 +0000 (11:26 -0700)
committerGood Guy <good1.2guy@gmail.com>
Wed, 19 Nov 2025 18:26:28 +0000 (11:26 -0700)
24 files changed:
cinelerra-5.1/blds/bld_prepare.sh
cinelerra-5.1/cinelerra/bdwrite.C
cinelerra-5.1/cinelerra/ffmpeg.C
cinelerra-5.1/cinelerra/fileac3.C
cinelerra-5.1/cinelerra/pluginfclient.C
cinelerra-5.1/configure.ac
cinelerra-5.1/ffmpeg/plugin.opts
cinelerra-5.1/info/plugins.txt
cinelerra-5.1/msg/txt
cinelerra-5.1/thirdparty/downloads.txt
cinelerra-5.1/thirdparty/src/ffmpeg-8.0.patch1 [new file with mode: 0644]
cinelerra-5.1/thirdparty/src/ffmpeg-8.0.patch10 [new file with mode: 0644]
cinelerra-5.1/thirdparty/src/ffmpeg-8.0.patch2 [new file with mode: 0644]
cinelerra-5.1/thirdparty/src/ffmpeg-8.0.patch3 [new file with mode: 0644]
cinelerra-5.1/thirdparty/src/ffmpeg-8.0.patch4 [new file with mode: 0644]
cinelerra-5.1/thirdparty/src/ffmpeg-8.0.patch5 [new file with mode: 0644]
cinelerra-5.1/thirdparty/src/ffmpeg-8.0.patch7 [new file with mode: 0644]
cinelerra-5.1/thirdparty/src/ffmpeg-8.0.patch9 [new file with mode: 0644]
cinelerra-5.1/thirdparty/src/ffmpeg-8.0.patchB [new file with mode: 0644]
cinelerra-5.1/thirdparty/src/ffmpeg-8.0.patchC [new file with mode: 0644]
cinelerra-5.1/thirdparty/src/ffmpeg-8.0.patchD [new file with mode: 0644]
cinelerra-5.1/thirdparty/src/ffmpeg-8.0.patchZ1 [new file with mode: 0644]
cinelerra-5.1/thirdparty/src/ffmpeg-8.0.patchZ2 [new file with mode: 0644]
cinelerra-5.1/thirdparty/src/ffmpeg-8.0.tar.xz [new file with mode: 0644]

index 0e7958d0750970b27d42104c24f518869e9360f1..d3378c61a28189a11020fda48d658fe71d605786 100755 (executable)
@@ -36,11 +36,13 @@ case "$dir" in
     rm -f /tmp/$yasm
   ;;
 #"fedora3*")
-#  dnf group install "Development Tools"
+#  dnf group install "Development Tools" -- substitute for older versions
+#  dnf -y --best --allowerasing -- substitute for older versions
 #  ... rpm-build lzma-sdk-devel libtool ...
+# fedora for newest versions
 "fedora")
-  dnf group install "Development Tools"
-  dnf -y --best --allowerasing \
+  dnf group install development-tools
+  dnf -y --best \
     install nasm yasm libavc1394-devel libusbx-devel flac-devel \
     libjpeg-devel libdv-devel libdvdnav-devel libdvdread-devel \
     libtheora-devel libiec61883-devel esound-devel uuid-devel \
index 1f7f027ef808e5bd54022381865fd52784905f24..1b027a7fe2658ce5654d49c89cfd8d52a415b31a 100644 (file)
@@ -2586,7 +2586,11 @@ static int field_probe(AVFormatContext *fmt_ctx, AVStream *st)
     }
     ret = avcodec_receive_frame(ctx, ipic);
     if( ret >= 0 ) {
+#if LIBAVCODEC_VERSION_INT <= AV_VERSION_INT(59,16,100)
       ilaced = ipic->interlaced_frame ? 1 : 0;
+#else
+    ilaced = ipic->flags & AV_FRAME_FLAG_INTERLACED  ? 1 : 0;
+#endif
       break;
     }
     if( ret != AVERROR(EAGAIN) )
@@ -2769,7 +2773,9 @@ int media_info::scan()
     ret = scan(fmt_ctx);
 
   for( int i=0; i<(int)streams.size(); ++i )
+#if LIBAVCODEC_VERSION_INT <= AV_VERSION_INT(59,16,100)
     avcodec_close(streams[i]->ctx);
+#endif
   avformat_close_input(&fmt_ctx);
 
   return ret;
index 1d0979df59f932628246678a920aca002d8dd88b..36fc196d6463c1c4e81b95321cff5669941c2424 100644 (file)
@@ -310,7 +310,9 @@ FFStream::FFStream(FFMPEG *ffmpeg, AVStream *st, int fidx)
 FFStream::~FFStream()
 {
        frm_lock->lock("FFStream::~FFStream");
+#if LIBAVCODEC_VERSION_INT <= AV_VERSION_INT(59,16,100)
        if( reading > 0 || writing > 0 ) avcodec_close(avctx);
+#endif 
        if( avctx ) avcodec_free_context(&avctx);
        if( fmt_ctx ) avformat_close_input(&fmt_ctx);
        if( hw_device_ctx ) av_buffer_unref(&hw_device_ctx);
@@ -475,7 +477,9 @@ int FFStream::decode_activate()
                        if( ret < 0 && hw_type != AV_HWDEVICE_TYPE_NONE ) {
                                ff_err(ret, "HW device init failed, using SW decode.\nfile:%s\n",
                                        ffmpeg->fmt_ctx->url);
+#if LIBAVCODEC_VERSION_INT <= AV_VERSION_INT(59,16,100)
                                avcodec_close(avctx);
+#endif
                                avcodec_free_context(&avctx);
                                av_buffer_unref(&hw_device_ctx);
                                hw_device_ctx = 0;
@@ -1305,7 +1309,7 @@ int FFVideoStream::probe(int64_t pos)
                if( ret > 0 ) {
                        //printf("codec interlace: %i \n",frame->interlaced_frame);
                        //printf("codec tff: %i \n",frame->top_field_first);
-
+#if LIBAVCODEC_VERSION_INT <= AV_VERSION_INT(59,16,100)
                        if (!frame->interlaced_frame)
                                ffmpeg->interlace_from_codec = AV_FIELD_PROGRESSIVE;
                        if ((frame->interlaced_frame) && (frame->top_field_first))
@@ -1313,7 +1317,14 @@ int FFVideoStream::probe(int64_t pos)
                        if ((frame->interlaced_frame) && (!frame->top_field_first))
                                ffmpeg->interlace_from_codec = AV_FIELD_BB;
                        //printf("Interlace mode from codec: %i\n", ffmpeg->interlace_from_codec);
-
+#else
+                       if (!frame->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST)
+                               ffmpeg->interlace_from_codec = AV_FIELD_PROGRESSIVE;
+                       if ((frame->flags & AV_FRAME_FLAG_INTERLACED) && (frame->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST))
+                               ffmpeg->interlace_from_codec = AV_FIELD_TT;
+                       if ((frame->flags & AV_FRAME_FLAG_INTERLACED ) && (!frame->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST))
+                               ffmpeg->interlace_from_codec = AV_FIELD_BB;
+#endif
        }
 
        if( frame->format == AV_PIX_FMT_NONE || frame->width <= 0 || frame->height <= 0 )
@@ -1339,7 +1350,11 @@ int FFVideoStream::load(VFrame *vframe, int64_t pos)
        while( ret>=0 && !flushed && curr_pos<=pos && --i>=0 ) {
                ret = read_frame(frame);
                if( ret > 0 ) {
+#if LIBAVCODEC_VERSION_INT <= AV_VERSION_INT(59,16,100)
                        if( frame->key_frame && seeking < 0 ) {
+#else
+                       if( (frame->flags & AV_FRAME_FLAG_KEY) && seeking < 0 ) {
+#endif
                                int use_cache = ffmpeg->get_use_cache();
                                if( use_cache < 0 ) {
 // for reverse read, reload file frame_cache from keyframe to pos
@@ -1511,8 +1526,15 @@ int FFVideoStream::drain()
 int FFVideoStream::encode_frame(AVFrame *frame)
 {
        if( frame ) {
+#if LIBAVCODEC_VERSION_INT <= AV_VERSION_INT(59,16,100)
                frame->interlaced_frame = interlaced;
                frame->top_field_first = top_field_first;
+#else
+               if(top_field_first)
+               frame->flags |= AV_FRAME_FLAG_TOP_FIELD_FIRST;
+               if(interlaced)
+               frame->flags |= AV_FRAME_FLAG_INTERLACED;
+#endif
        }
        if( frame && frame->format == AV_PIX_FMT_VAAPI ) { // ugly
                int ret = avcodec_send_frame(avctx, frame);
@@ -3846,7 +3868,20 @@ double FFVideoStream::get_rotation_angle()
 #else
        int size = 0;
 #endif
+
+#if LIBAVCODEC_VERSION_INT <= AV_VERSION_INT(59,16,100)
        int *matrix = (int*)av_stream_get_side_data(st, AV_PKT_DATA_DISPLAYMATRIX, &size);
+#else
+       int32_t *matrix = NULL;
+        if (!matrix) {
+            const AVPacketSideData *psd = av_packet_side_data_get(st->codecpar->coded_side_data,
+                                                                  st->codecpar->nb_coded_side_data,
+                                                                  AV_PKT_DATA_DISPLAYMATRIX);
+            if (psd)
+                matrix = (int32_t *)psd->data;
+        }
+       
+#endif
        int len = size/sizeof(*matrix);
        if( !matrix || len < 5 ) return 0;
        const double s = 1/65536.;
@@ -3903,7 +3938,9 @@ int FFVideoStream::create_filter(const char *filter_spec)
                while( --i>=0 && *sp!=0 && !strchr(" \t:=,",*sp) ) *np++ = *sp++;
                *np = 0;
                const AVFilter *filter = !filter_name[0] ? 0 : avfilter_get_by_name(filter_name);
-               if( !filter || avfilter_pad_get_type(filter->inputs,0) != AVMEDIA_TYPE_VIDEO ) {
+               //AVFilterContext *ctx = filter->ctx;
+               int       nb_pads = avfilter_filter_pad_count(filter,0);
+               if( !filter || (nb_pads>1 && avfilter_pad_get_type(filter->inputs,0)) != AVMEDIA_TYPE_VIDEO ) {
                        ff_err(AVERROR(EINVAL), "FFVideoStream::create_filter: %s\n", filter_spec);
                        return -1;
                }
@@ -3933,11 +3970,19 @@ int FFVideoStream::create_filter(const char *filter_spec)
                ret = insert_filter("buffersink", 0, "out");
                buffersink_ctx = filt_ctx;
        }
+       /*
+       if( ret >= 0 ) {
+       ret = av_opt_set(buffersink_ctx, "pixel_formats", av_get_pix_fmt_name(pix_fmt),
+                     AV_OPT_SEARCH_CHILDREN);
+       }
+       
        if( ret >= 0 ) {
                ret = av_opt_set_bin(buffersink_ctx, "pix_fmts",
                        (uint8_t*)&pix_fmt, sizeof(pix_fmt),
                        AV_OPT_SEARCH_CHILDREN);
        }
+       */
+       
        if( ret >= 0 )
                ret = config_filters(filter_spec, fsrc);
        else
@@ -3957,7 +4002,8 @@ int FFAudioStream::create_filter(const char *filter_spec)
                while( --i>=0 && *sp!=0 && !strchr(" \t:=,",*sp) ) *np++ = *sp++;
                *np = 0;
                const AVFilter *filter = !filter_name[0] ? 0 : avfilter_get_by_name(filter_name);
-               if( !filter || avfilter_pad_get_type(filter->inputs,0) != AVMEDIA_TYPE_AUDIO ) {
+               int       nb_pads = avfilter_filter_pad_count(filter,0);
+               if( !filter || (nb_pads >1 &&  avfilter_pad_get_type(filter->inputs,0)) != AVMEDIA_TYPE_AUDIO ) {
                        ff_err(AVERROR(EINVAL), "FFAudioStream::create_filter: %s\n", filter_spec);
                        return -1;
                }
index 63654f32ff430818dc459d8bd24ce97bfe43cbe4..34469aeffd394c9aef398f6e1b0e5ccb09600fdb 100644 (file)
@@ -191,7 +191,9 @@ int FileAC3::close_file()
        if(codec_context)
        {
                encode_flush();
+#if LIBAVCODEC_VERSION_INT <= AV_VERSION_INT(59,16,100)
                avcodec_close(codec_context);
+#endif
                avcodec_free_context(&codec_context);
                codec = 0;
        }
index b8694b120e29ca26a36adde2e701094d99b86070..7ff7bad993d689360f8e9dc4851e84de3d34c635 100644 (file)
@@ -864,18 +864,25 @@ int PluginFAClient::activate()
                        "in", args, NULL, graph);
                if(ret <0) printf("abuffer failed!\n");
        }
-       if( ret >= 0 )
+/*     if( ret >= 0 )
                ret = avfilter_graph_create_filter(&fsink, avfilter_get_by_name("abuffersink"),
-                       "out", NULL, NULL, graph);
+                       "out", NULL, NULL, graph); */
+       /*
        if( ret >= 0 )
                ret = av_opt_set_bin(fsink, "sample_fmts",
                        (uint8_t*)&sample_fmt, sizeof(sample_fmt), AV_OPT_SEARCH_CHILDREN);
-       if( ret >= 0 )
+       
+        if( ret >= 0 )
                ret = av_opt_set(fsink, "ch_layouts",
                        chLayoutDescription, AV_OPT_SEARCH_CHILDREN);
        if( ret >= 0 )
                ret = av_opt_set_bin(fsink, "sample_rates",
                        (uint8_t*)&sample_rate, sizeof(sample_rate), AV_OPT_SEARCH_CHILDREN);
+       */
+       if( ret >= 0 ) 
+           ret = avfilter_graph_create_filter(&fsink, avfilter_get_by_name("abuffersink"),
+               "out", NULL, NULL, graph);
+       
        if( ret >= 0 )
                ret = PluginFClient::activate();
        if( ret < 0 && activated >= 0 ) {
@@ -943,9 +950,11 @@ int PluginFVClient::activate(int width, int height, int color_model)
        if( ret >= 0 )
                ret = avfilter_graph_create_filter(&fsink, avfilter_get_by_name("buffersink"),
                        "out", NULL, NULL, graph);
+       /*
        if( ret >= 0 )
                ret = av_opt_set_bin(fsink, "pix_fmts",
                        (uint8_t*)&pix_fmt, sizeof(pix_fmt), AV_OPT_SEARCH_CHILDREN);
+       */
        if( ret >= 0 )
                ret = PluginFClient::activate();
        if( ret < 0 && activated >= 0 ) {
@@ -1096,9 +1105,13 @@ int PluginFVClient::process_buffer(VFrame **frames, int64_t position, double fra
 
        int colormodel = vframe->get_color_model();
        int ret = activate(width, height, colormodel);
-       AVPixelFormat pix_fmt = fsrc ?
+       AVPixelFormat pix_fmt;
+       if (fsrc && fsrc->outputs[0]) {
+               pix_fmt =  fsrc ?
                (AVPixelFormat) fsrc->outputs[0]->format :
                color_model_to_pix_fmt(colormodel);
+       } else {
+       pix_fmt = color_model_to_pix_fmt(colormodel);}
        if( pix_fmt <= AV_PIX_FMT_NONE || pix_fmt >= AV_PIX_FMT_NB )
                pix_fmt = AV_PIX_FMT_RGBA;
 
@@ -1255,7 +1268,7 @@ int PluginFFilter::init(const char *name, PluginFClientConfig *conf)
        PluginFLogLevel errs(AV_LOG_ERROR);
        this->filter = avfilter_get_by_name(name);
        if( !this->filter ) return AVERROR(ENOENT);
-       int flag_mask = AVFILTER_FLAG_DYNAMIC_INPUTS | AVFILTER_FLAG_DYNAMIC_OUTPUTS;
+       int flag_mask = /* AVFILTER_FLAG_DYNAMIC_INPUTS |*/ AVFILTER_FLAG_DYNAMIC_OUTPUTS;
        if( filter->flags & flag_mask ) return AVERROR(EPERM);
        if( !this->is_audio() && !this->is_video() ) return AVERROR(EIO);
        this->graph = avfilter_graph_alloc();
index f5134a785723386c2d9fa124cc7781542673cae9..e1f78d24059507af8e54a69fc82043c087aa0f54 100644 (file)
@@ -224,10 +224,9 @@ PKG_3RD([esound],[no],
   [ . ])
 
 PKG_3RD([ffmpeg],[yes],
-  [ffmpeg-7.0],
+  [ffmpeg-8.0],
   [ libavutil/libavutil.a \
     libavcodec/libavcodec.a \
-    libpostproc/libpostproc.a \
     libavformat/libavformat.a \
     libswscale/libswscale.a \
     libavfilter/libavfilter.a \
index 61aeff61628cddcc36c94527ef3bd4833b586995..dcf1009ee63ba22fee92d09aa2ea71b551830c4e 100644 (file)
@@ -510,3 +510,7 @@ afdelaysrc
 #vstack_qsv ###Operation not permitted
 #xstack_qsv ###Operation not permitted
 #transpose_vaapi ###Operation not permitted
+; do not work in 7.1.1
+#xpsnr ###Input/output error
+#drawbox_vaapi ###Operation not permitted
+#pad_vaapi ###Operation not permitted
index a24fa4e294b5ac0441cc6c78e206c4e562d12eda..582c69652cb754b0639e98ab7c4a918e65b4dbf7 100644 (file)
@@ -434,6 +434,7 @@ F_pal100bars:       Generate PAL 100% color bars. This only works with
                RGB 8-bit.
 F_pal75bars:   Generate PAL 75% color bars. This only works with
                RGB 8-bit.
+F_perlin:      Generate Perlin noise.
 F_perms:       Set permissions for the output video frame.
 F_perspective: Corrects the perspective of video.
 F_phase:       Phase shift fields.
index 62dbc78cd6803afc9b03e2e8d815c48443cf3800..c8d4f7b8a5e2e75edd0e6b31b06846116de802c1 100644 (file)
@@ -3,6 +3,8 @@ For usage help, refer to the following:
   https://cinelerra-gg.org/download/CinelerraGG_Manual.pdf
   http://g-raffa.eu/Cinelerra/HOWTO/basics.html
 .
+2025 November changes of note:
+  FFmpeg library has been updated for version 8.0.
 2025 March/April changes of note:
   An additional SYSLIB Blend Program of tone_mapping.bp
     has been created for tonemapping an HDR media and
index cb05ece9372a10f10417fe20d29b237572f4c8d6..a8a08d84b0684a85759db6c0f1655ee4c5f8c3bc 100644 (file)
@@ -37,7 +37,7 @@ https://download.osgeo.org/libtiff/tiff-4.7.0.tar.xz
 https://sourceforge.net/projects/libuuid/files/latest/download?source=directory - 1.0.3
 https://www.videolan.org/developers/x264.html (May 2024 version r3191)
 https://bitbucket.org/multicoreware/x265_git/downloads/x265_4.0.tar.gz (Sept. 2024)
-https://ffmpeg.org/releases/ffmpeg-7.0.tar.xz
+https://ffmpeg.org/releases/ffmpeg-8.0.tar.xz
 https://github.com/webmproject/libvpx/tags (v1.14.1.tar.gz)
 https://code.videolan.org/videolan/dav1d/-/archive/0.5.1/dav1d-0.5.1.tar.gz
 https://gitlab.com/AOMediaCodec/SVT-AV1/-/releases  (2.3.0)
diff --git a/cinelerra-5.1/thirdparty/src/ffmpeg-8.0.patch1 b/cinelerra-5.1/thirdparty/src/ffmpeg-8.0.patch1
new file mode 100644 (file)
index 0000000..4427ea6
--- /dev/null
@@ -0,0 +1,11 @@
+--- a/fftools/cmdutils.c       2025-04-18 12:38:40.562773988 -0600
++++ b/fftools/cmdutils.c       2025-04-18 12:37:06.493547153 -0600
+@@ -57,7 +57,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-8.0.patch10 b/cinelerra-5.1/thirdparty/src/ffmpeg-8.0.patch10
new file mode 100644 (file)
index 0000000..818da25
--- /dev/null
@@ -0,0 +1,16 @@
+--- a/libavutil/hwcontext_cuda.c       2025-04-18 14:35:01.291580404 -0600
++++ b/libavutil/hwcontext_cuda.c       2025-04-18 14:34:29.859129090 -0600
+@@ -365,11 +365,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-8.0.patch2 b/cinelerra-5.1/thirdparty/src/ffmpeg-8.0.patch2
new file mode 100644 (file)
index 0000000..9dcd928
--- /dev/null
@@ -0,0 +1,414 @@
+--- a/libavformat/mpegtsenc.c  2025-05-12 18:48:13.570751744 -0600
++++ b/libavformat/mpegtsenc.c  2025-05-13 12:12:38.534457031 -0600
+@@ -90,9 +90,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;
+@@ -259,7 +261,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;
+@@ -962,18 +964,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));
+@@ -1059,9 +1061,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)
+@@ -1124,6 +1123,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;
+@@ -1183,7 +1183,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++;
+@@ -1210,9 +1212,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;
+         }
+@@ -1280,9 +1282,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);
+@@ -1298,8 +1305,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");
+@@ -1308,36 +1315,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);
++        }
+     }
+ }
+@@ -1374,25 +1385,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++ = SYNC_BYTE;
+-    *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, STUFFING_BYTE, TS_PACKET_SIZE - (q - buf));
+@@ -1493,9 +1508,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);
+@@ -1512,21 +1527,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) * SYSTEM_CLOCK_FREQUENCY_DIVISOR;
+-
+-        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++) {
+@@ -1536,36 +1549,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 / SYSTEM_CLOCK_FREQUENCY_DIVISOR) > 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++ = SYNC_BYTE;
+@@ -1595,7 +1615,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 / SYSTEM_CLOCK_FREQUENCY_DIVISOR)
+                 av_log(s, AV_LOG_WARNING, "dts < pcr, TS is invalid\n");
+             extend_af(buf, write_pcr_bits(q, pcr));
+@@ -1867,8 +1886,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;
+@@ -1888,9 +1907,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)) {
+@@ -2357,8 +2376,10 @@
+       0, AV_OPT_TYPE_CONST, { .i64 = MPEGTS_SERVICE_TYPE_HEVC_DIGITAL_HDTV }, 0x01, 0xff, ENC, .unit = "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",
+@@ -2384,10 +2405,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     2025-05-12 18:48:32.808049998 -0600
++++ b/libavformat/mpegts.h     2025-05-13 12:23:31.824879487 -0600
+@@ -68,6 +68,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     2025-05-12 18:48:54.328383651 -0600
++++ b/libavformat/bluray.c     2025-05-12 18:52:51.113993748 -0600
+@@ -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  2025-05-12 18:49:20.456781375 -0600
++++ b/doc/muxers.texi  2025-05-13 12:19:17.959026488 -0600
+@@ -3116,7 +3116,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-8.0.patch3 b/cinelerra-5.1/thirdparty/src/ffmpeg-8.0.patch3
new file mode 100644 (file)
index 0000000..538c593
--- /dev/null
@@ -0,0 +1,68 @@
+--- a/libavformat/avformat.h   2025-05-08 15:58:37.933172640 -0600
++++ b/libavformat/avformat.h   2025-05-08 15:57:46.964410825 -0600
+@@ -496,6 +496,9 @@
+                                         The user or muxer can override this through
+                                         AVFormatContext.avoid_negative_ts
+                                         */
++#define AVFMT_SEEK_NOSTREAMS  0x80000 /**< Stream index ignored by seek,
++                                           or some streams fail to seek
++                                           */
+ #define AVFMT_SEEK_TO_PTS   0x4000000 /**< Seeking is based on PTS */
+@@ -559,7 +562,8 @@
+     /**
+      * Can use flags: AVFMT_NOFILE, AVFMT_NEEDNUMBER, AVFMT_SHOW_IDS,
+      * AVFMT_NOTIMESTAMPS, AVFMT_GENERIC_INDEX, AVFMT_TS_DISCONT, AVFMT_NOBINSEARCH,
+-     * AVFMT_NOGENSEARCH, AVFMT_NO_BYTE_SEEK, AVFMT_SEEK_TO_PTS.
++     * AVFMT_NOGENSEARCH, AVFMT_NO_BYTE_SEEK, AVFMT_SEEK_TO_PTS,
++     * AVFMT_SEEK_NOSTREAMS
+      */
+     int flags;
+--- a/libavformat/dv.c 2025-05-08 15:59:26.143851727 -0600
++++ b/libavformat/dv.c 2025-05-08 15:59:01.103509955 -0600
+@@ -714,6 +714,7 @@
+ const FFInputFormat ff_dv_demuxer = {
+     .p.name         = "dv",
+     .p.long_name    = NULL_IF_CONFIG_SMALL("DV (Digital Video)"),
++    .p.flags       = AVFMT_SEEK_NOSTREAMS,
+     .p.extensions   = "dv,dif",
+     .priv_data_size = sizeof(RawDVContext),
+     .read_probe     = dv_probe,
+
+--- a/libavformat/matroskadec.c        2025-05-08 16:00:34.406740107 -0600
++++ b/libavformat/matroskadec.c        2025-05-08 15:59:37.777003123 -0600
+@@ -4832,6 +4832,7 @@
+ const FFInputFormat ff_webm_dash_manifest_demuxer = {
+     .p.name         = "webm_dash_manifest",
+     .p.long_name    = NULL_IF_CONFIG_SMALL("WebM DASH Manifest"),
++    .p.flags        = AVFMT_SEEK_NOSTREAMS,
+     .p.priv_class   = &webm_dash_class,
+     .priv_data_size = sizeof(MatroskaDemuxContext),
+     .flags_internal = FF_INFMT_FLAG_INIT_CLEANUP,
+@@ -4844,6 +4845,7 @@
+ const FFInputFormat ff_matroska_demuxer = {
+     .p.name         = "matroska,webm",
+     .p.long_name    = NULL_IF_CONFIG_SMALL("Matroska / WebM"),
++    .p.flags        = AVFMT_SEEK_NOSTREAMS,
+     .p.extensions   = "mkv,mk3d,mka,mks,webm",
+     .p.mime_type    = "audio/webm,audio/x-matroska,video/webm,video/x-matroska",
+     .priv_data_size = sizeof(MatroskaDemuxContext),
+
+--- a/libavformat/seek.c       2025-05-08 16:01:47.828700137 -0600
++++ b/libavformat/seek.c       2025-05-08 16:00:44.845875964 -0600
+@@ -607,6 +607,13 @@
+         return seek_frame_byte(s, stream_index, timestamp, flags);
+     }
++    if (stream_index != -1 && (s->iformat->flags & AVFMT_SEEK_NOSTREAMS)) {
++            timestamp = av_rescale_q(timestamp,
++                    s->streams[stream_index]->time_base,
++                    AV_TIME_BASE_Q);
++            stream_index = -1;
++    }
++
+     if (stream_index < 0) {
+         stream_index = av_find_default_stream_index(s);
+         if (stream_index < 0)
diff --git a/cinelerra-5.1/thirdparty/src/ffmpeg-8.0.patch4 b/cinelerra-5.1/thirdparty/src/ffmpeg-8.0.patch4
new file mode 100644 (file)
index 0000000..b054f7a
--- /dev/null
@@ -0,0 +1,10 @@
+--- a/libavformat/avidec.c     2025-05-09 13:35:07.851155737 -0600
++++ b/libavformat/avidec.c     2025-05-09 13:34:45.702821357 -0600
+@@ -2021,6 +2021,7 @@
+     .p.name         = "avi",
+     .p.long_name    = NULL_IF_CONFIG_SMALL("AVI (Audio Video Interleaved)"),
+     .p.extensions   = "avi",
++    .p.flags        = AVFMT_SEEK_NOSTREAMS,
+     .p.priv_class   = &demuxer_class,
+     .priv_data_size = sizeof(AVIContext),
+     .flags_internal = FF_INFMT_FLAG_INIT_CLEANUP,
diff --git a/cinelerra-5.1/thirdparty/src/ffmpeg-8.0.patch5 b/cinelerra-5.1/thirdparty/src/ffmpeg-8.0.patch5
new file mode 100644 (file)
index 0000000..64ee262
--- /dev/null
@@ -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-8.0.patch7 b/cinelerra-5.1/thirdparty/src/ffmpeg-8.0.patch7
new file mode 100644 (file)
index 0000000..e2c43f7
--- /dev/null
@@ -0,0 +1,10 @@
+--- a/libavcodec/vdpau_mpeg12.c        2025-05-09 14:54:40.549494700 -0600
++++ b/libavcodec/vdpau_mpeg12.c        2025-05-09 14:53:57.284866101 -0600
+@@ -118,6 +118,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-8.0.patch9 b/cinelerra-5.1/thirdparty/src/ffmpeg-8.0.patch9
new file mode 100644 (file)
index 0000000..befd285
--- /dev/null
@@ -0,0 +1,14 @@
+--- a/libavformat/mpegenc.c    2025-05-11 15:05:24.437490237 -0600
++++ b/libavformat/mpegenc.c    2025-05-11 14:46:46.661934073 -0600
+@@ -989,9 +989,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);
diff --git a/cinelerra-5.1/thirdparty/src/ffmpeg-8.0.patchB b/cinelerra-5.1/thirdparty/src/ffmpeg-8.0.patchB
new file mode 100644 (file)
index 0000000..89e9989
--- /dev/null
@@ -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-8.0.patchC b/cinelerra-5.1/thirdparty/src/ffmpeg-8.0.patchC
new file mode 100644 (file)
index 0000000..63d187f
--- /dev/null
@@ -0,0 +1,41 @@
+--- a/libavcodec/encode.c      2025-05-12 08:52:53.070539488 -0600
++++ b/libavcodec/encode.c      2025-05-12 08:40:22.831978565 -0600
+@@ -306,7 +306,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;
+@@ -325,8 +325,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;
+ }
+@@ -501,10 +503,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-8.0.patchD b/cinelerra-5.1/thirdparty/src/ffmpeg-8.0.patchD
new file mode 100644 (file)
index 0000000..d782ae9
--- /dev/null
@@ -0,0 +1,24 @@
+--- a/libavcodec/pcm-dvdenc.c  2025-05-12 17:20:39.267102833 -0600
++++ b/libavcodec/pcm-dvdenc.c  2025-05-12 17:22:13.361600238 -0600
+@@ -38,6 +38,12 @@
+     int quant, freq, frame_size;
+     switch (avctx->sample_rate) {
++    case 32000:
++       freq = 3;
++       break;
++    case 44100:
++       freq = 2;
++       break;
+     case 48000:
+         freq = 0;
+         break;
+@@ -181,7 +187,7 @@
+     .priv_data_size = sizeof(PCMDVDContext),
+     .init           = pcm_dvd_encode_init,
+     FF_CODEC_ENCODE_CB(pcm_dvd_encode_frame),
+-    CODEC_SAMPLERATES(48000, 96000),
++    CODEC_SAMPLERATES(32000, 44100, 48000, 96000),
+     CODEC_CH_LAYOUTS(AV_CHANNEL_LAYOUT_MONO,    AV_CHANNEL_LAYOUT_STEREO,
+                      AV_CHANNEL_LAYOUT_5POINT1, AV_CHANNEL_LAYOUT_7POINT1),
+     CODEC_SAMPLEFMTS(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S32),
diff --git a/cinelerra-5.1/thirdparty/src/ffmpeg-8.0.patchZ1 b/cinelerra-5.1/thirdparty/src/ffmpeg-8.0.patchZ1
new file mode 100644 (file)
index 0000000..5354f74
--- /dev/null
@@ -0,0 +1,49 @@
+--- a/libavcodec/wrapped_avframe.c     2025-05-11 16:34:43.753546422 -0600
++++ b/libavcodec/wrapped_avframe.c     2025-05-11 15:08:08.157768438 -0600
+@@ -32,6 +32,38 @@
+ #include "libavutil/buffer.h"
+ #include "libavutil/mem.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;
+@@ -110,6 +142,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-8.0.patchZ2 b/cinelerra-5.1/thirdparty/src/ffmpeg-8.0.patchZ2
new file mode 100644 (file)
index 0000000..6a20f7a
--- /dev/null
@@ -0,0 +1,11 @@
+--- a/libavformat/yuv4mpegenc.c        2025-05-11 15:58:35.782501756 -0600
++++ b/libavformat/yuv4mpegenc.c        2025-05-11 15:58:08.480121797 -0600
+@@ -265,7 +265,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");
diff --git a/cinelerra-5.1/thirdparty/src/ffmpeg-8.0.tar.xz b/cinelerra-5.1/thirdparty/src/ffmpeg-8.0.tar.xz
new file mode 100644 (file)
index 0000000..1defa15
Binary files /dev/null and b/cinelerra-5.1/thirdparty/src/ffmpeg-8.0.tar.xz differ