Use macros to register boxed types thread safely
[platform/upstream/gstreamer.git] / libs / gst / base / gstbaseparse.c
index 09a5f69..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
@@ -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,8 +381,10 @@ 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,
     GstObject * parent);
@@ -440,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
@@ -469,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);
 
@@ -499,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;
@@ -557,11 +571,13 @@ gst_base_parse_init (GstBaseParse * parse, GstBaseParseClass * bclass)
 
   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;
@@ -1154,8 +1161,9 @@ gst_base_parse_sink_query (GstPad * pad, GstObject * parent, GstQuery * query)
           caps =
               gst_caps_intersect_full (filter, template_caps,
               GST_CAPS_INTERSECT_FIRST);
+          gst_caps_unref (template_caps);
         } else {
-          caps = gst_caps_copy (template_caps);
+          caps = template_caps;
         }
         gst_query_set_caps_result (query, caps);
         gst_caps_unref (caps);
@@ -1567,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;
@@ -1880,8 +1889,8 @@ 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 &&
@@ -2051,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;
+  }
 }
 
 
@@ -3541,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;
@@ -3563,9 +3582,17 @@ 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 */
@@ -3674,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) {
@@ -3698,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)
@@ -3986,12 +4013,13 @@ gst_base_parse_handle_tag (GstBaseParse * parse, GstEvent * event)
   }
 }
 
+#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) {
@@ -4002,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 *
@@ -4011,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)
@@ -4031,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;
@@ -4042,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;