[FFmpeg-user] FFMPEG introduces color shift to DNxHD MOVs

Robert Krüger krueger at lesspain.de
Sun Jul 8 15:48:35 CEST 2012


Hi,

On Sun, Jul 8, 2012 at 1:06 PM, Mark Himsley <mark at mdsh.com> wrote:
>> On 07/07/2012 04:52, Nathan Rusch wrote:
>>>
>>> -----Original Message----- From: Mike Scheutzow
>>> Sent: Friday, July 06, 2012 10:21 AM
>>> To: FFmpeg user questions and RTFMs
>>> Subject: Re: [FFmpeg-user] FFMPEG introduces color shift to DNxHD MOVs
>>>
>>> Nathan Rusch wrote:
>>>>
>>>> Hello all,
>>>>
>>>> In trying to troubleshoot another issue, I’ve run across a subtle,
>>>> consistent color shift being introduced by FFMPEG to DNxHD-encoded
>>>> MOVs. Thus, they fail to match both DNxHD MOVs generated with the
>>>> Avid codec, as well as both MOVs’ common source material (an 8-bit
>>>> RGB TIFF sequence).
>>>
>>>
>>>
>>> ffmpeg always assumes the BT.601 colorspace when converting from
>>> RGB->YUV and from YUV->RGB. A patch to fix this is welcome, but no one
>>> has ever cared enough to provide it.
>>>
>>> So if you do:
>>>
>>> ffmpeg: RGB -> [BT.601 matrix] -> YUV
>>>
>>> other tool: YUV -> [BT.709 matrix] -> RGB
>>>
>>> then you get a color shift like you describe.
>>>
>>> Workaround: feed ffmpeg with a file containing YUV that's been properly
>>> converted.
>
>
> Reformatted so your top-posting is converted into in-line threadding.
>
>> I wanted to follow up on this for posterity (in case anyone else comes
>> down this same road).
>>
>> I was able to get the colors to match 1:1 to the source by adding a
>
>> colormatrix operation to the conversion process via libavfilter. The flag
>> and value added are:
>>
>>
>> -vf colormatrix=bt601:bt709
>>
>> Thanks again for getting me moving in the right direction Mike.
>
>
> I'd like to post, for posterity, that this will reduce the fidelity of your
> video.
>
> RGB -> YUV (BT.601) is a lossy transformation (in the sense that you cannot
> go RGB -> YUV (BT.601) -> RGB and expect to get out exactly what you put in)
>
> AND
>
> YUV (BT.601) -> YUV (BT.709) is a lossy transformation (in the sense that
> you cannot go YUV (BT.601) -> YUV (BT.709) -> YUV (BT.601) and expect to get
> out exactly what you put in)
>
> Concatenating two lossy transforms is very bad. I understand that this is
> currently your only course of action.
>
>
> I think a worthwhile addition to the scale filter (which does the format
> conversion) would be to add a choice of colourspace, much like the use of
> "format" forces the scale filter to change colour format. Tim Nicholson has
> been discussing something similar.
>
> Perhaps (this is just off the top of my head, and I'm willing to be shot
> down) something like: "-vf scale=0:0:rgbyuv=bt709,format=yuv422p" may tell
> the scale filter to convert to yuv422p and if an RGB -> YUV conversion is
> needed then use the RGB -> BT.709 conversion.

wouldn't it be more flexible if one could specify something like
source and target colorspace because then you could also convert and
scale e.g. bt601 YUV to bt709 YUV or vice versa more like "-vf
scale=0:0:src_colorspace=bt709,format=yuv422p,colorspace=bt601"?

The source colorspace should ideally be set by default to the value of
the source stream's AVCodecContext.colorspace if the information is
there. I do not know the libavfilter API well enough to know if there
is a way to transport the colorspace information through the rest of
the chain (did not see it at first glance), so in the ffmpeg case the
corresponding AVCodecContext fields can be filled so the codecs which
support that information in their bitstream e.g. h264 and mpeg2 or
some container formats can make the corresponding entries when
encoding/muxing but this is getting more of a dev posting.


More information about the ffmpeg-user mailing list