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 }
