git: dfe0bac8fb41 - main - multimedia/smelter: Unbreak (was broken by ffmpeg-9.x)

From: Yuri Victorovich <yuri_at_FreeBSD.org>
Date: Tue, 15 Sep 2026 23:28:55 UTC
The branch main has been updated by yuri:

URL: https://cgit.FreeBSD.org/ports/commit/?id=dfe0bac8fb415220b299ff5d125b66eb959cde3f

commit dfe0bac8fb415220b299ff5d125b66eb959cde3f
Author:     Yuri Victorovich <yuri@FreeBSD.org>
AuthorDate: 2026-09-15 23:25:34 +0000
Commit:     Yuri Victorovich <yuri@FreeBSD.org>
CommitDate: 2026-09-15 23:28:46 +0000

    multimedia/smelter: Unbreak (was broken by ffmpeg-9.x)
---
 multimedia/smelter/Makefile                        | 17 +++--
 multimedia/smelter/distinfo                        | 24 +++---
 multimedia/smelter/files/patch-Cargo.toml          | 14 ++++
 ...-crates_aws-lc-sys-0.37.1_builder_cc_builder.rs | 67 ++++++++++++++++
 ...atch-smelter-core_src_pipeline_hls_hls_input.rs | 89 ++++++++++++++++++++++
 5 files changed, 192 insertions(+), 19 deletions(-)

diff --git a/multimedia/smelter/Makefile b/multimedia/smelter/Makefile
index 324d5282a091..97182658993f 100644
--- a/multimedia/smelter/Makefile
+++ b/multimedia/smelter/Makefile
@@ -1,7 +1,7 @@
 PORTNAME=	smelter
 DISTVERSIONPREFIX=	v
 DISTVERSION=	0.6.0
-PORTREVISION=	2
+PORTREVISION=	3
 CATEGORIES=	multimedia
 
 MAINTAINER=	yuri@FreeBSD.org
@@ -12,8 +12,6 @@ WWW=		https://smelter.dev \
 LICENSE=	MIT
 LICENSE_FILE=	${WRKSRC}/LICENSE
 
-BROKEN=		Fails to build with FFmpeg 9
-
 LIB_DEPENDS=	libavutil.so:multimedia/ffmpeg \
 		libopus.so:audio/opus
 
@@ -78,7 +76,7 @@ CARGO_CRATES=	ab_glyph-0.2.29 \
 		bit-vec-0.9.1 \
 		bit_field-0.10.2 \
 		bitflags-1.3.2 \
-		bitflags-2.11.0 \
+		bitflags-2.13.2 \
 		bitstream-io-2.6.0 \
 		block-buffer-0.10.4 \
 		block-padding-0.3.3 \
@@ -95,7 +93,7 @@ CARGO_CRATES=	ab_glyph-0.2.29 \
 		calloop-0.12.4 \
 		calloop-wayland-source-0.2.0 \
 		cbc-0.1.2 \
-		cc-1.2.56 \
+		cc-1.4.6 \
 		ccm-0.5.0 \
 		cesu8-1.1.0 \
 		cexpr-0.6.0 \
@@ -182,11 +180,11 @@ CARGO_CRATES=	ab_glyph-0.2.29 \
 		fdeflate-0.3.7 \
 		fdk-aac-sys-0.5.0 \
 		ff-0.13.0 \
-		ffmpeg-next-8.1.0 \
-		ffmpeg-sys-next-8.1.0 \
+		ffmpeg-next-9.0.0 \
+		ffmpeg-sys-next-9.0.0 \
 		fiat-crypto-0.2.9 \
 		filetime-0.2.26 \
-		find-msvc-tools-0.1.9 \
+		find-msvc-tools-0.1.12 \
 		flate2-1.1.4 \
 		float-cmp-0.9.0 \
 		float-cmp-0.10.0 \
@@ -497,6 +495,7 @@ CARGO_CRATES=	ab_glyph-0.2.29 \
 		sharded-slab-0.1.7 \
 		shared_memory-0.12.4 \
 		shlex-1.3.0 \
+		shlex-2.0.1 \
 		signal-hook-0.3.17 \
 		signal-hook-mio-0.2.4 \
 		signal-hook-registry-1.4.2 \
