flacparse: add support for the toc-select event
authorAnton Belka <antonbelka@gmail.com>
Sun, 17 Mar 2013 13:27:03 +0000 (16:27 +0300)
committerTim-Philipp Müller <tim.muller@collabora.co.uk>
Thu, 21 Mar 2013 00:38:48 +0000 (00:38 +0000)
Select tracks from the CUE sheet by sending a toc-select
event based on the uid in the TOC.

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

gst/audioparsers/gstflacparse.c

index c8ecf80..ddc686e 100644 (file)
@@ -204,6 +204,8 @@ static GstFlowReturn gst_flac_parse_pre_push_frame (GstBaseParse * parse,
 static gboolean gst_flac_parse_convert (GstBaseParse * parse,
     GstFormat src_format, gint64 src_value, GstFormat dest_format,
     gint64 * dest_value);
+static gboolean gst_flac_parse_src_event (GstBaseParse * parse,
+    GstEvent * event);
 static GstCaps *gst_flac_parse_get_sink_caps (GstBaseParse * parse,
     GstCaps * filter);
 
@@ -237,6 +239,7 @@ gst_flac_parse_class_init (GstFlacParseClass * klass)
   baseparse_class->pre_push_frame =
       GST_DEBUG_FUNCPTR (gst_flac_parse_pre_push_frame);
   baseparse_class->convert = GST_DEBUG_FUNCPTR (gst_flac_parse_convert);
+  baseparse_class->src_event = GST_DEBUG_FUNCPTR (gst_flac_parse_src_event);
   baseparse_class->get_sink_caps =
       GST_DEBUG_FUNCPTR (gst_flac_parse_get_sink_caps);
 
@@ -1694,7 +1697,6 @@ gst_flac_parse_pre_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
   if (flacparse->toc) {
     gst_pad_push_event (GST_BASE_PARSE_SRC_PAD (flacparse),
         gst_event_new_toc (flacparse->toc, FALSE));
-    flacparse->toc = NULL;
   }
 
   frame->flags |= GST_BASE_PARSE_FRAME_FLAG_CLIP;
@@ -1734,6 +1736,61 @@ gst_flac_parse_convert (GstBaseParse * parse,
       src_value, dest_format, dest_value);
 }
 
+static gboolean
+gst_flac_parse_src_event (GstBaseParse * parse, GstEvent * event)
+{
+  GstFlacParse *flacparse = GST_FLAC_PARSE (parse);
+  gboolean res = FALSE;
+
+  switch (GST_EVENT_TYPE (event)) {
+    case GST_EVENT_TOC_SELECT:
+    {
+      GstTocEntry *entry = NULL;
+      GstEvent *seek_event;
+      GstToc *toc = NULL;
+      gint64 start_pos;
+      gchar *uid = NULL;
+
+      /* FIXME: some locking would be good */
+      if (flacparse->toc)
+        toc = gst_toc_ref (flacparse->toc);
+
+      if (toc != NULL) {
+        gst_event_parse_toc_select (event, &uid);
+        if (uid != NULL) {
+          entry = gst_toc_find_entry (toc, uid);
+          if (entry != NULL) {
+            gst_toc_entry_get_start_stop_times (entry, &start_pos, NULL);
+
+            /* FIXME: use segment rate here instead? */
+            seek_event = gst_event_new_seek (1.0,
+                GST_FORMAT_TIME,
+                GST_SEEK_FLAG_FLUSH,
+                GST_SEEK_TYPE_SET, start_pos, GST_SEEK_TYPE_NONE, -1);
+
+            res =
+                GST_BASE_PARSE_CLASS (parent_class)->src_event (parse,
+                seek_event);
+
+            g_free (uid);
+          } else {
+            GST_WARNING_OBJECT (parse, "no TOC entry with given UID: %s", uid);
+          }
+        }
+        gst_toc_unref (toc);
+      } else {
+        GST_DEBUG_OBJECT (flacparse, "no TOC to select");
+      }
+      gst_event_unref (event);
+      break;
+    }
+    default:
+      res = GST_BASE_PARSE_CLASS (parent_class)->src_event (parse, event);
+      break;
+  }
+  return res;
+}
+
 static GstCaps *
 gst_flac_parse_get_sink_caps (GstBaseParse * parse, GstCaps * filter)
 {