Fix #60947: ffmpeg video colors shifted/banded in some players #130021
No reviewers
Labels
No Label
Interest
Alembic
Interest
Animation & Rigging
Interest
Asset System
Interest
Audio
Interest
Automated Testing
Interest
Blender Asset Bundle
Interest
BlendFile
Interest
Code Documentation
Interest
Collada
Interest
Compatibility
Interest
Compositing
Interest
Core
Interest
Cycles
Interest
Dependency Graph
Interest
Development Management
Interest
EEVEE
Interest
FBX
Interest
Freestyle
Interest
Geometry Nodes
Interest
glTF
Interest
Grease Pencil
Interest
ID Management
Interest
Images & Movies
Interest
Import Export
Interest
Line Art
Interest
Masking
Interest
Metal
Interest
Modeling
Interest
Modifiers
Interest
Motion Tracking
Interest
Nodes & Physics
Interest
OpenGL
Interest
Overlay
Interest
Overrides
Interest
Performance
Interest
Physics
Interest
Pipeline & IO
Interest
Platforms, Builds & Tests
Interest
Python API
Interest
Render & Cycles
Interest
Render Pipeline
Interest
Sculpt, Paint & Texture
Interest
Text Editor
Interest
Translations
Interest
Triaging
Interest
Undo
Interest
USD
Interest
User Interface
Interest
UV Editing
Interest
VFX & Video
Interest
Video Sequencer
Interest
Viewport & EEVEE
Interest
Virtual Reality
Interest
Vulkan
Interest
Wayland
Interest
Workbench
Interest: X11
Legacy
Asset Browser Project
Legacy
Blender 2.8 Project
Legacy
Milestone 1: Basic, Local Asset Browser
Legacy
OpenGL Error
Meta
Good First Issue
Meta
Papercut
Meta
Retrospective
Meta
Security
Module
Animation & Rigging
Module
Asset System
Module
Core
Module
Development Management
Module
Grease Pencil
Module
Modeling
Module
Nodes & Physics
Module
Pipeline & IO
Module
Platforms, Builds & Tests
Module
Python API
Module
Render & Cycles
Module
Sculpt, Paint & Texture
Module
Triaging
Module
User Interface
Module
VFX & Video
Module
Viewport & EEVEE
Platform
FreeBSD
Platform
Linux
Platform
macOS
Platform
Windows
Severity
High
Severity
Low
Severity
Normal
Severity
Unbreak Now!
Status
Archived
Status
Confirmed
Status
Duplicate
Status
Needs Info from Developers
Status
Needs Information from User
Status
Needs Triage
Status
Resolved
Type
Bug
Type
Design
Type
Known Issue
Type
Patch
Type
Report
Type
To Do
No Milestone
No project
No Assignees
3 Participants
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: blender/blender#130021
Loading…
Reference in New Issue
Block a user
No description provided.
Delete Branch "aras_p/blender:ffmpeg-color-metadata"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Videos written out of blender were not explicitly indicating the color metadata (color range, primaries, TRC, color space). While some video players assume BT.709, some others do not.
Explicitly indicate BT.709 and limited ("mpeg") YUV range for video codecs that are YUV based (i.e. final image is non-RGB(A)). Overall now the code does the same as these command line ffmpeg parameters:
-vf scale=out_color_matrix=bt709 -color_primaries 1 -color_trc 1 -colorspace 1
.Note that there's no need to setup
write_colr
option; ffmpeg since 4.4 (2020) does that by default when color metadata is provided.Attached
cc-test5.zip
test file which is slightly modified repro project from the bug report.Here's the rendered test file as PNG:
Here's VLC (Windows, 3.0.21) before this PR -- large color shifts. This is rendered into H.265 with perceptually lossless quality.
and VLC with this PR -- looks correct.
Here's ffplay (Windows, 7.1) before this PR -- mostly correct, a tiny bit of gray background darkening.
and ffplay with this PR -- looks correct.
Windows 10 "Movies & TV" app difference is very similar to VLC case.
I was just checking this out, and I did specify these parameters to
AVCodecParameters
instead ofAVCodecContext
. I did not expect these to be at multiple places at once. Not sure why, since I know what we did with reading framerate...That said, this PR does not seem to fix this issue when checking with ffplay and VLC.
Command from referenced issue seems to work best and probably is best from comments I read:
ffmpeg -i Original\ Color.png -vcodec libx264 -vf scale=out_color_matrix=bt709 -color_primaries 1 -color_trc 1 -colorspace 1 out/ref.mp4
So to me it seems, that we just need to figure out, what
-vf scale=out_color_matrix=bt709
does exactly.Fix #60947: ffmpeg video colors shifted/banded in some playersto WIP: Fix #60947: ffmpeg video colors shifted/banded in some playersI tried both, and there did not seem to be a difference between them. From the docs it feels like AVCodecParameters are supposed to be only "queried" and not "modified", but then the docs are not exactly clear nor detailed.
Yeah this is funny. From a quick test this seems to fix the issue with ffplay vs VLC on my Mac, but does not fix the issue on Windows. Aaaargh! I'll keep on looking (or I did some tests wrong).
But just for more info: what are your ffplay and VLC versions, on what OS, and on what GPU?
I'll look into that, thanks.
a10f87583d
tof411efc93a
WIP: Fix #60947: ffmpeg video colors shifted/banded in some playersto Fix #60947: ffmpeg video colors shifted/banded in some players@iss I think now I have it working correctly. The missing
-vf scale=out_color_matrix=bt709
part was color space details that need to be set forsws_scale
@blender-bot build
For the default OCIO configuration this makes sense.
What I am trying to understand figure out are a couple of things:
Good questions! My understanding of all things color management is very hand-wavy, but here's what I think happens:
Thanks for sharing the thoughts!
So the only possible downside is for people who use ACES config, and try to output video to something else than sRGB rec709. I'm not even sure if that is something people currently do, and whether it is really working reliably.
From fixing the standard Blender configuration I think it is a good step forward.
The more complete solution indeed would require some thinking, but I don't think we need to solve it now.
One thing I didn't mention is: is there a possibility of covering this with a render test somehow? The fact that "some player" (that is not Blender) is needed makes it kinda non-trivial =\
Perhaps, this could be for future PR, but Rec. 601, 709 and 2020 standards also define a movie resolutions - SD, HD, 4K/8K respectively. So I think, that we should either make a property for which encoding is to be used or switch encoding based on movie resolution. In case of automatic switching, question would be what to do about non-standard resolutions though.
Not sure how/if Rec.709 and Rec.2020 are "compatible". My point is, that we could avoid report like "Colors in my 4K render are off".
Tested PR now. The colors are correct in ffplay, but importing rendered movie back to VSE causes color shift. I suspect, that we also need to correct Rec.601 assumed colorspace when converting to RGB. Which could involve another round of
AVStream
vsAVCodecContext
dichotomy lol.While standards like
BT.709-6
define image resolution, frame rate, chromaticities, those are things that can/ should be tackled separately.The chromaticities are defined by the color management (in our case, the
config.ocio
). They define how colors are interpreted, transformed, displayed etc. The resolution is just the number of pixels in the image.Where does the Rec.601 come from? Standard Blender configuration uses Rec.709 primaries.
To me it sounds that these standards define a "thing" that has particular properties. So you can't mix and match properties of multiple standards in one "thing".
AFAIK it is ffmpeg assumption, but that should happen only for untagged files, would have to double check that
There mighr indeed some confusion. But when we're talking about colors, it is mainly about the chromaticities and such. it is not very handy to refer to the rest of the parameters like resolution or framerate. Outside of whatever strict cinema systems computer can play back almost everything. But it needs to know information colors.
If that's the case, then our writing code is wrong?
Also, a bit strange that FFmpeg will assume rec.601 when we explicitly set rec.709.
Fix #60947: ffmpeg video colors shifted/banded in some playersto WIP: Fix #60947: ffmpeg video colors shifted/banded in some playersI think I have a theory why decoding videos that explicitly have colorspace metadata goes wrong (and that's not a new issue; seemingly has been that way forever -- will also add test coverage). The issue so far seems to be that the YUV->RGB conversion done by sws_scale at decoding time does not get the colorspace information from the AVFrame into the sws_scale part.
Stay tuned! Nice catch Richard on this issue.
Actually... I can't reproduce this :( @iss do you have details in how does it reproduce for you?
Initially I thought I could reproduce it with movies produced by command line ffmpeg that explicitly indicate "yeah I'm BT.709", but turns out I was using ffmpeg command line incorrectly.
I did add a bunch of render test coverage with movies using various color space settings & whatnot (not comitted yet), and they also confirm that seemingly there's no problem. What I thought was a problem (sws_scale), was just my confusion; it gets both the YUV range and the colorspace correctly.
@aras_p Sorry, wall-o-text coming...
I've attached a test scene which, I believe, demonstrates the issue Richard run into. It might another issue, but an issue nevertheless :)
Steps to reprodce:
Some important observations:
main
branch before this PR.Ah, so this is not something caused by this PR? What Richard said sounded like an issue introduced by this PR. That said...
I can't reproduce the issue with your file. I have verified that proxies work (by explicitly trying proxy resolution & quality settings - I can see lower res & at low quality I see compression artifacts). But I don't see the color changes.
I'm testing on both 4.3 and current main. Windows 10, regular sRGB monitor. Which brings the question: which OS do you see this on, and what kind of monitor?
On more tests, I might be wrong. I can no longer reproduce the issue on
main
. Maybe I forgot to deleteBL_Proxy
folder? Or, deleted something else by accident?I'm on Apple M2 Ultra, macOS 14.6.1, using XDR screen.
I used png file from #127663.
Steps to repro:
Here are the files, with movie rendered on my machine, just in case. This does not happen in main. Also no proxies involved.
Speaking of proxies, We should add colorspace/encoding metadata to these as well.
There are proxies involved, and they are exactly the problem (proxies are involved by default; if you turn off "use proxies" in the preview N panel then the problem goes away).
And your last sentence is exactly the solution, actually. The problem is that proxies are built by using or scaling AVFrame contents directly (without going through YUV->RGB->YUV steps), but if the source video contains colorspace information, then the proxy file will not contain the colorspace metadata. Yet the actual frame data will be in that particular colorspace.
This means that the "bug with proxies" has existed for a long time, if your source video clips are in some specific colorspace. I think I have a fix, hold on!
(phew, this bug has confused me at least 7 times this week...)
@Sergey @iss ok now the issue with proxies should be fixed.
I don't fully understand why metadata on the source file would break colors in the proxy.
With the
test.blend
from my previous post I've rendered it inmain
, in the PR, pulled both renders into VSE without proxies. Their color matched. Just to confirm that there wouldn't be some regressions from the way how Blender handles videos.One thing I've notices is that in Finder on macOS the original
p8a.png
is darker than the video rendered fromtest.blend
with this PR applied. The colors of the videos after this PR looks more correct.We don't necessarily have to fix all the issues with this PR, it was the easiest way I could verify colors outside of Blender. If this PR makes things correct with some players (vlc? ffplay? maybe other editing software?) then we don't need to make thing more complicated than they should and can land this PR.
WIP: Fix #60947: ffmpeg video colors shifted/banded in some playersto Fix #60947: ffmpeg video colors shifted/banded in some playersAh sorry, I have checked incorrect location, you are correct, the proxy was a cause. Also did not notice building process because file was so small. That could be bug in logic for automatic proxy building if there are not enough frames to do heuristic analysis. Will check that.
I wanted to say, that it's the mismatch of metadata between proxy and original, but actually that is weird, because proxy should have same metadata as render in main, which is displayed correctly.
Looking at the code, it could be, because
sws_scale
did change the colorspace, but file was still tagged as bt.601.Sure, the issue I raised originally looked like regression. I will test this early tomorrow, but would say, go ahead and merge if you have both tested this.