@@ -774,4 +773,6 @@ PLIST_FILES=	bin/${PORTNAME}
 post-install:
 	@${STRIP_CMD} ${STAGEDIR}${PREFIX}/bin/${PORTNAME}
 
+# tests as of 0.6.0: not run because CARGO_FEATURES=--no-default-features disables the test suite
+
 .include <bsd.port.mk>
diff --git a/multimedia/smelter/distinfo b/multimedia/smelter/distinfo
index 4aa1bbb853f9..e0889270b041 100644
--- a/multimedia/smelter/distinfo
+++ b/multimedia/smelter/distinfo
@@ -1,4 +1,4 @@
-TIMESTAMP = 1783615340
+TIMESTAMP = 1789504897
 SHA256 (rust/crates/ab_glyph-0.2.29.crate) = ec3672c180e71eeaaac3a541fbbc5f5ad4def8b747c595ad30d674e43049f7b0
 SIZE (rust/crates/ab_glyph-0.2.29.crate) = 20011
 SHA256 (rust/crates/ab_glyph_rasterizer-0.1.8.crate) = c71b1793ee61086797f5c80b6efa2b8ffa6d5dd703f118545808a7f2e27f7046
@@ -105,8 +105,8 @@ SHA256 (rust/crates/bit_field-0.10.2.crate) = dc827186963e592360843fb5ba4b973e14
 SIZE (rust/crates/bit_field-0.10.2.crate) = 10568
 SHA256 (rust/crates/bitflags-1.3.2.crate) = bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a
 SIZE (rust/crates/bitflags-1.3.2.crate) = 23021
-SHA256 (rust/crates/bitflags-2.11.0.crate) = 843867be96c8daad0d758b57df9392b6d8d271134fce549de6ce169ff98a92af
-SIZE (rust/crates/bitflags-2.11.0.crate) = 48906
+SHA256 (rust/crates/bitflags-2.13.2.crate) = 3ded4057c258ba199e2d26386d3af3780957ecaee6c4ef4041c6b4b8b97c0b06
+SIZE (rust/crates/bitflags-2.13.2.crate) = 51678
 SHA256 (rust/crates/bitstream-io-2.6.0.crate) = 6099cdc01846bc367c4e7dd630dc5966dccf36b652fae7a74e17b640411a91b2
 SIZE (rust/crates/bitstream-io-2.6.0.crate) = 38256
 SHA256 (rust/crates/block-buffer-0.10.4.crate) = 3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71
@@ -139,8 +139,8 @@ SHA256 (rust/crates/calloop-wayland-source-0.2.0.crate) = 0f0ea9b9476c7fad82841a
 SIZE (rust/crates/calloop-wayland-source-0.2.0.crate) = 11304
 SHA256 (rust/crates/cbc-0.1.2.crate) = 26b52a9543ae338f279b96b0b9fed9c8093744685043739079ce85cd58f289a6
 SIZE (rust/crates/cbc-0.1.2.crate) = 23501
-SHA256 (rust/crates/cc-1.2.56.crate) = aebf35691d1bfb0ac386a69bac2fde4dd276fb618cf8bf4f5318fe285e821bb2
-SIZE (rust/crates/cc-1.2.56.crate) = 96059
+SHA256 (rust/crates/cc-1.4.6.crate) = a3eb0f42d6c360dc3f8a821f6bf2fdea7f72bfd36b3076eb0e6d1e9e0752fff4
+SIZE (rust/crates/cc-1.4.6.crate) = 101852
 SHA256 (rust/crates/ccm-0.5.0.crate) = 9ae3c82e4355234767756212c570e29833699ab63e6ffd161887314cc5b43847
 SIZE (rust/crates/ccm-0.5.0.crate) = 242273
 SHA256 (rust/crates/cesu8-1.1.0.crate) = 6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c
@@ -313,16 +313,16 @@ SHA256 (rust/crates/fdk-aac-sys-0.5.0.crate) = 24516d2611506d5cb1833555adc75f6ba
 SIZE (rust/crates/fdk-aac-sys-0.5.0.crate) = 2495555
 SHA256 (rust/crates/ff-0.13.0.crate) = ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449
 SIZE (rust/crates/ff-0.13.0.crate) = 17688
