{
  "schemaVersion": 1,
  "contentVersion": "ca42e61ede0a24f789d7287a0001244ad22f4abf",
  "id": "docs/reference/colorimetry/intro",
  "collection": "docs",
  "title": "Colorimetry: inspect before encoding",
  "description": "What primaries, transfer, matrix, range and chroma location tell a player, how to read them with ffprobe, and why tagging is not converting.",
  "canonicalUrl": "https://encode.wiki/reference/colorimetry/intro/",
  "apiUrl": "https://encode.wiki/api/v1/documents/docs/reference/colorimetry/intro.json",
  "markdownUrl": "https://encode.wiki/api/v1/markdown/docs/reference/colorimetry/intro.md",
  "status": "current",
  "tags": [
    "migrated"
  ],
  "license": "CC BY-SA 4.0",
  "dates": {
    "lastVerified": "2026-10-08T00:00:00.000Z"
  },
  "authors": [],
  "sources": [
    {
      "title": "ITU-T H.273 (07/2024), coding-independent code points for video signal type identification",
      "url": "https://www.itu.int/rec/T-REC-H.273-202407-I",
      "accessedAt": "2026-10-08T00:00:00.000Z"
    },
    {
      "title": "FFmpeg n9.0.2 color property names (libavutil/pixdesc.c)",
      "url": "https://github.com/FFmpeg/FFmpeg/blob/n9.0.2/libavutil/pixdesc.c",
      "accessedAt": "2026-10-08T00:00:00.000Z"
    },
    {
      "title": "ffprobe documentation",
      "url": "https://ffmpeg.org/ffprobe.html",
      "accessedAt": "2026-10-08T00:00:00.000Z"
    },
    {
      "title": "mpv v0.41.0 color guessing (video/csputils.c, video/mp_image.c)",
      "url": "https://github.com/mpv-player/mpv/blob/v0.41.0/video/mp_image.c",
      "accessedAt": "2026-10-08T00:00:00.000Z"
    }
  ],
  "provenance": {
    "originUrl": "https://github.com/av1-community-contributors/codec-wiki/blob/37c3317fd058b23c71a87679bed5619a98f77752/docs/colorimetry/intro.mdx",
    "originCommit": "37c3317fd058b23c71a87679bed5619a98f77752",
    "migratedAt": "2026-08-21T00:00:00.000Z",
    "modified": true,
    "originPath": "docs/colorimetry/intro.mdx"
  },
  "headings": [
    {
      "depth": 2,
      "text": "Read the source",
      "anchor": "read-the-source"
    },
    {
      "depth": 2,
      "text": "What players do with untagged video",
      "anchor": "what-players-do-with-untagged-video"
    },
    {
      "depth": 2,
      "text": "Tagging is not converting",
      "anchor": "tagging-is-not-converting"
    }
  ],
  "sections": [
    {
      "id": "_preamble",
      "title": "Page introduction",
      "depth": 0,
      "canonicalUrl": "https://encode.wiki/reference/colorimetry/intro/",
      "apiUrl": "https://encode.wiki/api/v1/sections/docs/reference/colorimetry/intro/_preamble.json",
      "markdownUrl": "https://encode.wiki/api/v1/sections/docs/reference/colorimetry/intro/_preamble.md",
      "checksum": "53bec041cbd3f28fbf0e4035c2c26022bdf7bbf7abeb165bb9ddea3bc69c4770",
      "bytes": 1633
    },
    {
      "id": "read-the-source",
      "title": "Read the source",
      "depth": 2,
      "anchor": "read-the-source",
      "canonicalUrl": "https://encode.wiki/reference/colorimetry/intro/#read-the-source",
      "apiUrl": "https://encode.wiki/api/v1/sections/docs/reference/colorimetry/intro/read-the-source.json",
      "markdownUrl": "https://encode.wiki/api/v1/sections/docs/reference/colorimetry/intro/read-the-source.md",
      "checksum": "034936bce2d8cf2fce4f1fbfec99081db41a27757c6e136072e3b8dcab10dcdb",
      "bytes": 852
    },
    {
      "id": "what-players-do-with-untagged-video",
      "title": "What players do with untagged video",
      "depth": 2,
      "anchor": "what-players-do-with-untagged-video",
      "canonicalUrl": "https://encode.wiki/reference/colorimetry/intro/#what-players-do-with-untagged-video",
      "apiUrl": "https://encode.wiki/api/v1/sections/docs/reference/colorimetry/intro/what-players-do-with-untagged-video.json",
      "markdownUrl": "https://encode.wiki/api/v1/sections/docs/reference/colorimetry/intro/what-players-do-with-untagged-video.md",
      "checksum": "7c461dd63b862670963703f0d868fa1f3bbbe143e5e2dbdca9ec0c99401bc3c9",
      "bytes": 752
    },
    {
      "id": "tagging-is-not-converting",
      "title": "Tagging is not converting",
      "depth": 2,
      "anchor": "tagging-is-not-converting",
      "canonicalUrl": "https://encode.wiki/reference/colorimetry/intro/#tagging-is-not-converting",
      "apiUrl": "https://encode.wiki/api/v1/sections/docs/reference/colorimetry/intro/tagging-is-not-converting.json",
      "markdownUrl": "https://encode.wiki/api/v1/sections/docs/reference/colorimetry/intro/tagging-is-not-converting.md",
      "checksum": "9afa4c7788e6642869330d317fd899da1a459cb7b9c4c43f1b5bb0eeef046240",
      "bytes": 961
    }
  ],
  "outboundReferences": [
    "/guides/preserve-color-and-hdr/",
    "/hdr/",
    "/reference/colorimetry/format/",
    "/reference/colorimetry/matrix/",
    "/reference/colorimetry/primaries/",
    "/reference/colorimetry/range/",
    "/reference/colorimetry/transfer/",
    "https://www.itu.int/rec/T-REC-H.273-202407-I"
  ],
  "checksum": "3c69dba40c59f9a0438e32e13298d193bb4674fc96016c26e12720838ddc09d5",
  "contentFormat": "markdown",
  "markdown": "A decoded video frame is just numbers. Four pieces of metadata tell the player how to turn those numbers into light, and a fifth tells it where the chroma samples sit. If any of them is missing or wrong, the encode still \"works\" but the colors shift, blacks lift or crush, or HDR looks flat — which is why color mistakes so often go unnoticed until someone watches the result on another player.\n\n| Property | What it answers | ffprobe field | Typical HD SDR | Typical HDR10 |\n| --- | --- | --- | --- | --- |\n| [Primaries](/reference/colorimetry/primaries/) | Which red, green, blue and white the RGB values refer to | `color_primaries` | `bt709` | `bt2020` |\n| [Transfer](/reference/colorimetry/transfer/) | How code values map to light | `color_transfer` | `bt709` | `smpte2084` (PQ) |\n| [Matrix](/reference/colorimetry/matrix/) | How Y′CbCr is converted back to R′G′B′ | `color_space` | `bt709` | `bt2020nc` |\n| [Range](/reference/colorimetry/range/) | Which code values are black and white | `color_range` | `tv` (limited) | `tv` (limited) |\n| Chroma location | Where subsampled chroma sits relative to luma | `chroma_location` | `left` | `left` or `topleft` |\n\nThe values are the integer code points from [ITU-T H.273](https://www.itu.int/rec/T-REC-H.273-202407-I), which AVC, HEVC, VVC, AV1, Matroska and MP4 all reuse. Tools give them different names — FFmpeg says `bt2020nc`, SVT-AV1 says `bt2020-ncl`, VapourSynth says `2020ncl` — but the number underneath is the same. How the [pixel format](/reference/colorimetry/format/) stores the samples (bit depth, subsampling, planar or packed) is a separate question.\n\n## Read the source\n\n```sh\nffprobe -v error -select_streams v:0 -show_entries stream=pix_fmt,color_range,color_space,color_transfer,color_primaries,chroma_location -of default=nw=1 input.mkv\n```\n\nFor an HD Blu-ray remux this prints something like:\n\n```text\npix_fmt=yuv420p\ncolor_range=tv\ncolor_space=bt709\ncolor_transfer=bt709\ncolor_primaries=bt709\nchroma_location=left\n```\n\n`unknown` means the file does not say. HDR mastering metadata and Dolby Vision or HDR10+ data are usually carried per frame in the bitstream, so inspect the first frame as well:\n\n```sh\nffprobe -v error -select_streams v:0 -read_intervals \"%+#1\" -show_frames input.mkv\n```\n\nLook for `side_data_type=Mastering display metadata`, `Content light level metadata`, `Dolby Vision Metadata` or `HDR Dynamic Metadata SMPTE2094-40 (HDR10+)`. See [HDR formats](/hdr/) for what each means.\n\n## What players do with untagged video\n\nWhen a field is `unknown` the player guesses, and players guess differently. mpv 0.41, for example:\n\n- **Matrix:** BT.709 if the width is at least 1280 or the height is above 576, otherwise BT.601.\n- **Primaries:** BT.2020 if the matrix is BT.2020, BT.709 if the matrix is BT.709; otherwise by height (576 → PAL, 480/486 → NTSC, anything else → BT.709).\n- **Transfer:** BT.1886 for limited-range video, sRGB for full-range.\n\nBrowsers, TVs and other players use their own rules. An untagged 720×480 file therefore looks right in one player and slightly green-shifted in another. Tag every encode, and never assume an untagged source is BT.709 just because most HD material is — check where it came from.\n\n## Tagging is not converting\n\nThere are three different operations, and confusing them is the most common color mistake:\n\n- **Preserve:** keep the samples and carry the same tags to the output. This is what you want for almost every encode.\n- **Retag:** change the metadata, leave the samples alone. Correct only when the source was tagged wrongly or not at all.\n- **Convert:** change the samples from one color system to another (matrix, range, primaries, transfer, tone mapping), then tag the result as the new system.\n\nTagging BT.601 pixels as BT.709 does not convert them; it makes the colors wrong. Tagging PQ video as `bt709` does not tone-map it; it makes it look washed out. Scaling SD to HD does not change the matrix by itself — if you want an HD BT.709 output, convert the matrix while you scale.\n\n[Preserve color and HDR metadata](/guides/preserve-color-and-hdr/) has the commands for each case in FFmpeg, VapourSynth and the standalone encoders.\n"
}
