Use macros to register boxed types thread safely
[platform/upstream/gstreamer.git] / libs / gst / base / gstbaseparse.c
index aefe5fb..adc33e8 100644 (file)
 
 #include "gstbaseparse.h"
 
+/* FIXME: get rid of old GstIndex code */
+#include "gstindex.h"
+#include "gstindex.c"
+#include "gstmemindex.c"
+
 #define GST_BASE_PARSE_FRAME_PRIVATE_FLAG_NOALLOC  (1 << 0)
 
 #define MIN_FRAMES_TO_POST_BITRATE 10
@@ -226,7 +231,7 @@ static const GstFormat fmtlist[] = {
 
 struct _GstBaseParsePrivate
 {
-  GstPadActivateMode pad_mode;
+  GstPadMode pad_mode;
 
   GstAdapter *adapter;
 
@@ -284,7 +289,7 @@ struct _GstBaseParsePrivate
   GstIndex *index;
   gint index_id;
   gboolean own_index;
-  GStaticMutex index_lock;
+  GMutex index_lock;
 
   /* seek table entries only maintained if upstream is BYTE seekable */
   gboolean upstream_seekable;
@@ -333,6 +338,11 @@ typedef struct _GstBaseParseSeek
   GstClockTime start_ts;
 } GstBaseParseSeek;
 
+#define GST_BASE_PARSE_INDEX_LOCK(parse) \
+  g_mutex_lock (&parse->priv->index_lock);
+#define GST_BASE_PARSE_INDEX_UNLOCK(parse) \
+  g_mutex_unlock (&parse->priv->index_lock);
+
 static GstElementClass *parent_class = NULL;
 
 static void gst_base_parse_class_init (GstBaseParseClass * klass);
@@ -371,25 +381,31 @@ static GstStateChangeReturn gst_base_parse_change_state (GstElement * element,
     GstStateChange transition);
 static void gst_base_parse_reset (GstBaseParse * parse);
 
+#if 0
 static void gst_base_parse_set_index (GstElement * element, GstIndex * index);
 static GstIndex *gst_base_parse_get_index (GstElement * element);
+#endif
 
-static gboolean gst_base_parse_sink_activate (GstPad * sinkpad);
-static gboolean gst_base_parse_sink_activate_push (GstPad * pad,
-    gboolean active);
-static gboolean gst_base_parse_sink_activate_pull (GstPad * pad,
-    gboolean active);
+static gboolean gst_base_parse_sink_activate (GstPad * sinkpad,
+    GstObject * parent);
+static gboolean gst_base_parse_sink_activate_mode (GstPad * pad,
+    GstObject * parent, GstPadMode mode, gboolean active);
 static gboolean gst_base_parse_handle_seek (GstBaseParse * parse,
     GstEvent * event);
 static void gst_base_parse_handle_tag (GstBaseParse * parse, GstEvent * event);
 
-static gboolean gst_base_parse_src_event (GstPad * pad, GstEvent * event);
-static gboolean gst_base_parse_sink_event (GstPad * pad, GstEvent * event);
-static gboolean gst_base_parse_query (GstPad * pad, GstQuery * query);
-static GstCaps *gst_base_parse_sink_getcaps (GstPad * pad, GstCaps * filter);
-static const GstQueryType *gst_base_parse_get_querytypes (GstPad * pad);
+static gboolean gst_base_parse_src_event (GstPad * pad, GstObject * parent,
+    GstEvent * event);
+static gboolean gst_base_parse_src_query (GstPad * pad, GstObject * parent,
+    GstQuery * query);
+
+static gboolean gst_base_parse_sink_event (GstPad * pad, GstObject * parent,
+    GstEvent * event);
+static gboolean gst_base_parse_sink_query (GstPad * pad, GstObject * parent,
+    GstQuery * query);
 
-static GstFlowReturn gst_base_parse_chain (GstPad * pad, GstBuffer * buffer);
+static GstFlowReturn gst_base_parse_chain (GstPad * pad, GstObject * parent,
+    GstBuffer * buffer);
 static void gst_base_parse_loop (GstPad * pad);
 
 static gboolean gst_base_parse_check_frame (GstBaseParse * parse,
@@ -436,6 +452,10 @@ gst_base_parse_clear_queues (GstBaseParse * parse)
   g_list_free (parse->priv->detect_buffers);
   parse->priv->detect_buffers = NULL;
   parse->priv->detect_buffers_size = 0;
+
+  g_queue_foreach (&parse->priv->queued_frames,
+      (GFunc) gst_base_parse_frame_free, NULL);
+  g_queue_clear (&parse->priv->queued_frames);
 }
 
 static void
@@ -465,16 +485,11 @@ gst_base_parse_finalize (GObject * object)
   g_list_free (parse->priv->pending_events);
   parse->priv->pending_events = NULL;
 
-  g_queue_foreach (&parse->priv->queued_frames,
-      (GFunc) gst_base_parse_frame_free, NULL);
-  g_queue_clear (&parse->priv->queued_frames);
-
   if (parse->priv->index) {
     gst_object_unref (parse->priv->index);
     parse->priv->index = NULL;
   }
-
-  g_static_mutex_free (&parse->priv->index_lock);
+  g_mutex_clear (&parse->priv->index_lock);
 
   gst_base_parse_clear_queues (parse);
 
@@ -495,8 +510,11 @@ gst_base_parse_class_init (GstBaseParseClass * klass)
   gstelement_class = (GstElementClass *) klass;
   gstelement_class->change_state =
       GST_DEBUG_FUNCPTR (gst_base_parse_change_state);
+
+#if 0
   gstelement_class->set_index = GST_DEBUG_FUNCPTR (gst_base_parse_set_index);
   gstelement_class->get_index = GST_DEBUG_FUNCPTR (gst_base_parse_get_index);
+#endif
 
   /* Default handlers */
   klass->check_valid_frame = gst_base_parse_check_frame;
@@ -523,16 +541,14 @@ gst_base_parse_init (GstBaseParse * parse, GstBaseParseClass * bclass)
   parse->sinkpad = gst_pad_new_from_template (pad_template, "sink");
   gst_pad_set_event_function (parse->sinkpad,
       GST_DEBUG_FUNCPTR (gst_base_parse_sink_event));
-  gst_pad_set_getcaps_function (parse->sinkpad,
-      GST_DEBUG_FUNCPTR (gst_base_parse_sink_getcaps));
+  gst_pad_set_query_function (parse->sinkpad,
+      GST_DEBUG_FUNCPTR (gst_base_parse_sink_query));
   gst_pad_set_chain_function (parse->sinkpad,
       GST_DEBUG_FUNCPTR (gst_base_parse_chain));
   gst_pad_set_activate_function (parse->sinkpad,
       GST_DEBUG_FUNCPTR (gst_base_parse_sink_activate));
-  gst_pad_set_activatepush_function (parse->sinkpad,
-      GST_DEBUG_FUNCPTR (gst_base_parse_sink_activate_push));
-  gst_pad_set_activatepull_function (parse->sinkpad,
-      GST_DEBUG_FUNCPTR (gst_base_parse_sink_activate_pull));
+  gst_pad_set_activatemode_function (parse->sinkpad,
+      GST_DEBUG_FUNCPTR (gst_base_parse_sink_activate_mode));
   gst_element_add_pad (GST_ELEMENT (parse), parse->sinkpad);
 
   GST_DEBUG_OBJECT (parse, "sinkpad created");
@@ -543,10 +559,8 @@ gst_base_parse_init (GstBaseParse * parse, GstBaseParseClass * bclass)
   parse->srcpad = gst_pad_new_from_template (pad_template, "src");
   gst_pad_set_event_function (parse->srcpad,
       GST_DEBUG_FUNCPTR (gst_base_parse_src_event));
-  gst_pad_set_query_type_function (parse->srcpad,
-      GST_DEBUG_FUNCPTR (gst_base_parse_get_querytypes));
   gst_pad_set_query_function (parse->srcpad,
-      GST_DEBUG_FUNCPTR (gst_base_parse_query));
+      GST_DEBUG_FUNCPTR (gst_base_parse_src_query));
   gst_pad_use_fixed_caps (parse->srcpad);
   gst_element_add_pad (GST_ELEMENT (parse), parse->srcpad);
   GST_DEBUG_OBJECT (parse, "src created");
