Skip to content

Add Colorspace.BT2020 for BT.2020 YUV matrix conversion#2325

Merged
WyattBlue merged 1 commit into
PyAV-Org:mainfrom
mark-oshea:feat/bt2020-colorspace
Jun 24, 2026
Merged

Add Colorspace.BT2020 for BT.2020 YUV matrix conversion#2325
WyattBlue merged 1 commit into
PyAV-Org:mainfrom
mark-oshea:feat/bt2020-colorspace

Conversation

@mark-oshea

Copy link
Copy Markdown
Contributor

Add Colorspace.BT2020 for BT.2020 YUV matrix conversion

Summary

Expose libswscale's SWS_CS_BT2020 in PyAV's Colorspace enum so HDR content tagged bt2020nc can use the correct YUV→RGB matrix coefficients through VideoFrame.reformat() and VideoFrame.to_ndarray().

libswscale already supports BT.2020 matrix conversion; PyAV's Cython declarations and Python enum were missing the constant, so users could not pass BT2020 as src_colorspace / dst_colorspace.

Changes

  • Declare SWS_CS_BT2020 in av/video/reformatter.pxd
  • Add Colorspace.BT2020 and backward-compat alias Colorspace.bt2020 in av/video/reformatter.py
  • Map SWS_CS_BT2020AVCOL_SPC_BT2020_NCL in _set_frame_colorspace (non-constant-luminance, the standard for consumer HDR / bt2020nc)
  • Update type stubs in av/video/reformatter.pyi
  • Add parametrized test test_reformat_dst_colorspace_metadata covering all distinct colorspace matrix mappings, including BT.2020
  • Add changelog entry under v18.0.0 (next)

Usage

import av

# Explicit matrix selection during YUV → RGB conversion
rgb = frame.reformat(format="rgb24", src_colorspace=av.video.reformatter.Colorspace.BT2020)

# Also works via to_ndarray kwargs
arr = frame.to_ndarray(format="rgb24", src_colorspace="BT2020")

Notes

  • AVCOL_SPC_BT2020_NCL was already declared in include/avutil.pxd; no FFmpeg binding changes were required.
  • SWS_CS_BT2020 is the only libswscale colorspace constant not previously exposed in PyAV's Colorspace enum.

Test plan

  • make — Cython build succeeds
  • python -m pytest tests/test_colorspace.py -v — all tests pass, including parametrized metadata test
  • python -m pytest tests/test_videoframe.py -k reformat -v — reformat regression tests pass
  • make test — full suite passes locally (471 passed, 17 skipped)
  • Validated against real HDR content in downstream application
@mark-oshea mark-oshea force-pushed the feat/bt2020-colorspace branch from f27dca8 to 98bb44d Compare June 23, 2026 23:36
@mark-oshea mark-oshea force-pushed the feat/bt2020-colorspace branch from 98bb44d to da771e0 Compare June 24, 2026 00:25
@WyattBlue WyattBlue merged commit 8005a4d into PyAV-Org:main Jun 24, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

2 participants