BT.601 vs BT.709: read with the wrong one, greens and cyans shift most
Your colours look wrong because the video was decoded with a different colour standard from the one it was made with. SD video uses BT.601, HD uses BT.709, and a file that doesn't say which gets a guess. We measured the mix-up. On ordinary footage the average shift is small, near the edge of what you can see. On strong colours it isn't: pure green loses 15% of its level, and green and cyan move about six times the just-visible amount. Confusing Rec.709 with Rec.2020 is worse still.
What a colour space actually is
A video file doesn't store colours. It stores numbers, and the number 200 in a channel means nothing on its own. A colour space is the agreement that turns those numbers back into colour. For video it has three parts, and a well-made file carries a tag for each:
- The matrix. Video stores brightness and two colour-difference signals (YCbCr), not red, green and blue. The matrix is the recipe for turning them back into RGB. BT.601 is the SD recipe and BT.709 the HD one, and they weight green differently: 0.587 in BT.601, 0.715 in BT.709.
- The primaries. Which red is the reddest red, and the same for green and blue. Rec.709 (and sRGB, which shares its primaries) covers ordinary HD. Rec.2020 reaches much further and is used for HDR.
- The transfer curve. How the numbers map to brightness. Our HDR explainer covers what goes wrong when that part is misread.
Log formats such as S-Log or C-Log sit apart from these. They store a wide range in a deliberately flat curve and expect you to grade them. Footage that looks grey straight out of a camera is usually log, not broken.
The BT.601 and BT.709 mix-up, measured
We stored the same picture with one matrix and decoded it with the other, in both directions, using ffmpeg 8.1.2 (the version inside Crisp). We measured the result against the correct decode in ΔE76, the standard distance between two colours. About 2.3 is the smallest difference most people can see. On colour bars, SD video decoded as HD moved each colour this far:
| Bar | Should be (RGB) | Came out | ΔE76 |
|---|---|---|---|
| Cyan | 0, 190, 190 | 0, 171, 192 | 14.9 |
| Green | 0, 190, 0 | 0, 161, 0 | 14.7 |
| Yellow | 191, 190, 0 | 194, 179, 0 | 7.7 |
| Red | 191, 0, 0 | 208, 18, 0 | 6.2 |
| Magenta | 191, 0, 192 | 205, 30, 197 | 5.3 |
| Blue | 0, 0, 191 | 0, 12, 200 | 2.8 |
| White / grey | 191, 191, 191 | 191, 191, 191 | 0.0 |
Decoded with the right matrix, every bar stayed within 0.4. Greys never move, because the two recipes agree about anything without colour. That's why this mistake is easy to miss: skies, skin and walls barely change. On a real scene, a canal with trees and water from the demo on our home page, the average shift was only 1.8 (SD read as HD) and 2.2 (HD read as SD). But reading HD as SD moved 6.3% of the frame by more than 5 (1.4% the other way). Those were the strongly coloured pixels, 2.4 times as colourful as the frame's average, and 97% of them were the yellow-greens of the trees.
How a player decides which one to use
It reads the file's tag first. If there isn't one, most players guess from the picture size: an SD-sized picture gets BT.601 and an HD-sized one BT.709. The guess is right far more often than not, which is why untagged files usually look fine.
Trouble starts when something doesn't guess. ffmpeg's own converter, which a great deal of video software is built on, uses BT.601 for an untagged file whatever its size. So an untagged HD clip, such as many screen recordings and older exports, can look right in your player and come out with shifted greens in a still or a GIF made from it. The same can happen when an SD clip is upscaled to HD but keeps its SD numbers without saying so: a player sees an HD frame and picks the HD recipe.
Rec.709 and Rec.2020 read wrong
Mixing up the primaries does far more damage than mixing up the matrix. Rec.2020 writes the same colour with smaller numbers, because its scale reaches further. Read on the narrower Rec.709 scale, everything looks dull: the frame kept 77% of its saturation, the average shift was 4.2, and 36% of pixels moved by more than 5. The reverse, ordinary video treated as Rec.2020, came out oversaturated at 152%, with an average shift of 6.5 and 60% of pixels moved by more than 5.
For the record, the correct conversion isn't perfect either. Rec.709 to Rec.2020 and back measured an average shift of 1.9, just under the 2.3 you can see.
Converting is not relabelling
Converting maps the actual pixel values from one space to another, so the colours stay the same. Relabelling only changes the tag, so every player reads the unchanged numbers with a new recipe. Every wrong reading on this page is a relabelling in effect. Relabelling is the right fix for a file that was tagged wrongly, and the wrong one for everything else.
What Crisp does
Measured on the installed app:
- Enhance reads the tag, or guesses the way players do. An untagged clip 576 lines tall or less is read as BT.601, and anything taller as BT.709. The upscaled file is saved with the BT.709 matrix and says so in its tags.
- An SD clip keeps its own primaries. A clip tagged with the SD primaries (SMPTE 170M) keeps that tag after upscaling, rather than being stamped as something it isn't.
- Stills, GIFs, previews and thumbnails match the clip from 1.0.1357. Before that, they were the case the section above describes. An untagged HD clip came out with green (0, 190, 0) turned into (15, 223, 5) in a PNG still, a GIF and the Compare view. Every JPG still and bin thumbnail of an HD clip had the same shift, tagged or not, because a JPEG is always decoded as BT.601. We found it while measuring this page.
The practical rules
Put every clip in one colour space before you edit. Otherwise a grade that looks right on one clip is wrong on the next. Convert on purpose, never by relabelling. And check a colour problem on a second screen before chasing it in the file: a fault on only one display is calibration, not video.
Colour space questions
Why do my greens look different after converting a video?
Most often the video was decoded with the other matrix, BT.601 instead of BT.709 or the reverse. Greys don't change, but saturated greens and cyans move the most: in our test pure green lost 15% of its level. Check that the converted file carries a colour tag, and that the tool converted the pixels rather than just changing the label.
How do I know which colour space my video uses?
A media inspector such as MediaInfo, or ffprobe, lists the colour matrix, primaries and transfer. If they say "unknown", the file has no tag and every player will guess, usually from the picture height.
Why does my footage look washed out before I have touched it?
Two likely causes. It is log footage, which is meant to look flat and expects grading, or it is HDR being shown by something that ignores its tags. Both look similar and have completely different fixes.
What is the difference between converting and relabelling?
Converting maps the actual pixel values from one space to another so the colours stay the same. Relabelling changes only the tag, so players read unchanged numbers with a different recipe and the colours shift. Relabelling is the right fix for a mis-tagged file and wrong for everything else.
Should I edit in Rec.2020?
Only if your whole chain supports it end to end and the footage has colour worth keeping. Otherwise you carry the complexity for a range your delivery will discard anyway.
Related
- Why iPhone HDR video looks washed out
- What is chroma subsampling?
- What is a video codec?
- Why video looks worse after uploading
- Why VHS tapes degrade
- How to colour grade video on a Mac
Download Crisp for Mac Free to try, one-time $129 to remove the watermark. Runs entirely on your Mac.