[FFmpeg-devel] [PATCH 3/7] fftools/ffmpeg_filter: use AV_BUFFERSINK_FLAG_PARAMS

Anton Khirnov anton at khirnov.net
Mon Sep 23 18:01:41 EEST 2024


---
 fftools/ffmpeg_filter.c | 96 ++++++++++++++++++-----------------------
 1 file changed, 42 insertions(+), 54 deletions(-)

diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c
index 81c4911b03..b4c0876fa6 100644
--- a/fftools/ffmpeg_filter.c
+++ b/fftools/ffmpeg_filter.c
@@ -197,13 +197,8 @@ typedef struct OutputFilterPriv {
 
     AVFilterContext        *filter;
 
-    /* desired output stream properties */
-    int                     format;
-    int                     width, height;
-    int                     sample_rate;
-    AVChannelLayout         ch_layout;
-    enum AVColorSpace       color_space;
-    enum AVColorRange       color_range;
+    /* frame holding desired output stream parameters */
+    AVFrame                *params;
 
     // time base in which the output is sent to our downstream
     // does not need to match the filtersink's timebase
@@ -212,8 +207,6 @@ typedef struct OutputFilterPriv {
     // to our downstream, so it cannot change anymore
     int                     tb_out_locked;
 
-    AVRational              sample_aspect_ratio;
-
     AVDictionary           *sws_opts;
     AVDictionary           *swr_opts;
 
@@ -373,11 +366,11 @@ static void sub2video_update(InputFilterPriv *ifp, int64_t heartbeat_pts,
 #define DEF_CHOOSE_FORMAT(name, type, var, supported_list, none, printf_format, get_name) \
 static void choose_ ## name (OutputFilterPriv *ofp, AVBPrint *bprint)          \
 {                                                                              \
-    if (ofp->var == none && !ofp->supported_list)                              \
+    if (ofp->params->var == none && !ofp->supported_list)                      \
         return;                                                                \
     av_bprintf(bprint, #name "=");                                             \
-    if (ofp->var != none) {                                                    \
-        av_bprintf(bprint, printf_format, get_name(ofp->var));                 \
+    if (ofp->params->var != none) {                                            \
+        av_bprintf(bprint, printf_format, get_name(ofp->params->var));         \
     } else {                                                                   \
         const type *p;                                                         \
                                                                                \
@@ -399,7 +392,7 @@ 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,
+DEF_CHOOSE_FORMAT(color_spaces, enum AVColorSpace, colorspace, color_spaces,
                   AVCOL_SPC_UNSPECIFIED, "%s", av_color_space_name);
 
 DEF_CHOOSE_FORMAT(color_ranges, enum AVColorRange, color_range, color_ranges,
@@ -407,9 +400,9 @@ DEF_CHOOSE_FORMAT(color_ranges, enum AVColorRange, color_range, color_ranges,
 
 static void choose_channel_layouts(OutputFilterPriv *ofp, AVBPrint *bprint)
 {
-    if (av_channel_layout_check(&ofp->ch_layout)) {
+    if (av_channel_layout_check(&ofp->params->ch_layout)) {
         av_bprintf(bprint, "channel_layouts=");
-        av_channel_layout_describe_bprint(&ofp->ch_layout, bprint);
+        av_channel_layout_describe_bprint(&ofp->params->ch_layout, bprint);
     } else if (ofp->ch_layouts) {
         const AVChannelLayout *p;
 
@@ -643,14 +636,15 @@ static OutputFilter *ofilter_alloc(FilterGraph *fg, enum AVMediaType type)
     if (!ofp)
         return NULL;
 
+    ofp->params = av_frame_alloc();
+    if (!ofp->params)
+        return NULL;
+
     ofilter           = &ofp->ofilter;
     ofilter->class    = &ofilter_class;
     ofp->log_parent   = fg;
     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",
@@ -747,7 +741,7 @@ static int set_channel_layout(OutputFilterPriv *f, const AVChannelLayout *layout
 
     if (layout_requested->order != AV_CHANNEL_ORDER_UNSPEC) {
         /* Pass the layout through for all orders but UNSPEC */
-        err = av_channel_layout_copy(&f->ch_layout, layout_requested);
+        err = av_channel_layout_copy(&f->params->ch_layout, layout_requested);
         if (err < 0)
             return err;
         return 0;
@@ -757,7 +751,7 @@ static int set_channel_layout(OutputFilterPriv *f, const AVChannelLayout *layout
     if (!layouts_allowed) {
         /* Use the default native layout for the requested amount of channels when the
            encoder doesn't have a list of supported layouts */
-        av_channel_layout_default(&f->ch_layout, layout_requested->nb_channels);
+        av_channel_layout_default(&f->params->ch_layout, layout_requested->nb_channels);
         return 0;
     }
     /* Encoder has a list of supported layouts. Pick the first layout in it with the
@@ -768,14 +762,14 @@ static int set_channel_layout(OutputFilterPriv *f, const AVChannelLayout *layout
     }
     if (layouts_allowed[i].nb_channels) {
         /* Use it if one is found */
-        err = av_channel_layout_copy(&f->ch_layout, &layouts_allowed[i]);
+        err = av_channel_layout_copy(&f->params->ch_layout, &layouts_allowed[i]);
         if (err < 0)
             return err;
         return 0;
     }
     /* If no layout for the amount of channels requested was found, use the default
        native layout for it. */
-    av_channel_layout_default(&f->ch_layout, layout_requested->nb_channels);
+    av_channel_layout_default(&f->params->ch_layout, layout_requested->nb_channels);
 
     return 0;
 }
@@ -827,20 +821,20 @@ int ofilter_bind_ost(OutputFilter *ofilter, OutputStream *ost,
 
     switch (ofilter->type) {
     case AVMEDIA_TYPE_VIDEO:
-        ofp->width      = opts->width;
-        ofp->height     = opts->height;
+        ofp->params->width      = opts->width;
+        ofp->params->height     = opts->height;
         if (opts->format != AV_PIX_FMT_NONE) {
-            ofp->format = opts->format;
+            ofp->params->format = opts->format;
         } else
             ofp->formats = opts->formats;
 
         if (opts->color_space != AVCOL_SPC_UNSPECIFIED)
-            ofp->color_space = opts->color_space;
+            ofp->params->colorspace = opts->color_space;
         else
             ofp->color_spaces = opts->color_spaces;
 
         if (opts->color_range != AVCOL_RANGE_UNSPECIFIED)
-            ofp->color_range = opts->color_range;
+            ofp->params->color_range = opts->color_range;
         else
             ofp->color_ranges = opts->color_ranges;
 
@@ -865,12 +859,12 @@ int ofilter_bind_ost(OutputFilter *ofilter, OutputStream *ost,
         break;
     case AVMEDIA_TYPE_AUDIO:
         if (opts->format != AV_SAMPLE_FMT_NONE) {
-            ofp->format = opts->format;
+            ofp->params->format = opts->format;
         } else {
             ofp->formats = opts->formats;
         }
         if (opts->sample_rate) {
-            ofp->sample_rate = opts->sample_rate;
+            ofp->params->sample_rate = opts->sample_rate;
         } else
             ofp->sample_rates = opts->sample_rates;
         if (opts->ch_layout.nb_channels) {
@@ -1012,6 +1006,7 @@ void fg_free(FilterGraph **pfg)
         OutputFilterPriv *ofp = ofp_from_ofilter(ofilter);
 
         av_frame_free(&ofp->fps.last_frame);
+        av_frame_free(&ofp->params);
         av_dict_free(&ofp->sws_opts);
         av_dict_free(&ofp->swr_opts);
 
@@ -1019,7 +1014,6 @@ void fg_free(FilterGraph **pfg)
         av_freep(&ofilter->name);
         av_freep(&ofilter->apad);
         av_freep(&ofp->name);
-        av_channel_layout_uninit(&ofp->ch_layout);
         av_freep(&fg->outputs[j]);
     }
     av_freep(&fg->outputs);
@@ -1484,13 +1478,14 @@ static int configure_output_video_filter(FilterGraph *fg, AVFilterGraph *graph,
     if (ret < 0)
         return ret;
 
-    if ((ofp->width || ofp->height) && (ofp->flags & OFILTER_FLAG_AUTOSCALE)) {
+    if ((ofp->params->width || ofp->params->height) &&
+        (ofp->flags & OFILTER_FLAG_AUTOSCALE)) {
         char args[255];
         AVFilterContext *filter;
         const AVDictionaryEntry *e = NULL;
 
         snprintf(args, sizeof(args), "%d:%d",
-                 ofp->width, ofp->height);
+                 ofp->params->width, ofp->params->height);
 
         while ((e = av_dict_iterate(ofp->sws_opts, e))) {
             av_strlcatf(args, sizeof(args), ":%s=%s", e->key, e->value);
@@ -1508,7 +1503,7 @@ static int configure_output_video_filter(FilterGraph *fg, AVFilterGraph *graph,
     }
 
     av_assert0(!(ofp->flags & OFILTER_FLAG_DISABLE_CONVERT) ||
-               ofp->format != AV_PIX_FMT_NONE || !ofp->formats);
+               ofp->params->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);
@@ -1931,12 +1926,11 @@ static int configure_filtergraph(FilterGraph *fg, FilterGraphThread *fgt)
         OutputFilterPriv *ofp = ofp_from_ofilter(ofilter);
         AVFilterContext *sink = ofp->filter;
 
-        ofp->format = av_buffersink_get_format(sink);
-
-        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);
+        av_frame_unref(ofp->params);
+        ret = av_buffersink_get_frame_flags(sink, ofp->params,
+                                            AV_BUFFERSINK_FLAG_PARAMS);
+        if (ret < 0)
+            return ret;
 
         // 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
@@ -1946,15 +1940,8 @@ static int configure_filtergraph(FilterGraph *fg, FilterGraphThread *fgt)
             if (ofp->fps.framerate.num <= 0 && ofp->fps.framerate.den <= 0 &&
                 fr.num > 0 && fr.den > 0)
                 ofp->fps.framerate = fr;
-            ofp->tb_out = av_buffersink_get_time_base(sink);
+            ofp->tb_out = ofp->params->time_base;
         }
-        ofp->sample_aspect_ratio = av_buffersink_get_sample_aspect_ratio(sink);
-
-        ofp->sample_rate    = av_buffersink_get_sample_rate(sink);
-        av_channel_layout_uninit(&ofp->ch_layout);
-        ret = av_buffersink_get_ch_layout(sink, &ofp->ch_layout);
-        if (ret < 0)
-            goto fail;
     }
 
     for (int i = 0; i < fg->nb_inputs; i++) {
@@ -2339,15 +2326,16 @@ static int close_output(OutputFilterPriv *ofp, FilterGraphThread *fgt)
         FrameData *fd;
 
         frame->time_base   = ofp->tb_out;
-        frame->format      = ofp->format;
 
-        frame->width               = ofp->width;
-        frame->height              = ofp->height;
-        frame->sample_aspect_ratio = ofp->sample_aspect_ratio;
+        frame->format              = ofp->params->format;
 
-        frame->sample_rate = ofp->sample_rate;
-        if (ofp->ch_layout.nb_channels) {
-            ret = av_channel_layout_copy(&frame->ch_layout, &ofp->ch_layout);
+        frame->width               = ofp->params->width;
+        frame->height              = ofp->params->height;
+        frame->sample_aspect_ratio = ofp->params->sample_aspect_ratio;
+
+        frame->sample_rate         = ofp->params->sample_rate;
+        if (ofp->params->ch_layout.nb_channels) {
+            ret = av_channel_layout_copy(&frame->ch_layout, &ofp->params->ch_layout);
             if (ret < 0)
                 return ret;
         }
-- 
2.43.0



More information about the ffmpeg-devel mailing list