[FFmpeg-trac] #9132(ffmpeg:open): Wrong pixel format/output when converting video to yuv444p*

FFmpeg trac at avcodec.org
Sat Aug 28 22:23:34 EEST 2021


#9132: Wrong pixel format/output when converting video to yuv444p*
------------------------------------+----------------------------------
             Reporter:  viley       |                    Owner:  (none)
                 Type:  defect      |                   Status:  open
             Priority:  important   |                Component:  ffmpeg
              Version:  git-master  |               Resolution:
             Keywords:  regression  |               Blocked By:
             Blocking:              |  Reproduced by developer:  1
Analyzed by developer:  0           |
------------------------------------+----------------------------------
Comment (by jeeb):

 1) Nobody stops you testing these patches before they land since it's not
 like they're hidden somewhere (and also with the hindsight of going back
 to this point of the message after writing the rest of it, you could have
 seen this issue that you are now complaining about was there even before).

 2) Can you please be less rambly and all over the place? It's really hard
 to understand what and where since the steps and expected and received
 results are all over the place. For the record, vf_scale '''never''' set
 the matrix coefficients, so unless out->format as a pix_fmt didn't for
 some reason had a mis-matching RGB flag I do not know how the flying
 f-word I could have made this any worse than it was. I just stopped a
 completely incorrect configuration from going forwards.

 Thus, step by step trying to decrypt your message:

 {{{
 ffmpeg -v verbose -i ffmpeg_samples\ticket_9374\rec.mkv -vf
 scale=out_color_matrix=bt709:flags=accurate_rnd,format=yuv420p -c:v
 libx264 -crf 10 -color_primaries 1 -color_trc 1 TESTCASE-yuvnew.mp4
 }}}
 leads to a result that I'd expect, which seems completely fine on
 playback.
 {{{
 Stream #0:0[0x1](und): Video: h264 (High), 1 reference frame (avc1 /
 0x31637661), yuv420p(tv, unknown/bt709/bt709, left), 1920x1200, 952 kb/s,
 25 fps, 25 tbr, 12800 tbn (default)
 }}}

 The matrix coefficients are not set to BT.709 or anything else specific
 because the filter '''never did that'''. One needs to go look into the
 swscale code to actually '''verify and add code''' to set the value
 according to swscale's behavior. And I've touched swscale enough during
 the past few months to not want to touch that thing for a while, so excuse
 me. The zscale filter has options for all these three values which is why
 if they're configured you then get them passed through and received from
 zimg's configuration. So no, I've not made this specific conversion any
 worse. At all.

 Alright, so let's go to the next step where you forcibly set the matrix
 coefficients through an AVOption for the encoder.
 {{{
 ffmpeg -v verbose -i ffmpeg_samples\ticket_9374\rec.mkv -vf
 scale=out_color_matrix=bt709:flags=accurate_rnd,format=yuv420p -c:v
 libx264 -crf 10 -color_primaries 1 -color_trc 1 -colorspace 1 TESTCASE-
 yuvnewer.mp4
 }}}
 That results in:
 {{{
 Stream #0:0[0x1](und): Video: h264 (High), 1 reference frame (avc1 /
 0x31637661), yuv420p(tv, bt709, left), 1920x1200, 952 kb/s, 25 fps, 25
 tbr, 12800 tbn (default)
 }}}
 Apparently when all values match the separate logging is skipped. So that
 says that all the metadata you've set is correctly passed on. Still
 everything good.

 Finally, the example where you convert YCbCr to RGB, and then forcibly set
 the output encoder's primaries and transfer to BT.709.
 {{{
 ffmpeg -v verbose -i TESTCASE-yuvnewer.mp4 -vf scale=flags=accurate_rnd
 -c:v libx264rgb -crf 10 -color_primaries 1 -color_trc 1 rgbsupper.mp4
 }}}
 Encoder configuration looks good to me (pix_fmt is RGB):
 {{{
  Stream #0:0(und): Video: h264 (avc1 / 0x31637661), rgb24(pc, bt709,
 progressive), 1920x1200, q=2-31, 25 fps, 12800 tbn (default)
 }}}
 vf_scale's internal conversion also seems Just Fine
 {{{
 [Parsed_scale_0 @ 000002009cc31700] w:1920 h:1200 fmt:yuv420p sar:0/1 ->
 w:1920 h:1200 fmt:rgb24 sar:0/1 flags:0x40000
 }}}

 But yes, it seems like for some reason when the encoded output is marked
 as full range4:4:4 YCbCr.
 {{{
 Stream #0:0[0x1](und): Video: h264 (High 4:4:4 Predictive), 1 reference
 frame (avc1 / 0x31637661), yuvj444p(pc, bt709, left), 1920x1200, 2230
 kb/s, 25 fps, 25 tbr, 12800 tbn (default)
 }}}

 I am not sure, though, why you think this is the fault of my change and
 why you have started pointing the finger at me.

 As I noted, vf_scale never set the matrix coefficients to anything. It
 just copied whatever metadata the input AVFrame might have had, and passed
 it on. I have now stopped that in a single case which is clearly wrong to
 fix a single problematic case.

 And if you don't trust me, just revert that commit I added and see what
 you get out of that last YCbCr->RGB conversion of yours. I just tested it
 here locally and my changes have nothing to do with it. You have
 successfully hit a separate bug somewhere along the range, most likely
 another case of where vf_scale should not be passing the input AVFrame's
 metadata out as-is. These bugs have been there since at least
 7e350379f87e7f74420b4813170fe808e2313911 , and the only reason why things
 hit my commit from late 2020 is because I for the first time in the
 history of ffmpeg.c actually plugged the input pipe into the output pipe,
 so people see all these bugs that always were there but were not visible
 in ffmpeg.c (But would have confused the heck out of other libavfilter
 users).
-- 
Ticket URL: <https://trac.ffmpeg.org/ticket/9132#comment:23>
FFmpeg <https://ffmpeg.org>
FFmpeg issue tracker


More information about the FFmpeg-trac mailing list