@@ -555,13 +569,15 @@ gst_base_parse_init (GstBaseParse * parse, GstBaseParseClass * bclass)
 
   parse->priv->adapter = gst_adapter_new ();
 
-  parse->priv->pad_mode = GST_PAD_ACTIVATE_NONE;
+  parse->priv->pad_mode = GST_PAD_MODE_NONE;
 
-  g_static_mutex_init (&parse->priv->index_lock);
+  g_mutex_init (&parse->priv->index_lock);
 
   /* init state */
   gst_base_parse_reset (parse);
   GST_DEBUG_OBJECT (parse, "init ok");
+
+  GST_OBJECT_FLAG_SET (parse, GST_ELEMENT_FLAG_INDEXABLE);
 }
 
 static GstBaseParseFrame *
@@ -595,21 +611,9 @@ gst_base_parse_frame_free (GstBaseParseFrame * frame)
   }
 }
 
-GType
-gst_base_parse_frame_get_type (void)
-{
-  static volatile gsize frame_type = 0;
-
-  if (g_once_init_enter (&frame_type)) {
-    GType _type;
-
-    _type = g_boxed_type_register_static ("GstBaseParseFrame",
-        (GBoxedCopyFunc) gst_base_parse_frame_copy,
-        (GBoxedFreeFunc) gst_base_parse_frame_free);
-    g_once_init_leave (&frame_type, _type);
-  }
-  return (GType) frame_type;
-}
+G_DEFINE_BOXED_TYPE (GstBaseParseFrame, gst_base_parse_frame,
+    (GBoxedCopyFunc) gst_base_parse_frame_copy,
+    (GBoxedFreeFunc) gst_base_parse_frame_free);
 
 /**
  * gst_base_parse_frame_init:
@@ -747,6 +751,9 @@ gst_base_parse_reset (GstBaseParse * parse)
   g_slist_free (parse->priv->pending_seeks);
   parse->priv->pending_seeks = NULL;
 
+  if (parse->priv->adapter)
+    gst_adapter_clear (parse->priv->adapter);
+
   /* we know it is not alloc'ed, but maybe other stuff to free, some day ... */
   parse->priv->frame._private_flags |=
       GST_BASE_PARSE_FRAME_PRIVATE_FLAG_NOALLOC;
