playback: Remove custom stream-change event

Applications can now use the STREAM_START message to know if a new
stream has started
This commit is contained in:
Edward Hervey 2012-07-10 18:34:41 +02:00
parent c9428c96b1
commit a0fbf92d43
2 changed files with 42 additions and 172 deletions

View file

@ -268,8 +268,6 @@ struct _GstSourceSelect
GstPad *sinkpad; /* the sinkpad of the sink when the selector
* is linked
*/
GstEvent *sinkpad_delayed_event;
gulong sinkpad_data_probe;
gulong block_id;
};
@ -1198,8 +1196,6 @@ gst_play_bin_class_init (GstPlayBinClass * klass)
static void
init_group (GstPlayBin * playbin, GstSourceGroup * group)
{
int n;
/* store the array for the different channels */
group->video_channels = g_ptr_array_new ();
group->audio_channels = g_ptr_array_new ();
@ -1228,27 +1224,11 @@ init_group (GstPlayBin * playbin, GstSourceGroup * group)
gst_subtitle_overlay_create_factory_caps;
group->selector[PLAYBIN_STREAM_TEXT].type = GST_PLAY_SINK_TYPE_TEXT;
group->selector[PLAYBIN_STREAM_TEXT].channels = group->text_channels;
for (n = 0; n < PLAYBIN_STREAM_LAST; n++) {
GstSourceSelect *select = &group->selector[n];
select->sinkpad_delayed_event = NULL;
select->sinkpad_data_probe = 0;
}
}
static void
free_group (GstPlayBin * playbin, GstSourceGroup * group)
{
int n;
for (n = 0; n < PLAYBIN_STREAM_LAST; n++) {
GstSourceSelect *select = &group->selector[n];
if (select->sinkpad && select->sinkpad_data_probe)
gst_pad_remove_probe (select->sinkpad, select->sinkpad_data_probe);
if (select->sinkpad_delayed_event)
gst_event_unref (select->sinkpad_delayed_event);
}
g_free (group->uri);
g_free (group->suburi);
g_ptr_array_free (group->video_channels, TRUE);
@ -2499,35 +2479,6 @@ gst_play_bin_handle_message (GstBin * bin, GstMessage * msg)
}
}
g_free (detail);
} else if (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_ELEMENT) {
const GstStructure *s = gst_message_get_structure (msg);
/* Drop all stream-changed messages except the last one */
if (strcmp ("playbin-stream-changed", gst_structure_get_name (s)) == 0) {
guint32 seqnum = gst_message_get_seqnum (msg);
GList *l, *l_prev;
group = playbin->curr_group;
g_mutex_lock (&group->stream_changed_pending_lock);
for (l = group->stream_changed_pending; l;) {
guint32 l_seqnum = GPOINTER_TO_UINT (l->data);
if (l_seqnum == seqnum) {
l_prev = l;
l = l->next;
group->stream_changed_pending =
g_list_delete_link (group->stream_changed_pending, l_prev);
if (group->stream_changed_pending) {
gst_message_unref (msg);
msg = NULL;
break;
}
} else {
l = l->next;
}
}
g_mutex_unlock (&group->stream_changed_pending_lock);
}
} else if (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_ASYNC_START ||
GST_MESSAGE_TYPE (msg) == GST_MESSAGE_ASYNC_DONE) {
GstObject *src = GST_OBJECT_CAST (msg->src);
@ -2693,40 +2644,6 @@ notify:
g_object_notify (G_OBJECT (playbin), property);
}
/* this callback sends a delayed event once the pad becomes unblocked */
static GstPadProbeReturn
stream_changed_data_probe (GstPad * pad, GstPadProbeInfo * info, gpointer data)
{
GstMiniObject *object = GST_PAD_PROBE_INFO_DATA (info);
GstSourceSelect *select = (GstSourceSelect *) data;
GstEvent *e;
/* we need do this just once, so cleanup first */
gst_pad_remove_probe (pad, select->sinkpad_data_probe);
select->sinkpad_data_probe = 0;
e = select->sinkpad_delayed_event;
select->sinkpad_delayed_event = NULL;
/* really, this should not happen */
if (!e) {
GST_WARNING ("Data probed called, but no delayed event");
return GST_PAD_PROBE_OK;
}
if (GST_IS_EVENT (object)
&& GST_EVENT_TYPE (GST_EVENT_CAST (object)) == GST_EVENT_SEGMENT) {
/* push the event first, then send the delayed one */
gst_event_ref (GST_EVENT_CAST (object));
gst_pad_send_event (pad, GST_EVENT_CAST (object));
gst_pad_send_event (pad, e);
return GST_PAD_PROBE_DROP;
} else {
/* send delayed event, then allow the caller to go on */
gst_pad_send_event (pad, e);
return GST_PAD_PROBE_OK;
}
}
static GstPadProbeReturn
_suburidecodebin_event_probe (GstPad * pad, GstPadProbeInfo * info,
gpointer udata)
@ -3224,47 +3141,6 @@ no_more_pads_cb (GstElement * decodebin, GstSourceGroup * group)
for (i = 0; i < PLAYBIN_STREAM_LAST; i++) {
GstSourceSelect *select = &group->selector[i];
/* All streamsynchronizer streams should see stream-changed message,
* to arrange for blocking unblocking. */
if (select->sinkpad) {
GstStructure *s;
GstMessage *msg;
GstEvent *event;
guint32 seqnum;
s = gst_structure_new ("playbin-stream-changed", "uri", G_TYPE_STRING,
group->uri, NULL);
if (group->suburi)
gst_structure_set (s, "suburi", G_TYPE_STRING, group->suburi, NULL);
msg = gst_message_new_element (GST_OBJECT_CAST (playbin), s);
seqnum = gst_message_get_seqnum (msg);
event = gst_event_new_sink_message ("GstPlaybin", msg);
g_mutex_lock (&group->stream_changed_pending_lock);
group->stream_changed_pending =
g_list_prepend (group->stream_changed_pending,
GUINT_TO_POINTER (seqnum));
/* remove any data probe we might have, and replace */
if (select->sinkpad_delayed_event)
gst_event_unref (select->sinkpad_delayed_event);
select->sinkpad_delayed_event = event;
if (select->sinkpad_data_probe)
gst_pad_remove_probe (select->sinkpad, select->sinkpad_data_probe);
/* we go to the trouble of setting a probe on the pad to send
the playbin-stream-changed event as sending it here might
find that the pad is blocked, so we'd block here, and the
pad might not be linked yet. Additionally, sending it here
apparently would be on the wrong thread */
select->sinkpad_data_probe =
gst_pad_add_probe (select->sinkpad,
GST_PAD_PROBE_TYPE_DATA_DOWNSTREAM,
stream_changed_data_probe, (gpointer) select, NULL);
g_mutex_unlock (&group->stream_changed_pending_lock);
gst_message_unref (msg);
}
if (select->srcpad) {
GST_DEBUG_OBJECT (playbin, "unblocking %" GST_PTR_FORMAT,
select->srcpad);

View file

@ -253,68 +253,62 @@ gst_stream_synchronizer_sink_event (GstPad * pad, GstObject * parent,
GST_EVENT_TYPE_NAME (event), event);
switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_SINK_MESSAGE:{
GstMessage *message;
case GST_EVENT_STREAM_START:
{
GstStream *stream;
gst_event_parse_sink_message (event, &message);
if (gst_message_has_name (message, "playbin-stream-changed")) {
GstStream *stream;
GST_STREAM_SYNCHRONIZER_LOCK (self);
stream = gst_pad_get_element_private (pad);
if (stream) {
GList *l;
gboolean all_wait = TRUE;
GST_STREAM_SYNCHRONIZER_LOCK (self);
stream = gst_pad_get_element_private (pad);
if (stream) {
GList *l;
gboolean all_wait = TRUE;
GST_DEBUG_OBJECT (pad, "Stream %d changed", stream->stream_number);
GST_DEBUG_OBJECT (pad, "Stream %d changed", stream->stream_number);
stream->is_eos = FALSE;
stream->wait = TRUE;
stream->new_stream = TRUE;
stream->is_eos = FALSE;
stream->wait = TRUE;
stream->new_stream = TRUE;
for (l = self->streams; l; l = l->next) {
GstStream *ostream = l->data;
all_wait = all_wait && ostream->wait;
if (!all_wait)
break;
}
if (all_wait) {
gint64 position = 0;
GST_DEBUG_OBJECT (self, "All streams have changed -- unblocking");
for (l = self->streams; l; l = l->next) {
GstStream *ostream = l->data;
gint64 stop_running_time;
gint64 position_running_time;
all_wait = all_wait && ostream->wait;
if (!all_wait)
break;
ostream->wait = FALSE;
stop_running_time =
gst_segment_to_running_time (&ostream->segment,
GST_FORMAT_TIME, ostream->segment.stop);
position_running_time =
gst_segment_to_running_time (&ostream->segment,
GST_FORMAT_TIME, ostream->segment.position);
position =
MAX (position, MAX (stop_running_time, position_running_time));
}
if (all_wait) {
gint64 position = 0;
position = MAX (0, position);
self->group_start_time = MAX (self->group_start_time, position);
GST_DEBUG_OBJECT (self, "All streams have changed -- unblocking");
GST_DEBUG_OBJECT (self, "New group start time: %" GST_TIME_FORMAT,
GST_TIME_ARGS (self->group_start_time));
for (l = self->streams; l; l = l->next) {
GstStream *ostream = l->data;
gint64 stop_running_time;
gint64 position_running_time;
ostream->wait = FALSE;
stop_running_time =
gst_segment_to_running_time (&ostream->segment,
GST_FORMAT_TIME, ostream->segment.stop);
position_running_time =
gst_segment_to_running_time (&ostream->segment,
GST_FORMAT_TIME, ostream->segment.position);
position =
MAX (position, MAX (stop_running_time,
position_running_time));
}
position = MAX (0, position);
self->group_start_time = MAX (self->group_start_time, position);
GST_DEBUG_OBJECT (self, "New group start time: %" GST_TIME_FORMAT,
GST_TIME_ARGS (self->group_start_time));
g_cond_broadcast (self->stream_finish_cond);
}
g_cond_broadcast (self->stream_finish_cond);
}
GST_STREAM_SYNCHRONIZER_UNLOCK (self);
}
gst_message_unref (message);
break;
GST_STREAM_SYNCHRONIZER_UNLOCK (self);
}
break;
case GST_EVENT_SEGMENT:{
GstStream *stream;
GstSegment segment;