[FFmpeg-devel] [PATCH v4 16/17] fftools/ffmpeg_filter: propagate codec yuv metadata to filters

Niklas Haas ffmpeg at haasn.xyz
Wed Sep 4 14:02:45 EEST 2024


From: Niklas Haas <git at haasn.dev>

To convert between color spaces/ranges, if needed by the codec
properties.

Signed-off-by: Anton Khirnov <anton at khirnov.net>
---
 fftools/ffmpeg.h          |  4 ++++
 fftools/ffmpeg_filter.c   | 26 ++++++++++++++++++++++++++
 fftools/ffmpeg_mux_init.c | 12 ++++++++++++
 3 files changed, 42 insertions(+)

diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h
index ca24b20640..f4a10b2a66 100644
--- a/fftools/ffmpeg.h
+++ b/fftools/ffmpeg.h
@@ -304,6 +304,8 @@ typedef struct OutputFilterOptions {
     int                 format;
     int                 width;
     int                 height;
+    enum AVColorSpace   color_space;
+    enum AVColorRange   color_range;
 
     enum VideoSyncMethod vsync_method;
 
@@ -314,6 +316,8 @@ typedef struct OutputFilterOptions {
     const int                *sample_rates;
     const AVChannelLayout    *ch_layouts;
     const AVRational         *frame_rates;
+    const enum AVColorSpace  *color_spaces;
+    const enum AVColorRange  *color_ranges;
 } OutputFilterOptions;
 
 typedef struct InputFilter {
diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c
index 9effa96aac..8b420e68ab 100644
--- a/fftools/ffmpeg_filter.c
+++ b/fftools/ffmpeg_filter.c
@@ -202,6 +202,8 @@ typedef struct OutputFilterPriv {
     int                     width, height;
     int                     sample_rate;
     AVChannelLayout         ch_layout;
+    enum AVColorSpace       color_space;
+    enum AVColorRange       color_range;
 
     // time base in which the output is sent to our downstream
     // does not need to match the filtersink's timebase
@@ -220,6 +222,8 @@ typedef struct OutputFilterPriv {
     const int              *formats;
     const AVChannelLayout  *ch_layouts;
     const int              *sample_rates;
+    const enum AVColorSpace *color_spaces;
+    const enum AVColorRange *color_ranges;
 
     AVRational              enc_timebase;
     int64_t                 trim_start_us;
@@ -395,6 +399,12 @@ DEF_CHOOSE_FORMAT(sample_fmts, enum AVSampleFormat, format, formats,
 DEF_CHOOSE_FORMAT(sample_rates, int, sample_rate, sample_rates, 0,
                   "%d", )
 
+DEF_CHOOSE_FORMAT(color_spaces, enum AVColorSpace, color_space, color_spaces,
+                  AVCOL_SPC_UNSPECIFIED, "%s", av_color_space_name);
+
+DEF_CHOOSE_FORMAT(color_ranges, enum AVColorRange, color_range, color_ranges,
+                  AVCOL_RANGE_UNSPECIFIED, "%s", av_color_range_name);
+
 static void choose_channel_layouts(OutputFilterPriv *ofp, AVBPrint *bprint)
 {
     if (av_channel_layout_check(&ofp->ch_layout)) {
@@ -639,6 +649,8 @@ static OutputFilter *ofilter_alloc(FilterGraph *fg, enum AVMediaType type)
     ofilter->graph    = fg;
     ofilter->type     = type;
     ofp->format       = -1;
+    ofp->color_space  = AVCOL_SPC_UNSPECIFIED;
+    ofp->color_range  = AVCOL_RANGE_UNSPECIFIED;
     ofp->index        = fg->nb_outputs - 1;
 
     snprintf(ofp->log_name, sizeof(ofp->log_name), "%co%d",
@@ -822,6 +834,16 @@ int ofilter_bind_ost(OutputFilter *ofilter, OutputStream *ost,
         } else
             ofp->formats = opts->formats;
 
+        if (opts->color_space != AVCOL_SPC_UNSPECIFIED)
+            ofp->color_space = opts->color_space;
+        else
+            ofp->color_spaces = opts->color_spaces;
+
+        if (opts->color_range != AVCOL_RANGE_UNSPECIFIED)
+            ofp->color_range = opts->color_range;
+        else
+            ofp->color_ranges = opts->color_ranges;
+
         fgp->disable_conversions |= !!(ofp->flags & OFILTER_FLAG_DISABLE_CONVERT);
 
         ofp->fps.last_frame = av_frame_alloc();
@@ -1485,6 +1507,8 @@ static int configure_output_video_filter(FilterGraph *fg, AVFilterGraph *graph,
                ofp->format != AV_PIX_FMT_NONE || !ofp->formats);
     av_bprint_init(&bprint, 0, AV_BPRINT_SIZE_UNLIMITED);
     choose_pix_fmts(ofp, &bprint);
+    choose_color_spaces(ofp, &bprint);
+    choose_color_ranges(ofp, &bprint);
     if (!av_bprint_is_complete(&bprint))
         return AVERROR(ENOMEM);
 
@@ -1907,6 +1931,8 @@ static int configure_filtergraph(FilterGraph *fg, FilterGraphThread *fgt)
 
         ofp->width  = av_buffersink_get_w(sink);
         ofp->height = av_buffersink_get_h(sink);
+        ofp->color_space = av_buffersink_get_colorspace(sink);
+        ofp->color_range = av_buffersink_get_color_range(sink);
 
         // If the timing parameters are not locked yet, get the tentative values
         // here but don't lock them. They will only be used if no output frames
diff --git a/fftools/ffmpeg_mux_init.c b/fftools/ffmpeg_mux_init.c
index decf63e7d5..d65167bf7e 100644
--- a/fftools/ffmpeg_mux_init.c
+++ b/fftools/ffmpeg_mux_init.c
@@ -934,6 +934,8 @@ ost_bind_filter(const Muxer *mux, MuxStream *ms, OutputFilter *ofilter,
                             enc_ctx->pix_fmt : enc_ctx->sample_fmt,
         .width            = enc_ctx->width,
         .height           = enc_ctx->height,
+        .color_space      = enc_ctx->colorspace,
+        .color_range      = enc_ctx->color_range,
         .vsync_method     = vsync_method,
         .sample_rate      = enc_ctx->sample_rate,
         .ch_layout        = enc_ctx->ch_layout,
@@ -967,6 +969,16 @@ ost_bind_filter(const Muxer *mux, MuxStream *ms, OutputFilter *ofilter,
             if (ret < 0)
                 return ret;
         }
+        ret = avcodec_get_supported_config(enc_ctx, NULL,
+                                           AV_CODEC_CONFIG_COLOR_SPACE, 0,
+                                           (const void **) &opts.color_spaces, NULL);
+        if (ret < 0)
+            return ret;
+        ret = avcodec_get_supported_config(enc_ctx, NULL,
+                                           AV_CODEC_CONFIG_COLOR_RANGE, 0,
+                                           (const void **) &opts.color_ranges, NULL);
+        if (ret < 0)
+            return ret;
     } else {
         ret = avcodec_get_supported_config(enc_ctx, NULL,
                                            AV_CODEC_CONFIG_SAMPLE_FORMAT, 0,
-- 
2.46.0



More information about the ffmpeg-devel mailing list