summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Dröge <sebastian@centricular.com>2016-09-30 09:55:58 +0300
committerSebastian Dröge <sebastian@centricular.com>2016-11-01 20:41:22 +0200
commitec7f69960484ce244495770b96808186ffe171eb (patch)
treedc9492274626a52d54c9b4101bf55c8d722ba294
parent53e436883a78865f85678f3a74e5a1c4cc3f2918 (diff)
qtdemux: Read colorimetry information from colr atom if available
https://bugzilla.gnome.org/show_bug.cgi?id=772181
-rw-r--r--gst/isomp4/qtdemux.c85
1 files changed, 85 insertions, 0 deletions
diff --git a/gst/isomp4/qtdemux.c b/gst/isomp4/qtdemux.c
index 183f74cd7..96a2394a6 100644
--- a/gst/isomp4/qtdemux.c
+++ b/gst/isomp4/qtdemux.c
@@ -277,6 +277,7 @@ struct _QtDemuxStream
/* Numerator/denominator framerate */
gint fps_n;
gint fps_d;
+ GstVideoColorimetry colorimetry;
guint16 bits_per_sample;
guint16 color_table_id;
GstMemory *rgb8_palette;
@@ -7544,6 +7545,17 @@ gst_qtdemux_configure_stream (GstQTDemux * qtdemux, QtDemuxStream * stream)
GST_TYPE_FRACTION, stream->par_w, stream->par_h, NULL);
}
+ /* Create incomplete colorimetry here if needed */
+ if (stream->colorimetry.range ||
+ stream->colorimetry.matrix ||
+ stream->colorimetry.transfer || stream->colorimetry.primaries) {
+ gchar *colorimetry =
+ gst_video_colorimetry_to_string_full (&stream->colorimetry, TRUE);
+ gst_caps_set_simple (stream->caps, "colorimetry", G_TYPE_STRING,
+ colorimetry, NULL);
+ g_free (colorimetry);
+ }
+
if (stream->multiview_mode != GST_VIDEO_MULTIVIEW_MODE_NONE) {
guint par_w = 1, par_h = 1;
@@ -9190,6 +9202,7 @@ qtdemux_parse_trak (GstQTDemux * qtdemux, GNode * trak)
GNode *wave;
GNode *esds;
GNode *pasp;
+ GNode *colr;
GNode *tref;
GNode *udta;
GNode *svmi;
@@ -9622,6 +9635,7 @@ qtdemux_parse_trak (GstQTDemux * qtdemux, GNode * trak)
esds = NULL;
pasp = NULL;
+ colr = NULL;
/* pick 'the' stsd child */
if (!stream->protected)
mp4v = qtdemux_tree_get_child_by_type (stsd, fourcc);
@@ -9631,6 +9645,7 @@ qtdemux_parse_trak (GstQTDemux * qtdemux, GNode * trak)
if (mp4v) {
esds = qtdemux_tree_get_child_by_type (mp4v, FOURCC_esds);
pasp = qtdemux_tree_get_child_by_type (mp4v, FOURCC_pasp);
+ colr = qtdemux_tree_get_child_by_type (mp4v, FOURCC_colr);
}
if (pasp) {
@@ -9643,6 +9658,76 @@ qtdemux_parse_trak (GstQTDemux * qtdemux, GNode * trak)
stream->par_h = 0;
}
+ if (colr) {
+ const guint8 *colr_data = (const guint8 *) colr->data;
+ gint len = QT_UINT32 (colr_data);
+
+ if (len == 19 || len == 18) {
+ guint32 color_type = GST_READ_UINT32_LE (colr_data + 8);
+
+ if (color_type == FOURCC_nclx || color_type == FOURCC_nclc) {
+ guint16 primaries = GST_READ_UINT16_BE (colr_data + 12);
+ guint16 transfer_function = GST_READ_UINT16_BE (colr_data + 14);
+ guint16 matrix = GST_READ_UINT16_BE (colr_data + 16);
+ gboolean full_range = len == 19 ? colr_data[17] >> 7 : FALSE;
+
+ switch (primaries) {
+ case 1:
+ stream->colorimetry.primaries = GST_VIDEO_COLOR_PRIMARIES_BT709;
+ break;
+ case 5:
+ stream->colorimetry.primaries = GST_VIDEO_COLOR_PRIMARIES_BT470BG;
+ break;
+ case 6:
+ stream->colorimetry.primaries =
+ GST_VIDEO_COLOR_PRIMARIES_SMPTE170M;
+ break;
+ case 9:
+ stream->colorimetry.primaries = GST_VIDEO_COLOR_PRIMARIES_BT2020;
+ break;
+ default:
+ break;
+ }
+
+ switch (transfer_function) {
+ case 1:
+ stream->colorimetry.transfer = GST_VIDEO_TRANSFER_BT709;
+ break;
+ case 7:
+ stream->colorimetry.transfer = GST_VIDEO_TRANSFER_SMPTE240M;
+ break;
+ default:
+ break;
+ }
+
+ switch (matrix) {
+ case 1:
+ stream->colorimetry.matrix = GST_VIDEO_COLOR_MATRIX_BT709;
+ break;
+ case 6:
+ stream->colorimetry.matrix = GST_VIDEO_COLOR_MATRIX_BT601;
+ break;
+ case 7:
+ stream->colorimetry.matrix = GST_VIDEO_COLOR_MATRIX_SMPTE240M;
+ break;
+ case 9:
+ stream->colorimetry.matrix = GST_VIDEO_COLOR_MATRIX_BT2020;
+ break;
+ default:
+ break;
+ }
+
+ stream->colorimetry.range =
+ full_range ? GST_VIDEO_COLOR_RANGE_0_255 :
+ GST_VIDEO_COLOR_RANGE_16_235;
+ } else {
+ GST_DEBUG_OBJECT (qtdemux, "Unsupported color type");
+ }
+ } else {
+ GST_WARNING_OBJECT (qtdemux, "Invalid colr atom size");
+ }
+ }
+
if (esds) {
gst_qtdemux_handle_esds (qtdemux, stream, esds, stream->pending_tags);
} else {