-SHA256 (rust/crates/ffmpeg-next-8.1.0.crate) = f7c4bd5ab1ac61f29c634df1175d350ded29cf74c3c6d4f7030431a5ae3c7d5d
-SIZE (rust/crates/ffmpeg-next-8.1.0.crate) = 99274
-SHA256 (rust/crates/ffmpeg-sys-next-8.1.0.crate) = a314bc0e022a33a99567ed4bd2576bd58ffd8fcff7891c29194cfecc26a62547
-SIZE (rust/crates/ffmpeg-sys-next-8.1.0.crate) = 23004
+SHA256 (rust/crates/ffmpeg-next-9.0.0.crate) = 6380599799e175191eb7ffe82c97f36a2a90a36cbc54c738a903e5287d7f516a
+SIZE (rust/crates/ffmpeg-next-9.0.0.crate) = 122284
+SHA256 (rust/crates/ffmpeg-sys-next-9.0.0.crate) = 9b939bf79dd5949412a4b81cfe21a07f48ea21b47fcbb5f57816c8c2de5ae30b
+SIZE (rust/crates/ffmpeg-sys-next-9.0.0.crate) = 27547
 SHA256 (rust/crates/fiat-crypto-0.2.9.crate) = 28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d
 SIZE (rust/crates/fiat-crypto-0.2.9.crate) = 495390
 SHA256 (rust/crates/filetime-0.2.26.crate) = bc0505cd1b6fa6580283f6bdf70a73fcf4aba1184038c90902b92b3dd0df63ed
 SIZE (rust/crates/filetime-0.2.26.crate) = 17273
-SHA256 (rust/crates/find-msvc-tools-0.1.9.crate) = 5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582
-SIZE (rust/crates/find-msvc-tools-0.1.9.crate) = 31493
+SHA256 (rust/crates/find-msvc-tools-0.1.12.crate) = 3e0f1c7c3a72c66fd80abe965175f7523475c0489a87d3ff9d6e8c87d87a9d2d
+SIZE (rust/crates/find-msvc-tools-0.1.12.crate) = 31570
 SHA256 (rust/crates/flate2-1.1.4.crate) = dc5a4e564e38c699f2880d3fda590bedc2e69f3f84cd48b457bd892ce61d0aa9
 SIZE (rust/crates/flate2-1.1.4.crate) = 77010
 SHA256 (rust/crates/float-cmp-0.9.0.crate) = 98de4bbd547a563b716d8dfa9aad1cb19bfab00f4fa09a6a4ed21dbcf44ce9c4
@@ -943,6 +943,8 @@ SHA256 (rust/crates/shared_memory-0.12.4.crate) = ba8593196da75d9dc4f69349682bd4
 SIZE (rust/crates/shared_memory-0.12.4.crate) = 15872
 SHA256 (rust/crates/shlex-1.3.0.crate) = 0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64
 SIZE (rust/crates/shlex-1.3.0.crate) = 18713
+SHA256 (rust/crates/shlex-2.0.1.crate) = f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba
+SIZE (rust/crates/shlex-2.0.1.crate) = 19332
 SHA256 (rust/crates/signal-hook-0.3.17.crate) = 8621587d4798caf8eb44879d42e56b9a93ea5dcd315a6487c357130095b62801
 SIZE (rust/crates/signal-hook-0.3.17.crate) = 50296
 SHA256 (rust/crates/signal-hook-mio-0.2.4.crate) = 34db1a06d485c9142248b7a054f034b349b212551f3dfd19c94d45a754a217cd
