diff options
author | Niklas Haas <git@haasn.xyz> | 2016-11-08 02:24:49 +0100 |
---|---|---|
committer | wm4 <wm4@nowhere> | 2016-11-08 19:16:24 +0100 |
commit | 81ceb7b6a57422e5d05593d49b14d99479f266a0 (patch) | |
tree | 4823fb314e6d6f50304a682a11665f0cf7896a56 | |
parent | 33012b4141fda7aaa35ba3eee32f31265ed837cc (diff) |
demux_mkv: parse colorimetry metadata
Matroska actually has lots of colorimetry metadata that video tracks can
use, including mastering metadata (HDR signal peak) etc.
This commit adds the EBML definitions and parses the most basic fields.
Note that nothing uses these fields yet, this commit is just adding the
necessary parsing and infrastructure.
-rw-r--r-- | TOOLS/lib/Parse/Matroska/Definitions.pm | 27 | ||||
-rw-r--r-- | demux/demux_mkv.c | 39 |
2 files changed, 66 insertions, 0 deletions
diff --git a/TOOLS/lib/Parse/Matroska/Definitions.pm b/TOOLS/lib/Parse/Matroska/Definitions.pm index a73c7b1fc6..5a5adcd6de 100644 --- a/TOOLS/lib/Parse/Matroska/Definitions.pm +++ b/TOOLS/lib/Parse/Matroska/Definitions.pm @@ -269,6 +269,33 @@ sub define_matroska { elem('FrameRate', '2383e3', 'float'), elem('ColourSpace', '2eb524', 'binary'), elem('StereoMode', '53b8', 'uint'), + elem('Colour', '55B0', { + elem('MatrixCoefficients', '55B1', 'uint'), + elem('BitsPerChannel', '55B2', 'uint'), + elem('ChromaSubsamplingHorz', '55B3', 'uint'), + elem('ChromaSubsamplingVert', '55B4', 'uint'), + elem('CbSubsamplingHorz', '55B5', 'uint'), + elem('CbSubsamplingVert', '55B6', 'uint'), + elem('ChromaSitingHorz', '55B7', 'uint'), + elem('ChromaSitingVert', '55B8', 'uint'), + elem('Range', '55B9', 'uint'), + elem('TransferCharacteristics', '55BA', 'uint'), + elem('Primaries', '55BB', 'uint'), + elem('MaxCLL', '55BC', 'uint'), + elem('MaxFALL', '55BD', 'uint'), + elem('MasteringMetadata', '55D0', { + elem('PrimaryRChromaticityX', '55D1', 'float'), + elem('PrimaryRChromaticityY', '55D2', 'float'), + elem('PrimaryGChromaticityX', '55D3', 'float'), + elem('PrimaryGChromaticityY', '55D4', 'float'), + elem('PrimaryBChromaticityX', '55D5', 'float'), + elem('PrimaryBChromaticityY', '55D6', 'float'), + elem('WhitePointChromaticityX', '55D7', 'float'), + elem('WhitePointChromaticityY', '55D8', 'float'), + elem('LuminanceMax', '55D9', 'float'), + elem('LuminanceMin', '55DA', 'float'), + }), + }), }), elem('Audio', 'e1', { elem('SamplingFrequency', 'b5', 'float'), diff --git a/demux/demux_mkv.c b/demux/demux_mkv.c index b9e723a53c..bf7a8e2d91 100644 --- a/demux/demux_mkv.c +++ b/demux/demux_mkv.c @@ -107,6 +107,7 @@ typedef struct mkv_track { double v_frate; uint32_t colorspace; int stereo_mode; + struct mp_colorspace color; uint32_t a_channels, a_bps; float a_sfreq; @@ -536,6 +537,42 @@ static void parse_trackaudio(struct demuxer *demuxer, struct mkv_track *track, } } +static void parse_trackcolour(struct demuxer *demuxer, struct mkv_track *track, + struct ebml_colour *colour) +{ + // Note: As per matroska spec, the order is consistent with ISO/IEC + // 23001-8:2013/DCOR1, which is the same order used by libavutil/pixfmt.h, + // so we can just re-use our avcol_ conversion functions. + if (colour->n_matrix_coefficients) { + track->color.space = avcol_spc_to_mp_csp(colour->matrix_coefficients); + MP_VERBOSE(demuxer, "| + Matrix: %s\n", + m_opt_choice_str(mp_csp_names, track->color.space)); + } + if (colour->n_primaries) { + track->color.primaries = avcol_pri_to_mp_csp_prim(colour->primaries); + MP_VERBOSE(demuxer, "| + Primaries: %s\n", + m_opt_choice_str(mp_csp_prim_names, track->color.primaries)); + } + if (colour->n_transfer_characteristics) { + track->color.gamma = avcol_trc_to_mp_csp_trc(colour->transfer_characteristics); + MP_VERBOSE(demuxer, "| + Gamma: %s\n", + m_opt_choice_str(mp_csp_trc_names, track->color.gamma)); + } + if (colour->n_range) { + track->color.levels = avcol_range_to_mp_csp_levels(colour->range); + MP_VERBOSE(demuxer, "| + Levels: %s\n", + m_opt_choice_str(mp_csp_levels_names, track->color.levels)); + } + if (colour->n_mastering_metadata) { + struct ebml_mastering_metadata *mastering = &colour->mastering_metadata; + + if (mastering->n_luminance_max) { + track->color.sig_peak = mastering->luminance_max; + MP_VERBOSE(demuxer, "| + HDR peak: %f\n", track->color.sig_peak); + } + } +} + static void parse_trackvideo(struct demuxer *demuxer, struct mkv_track *track, struct ebml_video *video) { @@ -575,6 +612,8 @@ static void parse_trackvideo(struct demuxer *demuxer, struct mkv_track *track, MP_WARN(demuxer, "Unknown StereoMode: %d\n", (int)video->stereo_mode); } } + if (video->n_colour) + parse_trackcolour(demuxer, track, &video->colour); } /** |