From: Arnaud Vrac <avrac@freebox.fr>
Date: Fri, 11 Jan 2013 18:20:02 +0100
Subject: qtdemux: send custom event downstream for transformation matrix


diff --git a/gst/isomp4/qtdemux.c b/gst/isomp4/qtdemux.c
--- a/gst/isomp4/qtdemux.c
+++ b/gst/isomp4/qtdemux.c
@@ -288,6 +288,7 @@ struct _QtDemuxStream
   gboolean send_global_tags;
 
   GstEvent *pending_event;
+  GstEvent *transform_event;
 
   GstByteReader stco;
   GstByteReader stsz;
@@ -3581,9 +3582,9 @@ gst_qtdemux_process_buffer (GstQTDemux * qtdemux, QtDemuxStream * stream,
   gchar *str;
 
   /* not many cases for now */
-  if (G_UNLIKELY (stream->fourcc == FOURCC_mp4s)) {
+  if (stream->pending_event) {
     /* send a one time dvd clut event */
-    if (stream->pending_event && stream->pad)
+    if (stream->pad)
       gst_pad_push_event (stream->pad, stream->pending_event);
     stream->pending_event = NULL;
     /* no further processing needed */
@@ -5268,6 +5269,10 @@ gst_qtdemux_add_stream (GstQTDemux * qtdemux,
         GST_ELEMENT_CAST (qtdemux), "%u", stream->track_id);
     gst_pad_push_event (stream->pad, gst_event_new_stream_start (stream_id));
     g_free (stream_id);
+    if (stream->transform_event) {
+      gst_pad_push_event (stream->pad, stream->transform_event);
+      stream->transform_event = NULL;
+    }
     gst_pad_set_caps (stream->pad, stream->caps);
 
     GST_DEBUG_OBJECT (qtdemux, "adding pad %s %p to qtdemux %p",
@@ -6423,6 +6428,49 @@ bad_data:
   return 0;
 }
 
+static gboolean
+_matrix_is_identity (gfloat matrix[9])
+{
+  static const gfloat identity[] = {
+    1, 0, 0,
+    0, 1, 0,
+    0, 0, 1
+  };
+  gint i;
+
+  for (i = 0; i < 9; i++)
+    if (matrix[i] != identity[i])
+      return FALSE;
+
+  return TRUE;
+}
+
+static GstEvent *
+_make_matrix_event (gfloat matrix[9])
+{
+  GstStructure *s;
+  GValue array = { 0 };
+  GValue f = { 0 };
+  gint i;
+
+  s = gst_structure_new_empty ("transform-matrix-3x3");
+
+  g_value_init (&array, GST_TYPE_ARRAY);
+  g_value_init (&f, G_TYPE_FLOAT);
+
+  for (i = 0; i < 9; i++) {
+    g_value_set_float (&f, matrix[i]);
+    gst_value_array_append_value (&array, &f);
+    g_value_reset (&f);
+  }
+
+  gst_structure_set_value (s, "transform", &array);
+  g_value_unset (&array);
+  g_value_unset (&f);
+
+  return gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM_STICKY, s);
+}
+
 /* parse the traks.
  * With each track we associate a new QtDemuxStream that contains all the info
  * about the trak.
@@ -6623,6 +6671,9 @@ qtdemux_parse_trak (GstQTDemux * qtdemux, GNode * trak)
           matrix[6], matrix[7], matrix[8]);
     }
 
+    if (!_matrix_is_identity (matrix))
+      stream->transform_event = _make_matrix_event (matrix);
+
     if (!gst_byte_reader_get_uint32_be (&tkhd, &w)
         || !gst_byte_reader_get_uint32_be (&tkhd, &h))
       goto corrupt_file;
