From 46990a835dd084e8294e74913daaa2c2ab31b2a2 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 8 Oct 2025 08:10:07 +0200 Subject: Support FFmpeg 8 (for Arch). --- src/lib/audio_filter_graph.cc | 12 ++++++++++++ src/lib/ffmpeg_content.cc | 12 ++++++++++++ src/lib/ffmpeg_file_encoder.cc | 7 ++++++- src/lib/filter_graph.cc | 13 +++++++++++++ src/lib/video_filter_graph.cc | 5 +++++ wscript | 6 +++++- 6 files changed, 53 insertions(+), 2 deletions(-) diff --git a/src/lib/audio_filter_graph.cc b/src/lib/audio_filter_graph.cc index 014ad6e5a..25a0bc7f2 100644 --- a/src/lib/audio_filter_graph.cc +++ b/src/lib/audio_filter_graph.cc @@ -79,17 +79,29 @@ AudioFilterGraph::src_parameters () const void AudioFilterGraph::set_parameters (AVFilterContext* context) const { +#ifdef DCPOMATIC_FFMPEG_8 + int r = av_opt_set(context, "sample_formats", "fltp", AV_OPT_SEARCH_CHILDREN); +#else AVSampleFormat sample_fmts[] = { AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE }; int r = av_opt_set_int_list (context, "sample_fmts", sample_fmts, AV_SAMPLE_FMT_NONE, AV_OPT_SEARCH_CHILDREN); +#endif DCPOMATIC_ASSERT (r >= 0); char ch_layout[64]; av_channel_layout_describe(&_channel_layout, ch_layout, sizeof(ch_layout)); +#ifdef DCPOMATIC_FFMPEG_8 + r = av_opt_set(context, "channel_layouts", ch_layout, AV_OPT_SEARCH_CHILDREN); +#else r = av_opt_set(context, "ch_layouts", ch_layout, AV_OPT_SEARCH_CHILDREN); +#endif DCPOMATIC_ASSERT (r >= 0); +#ifdef DCPOMATIC_FFMPEG_8 + r = av_opt_set_array(context, "samplerates", AV_OPT_SEARCH_CHILDREN, 0, 1, AV_OPT_TYPE_INT, &_sample_rate); +#else int sample_rates[] = { _sample_rate, -1 }; r = av_opt_set_int_list (context, "sample_rates", sample_rates, -1, AV_OPT_SEARCH_CHILDREN); +#endif DCPOMATIC_ASSERT (r >= 0); } diff --git a/src/lib/ffmpeg_content.cc b/src/lib/ffmpeg_content.cc index 3c5db11f4..e0c817934 100644 --- a/src/lib/ffmpeg_content.cc +++ b/src/lib/ffmpeg_content.cc @@ -656,10 +656,22 @@ FFmpegContent::add_properties (shared_ptr film, list& _("SMPTE 2085, Y'D'zD'x"), _("Chroma-derived non-constant luminance"), _("Chroma-derived constant luminance"), +#ifdef DCPOMATIC_FFMPEG_8 + _("BT2100"), + _("SMPTE ST 2128, IPT-C2"), + _("YCgCo-R, even addition"), + _("YCgCo-R, odd addition") +#else _("BT2100") +#endif }; +#ifdef DCPOMATIC_FFMPEG_8 + DCPOMATIC_ASSERT(AVCOL_SPC_NB == 18); +#else DCPOMATIC_ASSERT (AVCOL_SPC_NB == 15); +#endif + p.push_back (UserProperty (UserProperty::VIDEO, _("Colourspace"), spaces[_colorspace.get_value_or(AVCOL_SPC_UNSPECIFIED)])); if (_bits_per_pixel) { diff --git a/src/lib/ffmpeg_file_encoder.cc b/src/lib/ffmpeg_file_encoder.cc index 9f391df5d..1a1f8fed6 100644 --- a/src/lib/ffmpeg_file_encoder.cc +++ b/src/lib/ffmpeg_file_encoder.cc @@ -73,7 +73,12 @@ public: _codec_context->bit_rate = channels * 128 * 1024; _codec_context->sample_fmt = sample_format; _codec_context->sample_rate = frame_rate; - av_channel_layout_default(&_codec_context->ch_layout, channels); + if (codec_name == "aac" && channels == 16) { + /* The default layout for AAC with 16 channels is not valid */ + _codec_context->ch_layout = AV_CHANNEL_LAYOUT_HEXADECAGONAL; + } else { + av_channel_layout_default(&_codec_context->ch_layout, channels); + } int r = avcodec_open2(_codec_context, _codec, 0); if (r < 0) { diff --git a/src/lib/filter_graph.cc b/src/lib/filter_graph.cc index 809954b23..60f046374 100644 --- a/src/lib/filter_graph.cc +++ b/src/lib/filter_graph.cc @@ -80,12 +80,25 @@ FilterGraph::setup(vector const& filters) throw DecodeError (N_("could not create buffer source")); } +#ifdef DCPOMATIC_FFMPEG_8 + _buffer_sink_context = avfilter_graph_alloc_filter(_graph, buffer_sink, N_("out")); + if (!_buffer_sink_context) { + throw DecodeError(N_("could not allocate buffer sink.")); + } +#else if (avfilter_graph_create_filter (&_buffer_sink_context, buffer_sink, N_("out"), nullptr, nullptr, _graph) < 0) { throw DecodeError (N_("could not create buffer sink.")); } +#endif set_parameters (_buffer_sink_context); +#ifdef DCPOMATIC_FFMPEG_8 + if (avfilter_init_dict(_buffer_sink_context, nullptr) < 0) { + throw DecodeError(N_("could not initialise buffer sink.")); + } +#endif + auto outputs = avfilter_inout_alloc (); outputs->name = av_strdup(N_("in")); outputs->filter_ctx = _buffer_src_context; diff --git a/src/lib/video_filter_graph.cc b/src/lib/video_filter_graph.cc index d647acc6f..17b983c4d 100644 --- a/src/lib/video_filter_graph.cc +++ b/src/lib/video_filter_graph.cc @@ -28,6 +28,7 @@ extern "C" { #include #include #include +#include } #include "i18n.h" @@ -152,8 +153,12 @@ VideoFilterGraph::src_parameters () const void VideoFilterGraph::set_parameters (AVFilterContext* context) const { +#ifdef DCPOMATIC_FFMPEG_8 + auto const r = av_opt_set(context, "pixel_formats", av_get_pix_fmt_name(_pixel_format), AV_OPT_SEARCH_CHILDREN); +#else AVPixelFormat pix_fmts[] = { _pixel_format, AV_PIX_FMT_NONE }; int r = av_opt_set_int_list (context, "pix_fmts", pix_fmts, AV_PIX_FMT_NONE, AV_OPT_SEARCH_CHILDREN); +#endif DCPOMATIC_ASSERT (r >= 0); } diff --git a/wscript b/wscript index 8e0673bb1..d4e817230 100644 --- a/wscript +++ b/wscript @@ -498,7 +498,11 @@ def configure(conf): conf.check_cfg(package='libavcodec', args='--cflags --libs', uselib_store='AVCODEC', mandatory=True) conf.check_cfg(package='libavutil', args='--cflags --libs', uselib_store='AVUTIL', mandatory=True) conf.check_cfg(package='libswscale', args='--cflags --libs', uselib_store='SWSCALE', mandatory=True) - conf.check_cfg(package='libpostproc', args='--cflags --libs', uselib_store='POSTPROC', mandatory=True) + # Use a lack of libpostproc as a sign that we are on FFmpeg 8 + # We need this check while we're using ffmpeg 7 and arch already switched to 8 + if conf.check_cfg(package='libpostproc', args='--cflags --libs', uselib_store='POSTPROC', mandatory=False) is None: + conf.env.append_value('CXXFLAGS', '-DDCPOMATIC_FFMPEG_8') + conf.check_cfg(package='libswresample', args='--cflags --libs', uselib_store='SWRESAMPLE', mandatory=True) # Check to see if we have our version of FFmpeg that allows us to get at EBUR128 results -- cgit v1.2.3