@@ -865,14 +872,14 @@ gst_base_parse_convert (GstBaseParse * parse,
  * Returns: TRUE if the event was handled.
  */
 static gboolean
-gst_base_parse_sink_event (GstPad * pad, GstEvent * event)
+gst_base_parse_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
 {
   GstBaseParse *parse;
   GstBaseParseClass *bclass;
   gboolean handled = FALSE;
   gboolean ret = TRUE;
 
-  parse = GST_BASE_PARSE (gst_pad_get_parent (pad));
+  parse = GST_BASE_PARSE (parent);
   bclass = GST_BASE_PARSE_GET_CLASS (parse);
 
   GST_DEBUG_OBJECT (parse, "handling event %d, %s", GST_EVENT_TYPE (event),
@@ -883,7 +890,8 @@ gst_base_parse_sink_event (GstPad * pad, GstEvent * event)
   if (parse->priv->pending_segment && GST_EVENT_TYPE (event) != GST_EVENT_EOS
       && GST_EVENT_TYPE (event) != GST_EVENT_SEGMENT
       && GST_EVENT_TYPE (event) != GST_EVENT_FLUSH_START
-      && GST_EVENT_TYPE (event) != GST_EVENT_FLUSH_STOP) {
+      && GST_EVENT_TYPE (event) != GST_EVENT_FLUSH_STOP
+      && GST_EVENT_TYPE (event) != GST_EVENT_CAPS) {
 
     if (GST_EVENT_TYPE (event) == GST_EVENT_TAG)
       /* See if any bitrate tags were posted */
@@ -906,11 +914,11 @@ gst_base_parse_sink_event (GstPad * pad, GstEvent * event)
       handled = gst_base_parse_sink_eventfunc (parse, event);
 
     if (!handled)
-      ret = gst_pad_event_default (pad, event);
+      ret = gst_pad_event_default (pad, parent, event);
   }
 
-  gst_object_unref (parse);
   GST_DEBUG_OBJECT (parse, "event handled");
+
   return ret;
 }
 
@@ -1120,6 +1128,60 @@ gst_base_parse_sink_eventfunc (GstBaseParse * parse, GstEvent * event)
   return handled;
 }
 
+static gboolean
+gst_base_parse_sink_query (GstPad * pad, GstObject * parent, GstQuery * query)
+{
+  GstBaseParse *parse;
+  GstBaseParseClass *bclass;
+  gboolean res;
+
+  parse = GST_BASE_PARSE (parent);
+  bclass = GST_BASE_PARSE_GET_CLASS (parse);
+
+  switch (GST_QUERY_TYPE (query)) {
+    case GST_QUERY_CAPS:
+    {
+      if (bclass->get_sink_caps) {
+        GstCaps *caps, *filter;
+
+        gst_query_parse_caps (query, &filter);
+        caps = bclass->get_sink_caps (parse, filter);
+        GST_LOG_OBJECT (parse, "sink getcaps returning caps %" GST_PTR_FORMAT,
+            caps);
+        gst_query_set_caps_result (query, caps);
+        gst_caps_unref (caps);
+
+        res = TRUE;
+      } else {
+        GstCaps *caps, *template_caps, *filter;
+
+        gst_query_parse_caps (query, &filter);
+        template_caps = gst_pad_get_pad_template_caps (pad);
+        if (filter != NULL) {
+          caps =
+              gst_caps_intersect_full (filter, template_caps,
+              GST_CAPS_INTERSECT_FIRST);
+          gst_caps_unref (template_caps);
+        } else {
+          caps = template_caps;
+        }
+        gst_query_set_caps_result (query, caps);
+        gst_caps_unref (caps);
+
+        res = TRUE;
+      }
+      break;
+    }
+    default:
+    {
+      res = gst_pad_query_default (pad, parent, query);
+      break;
+    }
+  }
+
+  return res;
+}
+
 
 /* gst_base_parse_src_event:
  * @pad: #GstPad that received the event.
@@ -1130,14 +1192,14 @@ gst_base_parse_sink_eventfunc (GstBaseParse * parse, GstEvent * event)
  * Returns: TRUE if the event was handled.
  */
 static gboolean
-gst_base_parse_src_event (GstPad * pad, GstEvent * event)
+gst_base_parse_src_event (GstPad * pad, GstObject * parent, GstEvent * event)
 {
   GstBaseParse *parse;
   GstBaseParseClass *bclass;
   gboolean handled = FALSE;
   gboolean ret = TRUE;
 
-  parse = GST_BASE_PARSE (gst_pad_get_parent (pad));
+  parse = GST_BASE_PARSE (parent);
   bclass = GST_BASE_PARSE_GET_CLASS (parse);
 
   GST_DEBUG_OBJECT (parse, "event %d, %s", GST_EVENT_TYPE (event),
@@ -1147,9 +1209,8 @@ gst_base_parse_src_event (GstPad * pad, GstEvent * event)
     handled = bclass->src_event (parse, event);
 
   if (!handled)
-    ret = gst_pad_event_default (pad, event);
+    ret = gst_pad_event_default (pad, parent, event);
 
-  gst_object_unref (parse);
   return ret;
 }
 
@@ -1514,11 +1575,12 @@ gst_base_parse_add_index_entry (GstBaseParse * parse, guint64 offset,
   associations[1].value = offset;
 
   /* index might change on-the-fly, although that would be nutty app ... */
-  g_static_mutex_lock (&parse->priv->index_lock);
+  GST_BASE_PARSE_INDEX_LOCK (parse);
   gst_index_add_associationv (parse->priv->index, parse->priv->index_id,
-      (key) ? GST_ASSOCIATION_FLAG_KEY_UNIT : GST_ASSOCIATION_FLAG_DELTA_UNIT,
-      2, (const GstIndexAssociation *) &associations);
-  g_static_mutex_unlock (&parse->priv->index_lock);
+      (key) ? GST_INDEX_ASSOCIATION_FLAG_KEY_UNIT :
+      GST_INDEX_ASSOCIATION_FLAG_DELTA_UNIT, 2,
+      (const GstIndexAssociation *) &associations);
+  GST_BASE_PARSE_INDEX_UNLOCK (parse);
 
   if (key) {
     parse->priv->index_last_offset = offset;
@@ -1551,7 +1613,7 @@ gst_base_parse_check_seekability (GstBaseParse * parse)
   /* try harder to query upstream size if we didn't get it the first time */
   if (seekable && stop == -1) {
     GST_DEBUG_OBJECT (parse, "doing duration query to fix up unset stop");
-    gst_pad_query_peer_duration (parse->sinkpad, GST_FORMAT_BYTES, &stop);
+    gst_pad_peer_query_duration (parse->sinkpad, GST_FORMAT_BYTES, &stop);
   }
 
   /* if upstream doesn't know the size, it's likely that it's not seekable in
@@ -1589,7 +1651,7 @@ gst_base_parse_check_upstream (GstBaseParse * parse)
 {
   gint64 stop;
 
-  if (gst_pad_query_peer_duration (parse->sinkpad, GST_FORMAT_TIME, &stop))
+  if (gst_pad_peer_query_duration (parse->sinkpad, GST_FORMAT_TIME, &stop))
     if (GST_CLOCK_TIME_IS_VALID (stop) && stop) {
       /* upstream has one, accept it also, and no further updates */
       gst_base_parse_set_duration (parse, GST_FORMAT_TIME, stop, 0);
@@ -1698,7 +1760,7 @@ gst_base_parse_handle_and_push_frame (GstBaseParse * parse,
    * If so, that allows and enables extra seek and duration determining options */
   if (G_UNLIKELY (parse->priv->first_frame_offset < 0 && ret == GST_FLOW_OK)) {
     if (GST_BUFFER_TIMESTAMP_IS_VALID (buffer) && parse->priv->has_timing_info
-        && parse->priv->pad_mode == GST_PAD_ACTIVATE_PULL) {
+        && parse->priv->pad_mode == GST_PAD_MODE_PULL) {
       parse->priv->first_frame_offset = offset;
       parse->priv->first_frame_ts = GST_BUFFER_TIMESTAMP (buffer);
       GST_DEBUG_OBJECT (parse, "subclass provided ts %" GST_TIME_FORMAT
@@ -1827,12 +1889,12 @@ gst_base_parse_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
     last_stop = last_start + GST_BUFFER_DURATION (buffer);
 
   /* should have caps by now */
-  g_return_val_if_fail (gst_pad_has_current_caps (parse->srcpad),
-      GST_FLOW_ERROR);
+  if (!gst_pad_has_current_caps (parse->srcpad))
+    goto no_caps;
 
   /* segment adjustment magic; only if we are running the whole show */
   if (!parse->priv->passthrough && parse->segment.rate > 0.0 &&
-      (parse->priv->pad_mode == GST_PAD_ACTIVATE_PULL ||
+      (parse->priv->pad_mode == GST_PAD_MODE_PULL ||
           parse->priv->upstream_seekable)) {
     /* segment times are typically estimates,
      * actual frame data might lead subclass to different timestamps,
@@ -1900,7 +1962,7 @@ gst_base_parse_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
     parse->priv->pending_segment = NULL;
 
     GST_DEBUG_OBJECT (parse, "%s push pending segment",
-        parse->priv->pad_mode == GST_PAD_ACTIVATE_PULL ? "loop" : "chain");
+        parse->priv->pad_mode == GST_PAD_MODE_PULL ? "loop" : "chain");
     gst_pad_push_event (parse->srcpad, pending_segment);
 
     /* have caps; check identity */
@@ -1985,7 +2047,7 @@ gst_base_parse_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
     /* if we are not sufficiently in control, let upstream decide on EOS */
     if (ret == GST_FLOW_EOS &&
         (parse->priv->passthrough ||
-            (parse->priv->pad_mode == GST_PAD_ACTIVATE_PUSH &&
+            (parse->priv->pad_mode == GST_PAD_MODE_PUSH &&
                 !parse->priv->upstream_seekable)))
       ret = GST_FLOW_OK;
   }
@@ -1998,6 +2060,13 @@ gst_base_parse_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
   gst_base_parse_frame_free (frame);
 
   return ret;
+
+  /* ERRORS */
+no_caps:
+  {
+    GST_ELEMENT_ERROR (parse, STREAM, DECODE, ("No caps set"), (NULL));
+    return GST_FLOW_ERROR;
+  }
 }
 
 
@@ -2020,7 +2089,8 @@ gst_base_parse_drain (GstBaseParse * parse)
     if (!avail)
       break;
 
-    if (gst_base_parse_chain (parse->sinkpad, NULL) != GST_FLOW_OK) {
+    if (gst_base_parse_chain (parse->sinkpad, GST_OBJECT_CAST (parse),
+            NULL) != GST_FLOW_OK) {
       break;
     }
 
@@ -2207,7 +2277,7 @@ gst_base_parse_check_sync (GstBaseParse * parse)
 }
 
 static GstFlowReturn
-gst_base_parse_chain (GstPad * pad, GstBuffer * buffer)
+gst_base_parse_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
 {
   GstBaseParseClass *bclass;
   GstBaseParse *parse;
@@ -2221,7 +2291,7 @@ gst_base_parse_chain (GstPad * pad, GstBuffer * buffer)
   GstClockTime timestamp;
   GstBaseParseFrame *frame;
 
-  parse = GST_BASE_PARSE (GST_OBJECT_PARENT (pad));
+  parse = GST_BASE_PARSE (parent);
   bclass = GST_BASE_PARSE_GET_CLASS (parse);
 
   if (parse->priv->detecting) {
@@ -2260,7 +2330,7 @@ gst_base_parse_chain (GstPad * pad, GstBuffer * buffer)
         if (ret == GST_FLOW_OK && !parse->priv->flushing)
           ret =
               gst_base_parse_chain (GST_BASE_PARSE_SINK_PAD (parse),
-              GST_BUFFER_CAST (l->data));
+              parent, GST_BUFFER_CAST (l->data));
         else
           gst_buffer_unref (GST_BUFFER_CAST (l->data));
       }
@@ -2386,7 +2456,7 @@ gst_base_parse_chain (GstPad * pad, GstBuffer * buffer)
       skip = -1;
       gst_base_parse_frame_update (parse, frame, tmpbuf);
       res = bclass->check_valid_frame (parse, frame, &fsize, &skip);
-      gst_adapter_unmap (parse->priv->adapter, 0);
+      gst_adapter_unmap (parse->priv->adapter);
       gst_buffer_replace (&frame->buffer, NULL);
       gst_buffer_remove_memory_range (tmpbuf, 0, -1);
       if (res) {
@@ -2893,22 +2963,21 @@ pause:
 }
 
 static gboolean
-gst_base_parse_sink_activate (GstPad * sinkpad)
+gst_base_parse_sink_activate (GstPad * sinkpad, GstObject * parent)
 {
   GstBaseParse *parse;
   gboolean result = TRUE;
   GstQuery *query;
   gboolean pull_mode;
 
-  parse = GST_BASE_PARSE (gst_pad_get_parent (sinkpad));
+  parse = GST_BASE_PARSE (parent);
 
   GST_DEBUG_OBJECT (parse, "sink activate");
 
   query = gst_query_new_scheduling ();
   result = gst_pad_peer_query (sinkpad, query);
   if (result) {
-    gst_query_parse_scheduling (query, &pull_mode, NULL, NULL, NULL, NULL,
-        NULL);
+    pull_mode = gst_query_has_scheduling_mode (query, GST_PAD_MODE_PULL);
   } else {
     pull_mode = FALSE;
   }
@@ -2916,14 +2985,13 @@ gst_base_parse_sink_activate (GstPad * sinkpad)
 
   if (pull_mode) {
     GST_DEBUG_OBJECT (parse, "trying to activate in pull mode");
-    result = gst_pad_activate_pull (sinkpad, TRUE);
+    result = gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PULL, TRUE);
   } else {
     GST_DEBUG_OBJECT (parse, "trying to activate in push mode");
-    result = gst_pad_activate_push (sinkpad, TRUE);
+    result = gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PUSH, TRUE);
   }
 
   GST_DEBUG_OBJECT (parse, "sink activate return %d", result);
-  gst_object_unref (parse);
   return result;
 }
 
@@ -2938,7 +3006,7 @@ gst_base_parse_activate (GstBaseParse * parse, gboolean active)
   klass = GST_BASE_PARSE_GET_CLASS (parse);
 
   if (active) {
-    if (parse->priv->pad_mode == GST_PAD_ACTIVATE_NONE && klass->start)
+    if (parse->priv->pad_mode == GST_PAD_MODE_NONE && klass->start)
       result = klass->start (parse);
 
     /* If the subclass implements ::detect we want to
@@ -2950,71 +3018,53 @@ gst_base_parse_activate (GstBaseParse * parse, gboolean active)
     GST_PAD_STREAM_LOCK (parse->sinkpad);
     GST_PAD_STREAM_UNLOCK (parse->sinkpad);
 
-    if (parse->priv->pad_mode != GST_PAD_ACTIVATE_NONE && klass->stop)
+    if (parse->priv->pad_mode != GST_PAD_MODE_NONE && klass->stop)
       result = klass->stop (parse);
 
-    parse->priv->pad_mode = GST_PAD_ACTIVATE_NONE;
+    parse->priv->pad_mode = GST_PAD_MODE_NONE;
   }
   GST_DEBUG_OBJECT (parse, "activate return: %d", result);
   return result;
 }
 
 static gboolean
-gst_base_parse_sink_activate_push (GstPad * pad, gboolean active)
+gst_base_parse_sink_activate_mode (GstPad * pad, GstObject * parent,
+    GstPadMode mode, gboolean active)
 {
   gboolean result = TRUE;
   GstBaseParse *parse;
 
-  parse = GST_BASE_PARSE (gst_pad_get_parent (pad));
-
-  GST_DEBUG_OBJECT (parse, "sink activate push %d", active);
-
-  result = gst_base_parse_activate (parse, active);
-
-  if (result)
-    parse->priv->pad_mode =
-        active ? GST_PAD_ACTIVATE_PUSH : GST_PAD_ACTIVATE_NONE;
-
-  GST_DEBUG_OBJECT (parse, "sink activate push return: %d", result);
-
-  gst_object_unref (parse);
-  return result;
-}
-
-static gboolean
-gst_base_parse_sink_activate_pull (GstPad * sinkpad, gboolean active)
-{
-  gboolean result = FALSE;
-  GstBaseParse *parse;
-
-  parse = GST_BASE_PARSE (gst_pad_get_parent (sinkpad));
+  parse = GST_BASE_PARSE (parent);
 
-  GST_DEBUG_OBJECT (parse, "activate pull %d", active);
+  GST_DEBUG_OBJECT (parse, "sink activate mode %d, %d", mode, active);
 
   result = gst_base_parse_activate (parse, active);
 
   if (result) {
-    if (active) {
-      parse->priv->pending_segment = gst_event_new_segment (&parse->segment);
-      result &=
-          gst_pad_start_task (sinkpad, (GstTaskFunction) gst_base_parse_loop,
-          sinkpad);
-    } else {
-      result &= gst_pad_stop_task (sinkpad);
+    switch (mode) {
+      case GST_PAD_MODE_PULL:
+        if (active) {
+          parse->priv->pending_segment =
+              gst_event_new_segment (&parse->segment);
+          result &=
+              gst_pad_start_task (pad, (GstTaskFunction) gst_base_parse_loop,
+              pad);
+        } else {
+          result &= gst_pad_stop_task (pad);
+        }
+        break;
+      default:
+        break;
     }
   }
-
   if (result)
-    parse->priv->pad_mode =
-        active ? GST_PAD_ACTIVATE_PULL : GST_PAD_ACTIVATE_NONE;
+    parse->priv->pad_mode = active ? mode : GST_PAD_MODE_NONE;
 
-  GST_DEBUG_OBJECT (parse, "sink activate pull return: %d", result);
+  GST_DEBUG_OBJECT (parse, "sink activate return: %d", result);
 
-  gst_object_unref (parse);
   return result;
 }
 
-
 /**
  * gst_base_parse_set_duration:
  * @parse: #GstBaseParse.
@@ -3229,7 +3279,7 @@ gst_base_parse_set_passthrough (GstBaseParse * parse, gboolean passthrough)
  * by the parsing process.  If there is such a latency, which depends on the
  * particular parsing of the format, it typically corresponds to 1 frame duration.
  *
- * Since: 0.10.34
+ * Since: 0.10.36
  */
 void
 gst_base_parse_set_latency (GstBaseParse * parse, GstClockTime min_latency,
@@ -3272,28 +3322,13 @@ gst_base_parse_get_duration (GstBaseParse * parse, GstFormat format,
   return res;
 }
 
-static const GstQueryType *
-gst_base_parse_get_querytypes (GstPad * pad)
-{
-  static const GstQueryType list[] = {
-    GST_QUERY_POSITION,
-    GST_QUERY_DURATION,
-    GST_QUERY_FORMATS,
-    GST_QUERY_SEEKING,
-    GST_QUERY_CONVERT,
-    GST_QUERY_NONE
-  };
-
-  return list;
-}
-
 static gboolean
-gst_base_parse_query (GstPad * pad, GstQuery * query)
+gst_base_parse_src_query (GstPad * pad, GstObject * parent, GstQuery * query)
 {
   GstBaseParse *parse;
   gboolean res = FALSE;
 
-  parse = GST_BASE_PARSE (GST_PAD_PARENT (pad));
+  parse = GST_BASE_PARSE (parent);
 
   GST_LOG_OBJECT (parse, "handling query: %" GST_PTR_FORMAT, query);
 
@@ -3307,7 +3342,7 @@ gst_base_parse_query (GstPad * pad, GstQuery * query)
       gst_query_parse_position (query, &format, NULL);
 
       /* try upstream first */
-      res = gst_pad_query_default (pad, query);
+      res = gst_pad_query_default (pad, parent, query);
       if (!res) {
         /* Fall back on interpreting segment */
         GST_OBJECT_LOCK (parse);
@@ -3341,7 +3376,7 @@ gst_base_parse_query (GstPad * pad, GstQuery * query)
       gst_query_parse_duration (query, &format, NULL);
 
       /* consult upstream */
-      res = gst_pad_query_default (pad, query);
+      res = gst_pad_query_default (pad, parent, query);
 
       /* otherwise best estimate from us */
       if (!res) {
@@ -3361,7 +3396,7 @@ gst_base_parse_query (GstPad * pad, GstQuery * query)
       gst_query_parse_seeking (query, &fmt, NULL, NULL, NULL);
 
       /* consult upstream */
-      res = gst_pad_query_default (pad, query);
+      res = gst_pad_query_default (pad, parent, query);
 
       /* we may be able to help if in TIME */
       if (fmt == GST_FORMAT_TIME && gst_base_parse_is_seekable (parse)) {
@@ -3430,7 +3465,7 @@ gst_base_parse_query (GstPad * pad, GstQuery * query)
       break;
     }
     default:
-      res = gst_pad_query_default (pad, query);
+      res = gst_pad_query_default (pad, parent, query);
       break;
   }
   return res;
@@ -3522,6 +3557,9 @@ gst_base_parse_locate_time (GstBaseParse * parse, GstClockTime * _time,
   g_return_val_if_fail (_time != NULL, GST_FLOW_ERROR);
   g_return_val_if_fail (_offset != NULL, GST_FLOW_ERROR);
 
+  GST_DEBUG_OBJECT (parse, "Bisecting for time %" GST_TIME_FORMAT,
+      GST_TIME_ARGS (*_time));
+
   /* TODO also make keyframe aware if useful some day */
 
   time = *_time;
@@ -3544,13 +3582,21 @@ gst_base_parse_locate_time (GstBaseParse * parse, GstClockTime * _time,
   /* need initial positions; start and end */
   lpos = parse->priv->first_frame_offset;
   ltime = parse->priv->first_frame_ts;
-  htime = parse->priv->duration;
+  if (!gst_base_parse_get_duration (parse, GST_FORMAT_TIME, &htime)) {
+    GST_DEBUG_OBJECT (parse, "Unknown time duration, cannot bisect");
+    return GST_FLOW_ERROR;
+  }
   hpos = parse->priv->upstream_size;
 
+  GST_DEBUG_OBJECT (parse,
+      "Bisection initial bounds: bytes %" G_GINT64_FORMAT " %" G_GINT64_FORMAT
+      ", times %" GST_TIME_FORMAT " %" GST_TIME_FORMAT, lpos, htime,
+      GST_TIME_ARGS (ltime), GST_TIME_ARGS (htime));
+
   /* check preconditions are satisfied;
    * start and end are needed, except for special case where we scan for
    * last frame to determine duration */
-  if (parse->priv->pad_mode != GST_PAD_ACTIVATE_PULL || !hpos ||
+  if (parse->priv->pad_mode != GST_PAD_MODE_PULL || !hpos ||
       !GST_CLOCK_TIME_IS_VALID (ltime) ||
       (!GST_CLOCK_TIME_IS_VALID (htime) && time != G_MAXINT64)) {
     return GST_FLOW_OK;
@@ -3655,13 +3701,13 @@ gst_base_parse_find_offset (GstBaseParse * parse, GstClockTime time,
     goto exit;
   }
 
-  g_static_mutex_lock (&parse->priv->index_lock);
+  GST_BASE_PARSE_INDEX_LOCK (parse);
   if (parse->priv->index) {
     /* Let's check if we have an index entry for that time */
     entry = gst_index_get_assoc_entry (parse->priv->index,
         parse->priv->index_id,
         before ? GST_INDEX_LOOKUP_BEFORE : GST_INDEX_LOOKUP_AFTER,
-        GST_ASSOCIATION_FLAG_KEY_UNIT, GST_FORMAT_TIME, time);
+        GST_INDEX_ASSOCIATION_FLAG_KEY_UNIT, GST_FORMAT_TIME, time);
   }
 
   if (entry) {
@@ -3679,7 +3725,7 @@ gst_base_parse_find_offset (GstBaseParse * parse, GstClockTime time,
       ts = GST_CLOCK_TIME_NONE;
     }
   }
-  g_static_mutex_unlock (&parse->priv->index_lock);
+  GST_BASE_PARSE_INDEX_UNLOCK (parse);
 
 exit:
   if (_ts)
@@ -3710,7 +3756,7 @@ gst_base_parse_handle_seek (GstBaseParse * parse, GstEvent * event)
       cur_type, GST_TIME_ARGS (cur), stop_type, GST_TIME_ARGS (stop));
 
   /* no negative rates in push mode */
-  if (rate < 0.0 && parse->priv->pad_mode == GST_PAD_ACTIVATE_PUSH)
+  if (rate < 0.0 && parse->priv->pad_mode == GST_PAD_MODE_PUSH)
     goto negative_rate;
 
   if (cur_type != GST_SEEK_TYPE_SET ||
@@ -3780,7 +3826,7 @@ gst_base_parse_handle_seek (GstBaseParse * parse, GstEvent * event)
       "seek stop %" G_GINT64_FORMAT " in bytes: %" G_GINT64_FORMAT,
       seeksegment.stop, seekstop);
 
-  if (parse->priv->pad_mode == GST_PAD_ACTIVATE_PULL) {
+  if (parse->priv->pad_mode == GST_PAD_MODE_PULL) {
     gint64 last_stop;
 
     GST_DEBUG_OBJECT (parse, "seek in PULL mode");
@@ -3967,35 +4013,13 @@ gst_base_parse_handle_tag (GstBaseParse * parse, GstEvent * event)
   }
 }
 
-static GstCaps *
-gst_base_parse_sink_getcaps (GstPad * pad, GstCaps * filter)
-{
-  GstBaseParse *parse;
-  GstBaseParseClass *klass;
-  GstCaps *caps;
-
-  parse = GST_BASE_PARSE (gst_pad_get_parent (pad));
-  klass = GST_BASE_PARSE_GET_CLASS (parse);
-  g_assert (pad == GST_BASE_PARSE_SINK_PAD (parse));
-
-  if (klass->get_sink_caps)
-    caps = klass->get_sink_caps (parse, filter);
-  else
-    caps = gst_pad_proxy_getcaps (pad, filter);
-  gst_object_unref (parse);
-
-  GST_LOG_OBJECT (parse, "sink getcaps returning caps %" GST_PTR_FORMAT, caps);
-
-  return caps;
-
-}
-
+#if 0
 static void
 gst_base_parse_set_index (GstElement * element, GstIndex * index)
 {
   GstBaseParse *parse = GST_BASE_PARSE (element);
 
-  g_static_mutex_lock (&parse->priv->index_lock);
+  GST_BASE_PARSE_INDEX_LOCK (parse);
   if (parse->priv->index)
     gst_object_unref (parse->priv->index);
   if (index) {
@@ -4006,7 +4030,7 @@ gst_base_parse_set_index (GstElement * element, GstIndex * index)
   } else {
     parse->priv->index = NULL;
   }
-  g_static_mutex_unlock (&parse->priv->index_lock);
+  GST_BASE_PARSE_INDEX_UNLOCK (parse);
 }
 
 static GstIndex *
@@ -4015,13 +4039,14 @@ gst_base_parse_get_index (GstElement * element)
   GstBaseParse *parse = GST_BASE_PARSE (element);
   GstIndex *result = NULL;
 
-  g_static_mutex_lock (&parse->priv->index_lock);
+  GST_BASE_PARSE_INDEX_LOCK (parse);
   if (parse->priv->index)
     result = gst_object_ref (parse->priv->index);
-  g_static_mutex_unlock (&parse->priv->index_lock);
+  GST_BASE_PARSE_INDEX_UNLOCK (parse);
 
   return result;
 }
+#endif
 
 static GstStateChangeReturn
 gst_base_parse_change_state (GstElement * element, GstStateChange transition)
@@ -4035,7 +4060,7 @@ gst_base_parse_change_state (GstElement * element, GstStateChange transition)
     case GST_STATE_CHANGE_READY_TO_PAUSED:
       /* If this is our own index destroy it as the
        * old entries might be wrong for the new stream */
-      g_static_mutex_lock (&parse->priv->index_lock);
+      GST_BASE_PARSE_INDEX_LOCK (parse);
       if (parse->priv->own_index) {
         gst_object_unref (parse->priv->index);
         parse->priv->index = NULL;
@@ -4046,12 +4071,12 @@ gst_base_parse_change_state (GstElement * element, GstStateChange transition)
       if (G_UNLIKELY (!parse->priv->index)) {
         GST_DEBUG_OBJECT (parse, "no index provided creating our own");
 
-        parse->priv->index = gst_index_factory_make ("memindex");
+        parse->priv->index = g_object_new (gst_mem_index_get_type (), NULL);
         gst_index_get_writer_id (parse->priv->index, GST_OBJECT (parse),
             &parse->priv->index_id);
         parse->priv->own_index = TRUE;
       }
-      g_static_mutex_unlock (&parse->priv->index_lock);
+      GST_BASE_PARSE_INDEX_UNLOCK (parse);
       break;
     default:
       break;