[FFmpeg-devel] [PATCH v2] swscale: separate exported and internal range flags

Jan Ekström jeebjp at gmail.com
Sat Oct 10 00:59:30 EEST 2020


On Fri, Oct 9, 2020 at 10:02 PM Michael Niedermayer
<michael at niedermayer.cc> wrote:
>
> On Wed, Oct 07, 2020 at 09:27:20PM +0300, Jan Ekström wrote:
> > Fixes vf_scale outputting RGB AVFrames with limited range in
> > case either input or output specifically sets the range.
> >
> > Keeps the external interfaces the same, but allows us to retrieve
> > and set nonzero value for RGB. Additionally defines the default
> > value of the AVOption as -1 so we can differentiate between
> > attempting to force limited range and requesting the default.
> > ---
> >  libswscale/options.c          |   4 +-
> >  libswscale/swscale_internal.h |   3 +
> >  libswscale/utils.c            | 160 +++++++++++++++++++++++-----------
> >  3 files changed, 114 insertions(+), 53 deletions(-)
>
> This changes the output for:
> ./ffmpeg -i ~/tickets/4926/5611842b1f09f2_20295212.png -vf scale=34:44 file.tga
> same with png output
>
> That is the red looks a bit different, the filesize also changes
> file should be here:
> https://trac.ffmpeg.org/attachment/ticket/4926/5611842b1f09f2_20295212.png
>
> I dont know if the one after the patch is more or less correct, but why
> does your patch change this ?
> is that change intentional ?
>

Had a look at the stuff that happens by adding a bunch of debug logging:

before:

[Parsed_scale_0 @ 0x611000001080] w:34 h:33 flags:'bicubic' interl:0
[graph 0 input from stream 0:0 @ 0x6110000011c0] w:2200 h:2827
pixfmt:rgba tb:1/25 fr:25/1 sar:0/1
[swscaler @ 0x62f00000e400] sws_init_context: Initial configured range
values: src: 0, dst: 0
[swscaler @ 0x62f00000e400] sws_init_context: color ranges: src
(rgba): 0 dst (rgba): 0
[swscaler @ 0x62f00000e400] sws_setColorspaceDetails: color ranges:
src (rgba): 0, dst (rgba): 0 (given arguments: src: 0, dst: 0)
[swscaler @ 0x62f00001c400] sws_init_context: Initial configured range
values: src: 0, dst: 0
[swscaler @ 0x62f00001c400] sws_init_context: color ranges: src
(rgba): 0 dst (yuva420p): 0
[swscaler @ 0x62f00001c400] sws_setColorspaceDetails: color ranges:
src (rgba): 0, dst (yuva420p): 0 (given arguments: src: 0, dst: 0)
[swscaler @ 0x62f00002a400] sws_init_context: Initial configured range
values: src: 0, dst: 0
[swscaler @ 0x62f00002a400] sws_init_context: color ranges: src
(yuva420p): 0 dst (rgba): 0
[swscaler @ 0x62f00002a400] sws_setColorspaceDetails: color ranges:
src (yuva420p): 0, dst (rgba): 0 (given arguments: src: 0, dst: 0)
[Parsed_scale_0 @ 0x611000001080] w:2200 h:2827 fmt:rgba sar:0/1 ->
w:34 h:33 fmt:rgba sar:0/1 flags:0x4
[Parsed_scale_0 @ 0x611000001080] scale_frame: received range info: 0, dst: 0
[Parsed_scale_0 @ 0x611000001080] scale_frame: filter chain logic
range info: 1, dst: 0
[swscaler @ 0x62f00000e400] sws_setColorspaceDetails: color ranges:
src (rgba): 0, dst (rgba): 0 (given arguments: src: 1, dst: 0)
[swscaler @ 0x62f00001c400] sws_setColorspaceDetails: color ranges:
src (rgba): 0, dst (yuva420p): 0 (given arguments: src: 0, dst: 0)

before with 'scale=w=34:h=33:out_range=full' filter chain:

