On Thu, 04 Apr 2024 12:01:36 +0000 Nicolas Gaullier <nicolas.gaullier@cji.paris> wrote: > >De : Niklas Haas <ffm...@haasn.xyz> > >Envoyé : jeudi 4 avril 2024 12:18 > >> --- a/libavfilter/vf_colorspace.c > >> +++ b/libavfilter/vf_colorspace.c > >> @@ -433,8 +433,7 @@ static int create_filtergraph(AVFilterContext *ctx, > >> if (out->color_trc != s->out_trc) s->out_txchr = NULL; > >> if (in->colorspace != s->in_csp || > >> in->color_range != s->in_rng) s->in_lumacoef = NULL; > >> - if (out->colorspace != s->out_csp || > >> - out->color_range != s->out_rng) s->out_lumacoef = NULL; > >> + if (out->color_range != s->out_rng) s->rgb2yuv = NULL; > > > >Can you explain this change to me? > > This is how I understand things: the output colorspace is a mandatory > parameter of the filter, so it can be set early and negotiated, > So I lifted some part of the code from the "dynamic" part > (filter_frame/create_filtergraph) to upstream "init/query_formats". > out_lumacoef depends on colorspace solely, so it seems there is no point to > unset it and re-set it again. > rgb2yuv is dynamic, dependent on the range, so this is the new trigger, the > pointer that has to be updated. > > >> @@ -735,6 +736,9 @@ static int filter_frame(AVFilterLink *link, AVFrame > >> *in) > >> return res; > >> } > >> > >> + out->colorspace = s->out_csp; > >> + outlink->color_range = s->user_rng != AVCOL_RANGE_UNSPECIFIED ? > >> s->user_rng : in->color_range; > >> + out->color_range = outlink->color_range; > > > >Changing outlink dynamically like this seems not correct to me (what if the > >next filter in the chain only supports one color range?). Changing the range > >on the fly would at the minimum require reconfiguring the filter graph, and > >>possibly insertion of more auto-scale filters. > This is the kind of questioning I had when working on this issue. This seems > very annoying and overly complex for a very uncommon scenario; is it even > possible within the filter to ask for a reconfiguration of the filter graph ?
No, reconfiguring the filter graph is (currently) the API user's responsibility. (See fftools/ffmpeg_filter.c for an example) vf_buffersrc even warns you if you try and change colorspace properties mid-stream, and for good reason - IMO there is no general expectation that filters should be able to handle dynamically changing colorspace properties. (This is a feature, not a bug) There *are* some filters that handle dynamically changing input properties (e.g. scale, zscale, libplacebo), but these are the exception rather than the norm, and it's only because they're already written in a way that can trivially handle dynamic conversions. If it's difficult to do from within vf_colorspace, there's no need to do so. Feel free to assume that frame->colorspace == inlink->colorspace == constant. (Ditto color_range) > > >The logic that is used in the other YUV negotiation aware filters is to just > >set `out->colorspace = outlink->colorspace` and `out->color_range = > >outlink->color_range`, since the link properties are authoritative. > This is the kind of easy logic I tried at the beginning. Some water has > flowed under the bridge, notably b89ee26539, but I just tried at the moment > (with current code) an easy patch with just these two lines, and it still > does not work as "I" expected. > More specifically: > When running: ./ffprobe -f lavfi -i > yuvtestsrc,setparams=color_primaries=bt470bg:color_trc=smpte170m:colorspace=bt470bg,colorspace=bt709:range=tv,scale,showinfo > At the entry of filter_frame(), the outlink values are incorrect: > colorspace = AVCOL_SPC_BT470BG > And color_range = AVCOL_RANGE_UNSPECIFIED > So, this is why I introduced the negotiation for the colorspace to early set > and persist this outlink property. > But for the range, I am bit confused with the documentation, it is not clear > to me, but possibly it is expected to pass through? so it cannot be > negotiated, so I am sticked if the outlink range cannot be changed > dynamically... Note: passing through the range untouched *is* the default behavior (via ff_default_query_formats). So I think the correct logic can be condensed into just: if (out_rng != UNSPEC) { ret = set_common_color_ranges(make_singleton(out_rng)); if (ret < 0) return ret; } That way, if the user passes unspec, it's guaranteed that the input range == output_range (but with no preference for any specific range); but if the user passes a specific range, both the input and output of the filter are forced to be this range. Hopefully that clears up some confusion? > > >Nit: Why introduce a new result variable instead of re-using the one that's > >already declared? > >IMO this logic would look cleaner if you assigned ret before testing it, > >especially since it's nested. > Thanks, ok, will fix this in the next version. > > Thank you for your review; as you can see, I have no certainty, rather many > questions... > > Nicolas > _______________________________________________ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > To unsubscribe, visit link above, or email > ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe". _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".