summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNiklas Haas <git@nand.wakku.to>2014-04-02 00:40:36 +0200
committerwm4 <wm4@nowhere>2014-06-22 19:05:43 +0200
commit664f8e9832e7ee9835816621faf4b57ffbcc8628 (patch)
tree5a4183678358bdfa04a3a88ec94350b6a430323a
parentfbd35caef830a1d0a25f1ee6e3b5d71453c98a59 (diff)
downloadmpv-664f8e9832e7ee9835816621faf4b57ffbcc8628.tar.bz2
mpv-664f8e9832e7ee9835816621faf4b57ffbcc8628.tar.xz
video: Include better heuristics for guessing primaries
These consult the vertical resolution, matching against 576 for PAL and 480/486 for NTSC. The documentation has also been updated. Signed-off-by: wm4 <wm4@nowhere>
-rw-r--r--DOCS/man/options.rst13
-rw-r--r--video/csputils.c19
-rw-r--r--video/csputils.h1
-rw-r--r--video/mp_image.c9
4 files changed, 36 insertions, 6 deletions
diff --git a/DOCS/man/options.rst b/DOCS/man/options.rst
index 018be5919d..af085bd822 100644
--- a/DOCS/man/options.rst
+++ b/DOCS/man/options.rst
@@ -585,12 +585,21 @@ OPTIONS
management, for example ``opengl`` with the ``srgb`` or ``icc-profile``
suboptions set.
+ If this option is set to ``auto`` (which is the default), the video's
+ primaries flag will be used. If that flag is unset, the color space will
+ be selected automatically, using the following heuristics: If the
+ ``--colormatrix`` is set or determined as BT.2020 or BT.709, the
+ corresponding primaries are used. Otherwise, if the video height is
+ exactly 576 (PAL), BT.601-625 is used. If it's exactly 480 or 486 (NTSC),
+ BT.601-525 is used. If the video resolution is anything else, BT.709 is
+ used.
+
Available primaries are:
:auto: automatic selection (default)
- :BT.601-525: ITU-R BT.601 (SD) 525-line systems (NTSC)
+ :BT.601-525: ITU-R BT.601 (SD) 525-line systems (NTSC, SMPTE-C)
:BT.601-625: ITU-R BT.601 (SD) 625-line systems (PAL, SECAM)
- :BT.709: ITU-R BT.709 (HD)
+ :BT.709: ITU-R BT.709 (HD) (same primaries as sRGB)
:BT.2020: ITU-R BT.2020 (UHD)
``--config-dir=<path>``
diff --git a/video/csputils.c b/video/csputils.c
index 202585187a..c462c43c34 100644
--- a/video/csputils.c
+++ b/video/csputils.c
@@ -160,6 +160,25 @@ enum mp_csp mp_csp_guess_colorspace(int width, int height)
return width >= 1280 || height > 576 ? MP_CSP_BT_709 : MP_CSP_BT_601;
}
+enum mp_csp_prim mp_csp_guess_primaries(int width, int height)
+{
+ // HD content
+ if (width >= 1280 || height > 576)
+ return MP_CSP_PRIM_BT_709;
+
+ switch (height) {
+ case 576: // Typical PAL content, including anamorphic/squared
+ return MP_CSP_PRIM_BT_601_625;
+
+ case 480: // Typical NTSC content, including squared
+ case 486: // NTSC Pro or anamorphic NTSC
+ return MP_CSP_PRIM_BT_601_525;
+
+ default: // No good metric, just pick BT.709 to minimize damage
+ return MP_CSP_PRIM_BT_709;
+ }
+}
+
enum mp_chroma_location avchroma_location_to_mp(int avloc)
{
switch (avloc) {
diff --git a/video/csputils.h b/video/csputils.h
index 9257102df5..757ac72cdc 100644
--- a/video/csputils.h
+++ b/video/csputils.h
@@ -180,6 +180,7 @@ int mp_csp_levels_to_avcol_range(enum mp_csp_levels range);
int mp_csp_prim_to_avcol_pri(enum mp_csp_prim prim);
enum mp_csp mp_csp_guess_colorspace(int width, int height);
+enum mp_csp_prim mp_csp_guess_primaries(int width, int height);
enum mp_chroma_location avchroma_location_to_mp(int avloc);
int mp_chroma_location_to_av(enum mp_chroma_location mploc);
diff --git a/video/mp_image.c b/video/mp_image.c
index eb754499d1..d83a9ae3c1 100644
--- a/video/mp_image.c
+++ b/video/mp_image.c
@@ -537,14 +537,15 @@ void mp_image_params_guess_csp(struct mp_image_params *params)
if (params->colorlevels == MP_CSP_LEVELS_AUTO)
params->colorlevels = MP_CSP_LEVELS_TV;
if (params->primaries == MP_CSP_PRIM_AUTO) {
- // We assume BT.709 primaries for all untagged BT.609/BT.709
- // content, because it offers the minimal deviation from all three,
- // including both NTSC and PAL/SECAM.
+ // Guess based on the colormatrix as a first priority
if (params->colorspace == MP_CSP_BT_2020_NC ||
params->colorspace == MP_CSP_BT_2020_C) {
params->primaries = MP_CSP_PRIM_BT_2020;
- } else {
+ } else if (params->colorspace == MP_CSP_BT_709) {
params->primaries = MP_CSP_PRIM_BT_709;
+ } else {
+ // Ambiguous colormatrix for BT.601, guess based on res
+ params->primaries = mp_csp_guess_primaries(params->w, params->h);
}
}
} else if (fmt.flags & MP_IMGFLAG_RGB) {