[Parsed_scale_0 @ 0x611000001080] w:34 h:33 flags:'bicubic' interl:0
[graph 0 input from stream 0:0 @ 0x6110000011c0] w:2200 h:2827
pixfmt:rgba tb:1/25 fr:25/1 sar:0/1
[swscaler @ 0x62f00000e400] sws_init_context: Initial configured range
values: src: 0, dst: 1
[swscaler @ 0x62f00000e400] sws_init_context: color ranges: src
(rgba): 0 dst (rgba): 1
[swscaler @ 0x62f00000e400] sws_setColorspaceDetails: color ranges:
src (rgba): 0, dst (rgba): 0 (given arguments: src: 0, dst: 1)
[swscaler @ 0x62f00001c400] sws_init_context: Initial configured range
values: src: 0, dst: 0
[swscaler @ 0x62f00001c400] sws_init_context: color ranges: src
(rgba): 0 dst (yuva420p): 0
[swscaler @ 0x62f00001c400] sws_setColorspaceDetails: color ranges:
src (rgba): 0, dst (yuva420p): 0 (given arguments: src: 0, dst: 0)
[swscaler @ 0x62f00002a400] sws_init_context: Initial configured range
values: src: 0, dst: 0
[swscaler @ 0x62f00002a400] sws_init_context: color ranges: src
(yuva420p): 0 dst (rgba): 0
[swscaler @ 0x62f00002a400] sws_setColorspaceDetails: color ranges:
src (yuva420p): 0, dst (rgba): 0 (given arguments: src: 0, dst: 0)
[Parsed_scale_0 @ 0x611000001080] w:2200 h:2827 fmt:rgba sar:0/1 ->
w:34 h:33 fmt:rgba sar:0/1 flags:0x4
[Parsed_scale_0 @ 0x611000001080] scale_frame: received range info: 0, dst: 0
[Parsed_scale_0 @ 0x611000001080] scale_frame: filter chain logic
range info: 1, dst: 1
[swscaler @ 0x62f00000e400] sws_setColorspaceDetails: color ranges:
src (rgba): 0, dst (rgba): 0 (given arguments: src: 1, dst: 1)
[swscaler @ 0x62f00001c400] sws_setColorspaceDetails: color ranges:
src (rgba): 0, dst (yuva420p): 0 (given arguments: src: 0, dst: 0)

after:

[Parsed_scale_0 @ 0x611000001080] w:34 h:33 flags:'bicubic' interl:0
[graph 0 input from stream 0:0 @ 0x6110000011c0] w:2200 h:2827
pixfmt:rgba tb:1/25 fr:25/1 sar:0/1
[swscaler @ 0x62f00000e400] sws_init_context: Initial configured range
values: src: -1, dst: -1
[swscaler @ 0x62f00000e400] sws_init_context: color ranges: src
(rgba): 0 src exported: 1, dst (rgba): 0, dst exported: 1
[swscaler @ 0x62f00000e400] sws_setColorspaceDetails: color ranges:
src (rgba): 0, dst (rgba): 0 (given arguments: src: 1, dst: 1)
[swscaler @ 0x62f00001c400] sws_init_context: Initial configured range
values: src: -1, dst: -1
[swscaler @ 0x62f00001c400] sws_init_context: color ranges: src
(rgba): 0 src exported: 1, dst (yuva420p): 0, dst exported: 0
[swscaler @ 0x62f00001c400] sws_setColorspaceDetails: color ranges:
src (rgba): 0, dst (yuva420p): 0 (given arguments: src: 1, dst: 0)
[swscaler @ 0x62f00002a400] sws_init_context: Initial configured range
values: src: -1, dst: -1
[swscaler @ 0x62f00002a400] sws_init_context: color ranges: src
(yuva420p): 0 src exported: 0, dst (rgba): 0, dst exported: 1
[swscaler @ 0x62f00002a400] sws_setColorspaceDetails: color ranges:
src (yuva420p): 0, dst (rgba): 0 (given arguments: src: 0, dst: 1)
[Parsed_scale_0 @ 0x611000001080] w:2200 h:2827 fmt:rgba sar:0/1 ->
w:34 h:33 fmt:rgba sar:0/1 flags:0x4
[Parsed_scale_0 @ 0x611000001080] scale_frame: received range info: 1, dst: 1
[Parsed_scale_0 @ 0x611000001080] scale_frame: filter chain logic
range info: 1, dst: 1
[swscaler @ 0x62f00000e400] sws_setColorspaceDetails: color ranges:
src (rgba): 0, dst (rgba): 0 (given arguments: src: 1, dst: 1)
[swscaler @ 0x62f00001c400] sws_setColorspaceDetails: color ranges:
src (rgba): 0, dst (yuva420p): 1 (given arguments: src: 1, dst: 1)

So how I see this:
1. RGBA is apparently handled with a primary RGBA swscaler and a
secondary yuva420p scaler.
2. This yuva420p scaler is called in limited range currently.
3. sws_setColorspaceDetails blindly passes the range value to
sub-scalers. In this case a yuva420p one.
4. Before there was no difference between the internal and external
range value, and for the base thing RGBA became 0,0.
3. Now the value being passed is the external one, which ends up being 1,1.
4. For RGBA we override the value to 0 internally, but for yuva420p
full range is valid, so no adjustment is made. Thus we get a
zero-standard RGBA and full range yuva420p.
5. The yuva420p to RGBA conversion is still 0 on both sides.

So yes, this is one of these cases not caught by FATE tests, and I
would guess the largest difference comes from now the ranges of the
yuva420p sub-scalers not matching? Not sure how to improve this
quickly other than just scrapping the idea of attempting to properly
have two separate flags, and just adjusting the flag to full range in
sws_getColorspaceDetails. Which is ugly, but will not require us to go
through any more untested swscale area...

Jan


More information about the ffmpeg-devel mailing list