summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEdward Hervey <bilboed@bilboed.com>2009-03-21 15:41:15 +0100
committerEdward Hervey <bilboed@bilboed.com>2009-03-21 15:41:15 +0100
commit8176747c4538b4d60d7ade9d2b52a24088b13064 (patch)
treeeb17f5ce09c8daf3c313d3d871dd0903f35afdf2
parent1b5ea09b0e26829e67ef2591fc64560bb858a3f0 (diff)
GnlComposition: Switch to using regular segment seeks. Fixes #575972
-rw-r--r--gnl/gnlcomposition.c211
-rw-r--r--gnl/gnlobject.c8
2 files changed, 55 insertions, 164 deletions
diff --git a/gnl/gnlcomposition.c b/gnl/gnlcomposition.c
index 85f2309..c27371a 100644
--- a/gnl/gnlcomposition.c
+++ b/gnl/gnlcomposition.c
@@ -77,6 +77,7 @@ struct _GnlCompositionPrivate
/* source top-level ghostpad */
GstPad *ghostpad;
+ guint ghosteventprobe;
/* current stack, list of GnlObject* */
GNode *current;
@@ -107,9 +108,6 @@ struct _GnlCompositionPrivate
*/
GstPadEventFunction gnl_event_pad_func;
- /* List of SEGMENT_START/SEGMENT_DONE, protected by objects lock */
- GList *segmessages;
- GMutex *messages_lock;
};
#define OBJECT_IN_ACTIVE_SEGMENT(comp,element) \
@@ -142,7 +140,6 @@ static gboolean
update_pipeline (GnlComposition * comp, GstClockTime currenttime,
gboolean initial, gboolean change_state, gboolean modify);
-static void flush_messages (GnlComposition * comp);
#define COMP_REAL_START(comp) \
(MAX (comp->private->segment->start, ((GnlObject*)comp)->start))
@@ -169,19 +166,6 @@ static void flush_messages (GnlComposition * comp);
g_mutex_unlock (comp->private->objects_lock); \
} G_STMT_END
-#define COMP_MESSAGES_LOCK(comp) G_STMT_START { \
- GST_LOG_OBJECT (comp, "locking messages_lock from thread %p", \
- g_thread_self()); \
- g_mutex_lock (comp->private->messages_lock); \
- GST_LOG_OBJECT (comp, "locked messages_lock from thread %p", \
- g_thread_self()); \
- } G_STMT_END
-
-#define COMP_MESSAGES_UNLOCK(comp) G_STMT_START { \
- GST_LOG_OBJECT (comp, "unlocking messages_lock from thread %p", \
- g_thread_self()); \
- g_mutex_unlock (comp->private->messages_lock); \
- } G_STMT_END
#define COMP_FLUSHING_LOCK(comp) G_STMT_START { \
GST_LOG_OBJECT (comp, "locking flushing_lock from thread %p", \
@@ -302,7 +286,6 @@ gnl_composition_init (GnlComposition * comp, GnlCompositionClass * klass)
(g_direct_hash,
g_direct_equal, NULL, (GDestroyNotify) hash_value_destroy);
- comp->private->messages_lock = g_mutex_new ();
gnl_composition_reset (comp);
}
@@ -355,8 +338,6 @@ gnl_composition_finalize (GObject * object)
g_mutex_free (comp->private->flushing_lock);
- g_mutex_free (comp->private->messages_lock);
- flush_messages (comp);
g_free (comp->private);
@@ -484,7 +465,7 @@ gnl_composition_reset (GnlComposition * comp)
}
static gboolean
-segment_done_main_thread (GnlComposition * comp)
+eos_main_thread (GnlComposition * comp)
{
/* Set up a non-initial seek on segment_stop */
GST_DEBUG_OBJECT (comp,
@@ -512,8 +493,7 @@ segment_done_main_thread (GnlComposition * comp)
GST_LOG_OBJECT (comp, "Emitting segment done pos %" GST_TIME_FORMAT,
GST_TIME_ARGS (epos));
- GST_BIN_CLASS (parent_class)->handle_message
- (GST_BIN (comp),
+ gst_element_post_message (GST_ELEMENT_CAST (comp),
gst_message_new_segment_done (GST_OBJECT (comp),
comp->private->segment->format, epos));
}
@@ -521,107 +501,16 @@ segment_done_main_thread (GnlComposition * comp)
return FALSE;
}
-/* add_message
- * flush_messages
- * replace_message
- * has_message
- *
- * Must be called with the MESSAGES_LOCK taken
- */
-
-static void
-add_message (GnlComposition * comp, GstMessage * msg)
-{
- GList *tmp;
-
- /* make sure we don't already have a msg with the
- * same src/type */
- for (tmp = comp->private->segmessages; tmp; tmp = tmp->next) {
- GstMessage *tmpmsg = (GstMessage *) tmp->data;
-
- if ((GST_MESSAGE_SRC (msg) == GST_MESSAGE_SRC (tmpmsg)) &&
- (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_TYPE (tmpmsg)))
- return;
- }
- comp->private->segmessages = g_list_append (comp->private->segmessages,
- gst_message_ref (msg));
-}
-
-static void
-flush_messages (GnlComposition * comp)
-{
- GList *tmp;
-
- for (tmp = comp->private->segmessages; tmp; tmp = tmp->next)
- gst_message_unref ((GstMessage *) tmp->data);
- g_list_free (comp->private->segmessages);
- comp->private->segmessages = NULL;
-}
-
-static void
-replace_message (GnlComposition * comp, GstMessage * msg, GstMessageType type)
-{
- GList *tmp = NULL;
-
- /* Find msg of type 'type' and source 'msg'->src */
- for (tmp = comp->private->segmessages; tmp; tmp = tmp->next) {
- GstMessage *tmpmsg = (GstMessage *) tmp->data;
-
- if ((GST_MESSAGE_TYPE (tmpmsg) == type) &&
- (GST_MESSAGE_SRC (tmpmsg) == GST_MESSAGE_SRC (msg)))
- break;
- }
-
- if (tmp != NULL) {
- gst_message_unref ((GstMessage *) tmp->data);
- comp->private->segmessages =
- g_list_delete_link (comp->private->segmessages, tmp);
- }
- add_message (comp, msg);
-}
-
static gboolean
-has_message (GnlComposition * comp, GstMessageType type)
-{
- GList *tmp;
- gboolean res = FALSE;
-
- for (tmp = comp->private->segmessages; tmp; tmp = tmp->next)
- if (GST_MESSAGE_TYPE ((GstMessage *) tmp->data) == type) {
- res = TRUE;
- break;
- }
-
- return res;
-}
-
-static void
-dump_messages (GnlComposition * comp)
-{
- GList *tmp;
-
- for (tmp = comp->private->segmessages; tmp; tmp = tmp->next) {
- GstMessage *msg = (GstMessage *) tmp->data;
-
- GST_LOG ("type:%s , src:%s",
- GST_MESSAGE_TYPE_NAME (msg), GST_ELEMENT_NAME (GST_MESSAGE_SRC (msg)));
- }
-}
-
-/* Warning : Don't take the objects lock in this method */
-static void
-gnl_composition_handle_message (GstBin * bin, GstMessage * message)
+ghost_event_probe_handler (GstPad * ghostpad, GstEvent * event,
+ GnlComposition * comp)
{
- GnlComposition *comp = (GnlComposition *) bin;
- gboolean dropit = FALSE;
+ gboolean keepit = TRUE;
- GST_DEBUG_OBJECT (comp, "message:%s from %s",
- gst_message_type_get_name (GST_MESSAGE_TYPE (message)),
- GST_MESSAGE_SRC (message) ? GST_ELEMENT_NAME (GST_MESSAGE_SRC (message)) :
- "UNKNOWN");
+ GST_DEBUG_OBJECT (comp, "event: %s", GST_EVENT_TYPE_NAME (event));
- switch (GST_MESSAGE_TYPE (message)) {
- case GST_MESSAGE_SEGMENT_START:{
+ switch (GST_EVENT_TYPE (event)) {
+ case GST_EVENT_NEWSEGMENT:{
COMP_FLUSHING_LOCK (comp);
if (comp->private->pending_idle) {
GST_DEBUG_OBJECT (comp, "removing pending seek for main thread");
@@ -630,43 +519,22 @@ gnl_composition_handle_message (GstBin * bin, GstMessage * message)
comp->private->pending_idle = 0;
comp->private->flushing = FALSE;
COMP_FLUSHING_UNLOCK (comp);
-
- COMP_MESSAGES_LOCK (comp);
- add_message (comp, message);
- dump_messages (comp);
- COMP_MESSAGES_UNLOCK (comp);
-
- dropit = TRUE;
- break;
}
- case GST_MESSAGE_SEGMENT_DONE:{
- gboolean has_start = FALSE;
-
+ break;
+ case GST_EVENT_EOS:{
COMP_FLUSHING_LOCK (comp);
if (comp->private->flushing) {
GST_DEBUG_OBJECT (comp, "flushing, bailing out");
COMP_FLUSHING_UNLOCK (comp);
- dropit = TRUE;
+ keepit = FALSE;
break;
}
COMP_FLUSHING_UNLOCK (comp);
- COMP_MESSAGES_LOCK (comp);
- replace_message (comp, message, GST_MESSAGE_SEGMENT_START);
- has_start = has_message (comp, GST_MESSAGE_SEGMENT_START);
- dump_messages (comp);
- COMP_MESSAGES_UNLOCK (comp);
-
- if (has_start == TRUE) {
- GST_DEBUG_OBJECT (comp, "Still waiting for more SEGMENT_DONE");
- dropit = TRUE;
- break;
- }
-
- GST_DEBUG_OBJECT (comp, "Adding segment_done handling to main thread");
+ GST_DEBUG_OBJECT (comp, "Adding eos handling to main thread");
if (comp->private->pending_idle) {
GST_WARNING_OBJECT (comp,
- "There was already a pending segment_done in main thread !");
+ "There was already a pending eos in main thread !");
g_source_remove (comp->private->pending_idle);
}
@@ -674,11 +542,33 @@ gnl_composition_handle_message (GstBin * bin, GstMessage * message)
* of a g_idle_add(). EXTENSIVE TESTING AND ANALYSIS REQUIRED BEFORE
* DOING THE SWITCH !!! */
comp->private->pending_idle =
- g_idle_add ((GSourceFunc) segment_done_main_thread, (gpointer) comp);
+ g_idle_add ((GSourceFunc) eos_main_thread, (gpointer) comp);
- dropit = TRUE;
- break;
+ keepit = FALSE;
}
+ break;
+ default:
+ break;
+ }
+
+ return keepit;
+}
+
+
+
+/* Warning : Don't take the objects lock in this method */
+static void
+gnl_composition_handle_message (GstBin * bin, GstMessage * message)
+{
+ GnlComposition *comp = (GnlComposition *) bin;
+ gboolean dropit = FALSE;
+
+ GST_DEBUG_OBJECT (comp, "message:%s from %s",
+ gst_message_type_get_name (GST_MESSAGE_TYPE (message)),
+ GST_MESSAGE_SRC (message) ? GST_ELEMENT_NAME (GST_MESSAGE_SRC (message)) :
+ "UNKNOWN");
+
+ switch (GST_MESSAGE_TYPE (message)) {
case GST_MESSAGE_ERROR:
case GST_MESSAGE_WARNING:{
/* FIXME / HACK
@@ -760,8 +650,7 @@ get_new_seek_event (GnlComposition * comp, gboolean initial,
if (!(initial))
flags = comp->private->segment->flags;
else
- flags =
- GST_SEEK_FLAG_SEGMENT | GST_SEEK_FLAG_ACCURATE | GST_SEEK_FLAG_FLUSH;
+ flags = GST_SEEK_FLAG_ACCURATE | GST_SEEK_FLAG_FLUSH;
GST_DEBUG_OBJECT (comp,
"private->segment->start:%" GST_TIME_FORMAT " segment_start%"
@@ -979,6 +868,7 @@ gnl_composition_ghost_pad_set_target (GnlComposition * comp, GstPad * target)
GST_DEBUG_OBJECT (comp, "Removing target, hadghost:%d", hadghost);
if (!(hadghost)) {
+ /* Create new ghostpad */
comp->private->ghostpad =
gnl_object_ghost_pad_no_target ((GnlObject *) comp, "src", GST_PAD_SRC);
GST_DEBUG_OBJECT (comp->private->ghostpad,
@@ -1000,17 +890,31 @@ gnl_composition_ghost_pad_set_target (GnlComposition * comp, GstPad * target)
return;
}
+ /* Unset previous target */
if (ptarget) {
GST_DEBUG_OBJECT (comp, "Previous target was %s:%s, blocking that pad",
GST_DEBUG_PAD_NAME (ptarget));
gst_pad_set_blocked_async (ptarget, TRUE,
(GstPadBlockCallback) pad_blocked, comp);
+ /* remove event probe */
+ if (comp->private->ghosteventprobe) {
+ gst_pad_remove_event_probe (ptarget, comp->private->ghosteventprobe);
+ comp->private->ghosteventprobe = 0;
+ }
gst_object_unref (ptarget);
}
}
gnl_object_ghost_pad_set_target ((GnlObject *) comp,
comp->private->ghostpad, target);
+
+ if (target && (comp->private->ghosteventprobe == 0)) {
+ GST_DEBUG ("Setting event probe");
+ comp->private->ghosteventprobe =
+ gst_pad_add_event_probe (target, G_CALLBACK (ghost_event_probe_handler),
+ comp);
+ }
+
if (!(hadghost)) {
gst_pad_set_active (comp->private->ghostpad, TRUE);
if (!(gst_element_add_pad (GST_ELEMENT (comp), comp->private->ghostpad)))
@@ -2037,11 +1941,6 @@ update_pipeline (GnlComposition * comp, GstClockTime currenttime,
"now really updating the pipeline, current-state:%s",
gst_element_state_get_name (state));
- /* Flush pending segment messages */
-
- COMP_MESSAGES_LOCK (comp);
- flush_messages (comp);
- COMP_MESSAGES_UNLOCK (comp);
/* (re)build the stack and relink new elements */
stack =
diff --git a/gnl/gnlobject.c b/gnl/gnlobject.c
index 7b08758..7e4eef4 100644
--- a/gnl/gnlobject.c
+++ b/gnl/gnlobject.c
@@ -465,14 +465,6 @@ translate_incoming_seek (GnlObject * object, GstEvent * event)
GST_TIME_ARGS (nstop));
}
- /* add segment seekflags */
- if (!(flags & GST_SEEK_FLAG_SEGMENT)) {
- GST_DEBUG_OBJECT (object, "Adding GST_SEEK_FLAG_SEGMENT");
- flags |= GST_SEEK_FLAG_SEGMENT;
- } else {
- GST_DEBUG_OBJECT (object,
- "event already has GST_SEEK_FLAG_SEGMENT : %d", flags);
- }
/* add accurate seekflags */
if (!(flags & GST_SEEK_FLAG_ACCURATE)) {