diff --git a/multimedia/smelter/files/patch-Cargo.toml b/multimedia/smelter/files/patch-Cargo.toml
new file mode 100644
index 000000000000..d2437f52acf4
--- /dev/null
+++ b/multimedia/smelter/files/patch-Cargo.toml
@@ -0,0 +1,14 @@
+-- Bump ffmpeg-next to 9.0.0 for FFmpeg 9 support.
+-- https://github.com/software-mansion/smelter/pull/2182
+
+--- Cargo.toml.orig
++++ Cargo.toml
+@@ -46,7 +46,7 @@ thiserror = "1.0.40"
+ crossbeam-channel = "0.5.15"
+ reqwest = { version = "0.12.3", features = ["blocking", "json"] }
+ signal-hook = "0.3.15"
+-ffmpeg-next = "8.1.0"
++ffmpeg-next = "9.0.0"
+ fs_extra = "1.3.0"
+ anyhow = "1.0.71"
+ image = { version = "0.24.7", features = ["jpeg", "png"] }
diff --git a/multimedia/smelter/files/patch-cargo-crates_aws-lc-sys-0.37.1_builder_cc_builder.rs b/multimedia/smelter/files/patch-cargo-crates_aws-lc-sys-0.37.1_builder_cc_builder.rs
new file mode 100644
index 000000000000..02c7c2281179
--- /dev/null
+++ b/multimedia/smelter/files/patch-cargo-crates_aws-lc-sys-0.37.1_builder_cc_builder.rs
@@ -0,0 +1,67 @@
+-- cc 1.4.x appends CFLAGS after build-script flags, so a -O2 from the
+-- environment overrides the -O0 aws-lc-sys adds for jitterentropy.
+-- Strip optimization flags from both CFLAGS and CFLAGS_${TARGET} before
+-- building jitterentropy, and restore them afterwards.
+-- https://github.com/aws/aws-lc-rs/issues/681
+
+--- cargo-crates/aws-lc-sys-0.37.1/builder/cc_builder.rs.orig
++++ cargo-crates/aws-lc-sys-0.37.1/builder/cc_builder.rs
+@@ -20,7 +20,7 @@
+ use crate::nasm_builder::NasmBuilder;
+ use crate::{
+     cargo_env, disable_jitter_entropy, emit_warning, env_var_to_bool, execute_command,
+-    get_crate_cc, get_crate_cflags, get_crate_cxx, is_no_asm, out_dir, requested_c_std,
++    get_crate_cc, get_crate_cflags, get_crate_cxx, is_no_asm, out_dir, requested_c_std, set_env,
+     set_env_for_target, target, target_arch, target_env, target_os, target_vendor,
+     test_clang_cl_command, CStdRequested, OutputLibType,
+ };
+@@ -431,17 +431,21 @@
+         }
+ 
+         if let Some(original_cflags) = get_crate_cflags() {
+-            let mut new_cflags = original_cflags.clone();
++            let mut new_cflags = original_cflags
++                .split_whitespace()
++                .filter(|arg| !arg.starts_with("-O"))
++                .collect::<Vec<_>>()
++                .join(" ");
+             if is_like_msvc {
+                 new_cflags.push_str(" -Od");
+             } else {
+                 new_cflags.push_str(" -O0 -Wp,-U_FORTIFY_SOURCE");
+             }
++            set_env("CFLAGS", &new_cflags);
+             set_env_for_target("CFLAGS", &new_cflags);
+             // cc-rs currently prioritizes flags provided by CFLAGS over the flags provided by the build script.
+             // The environment variables used by the compiler are set when `get_compiler` is called.
+             je_builder.get_compiler();
+-            set_env_for_target("CFLAGS", &original_cflags);
+         }
+ 
+         je_builder.define("AWSLC", "1");
+@@ -500,6 +504,8 @@
+         // CPU Jitter Entropy is compiled separately due to needing specific flags
+         let mut jitter_entropy_builder =
+             self.prepare_jitter_entropy_builder(compiler.is_like_msvc());
++        let jitter_entropy_original_cflags = get_crate_cflags();
++
+         jitter_entropy_builder.flag(format!(
+             "{}{}",
+             force_include_option,
+@@ -568,9 +574,16 @@
+         }
+         if Some(true) != disable_jitter_entropy() {
+             let jitter_entropy_object_files = jitter_entropy_builder.compile_intermediates();
++            if let Some(ref original_cflags) = jitter_entropy_original_cflags {
++                set_env("CFLAGS", original_cflags);
++                set_env_for_target("CFLAGS", original_cflags);
++            }
+             for object in jitter_entropy_object_files {
+                 cc_build.object(object);
+             }
++        } else if let Some(ref original_cflags) = jitter_entropy_original_cflags {
++            set_env("CFLAGS", original_cflags);
++            set_env_for_target("CFLAGS", original_cflags);
+         }
+         let nasm_object_files = nasm_builder.compile_intermediates();
+         for object in nasm_object_files {
diff --git a/multimedia/smelter/files/patch-smelter-core_src_pipeline_hls_hls_input.rs b/multimedia/smelter/files/patch-smelter-core_src_pipeline_hls_hls_input.rs
new file mode 100644
index 000000000000..d150628c34df
--- /dev/null
+++ b/multimedia/smelter/files/patch-smelter-core_src_pipeline_hls_hls_input.rs
@@ -0,0 +1,89 @@
+-- Adapt HLS input to ffmpeg-next 9.0.0 API.
+-- Replaces the custom input_with_dictionary_and_interrupt wrapper with
+-- ffmpeg_next::format::input_with_interrupt_and_dictionary.
+-- https://github.com/software-mansion/smelter/pull/2182
+
+--- smelter-core/src/pipeline/hls/hls_input.rs.orig
++++ smelter-core/src/pipeline/hls/hls_input.rs
+@@ -1,6 +1,5 @@
+ use std::{
+-    ffi::CString,
+-    ptr, slice,
++    slice,
+     sync::{
+         Arc,
+         atomic::{AtomicBool, Ordering},
+@@ -11,13 +10,8 @@
+ use bytes::Bytes;
+ use ffmpeg_next::{
+     Dictionary, Packet, Stream,
+-    ffi::{
+-        avformat_alloc_context, avformat_close_input, avformat_find_stream_info,
+-        avformat_open_input,
+-    },
+-    format::context,
++    format::{context, input_with_interrupt_and_dictionary},
+     media::Type,
+-    util::interrupt,
+ };
+ use tracing::{Level, debug, info, span, trace, warn};
+ 
+@@ -552,11 +546,10 @@
+ 
+ impl FfmpegInputContext {
+     fn new(url: &Arc<str>, should_close: Arc<AtomicBool>) -> Result<Self, ffmpeg_next::Error> {
+-        let ctx = input_with_dictionary_and_interrupt(
+-            url,
+-            Dictionary::from_iter([("protocol_whitelist", "tcp,hls,http,https,file,tls")]),
+-            // move is required even though types do not require it
++        let ctx = input_with_interrupt_and_dictionary(
++            &**url,
+             move || should_close.load(Ordering::Relaxed),
++            Dictionary::from_iter([("protocol_whitelist", "tcp,hls,http,https,file,tls")]),
+         )?;
+         Ok(Self { ctx })
+     }
+@@ -579,43 +572,8 @@
+         Ok(packet)
+     }
+ }
+-
+-/// Combined implementation of ffmpeg_next::format:input_with_interrupt and
+-/// ffmpeg_next::format::input_with_dictionary that allows passing both interrupt
+-/// callback and Dictionary with options
+-fn input_with_dictionary_and_interrupt<F>(
+-    path: &str,
+-    options: Dictionary,
+-    interrupt_fn: F,
+-) -> Result<context::Input, ffmpeg_next::Error>
+-where
+-    F: FnMut() -> bool + 'static,
+-{
+-    unsafe {
+-        let mut ps = avformat_alloc_context();
+ 
+-        (*ps).interrupt_callback = interrupt::new(Box::new(interrupt_fn)).interrupt;
+ 
+-        let path = CString::new(path).unwrap();
+-        let mut opts = options.disown();
+-        let res = avformat_open_input(&mut ps, path.as_ptr(), ptr::null_mut(), &mut opts);
+-
+-        Dictionary::own(opts);
+-
+-        match res {
+-            0 => match avformat_find_stream_info(ps, ptr::null_mut()) {
+-                r if r >= 0 => Ok(context::Input::wrap(ps)),
+-                e => {
+-                    avformat_close_input(&mut ps);
+-                    Err(ffmpeg_next::Error::from(e))
+-                }
+-            },
+-
+-            e => Err(ffmpeg_next::Error::from(e)),
+-        }
+-    }
+-}
+-
+ #[derive(Clone, Copy)]
+ enum TrackKind {
+     Audio,