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

Niklas Haas ffmpeg at haasn.xyz
Mon Apr 8 15:57:20 EEST 2024


From: Niklas Haas <git at haasn.dev>

To convert between color spaces/ranges, if needed by the codec
properties.
---
 fftools/ffmpeg_filter.c | 34 ++++++++++++++++++++++++++++++++++
 1 file changed, 34 insertions(+)

diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c
index 83259416a68..a40c6f381f2 100644
--- a/fftools/ffmpeg_filter.c
+++ b/fftools/ffmpeg_filter.c
@@ -193,6 +193,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
@@ -208,6 +210,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;
     // offset for output timestamps, in AV_TIME_BASE_Q
@@ -379,6 +383,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)) {
@@ -607,6 +617,8 @@ static OutputFilter *ofilter_alloc(FilterGraph *fg)
     ofilter->graph    = fg;
     ofp->format       = -1;
     ofp->index        = fg->nb_outputs - 1;
+    ofp->color_space  = AVCOL_SPC_UNSPECIFIED;
+    ofp->color_range  = AVCOL_RANGE_UNSPECIFIED;
 
     return ofilter;
 }
@@ -789,6 +801,24 @@ int ofilter_bind_ost(OutputFilter *ofilter, OutputStream *ost,
                     ofp->formats = mjpeg_formats;
             }
         }
+        if (ost->enc_ctx->colorspace != AVCOL_SPC_UNSPECIFIED) {
+            ofp->color_space = ost->enc_ctx->colorspace;
+        } else {
+            ret = avcodec_get_supported_config(ost->enc_ctx, NULL,
+                                               AV_CODEC_CONFIG_COLOR_SPACE, 0,
+                                               (const void **) &ofp->color_spaces);
+            if (ret < 0)
+                return ret;
+        }
+        if (ost->enc_ctx->color_range != AVCOL_RANGE_UNSPECIFIED) {
+            ofp->color_range = ost->enc_ctx->color_range;
+        } else {
+            ret = avcodec_get_supported_config(ost->enc_ctx, NULL,
+                                               AV_CODEC_CONFIG_COLOR_RANGE, 0,
+                                               (const void **) &ofp->color_ranges);
+            if (ret < 0)
+                return ret;
+        }
 
         fgp->disable_conversions |= ost->keep_pix_fmt;
 
@@ -1347,6 +1377,8 @@ static int configure_output_video_filter(FilterGraph *fg, AVFilterGraph *graph,
     av_assert0(!ost->keep_pix_fmt || (!ofp->format && !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);
     if (bprint.len) {
@@ -1777,6 +1809,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
-- 
2.44.0



More information about the ffmpeg-devel mailing list