[FFmpeg-devel] Towards YUVJ removal
Andreas Rheinhardt
andreas.rheinhardt at outlook.com
Fri Dec 9 14:10:02 EET 2022
Niklas Haas:
> So, as was discussed at the last meeting, we should move towards
> removing YUVJ. I want to gather feedback on what appears to be to the
> major hurdle, and possible ways to solve it.
>
> The basic major issue is how to handle the case of combining limited
> range input with an encoder for a format that only accepts full range
> data. The common case, for example, would be converting a frame from a
> typical video file to a JPEG:
>
> $ ffmpeg -f lavfi -i smptebars -vframes 1 output.jpg
>
> Currently, this works because the JPEG encoder only advertises YUVJ
> pixel formats, and therefore ffmpeg auto-inserts swscaler to convert
> from limited range to full range. But this depends on conflating color
> range and pixel formats, which is exactly what has been marked
> deprecated for an eternity.
>
This is incorrect: Here are the pixel formats advertised by the mjpeg
encoder:
.p.pix_fmts = (const enum AVPixelFormat[]) {
AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUVJ444P,
AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV444P,
AV_PIX_FMT_NONE
},
ffmpeg only inserts the swscale filters, because said list is overridden
in get_compliance_normal_pix_fmts() in fftools/ffmpeg_filter.c. See
059fc2d9da5364627613fb3e6424079e14dbdfd3.
Also notice that the encoder errors out if fed with limited range data
depending upon strict_std_compliance (see
ff_mjpeg_encode_check_pix_fmt()), which is very similar to the first
approach below; the override being in fftools implies that the breakage
of the first approach would be confined to users of fftools.
> Now, there are some solutions I can see for how to handle this case in
> a non-YUVJ world:
>
> 1. Simply output an error, and rely on the user to insert a conversion
> filter, e.g.:
>
> $ ffmpeg -f lavfi -i smptebars -vframes 1 output.jpg
> error: inputs to jpeg encoder must be full range
>
> $ ffmpeg -f lavfi -i smptebars -vframes 1 -vf scale=out_range=jpeg output.jpg
> ... works
>
> 2. Have the JPEG encoder take care of range conversion internally, by
> using sws to convert limited to full range.
>
> 3. Allow filters to start exposing color space metadata as part of
> filter negotiation, and then auto-insert swscaler whenever colorspace
> conversion needs to happen as a result of filters not accepting the
> corresponding color metadata. This would also allow more than just
> conversion between limited/full range.
>
> 4. Combine approach 1 with an encoder flag for "supports full range
> only", and have ffmpeg.c auto-insert a scale filter as the last step
> before the encoder if this flag is set (and input is limited range).
>
> 1 would be the most explicit but would break any existing pipeline that
> includes conversion to jpeg, which is probably a very large number.
>
> 2 would be the least work, but violates abstraction boundaries.
>
> 3 would be the most work and is, IMO, of questionable gain.
>
> 4 would be both explicit and not break existing workflows.
>
> Thoughts?
More information about the ffmpeg-devel
mailing list