matroskaparse: better default caps when none set
authorReynaldo H. Verdejo Pinochet <r.verdejo@sisa.samsung.com>
Thu, 16 Jan 2014 17:23:13 +0000 (14:23 -0300)
committerReynaldo H. Verdejo Pinochet <r.verdejo@sisa.samsung.com>
Tue, 21 Jan 2014 14:11:46 +0000 (11:11 -0300)
Uses information gathered during EBML parsing to
forge a more suitable set of caps instead of blindly
assuming everything is video/x-matroska.

For consistency, stream type reset was added to
matroska-demux too.

https://bugzilla.gnome.org/show_bug.cgi?id=722311

gst/matroska/matroska-demux.c
gst/matroska/matroska-parse.c
gst/matroska/matroska-read-common.c
gst/matroska/matroska-read-common.h

index 72e5335..90424fb 100644 (file)
@@ -407,6 +407,10 @@ gst_matroska_demux_reset (GstElement * element)
   g_free (demux->common.muxing_app);
   demux->common.muxing_app = NULL;
 
+  /* reset stream type */
+  demux->common.is_webm = FALSE;
+  demux->common.has_video = FALSE;
+
   /* reset indexes */
   if (demux->common.index) {
     g_array_free (demux->common.index, TRUE);
index 83b0d63..480d5c1 100644 (file)
@@ -135,6 +135,8 @@ static GstIndex *gst_matroska_parse_get_index (GstElement * element);
 static void gst_matroska_parse_reset (GstElement * element);
 static gboolean perform_seek_to_offset (GstMatroskaParse * parse,
     guint64 offset);
+static GstCaps *gst_matroska_parse_forge_caps (gboolean is_webm,
+    gboolean has_video);
 
 GType gst_matroska_parse_get_type (void);
 #define parent_class gst_matroska_parse_parent_class
@@ -306,6 +308,10 @@ gst_matroska_parse_reset (GstElement * element)
   g_free (parse->common.muxing_app);
   parse->common.muxing_app = NULL;
 
+  /* reset stream type */
+  parse->common.is_webm = FALSE;
+  parse->common.has_video = FALSE;
+
   /* reset indexes */
   if (parse->common.index) {
     g_array_free (parse->common.index, TRUE);
@@ -493,6 +499,7 @@ gst_matroska_parse_add_stream (GstMatroskaParse * parse, GstEbmlRead * ebml)
         switch (track_type) {
           case GST_MATROSKA_TRACK_TYPE_VIDEO:
             gst_matroska_track_init_video_context (&context);
+            parse->common.has_video = TRUE;
             break;
           case GST_MATROSKA_TRACK_TYPE_AUDIO:
             gst_matroska_track_init_audio_context (&context);
@@ -2526,10 +2533,10 @@ gst_matroska_parse_output (GstMatroskaParse * parse, GstBuffer * buffer,
     GstBuffer *buf;
 
     caps = gst_pad_get_current_caps (parse->common.sinkpad);
-    /* FIXME: could run typefinding over header and pick better default */
-    if (caps == NULL)
-      caps = gst_caps_new_empty_simple ("video/x-matroska");
-    else
+    if (caps == NULL) {
+      caps = gst_matroska_parse_forge_caps (parse->common.is_webm,
+          parse->common.has_video);
+    else
       caps = gst_caps_make_writable (caps);
 
     s = gst_caps_get_structure (caps, 0);
@@ -3037,6 +3044,31 @@ perform_seek_to_offset (GstMatroskaParse * parse, guint64 offset)
   return res;
 }
 
+/*
+ * Forge empty default caps when all we know is the stream's EBML
+ * type and whether it has video or not.
+ *
+ * FIXME: Do something with video/x-matroska-3d if possible
+ */
+static GstCaps *
+gst_matroska_parse_forge_caps (gboolean is_webm, gboolean has_video)
+{
+  GstCaps *caps;
+
+  if (is_webm) {
+    if (has_video)
+      caps = gst_caps_new_empty_simple ("video/webm");
+    else
+      caps = gst_caps_new_empty_simple ("audio/webm");
+  } else {
+    if (has_video)
+      caps = gst_caps_new_empty_simple ("video/x-matroska");
+    else
+      caps = gst_caps_new_empty_simple ("audio/x-matroska");
+  }
+  return caps;
+}
+
 static GstFlowReturn
 gst_matroska_parse_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
 {
index 2530479..8a54a09 100644 (file)
@@ -1302,6 +1302,8 @@ exit:
     if (version <= 2) {
       if (doctype) {
         GST_INFO_OBJECT (common, "Input is %s version %d", doctype, version);
+        if (!strcmp (doctype, GST_MATROSKA_DOCTYPE_WEBM))
+          common->is_webm = TRUE;
       } else {
         GST_WARNING_OBJECT (common, "Input is EBML without doctype, assuming "
             "matroska (version %d)", version);
index 10054b0..148cd1f 100644 (file)
@@ -61,6 +61,9 @@ typedef struct _GstMatroskaReadCommon {
   /* state */
   GstMatroskaReadState     state;
 
+  /* stream type */
+  gboolean                 is_webm;
+  gboolean                 has_video;
 
   /* did we parse cues/tracks/segmentinfo already? */
   gboolean                 index_parsed;