aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Niklas Haas <git@haasn.xyz>2016-11-08 02:24:49 +0100
committerGravatar wm4 <wm4@nowhere>2016-11-08 19:16:24 +0100
commit81ceb7b6a57422e5d05593d49b14d99479f266a0 (patch)
tree4823fb314e6d6f50304a682a11665f0cf7896a56
parent33012b4141fda7aaa35ba3eee32f31265ed837cc (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.pm27
-rw-r--r--demux/demux_mkv.c39
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);
}
/**