Hi Adrian On 2026-10-03 18:55:53 +0300, Adrian Bunk wrote: > Control: tags 1144240 + patch > Control: tags 1144240 + pending > > Dear maintainer, > > I've prepared an NMU for cyanrip (versioned as 0.9.3.1-2.1) and uploaded > it to DELAYED/2. Please feel free to tell me if I should cancel it.
Please cancel it. Upstream is supposed to release a new version. Cheers > > cu > Adrian > diffstat for cyanrip-0.9.3.1 cyanrip-0.9.3.1 > > changelog | 7 > patches/0001-Support-the-FFmpeg-7.1-codec-and-buffersink-APIs.patch | 240 > ++++++++++ > patches/series | 1 > 3 files changed, 248 insertions(+) > > diff -Nru cyanrip-0.9.3.1/debian/changelog cyanrip-0.9.3.1/debian/changelog > --- cyanrip-0.9.3.1/debian/changelog 2026-06-15 23:07:11.000000000 +0300 > +++ cyanrip-0.9.3.1/debian/changelog 2026-10-03 18:51:06.000000000 +0300 > @@ -1,3 +1,10 @@ > +cyanrip (0.9.3.1-2.1) unstable; urgency=medium > + > + * Non-maintainer upload. > + * Backport upstream fix for FTBFS with ffmpeg 9. (Closes: #1144240) > + > + -- Adrian Bunk <[email protected]> Sat, 03 Oct 2026 18:51:06 +0300 > + > cyanrip (0.9.3.1-2) unstable; urgency=medium > > * debian/control: > diff -Nru > cyanrip-0.9.3.1/debian/patches/0001-Support-the-FFmpeg-7.1-codec-and-buffersink-APIs.patch > > cyanrip-0.9.3.1/debian/patches/0001-Support-the-FFmpeg-7.1-codec-and-buffersink-APIs.patch > --- > cyanrip-0.9.3.1/debian/patches/0001-Support-the-FFmpeg-7.1-codec-and-buffersink-APIs.patch > 1970-01-01 02:00:00.000000000 +0200 > +++ > cyanrip-0.9.3.1/debian/patches/0001-Support-the-FFmpeg-7.1-codec-and-buffersink-APIs.patch > 2026-10-03 18:51:01.000000000 +0300 > @@ -0,0 +1,240 @@ > +From 63b6fca448bad6ba8a7b6d295f56853c5d0f89e0 Mon Sep 17 00:00:00 2001 > +From: Lynne <[email protected]> > +Date: Sun, 12 Jul 2026 19:18:46 +0900 > +Subject: Support the FFmpeg 7.1+ codec and buffersink APIs > + > +FFmpeg master (lavc 63) removed AVCodec.ch_layouts/sample_fmts/ > +supported_samplerates and the buffersink int-list options that were > +deprecated in 7.1. Query codec capabilities through > +avcodec_get_supported_config() and configure the buffersink via > +av_opt_set_array() on lavc >= 61.13.100/lavfi >= 10.6.100, keeping > +the old paths for older FFmpeg. > + > +The buffersink is now allocated, configured and then initialized > +explicitly, as setting non-runtime options on an initialized object > +is rejected since FFmpeg 8.0. This is what broke -E and HDCD/ > +deemphasis ripping in general against FFmpeg 8: > +"Error setting filter sample format: Invalid argument!" > + > +Closes #137 > +Closes #142 > + > +Co-Authored-By: Claude Fable 5 <[email protected]> > +Claude-Session: https://claude.ai/code/session_014GYNg8856YE285XHQSF1ZV > +--- > + src/cyanrip_encode.c | 115 ++++++++++++++++++++++++++++++++++--------- > + 1 file changed, 92 insertions(+), 23 deletions(-) > + > +diff --git a/src/cyanrip_encode.c b/src/cyanrip_encode.c > +index e3ad09f..915094f 100644 > +--- a/src/cyanrip_encode.c > ++++ b/src/cyanrip_encode.c > +@@ -132,6 +132,31 @@ const char *cyanrip_fmt_folder(enum > cyanrip_output_formats format) > + return format < CYANRIP_FORMATS_NB ? > crip_fmt_info[format].folder_suffix : NULL; > + } > + > ++/* The AVCodec.ch_layouts/sample_fmts/supported_samplerates fields were > ++ * replaced by avcodec_get_supported_config() in lavc 61.13.100 (FFmpeg 7.1) > ++ * and later removed. All lists remain terminated, so NULL still means > ++ * "supports anything". */ > ++#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(61, 13, 100) > ++static const void *codec_supported_config(const AVCodec *codec, > ++ enum AVCodecConfig config) > ++{ > ++ const void *list = NULL; > ++ if (avcodec_get_supported_config(NULL, codec, config, 0, &list, NULL) < > 0) > ++ return NULL; > ++ return list; > ++} > ++#define CODEC_CH_LAYOUTS(codec) \ > ++ ((const AVChannelLayout *)codec_supported_config(codec, > AV_CODEC_CONFIG_CHANNEL_LAYOUT)) > ++#define CODEC_SAMPLE_FMTS(codec) \ > ++ ((const enum AVSampleFormat *)codec_supported_config(codec, > AV_CODEC_CONFIG_SAMPLE_FORMAT)) > ++#define CODEC_SAMPLERATES(codec) \ > ++ ((const int *)codec_supported_config(codec, > AV_CODEC_CONFIG_SAMPLE_RATE)) > ++#else > ++#define CODEC_CH_LAYOUTS(codec) ((codec)->ch_layouts) > ++#define CODEC_SAMPLE_FMTS(codec) ((codec)->sample_fmts) > ++#define CODEC_SAMPLERATES(codec) ((codec)->supported_samplerates) > ++#endif > ++ > + static AVChannelLayout pick_codec_channel_layout(const AVCodec *codec) > + { > + int i = 0; > +@@ -139,17 +164,18 @@ static AVChannelLayout pick_codec_channel_layout(const > AVCodec *codec) > + AVChannelLayout ilayout = AV_CHANNEL_LAYOUT_STEREO; > + int in_channels = ilayout.nb_channels; > + AVChannelLayout best_layout = { 0 }; > ++ const AVChannelLayout *ch_layouts = CODEC_CH_LAYOUTS(codec); > + > + /* Supports anything */ > +- if (!codec->ch_layouts) > ++ if (!ch_layouts) > + return ilayout; > + > + /* Try to match */ > + while (1) { > +- if (!codec->ch_layouts[i].nb_channels) > ++ if (!ch_layouts[i].nb_channels) > + break; > +- if (!av_channel_layout_compare(&codec->ch_layouts[i], &ilayout)) > +- return codec->ch_layouts[i]; > ++ if (!av_channel_layout_compare(&ch_layouts[i], &ilayout)) > ++ return ch_layouts[i]; > + i++; > + } > + > +@@ -157,15 +183,15 @@ static AVChannelLayout pick_codec_channel_layout(const > AVCodec *codec) > + > + /* Try to match channel counts */ > + while (1) { > +- if (!codec->ch_layouts[i].nb_channels) > ++ if (!ch_layouts[i].nb_channels) > + break; > +- int num = codec->ch_layouts[i].nb_channels; > ++ int num = ch_layouts[i].nb_channels; > + if (num > max_channels) { > + max_channels = num; > +- best_layout = codec->ch_layouts[i]; > ++ best_layout = ch_layouts[i]; > + } > + if (num >= in_channels) > +- return codec->ch_layouts[i]; > ++ return ch_layouts[i]; > + i++; > + } > + > +@@ -184,19 +210,21 @@ static enum AVSampleFormat pick_codec_sample_fmt(const > AVCodec *codec, int hdcd) > + AV_SAMPLE_FMT_S16P; > + enum AVSampleFormat max_bps_fmt = AV_SAMPLE_FMT_NONE; > + > ++ const enum AVSampleFormat *sample_fmts = CODEC_SAMPLE_FMTS(codec); > ++ > + ibps = ibps >> 3; > + > + /* Accepts anything */ > +- if (!codec->sample_fmts) > ++ if (!sample_fmts) > + return ifmt; > + > + /* Try to match the input sample format first */ > + while (1) { > +- if (codec->sample_fmts[i] == AV_SAMPLE_FMT_NONE) > ++ if (sample_fmts[i] == AV_SAMPLE_FMT_NONE) > + break; > +- if (codec->sample_fmts[i] == ifmt || > +- codec->sample_fmts[i] == ifmt_p) > +- return codec->sample_fmts[i]; > ++ if (sample_fmts[i] == ifmt || > ++ sample_fmts[i] == ifmt_p) > ++ return sample_fmts[i]; > + i++; > + } > + > +@@ -204,15 +232,15 @@ static enum AVSampleFormat pick_codec_sample_fmt(const > AVCodec *codec, int hdcd) > + > + /* Try to match bits per sample */ > + while (1) { > +- if (codec->sample_fmts[i] == -1) > ++ if (sample_fmts[i] == -1) > + break; > +- int bps = av_get_bytes_per_sample(codec->sample_fmts[i]); > ++ int bps = av_get_bytes_per_sample(sample_fmts[i]); > + if (bps > max_bps) { > + max_bps = bps; > +- max_bps_fmt = codec->sample_fmts[i]; > ++ max_bps_fmt = sample_fmts[i]; > + } > + if (bps == ibps) > +- return codec->sample_fmts[i]; > ++ return sample_fmts[i]; > + i++; > + } > + > +@@ -224,15 +252,16 @@ static int pick_codec_sample_rate(const AVCodec *codec) > + { > + int i = 0, ret; > + int irate = 44100; > ++ const int *samplerates = CODEC_SAMPLERATES(codec); > + > +- if (!codec->supported_samplerates) > ++ if (!samplerates) > + return irate; > + > + /* Go to the array terminator (0) */ > +- while (codec->supported_samplerates[++i] > 0); > ++ while (samplerates[++i] > 0); > + /* Alloc, copy and sort array upwards */ > + int *tmp = av_malloc(i*sizeof(int)); > +- memcpy(tmp, codec->supported_samplerates, i*sizeof(int)); > ++ memcpy(tmp, samplerates, i*sizeof(int)); > + qsort(tmp, i, sizeof(int), cmp_numbers); > + > + /* Pick lowest one above the input rate, otherwise just use the highest > one */ > +@@ -327,13 +356,46 @@ static int init_filtering(cyanrip_ctx *ctx, > cyanrip_filt_ctx *s, > + > + if (!peak) { > + const AVFilter *abuffersink = avfilter_get_by_name("abuffersink"); > +- ret = avfilter_graph_create_filter(&s->buffersink_ctx, abuffersink, > "out", > +- NULL, NULL, s->graph); > +- if (ret < 0) { > ++ /* Options must be set between allocation and init, non-runtime > ++ * option changes on initialized objects are rejected */ > ++ s->buffersink_ctx = avfilter_graph_alloc_filter(s->graph, > abuffersink, "out"); > ++ if (!s->buffersink_ctx) { > ++ ret = AVERROR(ENOMEM); > + cyanrip_log(ctx, 0, "Error creating filter sink: %s!\n", > av_err2str(ret)); > + goto fail; > + } > + > ++#if LIBAVFILTER_VERSION_INT >= AV_VERSION_INT(10, 6, 100) > ++ /* Buffersink switched to array-type options in lavfi 10.6.100 > ++ * (FFmpeg 7.1); the int-list options were later removed */ > ++ if (hdcd || deemphasis) { > ++ const enum AVSampleFormat out_sample_fmt = hdcd ? > AV_SAMPLE_FMT_S32 : > ++ > AV_SAMPLE_FMT_DBLP; > ++ ret = av_opt_set_array(s->buffersink_ctx, "sample_formats", > ++ AV_OPT_SEARCH_CHILDREN, 0, 1, > ++ AV_OPT_TYPE_SAMPLE_FMT, &out_sample_fmt); > ++ if (ret < 0) { > ++ cyanrip_log(ctx, 0, "Error setting filter sample format: > %s!\n", av_err2str(ret)); > ++ goto fail; > ++ } > ++ } > ++ > ++ ret = av_opt_set(s->buffersink_ctx, "channel_layouts", "stereo", > ++ AV_OPT_SEARCH_CHILDREN); > ++ if (ret < 0) { > ++ cyanrip_log(ctx, 0, "Error setting filter channel layout: > %s!\n", av_err2str(ret)); > ++ goto fail; > ++ } > ++ > ++ const int out_sample_rate = 44100; > ++ ret = av_opt_set_array(s->buffersink_ctx, "samplerates", > ++ AV_OPT_SEARCH_CHILDREN, 0, 1, > ++ AV_OPT_TYPE_INT, &out_sample_rate); > ++ if (ret < 0) { > ++ cyanrip_log(ctx, 0, "Error setting filter sample rate: %s!\n", > av_err2str(ret)); > ++ goto fail; > ++ } > ++#else > + static const enum AVSampleFormat out_sample_fmts_hdcd[] = { > AV_SAMPLE_FMT_S32, -1 }; > + static const enum AVSampleFormat out_sample_fmts_deemph[] = { > AV_SAMPLE_FMT_DBLP, -1 }; > + > +@@ -360,6 +422,13 @@ static int init_filtering(cyanrip_ctx *ctx, > cyanrip_filt_ctx *s, > + cyanrip_log(ctx, 0, "Error setting filter sample rate: %s!\n", > av_err2str(ret)); > + goto fail; > + } > ++#endif > ++ > ++ ret = avfilter_init_str(s->buffersink_ctx, NULL); > ++ if (ret < 0) { > ++ cyanrip_log(ctx, 0, "Error initializing filter sink: %s!\n", > av_err2str(ret)); > ++ goto fail; > ++ } > + } > + > + outputs = avfilter_inout_alloc(); > +-- > +2.47.3 > + > diff -Nru cyanrip-0.9.3.1/debian/patches/series > cyanrip-0.9.3.1/debian/patches/series > --- cyanrip-0.9.3.1/debian/patches/series 1970-01-01 02:00:00.000000000 > +0200 > +++ cyanrip-0.9.3.1/debian/patches/series 2026-10-03 18:51:06.000000000 > +0300 > @@ -0,0 +1 @@ > +0001-Support-the-FFmpeg-7.1-codec-and-buffersink-APIs.patch -- Sebastian Ramacher

