commit:     a221ba81bc1cb848bb9aff51f5558e1072979386
Author:     Andreas Sturmlechner <asturm <AT> gentoo <DOT> org>
AuthorDate: Thu Oct  2 21:11:41 2025 +0000
Commit:     Andreas Sturmlechner <asturm <AT> gentoo <DOT> org>
CommitDate: Thu Oct  2 21:27:30 2025 +0000
URL:        https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=a221ba81

media-libs/mlt: Fix build w/ media-video/ffmpeg-8

Since upstream continues to not release a 7.34.0, let's use this patch
(scrubbed) by "crabbed halo ablution" (thanks!).

Because the patch is so big, and this is a stable ebuild, it was put
behind a conditional on has_version ">=media-video/ffmpeg-8".

Closes: https://bugs.gentoo.org/961698
Signed-off-by: Andreas Sturmlechner <asturm <AT> gentoo.org>

 media-libs/mlt/files/mlt-7.32.0-ffmpeg8.patch | 355 ++++++++++++++++++++++++++
 media-libs/mlt/mlt-7.32.0.ebuild              |   4 +
 2 files changed, 359 insertions(+)

diff --git a/media-libs/mlt/files/mlt-7.32.0-ffmpeg8.patch 
b/media-libs/mlt/files/mlt-7.32.0-ffmpeg8.patch
new file mode 100644
index 000000000000..e2e83eeb5f82
--- /dev/null
+++ b/media-libs/mlt/files/mlt-7.32.0-ffmpeg8.patch
@@ -0,0 +1,355 @@
+From 3501f4e70905e310a7b61b3cd37a1632b9e834ca Mon Sep 17 00:00:00 2001
+From: Dan Dennedy <[email protected]>
+Date: Tue, 26 Aug 2025 11:19:13 -0700
+Subject: [PATCH] Support FFmpeg 8 (#1142)
+
+* Support FFmpeg 8
+
+* Fix support for FFmpeg 6 & 7
+---
+ src/modules/avformat/common.c            | 12 +++-
+ src/modules/avformat/consumer_avformat.c | 23 ++++---
+ src/modules/avformat/filter_avfilter.c   | 11 ++++
+ src/modules/avformat/filter_swscale.c    |  7 +++
+ src/modules/avformat/link_avfilter.c     | 13 +++-
+ src/modules/avformat/producer_avformat.c | 79 +++++++++++++++++++++---
+ 6 files changed, 126 insertions(+), 19 deletions(-)
+
+diff --git a/src/modules/avformat/common.c b/src/modules/avformat/common.c
+index e337651..eca4a04 100644
+--- a/src/modules/avformat/common.c
++++ b/src/modules/avformat/common.c
+@@ -367,10 +367,20 @@ void mlt_image_to_avframe(mlt_image image, mlt_frame 
mltframe, AVFrame *avframe)
+     avframe->height = image->height;
+     avframe->format = mlt_to_av_image_format(image->format);
+     avframe->sample_aspect_ratio = 
av_d2q(mlt_frame_get_aspect_ratio(mltframe), 1024);
+-    ;
+     avframe->pts = mlt_frame_get_position(mltframe);
++#if LIBAVUTIL_VERSION_INT >= ((58 << 16) + (7 << 8) + 100)
++    if (!mlt_properties_get_int(frame_properties, "progressive"))
++        avframe->flags |= AV_FRAME_FLAG_INTERLACED;
++    else
++        avframe->flags &= ~AV_FRAME_FLAG_INTERLACED;
++    if (mlt_properties_get_int(frame_properties, "top_field_first"))
++        avframe->flags |= AV_FRAME_FLAG_TOP_FIELD_FIRST;
++    else
++        avframe->flags &= ~AV_FRAME_FLAG_TOP_FIELD_FIRST;
++#else
+     avframe->interlaced_frame = !mlt_properties_get_int(frame_properties, 
"progressive");
+     avframe->top_field_first = mlt_properties_get_int(frame_properties, 
"top_field_first");
++#endif
+     avframe->color_primaries = mlt_properties_get_int(frame_properties, 
"color_primaries");
+     avframe->color_trc = mlt_properties_get_int(frame_properties, 
"color_trc");
+     avframe->color_range = mlt_properties_get_int(frame_properties, 
"full_range")
+diff --git a/src/modules/avformat/consumer_avformat.c 
b/src/modules/avformat/consumer_avformat.c
+index 22a90dc..d44d555 100644
+--- a/src/modules/avformat/consumer_avformat.c
++++ b/src/modules/avformat/consumer_avformat.c
+@@ -1923,18 +1923,27 @@ static int encode_video(encode_ctx_t *enc_ctx,
+         avframe->pts = enc_ctx->frame_count;
+ 
+         // Set frame interlace hints
++#if LIBAVUTIL_VERSION_INT >= ((58 << 16) + (7 << 8) + 100)
++        if (!mlt_properties_get_int(frame_properties, "progressive"))
++            avframe->flags |= AV_FRAME_FLAG_INTERLACED;
++        else
++            avframe->flags &= ~AV_FRAME_FLAG_INTERLACED;
++        const int tff = mlt_properties_get_int(frame_properties, 
"top_field_first");
++        if (tff)
++            avframe->flags |= AV_FRAME_FLAG_TOP_FIELD_FIRST;
++        else
++            avframe->flags &= ~AV_FRAME_FLAG_TOP_FIELD_FIRST;
++#else
+         avframe->interlaced_frame = !mlt_properties_get_int(frame_properties, 
"progressive");
+-        avframe->top_field_first = mlt_properties_get_int(frame_properties, 
"top_field_first");
++        const int tff = avframe->top_field_first = 
mlt_properties_get_int(frame_properties,
++                                                                          
"top_field_first");
++#endif
+         if (mlt_properties_get_int(frame_properties, "progressive"))
+             c->field_order = AV_FIELD_PROGRESSIVE;
+         else if (c->codec_id == AV_CODEC_ID_MJPEG)
+-            c->field_order = (mlt_properties_get_int(frame_properties, 
"top_field_first"))
+-                                 ? AV_FIELD_TT
+-                                 : AV_FIELD_BB;
++            c->field_order = tff ? AV_FIELD_TT : AV_FIELD_BB;
+         else
+-            c->field_order = (mlt_properties_get_int(frame_properties, 
"top_field_first"))
+-                                 ? AV_FIELD_TB
+-                                 : AV_FIELD_BT;
++            c->field_order = tff ? AV_FIELD_TB : AV_FIELD_BT;
+ 
+         // Encode the image
+         ret = avcodec_send_frame(c, avframe);
+diff --git a/src/modules/avformat/filter_avfilter.c 
b/src/modules/avformat/filter_avfilter.c
+index 32736c1..8e7ff68 100644
+--- a/src/modules/avformat/filter_avfilter.c
++++ b/src/modules/avformat/filter_avfilter.c
+@@ -802,10 +802,21 @@ static int filter_get_image(mlt_frame frame,
+         pdata->avinframe->sample_aspect_ratio = 
(AVRational){profile->sample_aspect_num,
+                                                              
profile->sample_aspect_den};
+         pdata->avinframe->pts = pos;
++#if LIBAVUTIL_VERSION_INT >= ((58 << 16) + (7 << 8) + 100)
++        if (!mlt_properties_get_int(frame_properties, "progressive"))
++            pdata->avinframe->flags |= AV_FRAME_FLAG_INTERLACED;
++        else
++            pdata->avinframe->flags &= ~AV_FRAME_FLAG_INTERLACED;
++        if (mlt_properties_get_int(frame_properties, "top_field_first"))
++            pdata->avinframe->flags |= AV_FRAME_FLAG_TOP_FIELD_FIRST;
++        else
++            pdata->avinframe->flags &= ~AV_FRAME_FLAG_TOP_FIELD_FIRST;
++#else
+         pdata->avinframe->interlaced_frame = 
!mlt_properties_get_int(frame_properties,
+                                                                      
"progressive");
+         pdata->avinframe->top_field_first = 
mlt_properties_get_int(frame_properties,
+                                                                    
"top_field_first");
++#endif
+         pdata->avinframe->color_primaries = 
mlt_properties_get_int(frame_properties,
+                                                                    
"color_primaries");
+         pdata->avinframe->color_trc = 
mlt_properties_get_int(frame_properties, "color_trc");
+diff --git a/src/modules/avformat/filter_swscale.c 
b/src/modules/avformat/filter_swscale.c
+index 938d074..5b56e22 100644
+--- a/src/modules/avformat/filter_swscale.c
++++ b/src/modules/avformat/filter_swscale.c
+@@ -170,8 +170,15 @@ static int filter_scale(mlt_frame frame,
+         avinframe->height = iheight;
+         avinframe->format = avformat;
+         avinframe->sample_aspect_ratio = 
av_d2q(mlt_frame_get_aspect_ratio(frame), 1024);
++#if LIBAVUTIL_VERSION_INT >= ((58 << 16) + (7 << 8) + 100)
++        if (!mlt_properties_get_int(properties, "progressive"))
++            avinframe->flags |= AV_FRAME_FLAG_INTERLACED;
++        if (mlt_properties_get_int(properties, "top_field_first"))
++            avinframe->flags |= AV_FRAME_FLAG_TOP_FIELD_FIRST;
++#else
+         avinframe->interlaced_frame = !mlt_properties_get_int(properties, 
"progressive");
+         avinframe->top_field_first = mlt_properties_get_int(properties, 
"top_field_first");
++#endif
+         av_image_fill_arrays(avinframe->data,
+                              avinframe->linesize,
+                              *image,
+diff --git a/src/modules/avformat/link_avfilter.c 
b/src/modules/avformat/link_avfilter.c
+index 8efda84..f041c67 100644
+--- a/src/modules/avformat/link_avfilter.c
++++ b/src/modules/avformat/link_avfilter.c
+@@ -1,6 +1,6 @@
+ /*
+  * link_avfilter.c -- provide various links based on libavfilter
+- * Copyright (C) 2023-2024 Meltytech, LLC
++ * Copyright (C) 2023-2025 Meltytech, LLC
+  *
+  * This library is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU Lesser General Public
+@@ -917,10 +917,21 @@ static int link_get_image(mlt_frame frame,
+         pdata->avinframe->sample_aspect_ratio = 
(AVRational){profile->sample_aspect_num,
+                                                              
profile->sample_aspect_den};
+         pdata->avinframe->pts = pos;
++#if LIBAVUTIL_VERSION_INT >= ((58 << 16) + (7 << 8) + 100)
++        if (!mlt_properties_get_int(frame_properties, "progressive"))
++            pdata->avinframe->flags |= AV_FRAME_FLAG_INTERLACED;
++        else
++            pdata->avinframe->flags &= ~AV_FRAME_FLAG_INTERLACED;
++        if (mlt_properties_get_int(frame_properties, "top_field_first"))
++            pdata->avinframe->flags |= AV_FRAME_FLAG_TOP_FIELD_FIRST;
++        else
++            pdata->avinframe->flags &= ~AV_FRAME_FLAG_TOP_FIELD_FIRST;
++#else
+         pdata->avinframe->interlaced_frame = 
!mlt_properties_get_int(frame_properties,
+                                                                      
"progressive");
+         pdata->avinframe->top_field_first = 
mlt_properties_get_int(frame_properties,
+                                                                    
"top_field_first");
++#endif
+         pdata->avinframe->color_primaries = 
mlt_properties_get_int(frame_properties,
+                                                                    
"color_primaries");
+         pdata->avinframe->color_trc = 
mlt_properties_get_int(frame_properties, "color_trc");
+diff --git a/src/modules/avformat/producer_avformat.c 
b/src/modules/avformat/producer_avformat.c
+index 1ce59ef..895b68a 100644
+--- a/src/modules/avformat/producer_avformat.c
++++ b/src/modules/avformat/producer_avformat.c
+@@ -335,11 +335,20 @@ static int first_video_index(producer_avformat self)
+ 
+ static const char *get_projection(AVStream *st)
+ {
++#if LIBAVCODEC_VERSION_INT >= ((60 << 16) + (29 << 8) + 100)
++    const AVPacketSideData *psd = 
av_packet_side_data_get(st->codecpar->coded_side_data,
++                                                          
st->codecpar->nb_coded_side_data,
++                                                          
AV_PKT_DATA_SPHERICAL);
++    if (psd) {
++        const AVSphericalMapping *spherical = (const AVSphericalMapping *) 
psd->data;
++#else
+     const AVSphericalMapping *spherical
+         = (const AVSphericalMapping *) av_stream_get_side_data(st, 
AV_PKT_DATA_SPHERICAL, NULL);
+ 
+-    if (spherical)
++    if (spherical) {
++#endif
+         return av_spherical_projection_name(spherical->projection);
++    }
+     return NULL;
+ }
+ 
+@@ -349,7 +358,16 @@ static double get_rotation(mlt_properties properties, 
AVStream *st)
+ {
+     AVDictionaryEntry *rotate_tag = av_dict_get(st->metadata, "rotate", NULL, 
0);
+     int has_rotate_metadata = rotate_tag && *rotate_tag->value && 
strcmp(rotate_tag->value, "0");
++#if LIBAVCODEC_VERSION_INT >= ((60 << 16) + (29 << 8) + 100)
++    int32_t *displaymatrix = NULL;
++    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)
++        displaymatrix = (int32_t *) psd->data;
++#else
+     uint8_t *displaymatrix = av_stream_get_side_data(st, 
AV_PKT_DATA_DISPLAYMATRIX, NULL);
++#endif
+     double theta = mlt_properties_get_double(properties, "rotate");
+     int has_mlt_rotate = !!mlt_properties_get(properties, "rotate");
+ 
+@@ -418,13 +436,6 @@ static AVRational guess_frame_rate(producer_avformat 
self, AVStream *stream)
+         frame_rate = av_d2q(av_q2d(stream->avg_frame_rate), 1024);
+         fps = av_q2d(frame_rate);
+     }
+-    // XXX frame rates less than 1 fps are not considered sane
+-    if (isnan(fps) || isinf(fps) || fps < 1.0) {
+-        // Get the frame rate from the codec.
+-        frame_rate.num = self->video_codec->time_base.den;
+-        frame_rate.den = self->video_codec->time_base.num * 
self->video_codec->ticks_per_frame;
+-        fps = av_q2d(frame_rate);
+-    }
+     if (isnan(fps) || isinf(fps) || fps < 1.0) {
+         // Use the profile frame rate if all else fails.
+         mlt_profile profile = 
mlt_service_profile(MLT_PRODUCER_SERVICE(self->parent));
+@@ -1580,7 +1591,7 @@ static void get_audio_streams_info(producer_avformat 
self)
+ #endif
+                 if (codec_params->sample_rate > self->max_frequency)
+                     self->max_frequency = codec_params->sample_rate;
+-                avcodec_close(codec_context);
++                avcodec_free_context(&codec_context);
+             }
+             pthread_mutex_unlock(&self->open_mutex);
+         }
+@@ -1716,7 +1727,11 @@ static int sliced_h_pix_fmt_conv_proc(int id, int idx, 
int jobs, void *cookie)
+     struct SwsContext *sws;
+     struct sliced_pix_fmt_conv_t *ctx = (struct sliced_pix_fmt_conv_t *) 
cookie;
+ 
++#if LIBAVUTIL_VERSION_INT >= ((58 << 16) + (7 << 8) + 100)
++    interlaced = ctx->frame->flags & AV_FRAME_FLAG_INTERLACED;
++#else
+     interlaced = ctx->frame->interlaced_frame;
++#endif
+     field = (interlaced) ? (idx & 1) : 0;
+     idx = (interlaced) ? (idx / 2) : idx;
+     slices = (interlaced) ? (jobs / 2) : jobs;
+@@ -1865,7 +1880,11 @@ static void convert_image_rgb(producer_avformat self,
+     uint8_t *out_data[4];
+     int out_stride[4];
+ 
++#if LIBAVUTIL_VERSION_INT >= ((58 << 16) + (7 << 8) + 100)
++    if (src_pix_fmt == AV_PIX_FMT_YUV420P && (frame->flags & 
AV_FRAME_FLAG_INTERLACED)) {
++#else
+     if (src_pix_fmt == AV_PIX_FMT_YUV420P && frame->interlaced_frame) {
++#endif
+         // Perform field-aware conversion for 4:2:0
+         int field_height = height / 2;
+         const uint8_t *in_data[4];
+@@ -2041,8 +2060,13 @@ static int convert_image(producer_avformat self,
+ 
+         int sliced = !getenv("MLT_AVFORMAT_SLICED_PIXFMT_DISABLE") && 
src_pix_fmt != ctx.dst_format;
+         if (sliced) {
++#if LIBAVUTIL_VERSION_INT >= ((58 << 16) + (7 << 8) + 100)
++            ctx.slice_w = (width < 1000) ? (256 >> (frame->flags & 
AV_FRAME_FLAG_INTERLACED))
++                                         : (512 >> (frame->flags & 
AV_FRAME_FLAG_INTERLACED));
++#else
+             ctx.slice_w = (width < 1000) ? (256 >> frame->interlaced_frame)
+                                          : (512 >> frame->interlaced_frame);
++#endif
+         } else {
+             ctx.slice_w = width;
+         }
+@@ -2052,10 +2076,18 @@ static int convert_image(producer_avformat self,
+ 
+         if (sliced && (last_slice_w % 8) == 0
+             && !(ctx.src_format == AV_PIX_FMT_YUV422P && last_slice_w % 16)) {
++#if LIBAVUTIL_VERSION_INT >= ((58 << 16) + (7 << 8) + 100)
++            c *= (frame->flags & AV_FRAME_FLAG_INTERLACED) ? 2 : 1;
++#else
+             c *= frame->interlaced_frame ? 2 : 1;
++#endif
+             mlt_slices_run_normal(c, sliced_h_pix_fmt_conv_proc, &ctx);
+         } else {
++#if LIBAVUTIL_VERSION_INT >= ((58 << 16) + (7 << 8) + 100)
++            c = (frame->flags & AV_FRAME_FLAG_INTERLACED) ? 2 : 1;
++#else
+             c = frame->interlaced_frame ? 2 : 1;
++#endif
+             ctx.slice_w = width;
+             for (i = 0; i < c; i++)
+                 sliced_h_pix_fmt_conv_proc(i, i, c, &ctx);
+@@ -2524,7 +2556,11 @@ static int producer_get_image(mlt_frame frame,
+                         // there are I frames, and find_first_pts() fails as 
a result.
+                         // Try to set first_pts here after getting pict_type.
+                         if (self->first_pts == AV_NOPTS_VALUE
++#if LIBAVUTIL_VERSION_INT >= ((58 << 16) + (7 << 8) + 100)
++                            && ((self->video_frame->flags & AV_FRAME_FLAG_KEY)
++#else
+                             && (self->video_frame->key_frame
++#endif
+                                 || self->video_frame->pict_type == 
AV_PICTURE_TYPE_I))
+                             self->first_pts = pts;
+                         if (self->first_pts != AV_NOPTS_VALUE)
+@@ -2558,22 +2594,45 @@ static int producer_get_image(mlt_frame frame,
+                 if (mlt_properties_get(properties, "force_progressive")) {
+                     self->progressive = !!mlt_properties_get_int(properties, 
"force_progressive");
+                 } else if (self->video_frame && codec_params) {
++#if LIBAVUTIL_VERSION_INT >= ((58 << 16) + (7 << 8) + 100)
++                    self->progressive = !(self->video_frame->flags & 
AV_FRAME_FLAG_INTERLACED)
++#else
+                     self->progressive = !self->video_frame->interlaced_frame
++#endif
+                                         && (codec_params->field_order == 
AV_FIELD_PROGRESSIVE
+                                             || codec_params->field_order == 
AV_FIELD_UNKNOWN);
+                 } else {
+                     self->progressive = 0;
+                 }
++#if LIBAVUTIL_VERSION_INT >= ((58 << 16) + (7 << 8) + 100)
++                if (!self->progressive)
++                    self->video_frame->flags |= AV_FRAME_FLAG_INTERLACED;
++                else
++                    self->video_frame->flags &= ~AV_FRAME_FLAG_INTERLACED;
++#else
+                 self->video_frame->interlaced_frame = !self->progressive;
++#endif
+                 // Detect and correct field order
+                 if (mlt_properties_get(properties, "force_tff")) {
+                     self->top_field_first = 
!!mlt_properties_get_int(properties, "force_tff");
+                 } else {
++#if LIBAVUTIL_VERSION_INT >= ((58 << 16) + (7 << 8) + 100)
++                    self->top_field_first = (self->video_frame->flags
++                                             & AV_FRAME_FLAG_TOP_FIELD_FIRST)
++#else
+                     self->top_field_first = self->video_frame->top_field_first
++#endif
+                                             || codec_params->field_order == 
AV_FIELD_TT
+                                             || codec_params->field_order == 
AV_FIELD_TB;
+                 }
++#if LIBAVUTIL_VERSION_INT >= ((58 << 16) + (7 << 8) + 100)
++                if (self->top_field_first)
++                    self->video_frame->flags |= AV_FRAME_FLAG_TOP_FIELD_FIRST;
++                else
++                    self->video_frame->flags &= 
~AV_FRAME_FLAG_TOP_FIELD_FIRST;
++#else
+                 self->video_frame->top_field_first = self->top_field_first;
++#endif
+ #ifdef AVFILTER
+                 if ((self->autorotate || mlt_properties_get(properties, 
"filtergraph"))
+                     && !setup_filters(self) && self->vfilter_graph) {
+@@ -3690,7 +3749,7 @@ static int audio_codec_init(producer_avformat self, int 
index, mlt_properties pr
+         if (codec && avcodec_open2(codec_context, codec, NULL) >= 0) {
+             // Now store the codec with its destructor
+             if (self->audio_codec[index])
+-                avcodec_close(self->audio_codec[index]);
++                avcodec_free_context(&self->audio_codec[index]);
+             self->audio_codec[index] = codec_context;
+             self->audio_index = index;
+         } else {
+-- 
+2.51.0
+

diff --git a/media-libs/mlt/mlt-7.32.0.ebuild b/media-libs/mlt/mlt-7.32.0.ebuild
index 6faed6f5fa49..e40b649efdb8 100644
--- a/media-libs/mlt/mlt-7.32.0.ebuild
+++ b/media-libs/mlt/mlt-7.32.0.ebuild
@@ -102,6 +102,10 @@ src_prepare() {
                python_fix_shebang src/swig/python
        fi
 
+       if has_version ">=media-video/ffmpeg-8"; then
+               PATCHES+=( "${FILESDIR}"/${P}-ffmpeg8.patch ) # bug 961698, git 
master
+       fi
+
        cmake_src_prepare
 }
 

Reply via email to