ext/ogg/gstoggdemux.c: Send EOS when deactivating.

Original commit message from CVS:
* ext/ogg/gstoggdemux.c: (gst_ogg_demux_deactivate_current_chain):
Send EOS when deactivating.
* gst/playback/gstplaybasebin.c: (gst_play_base_bin_init),
(check_queue), (queue_threshold_reached), (queue_out_of_data),
(gen_preroll_element), (probe_triggered), (mute_stream),
(silence_stream), (new_decoded_pad), (setup_substreams),
(set_active_source):
* gst/playback/gstplaybin.c: (gst_play_bin_get_property),
(remove_sinks), (add_sink):
* gst/playback/gststreaminfo.c: (cb_probe), (gst_stream_info_new):
Change for new probe API.
This commit is contained in:
Ronald S. Bultje 2005-06-29 15:46:00 +00:00
parent 85ce238308
commit 1ce6923abb
5 changed files with 140 additions and 135 deletions

View file

@ -1,3 +1,17 @@
2005-06-29 Ronald S. Bultje <rbultje@ronald.bitfreak.net>
* ext/ogg/gstoggdemux.c: (gst_ogg_demux_deactivate_current_chain):
Send EOS when deactivating.
* gst/playback/gstplaybasebin.c: (gst_play_base_bin_init),
(check_queue), (queue_threshold_reached), (queue_out_of_data),
(gen_preroll_element), (probe_triggered), (mute_stream),
(silence_stream), (new_decoded_pad), (setup_substreams),
(set_active_source):
* gst/playback/gstplaybin.c: (gst_play_bin_get_property),
(remove_sinks), (add_sink):
* gst/playback/gststreaminfo.c: (cb_probe), (gst_stream_info_new):
Change for new probe API.
2005-06-29 Wim Taymans <wim@fluendo.com>
* gst-libs/gst/audio/gstaudiosink.c: (gst_audioringbuffer_init):

View file

@ -1143,6 +1143,7 @@ gst_ogg_demux_deactivate_current_chain (GstOggDemux * ogg)
for (i = 0; i < chain->streams->len; i++) {
GstOggPad *pad = g_array_index (chain->streams, GstOggPad *, i);
gst_pad_push_event (GST_PAD (pad), gst_event_new (GST_EVENT_EOS));
gst_element_remove_pad (GST_ELEMENT (ogg), GST_PAD (pad));
}
/* if we cannot seek, we can destroy the chain completely */

View file

@ -69,7 +69,7 @@ const GList *gst_play_base_bin_get_streaminfo (GstPlayBaseBin * play_base_bin);
static gboolean prepare_output (GstPlayBaseBin * play_base_bin);
static void set_active_source (GstPlayBaseBin * play_base_bin,
GstStreamType type, gint source_num);
static gboolean probe_triggered (GstProbe * probe, GstMiniObject ** data,
static gboolean probe_triggered (GstPad * pad, GstEvent * event,
gpointer user_data);
static void setup_substreams (GstPlayBaseBin * play_base_bin);
@ -187,7 +187,7 @@ gst_play_base_bin_init (GstPlayBaseBin * play_base_bin)
play_base_bin->building_group = NULL;
play_base_bin->queued_groups = NULL;
play_base_bin->queue_size = DEFAULT_QUEUE_SIZE;
play_base_bin->queue_size = 0; //DEFAULT_QUEUE_SIZE;
play_base_bin->queue_threshold = DEFAULT_QUEUE_THRESHOLD;
}
@ -443,7 +443,7 @@ fill_buffer (GstPlayBaseBin * play_base_bin, gint percent)
}
static gboolean
check_queue (GstProbe * probe, GstMiniObject ** data, gpointer user_data)
check_queue (GstPad * pad, GstBuffer * data, gpointer user_data)
{
GstElement *queue = GST_ELEMENT (user_data);
GstPlayBaseBin *play_base_bin = g_object_get_data (G_OBJECT (queue), "pbb");
@ -478,26 +478,23 @@ queue_overrun (GstElement * element, GstPlayBaseBin * play_base_bin)
static void
queue_threshold_reached (GstElement * queue, GstPlayBaseBin * play_base_bin)
{
GstProbe *probe;
GST_DEBUG ("Running");
/* play */
g_object_set (queue, "min-threshold-time", (guint64) 0, NULL);
if ((probe = g_object_get_data (G_OBJECT (queue), "probe"))) {
if (g_object_get_data (G_OBJECT (queue), "probe")) {
GstPad *sinkpad;
sinkpad = gst_element_get_pad (queue, "sink");
GST_DEBUG_OBJECT (play_base_bin,
"Removing buffer probe %p from pad %s:%s (%p)",
probe, GST_DEBUG_PAD_NAME (sinkpad), sinkpad);
"Removing buffer probe from pad %s:%s (%p)",
GST_DEBUG_PAD_NAME (sinkpad), sinkpad);
fill_buffer (play_base_bin, 100);
g_object_set_data (G_OBJECT (queue), "probe", NULL);
gst_pad_remove_probe (sinkpad, probe);
gst_probe_destroy (probe);
gst_pad_remove_buffer_probe (sinkpad, G_CALLBACK (check_queue), queue);
g_object_unref (G_OBJECT (sinkpad));
}
@ -506,8 +503,6 @@ queue_threshold_reached (GstElement * queue, GstPlayBaseBin * play_base_bin)
static void
queue_out_of_data (GstElement * queue, GstPlayBaseBin * play_base_bin)
{
GstProbe *probe;
GST_DEBUG ("Underrun, re-caching");
/* On underrun, we want to temoprarily pause playback, set a "min-size"
@ -517,16 +512,15 @@ queue_out_of_data (GstElement * queue, GstPlayBaseBin * play_base_bin)
(guint64) play_base_bin->queue_threshold, NULL);
/* re-connect probe */
if (!(probe = g_object_get_data (G_OBJECT (queue), "probe"))) {
if (!g_object_get_data (G_OBJECT (queue), "probe")) {
GstPad *sinkpad;
probe = gst_probe_new (FALSE, check_queue, queue);
sinkpad = gst_element_get_pad (queue, "sink");
gst_pad_add_probe (sinkpad, probe);
g_object_set_data (G_OBJECT (queue), "probe", probe);
gst_pad_add_buffer_probe (sinkpad, G_CALLBACK (check_queue), queue);
g_object_set_data (G_OBJECT (queue), "probe", (gpointer) 0x1);
GST_DEBUG_OBJECT (play_base_bin,
"Re-attaching buffering probe %p to pad %s:%s (%p)",
probe, GST_DEBUG_PAD_NAME (sinkpad), sinkpad);
"Re-attaching buffering probe to pad %s:%s",
GST_DEBUG_PAD_NAME (sinkpad), sinkpad);
g_object_unref (G_OBJECT (sinkpad));
fill_buffer (play_base_bin, 0);
@ -551,7 +545,6 @@ gen_preroll_element (GstPlayBaseBin * play_base_bin,
const gchar *prename;
guint sig;
GstPad *preroll_pad;
GstProbe *probe;
if (type == GST_STREAM_TYPE_VIDEO)
prename = "video";
@ -588,7 +581,6 @@ gen_preroll_element (GstPlayBaseBin * play_base_bin,
group->type[GST_STREAM_TYPE_AUDIO - 1].npads == 0) ||
(type == GST_STREAM_TYPE_AUDIO &&
group->type[GST_STREAM_TYPE_VIDEO - 1].npads == 0))) {
GstProbe *probe;
GstPad *sinkpad;
g_signal_connect (G_OBJECT (preroll), "running",
@ -597,14 +589,13 @@ gen_preroll_element (GstPlayBaseBin * play_base_bin,
"min-threshold-time", (guint64) play_base_bin->queue_threshold, NULL);
/* give updates on queue size */
probe = gst_probe_new (FALSE, check_queue, preroll);
sinkpad = gst_element_get_pad (preroll, "sink");
gst_pad_add_probe (sinkpad, probe);
GST_DEBUG_OBJECT (play_base_bin, "Attaching probe %p to pad %s:%s (%p)",
probe, GST_DEBUG_PAD_NAME (sinkpad), sinkpad);
gst_pad_add_buffer_probe (sinkpad, G_CALLBACK (check_queue), preroll);
GST_DEBUG_OBJECT (play_base_bin, "Attaching probe to pad %s:%s (%p)",
GST_DEBUG_PAD_NAME (sinkpad), sinkpad);
g_object_unref (G_OBJECT (sinkpad));
g_object_set_data (G_OBJECT (preroll), "pbb", play_base_bin);
g_object_set_data (G_OBJECT (preroll), "probe", probe);
g_object_set_data (G_OBJECT (preroll), "probe", (gpointer) 0x1);
g_signal_connect (G_OBJECT (preroll), "underrun",
G_CALLBACK (queue_out_of_data), play_base_bin);
@ -615,10 +606,7 @@ gen_preroll_element (GstPlayBaseBin * play_base_bin,
/* listen for EOS */
preroll_pad = gst_element_get_pad (preroll, "src");
probe = gst_probe_new (FALSE, probe_triggered, info);
/* have to REALIZE the pad as we cannot attach a padprobe to a ghostpad */
gst_pad_add_probe (preroll_pad, probe);
gst_object_unref (preroll_pad);
gst_pad_add_event_probe (preroll_pad, G_CALLBACK (probe_triggered), info);
/* add to group list */
/* FIXME refcount elements */
@ -760,7 +748,7 @@ no_more_pads (GstElement * element, GstPlayBaseBin * play_base_bin)
}
static gboolean
probe_triggered (GstProbe * probe, GstMiniObject ** data, gpointer user_data)
probe_triggered (GstPad * pad, GstEvent * event, gpointer user_data)
{
GstPlayBaseGroup *group;
GstPlayBaseBin *play_base_bin;
@ -769,73 +757,70 @@ probe_triggered (GstProbe * probe, GstMiniObject ** data, gpointer user_data)
group = (GstPlayBaseGroup *) g_object_get_data (G_OBJECT (info), "group");
play_base_bin = group->bin;
if (GST_IS_EVENT (*data)) {
GstEvent *event = GST_EVENT (*data);
if (GST_EVENT_TYPE (event) == GST_EVENT_EOS) {
gint num_groups = 0;
gboolean have_left;
if (GST_EVENT_TYPE (event) == GST_EVENT_EOS) {
gint num_groups = 0;
gboolean have_left;
GST_DEBUG ("probe got EOS in group %p", group);
GST_DEBUG ("probe got EOS in group %p", group);
GROUP_LOCK (play_base_bin);
GROUP_LOCK (play_base_bin);
/* mute this stream */
//g_object_set (G_OBJECT (info), "mute", TRUE, NULL);
if (info->type > 0 && info->type <= NUM_TYPES)
group->type[info->type - 1].done = TRUE;
/* mute this stream */
//g_object_set (G_OBJECT (info), "mute", TRUE, NULL);
if (info->type > 0 && info->type <= NUM_TYPES)
group->type[info->type - 1].done = TRUE;
/* see if we have some more groups left to play */
num_groups = g_list_length (play_base_bin->queued_groups);
if (play_base_bin->building_group)
num_groups++;
have_left = (num_groups > 1);
/* see if we have some more groups left to play */
num_groups = g_list_length (play_base_bin->queued_groups);
if (play_base_bin->building_group)
num_groups++;
have_left = (num_groups > 1);
/* see if the complete group is muted */
if (!group_is_muted (group)) {
/* group is not completely muted, we remove the EOS event
* and continue, eventually the other streams will be EOSed and
* we can switch out this group. */
GST_DEBUG ("group %p not completely muted", group);
/* see if the complete group is muted */
if (!group_is_muted (group)) {
/* group is not completely muted, we remove the EOS event
* and continue, eventually the other streams will be EOSed and
* we can switch out this group. */
GST_DEBUG ("group %p not completely muted", group);
GROUP_UNLOCK (play_base_bin);
GROUP_UNLOCK (play_base_bin);
/* remove the EOS if we have something left */
return !have_left;
}
/* remove the EOS if we have something left */
return !have_left;
if (have_left) {
/* ok, get rid of the current group then */
//group_destroy (group);
/* removing the current group brings the next group
* active */
play_base_bin->queued_groups =
g_list_remove (play_base_bin->queued_groups, group);
/* and wait for the next one to be ready */
while (!play_base_bin->queued_groups) {
GROUP_WAIT (play_base_bin);
}
group = play_base_bin->queued_groups->data;
if (have_left) {
/* ok, get rid of the current group then */
group_destroy (group);
/* removing the current group brings the next group
* active */
play_base_bin->queued_groups =
g_list_remove (play_base_bin->queued_groups, group);
/* and wait for the next one to be ready */
while (!play_base_bin->queued_groups) {
GROUP_WAIT (play_base_bin);
}
/* now activate the next one */
setup_substreams (play_base_bin);
GST_DEBUG ("switching to next group %p - emitting signal", group);
/* and signal the new group */
GST_PLAY_BASE_BIN_GET_CLASS (play_base_bin)->
setup_output_pads (play_base_bin, group);
/* now activate the next one */
setup_substreams (play_base_bin);
GST_DEBUG ("switching to next group %p - emitting signal",
play_base_bin->queued_groups->data);
/* and signal the new group */
GST_PLAY_BASE_BIN_GET_CLASS (play_base_bin)->
setup_output_pads (play_base_bin, group);
GROUP_UNLOCK (play_base_bin);
GROUP_UNLOCK (play_base_bin);
g_object_notify (G_OBJECT (play_base_bin), "stream-info");
g_object_notify (G_OBJECT (play_base_bin), "streaminfo");
/* get rid of the EOS event */
return FALSE;
} else {
GROUP_UNLOCK (play_base_bin);
GST_LOG ("Last group done, EOS");
}
/* get rid of the EOS event */
return FALSE;
} else {
GROUP_UNLOCK (play_base_bin);
GST_LOG ("Last group done, EOS");
}
}
return TRUE;
}
@ -877,15 +862,13 @@ preroll_unlinked (GstPad * pad, GstPad * peerpad,
/* Mute stream on first data - for header-is-in-stream-stuff
* (vorbis, ogmtext). */
static gboolean
mute_stream (GstProbe * probe, GstMiniObject ** d, gpointer data)
mute_stream (GstPad * pad, GstBuffer * buf, gpointer data)
{
GstStreamInfo *info = GST_STREAM_INFO (data);
if (GST_IS_BUFFER (*d)) {
g_object_set (G_OBJECT (info), "mute", TRUE, NULL);
gst_pad_remove_probe (GST_PAD_CAST (info->object), probe);
gst_probe_destroy (probe);
}
g_object_set (G_OBJECT (info), "mute", TRUE, NULL);
gst_pad_remove_buffer_probe (GST_PAD_CAST (info->object),
G_CALLBACK (mute_stream), data);
/* no data */
return FALSE;
@ -893,7 +876,7 @@ mute_stream (GstProbe * probe, GstMiniObject ** d, gpointer data)
/* Eat data. */
static gboolean
silence_stream (GstProbe * probe, GstMiniObject ** d, gpointer data)
silence_stream (GstPad * pad, GstMiniObject * data, gpointer user_data)
{
/* no data */
return FALSE;
@ -913,7 +896,6 @@ new_decoded_pad (GstElement * element, GstPad * pad, gboolean last,
GstStreamType type;
GstPad *sinkpad;
GstPlayBaseGroup *group;
GstProbe *probe;
guint sig;
GstObject *parent;
@ -973,9 +955,9 @@ new_decoded_pad (GstElement * element, GstPad * pad, gboolean last,
/* select 1st for now - we'll select a preferred one after preroll */
if (type == GST_STREAM_TYPE_UNKNOWN || group->type[type - 1].npads > 0) {
probe = gst_probe_new (FALSE, silence_stream, info);
gst_pad_add_probe (GST_PAD_CAST (pad), probe);
g_object_set_data (G_OBJECT (pad), "eat_probe", probe);
gst_pad_add_data_probe (GST_PAD_CAST (pad),
G_CALLBACK (silence_stream), info);
g_object_set_data (G_OBJECT (pad), "eat_probe", (gpointer) 0x1);
}
add_stream (group, info);
@ -1065,7 +1047,6 @@ static void
setup_substreams (GstPlayBaseBin * play_base_bin)
{
GstPlayBaseGroup *group;
GstProbe *probe;
gint n;
const GList *item;
@ -1074,18 +1055,16 @@ setup_substreams (GstPlayBaseBin * play_base_bin)
for (item = group->streaminfo; item; item = item->next) {
GstStreamInfo *info = item->data;
probe = g_object_get_data (G_OBJECT (info->object), "eat_probe");
if (probe) {
gst_pad_remove_probe (GST_PAD_CAST (info->object), probe);
gst_probe_destroy (probe);
if (g_object_get_data (G_OBJECT (info->object), "eat_probe")) {
gst_pad_remove_data_probe (GST_PAD_CAST (info->object),
G_CALLBACK (silence_stream), info);
g_object_set_data (G_OBJECT (info->object), "eat_probe", NULL);
}
/* now remove unknown pads */
if (info->type == GST_STREAM_TYPE_UNKNOWN) {
GstProbe *probe;
probe = gst_probe_new (FALSE, mute_stream, info);
gst_pad_add_probe (GST_PAD_CAST (info->object), probe);
gst_pad_add_buffer_probe (GST_PAD_CAST (info->object),
G_CALLBACK (mute_stream), info);
}
}
@ -1501,10 +1480,8 @@ set_active_source (GstPlayBaseBin * play_base_bin,
g_object_set (s->data, "mute", FALSE, NULL);
have_active = TRUE;
} else {
GstProbe *probe;
probe = gst_probe_new (FALSE, mute_stream, info);
gst_pad_add_probe (GST_PAD_CAST (info->object), probe);
gst_pad_add_buffer_probe (GST_PAD_CAST (info->object),
G_CALLBACK (mute_stream), info);
}
num++;
}

View file

@ -332,7 +332,7 @@ gst_play_bin_get_property (GObject * object, guint prop_id, GValue * value,
g_value_set_double (value, play_bin->volume);
break;
case ARG_FRAME:
g_value_set_boxed (value, play_bin->frame);
gst_value_set_mini_object (value, GST_MINI_OBJECT (play_bin->frame));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@ -630,6 +630,7 @@ remove_sinks (GstPlayBin * play_bin)
GList *sinks;
GstObject *parent;
GstElement *element;
GstPad *pad, *peer;
GST_DEBUG ("removesinks");
element = g_hash_table_lookup (play_bin->cache, "abin");
@ -643,6 +644,15 @@ remove_sinks (GstPlayBin * play_bin)
gst_bin_remove (GST_BIN (parent), element);
gst_object_unref (parent);
}
pad = gst_element_get_pad (element, "sink");
if (pad != NULL) {
peer = gst_pad_get_peer (pad);
if (peer != NULL) {
gst_pad_unlink (peer, pad);
gst_object_unref (peer);
}
gst_object_unref (pad);
}
}
element = g_hash_table_lookup (play_bin->cache, "vbin");
if (element != NULL) {
@ -652,6 +662,15 @@ remove_sinks (GstPlayBin * play_bin)
gst_bin_remove (GST_BIN (parent), element);
gst_object_unref (parent);
}
pad = gst_element_get_pad (element, "sink");
if (pad != NULL) {
peer = gst_pad_get_peer (pad);
if (peer != NULL) {
gst_pad_unlink (peer, pad);
gst_object_unref (peer);
}
gst_object_unref (pad);
}
}
for (sinks = play_bin->sinks; sinks; sinks = g_list_next (sinks)) {
@ -717,7 +736,7 @@ add_sink (GstPlayBin * play_bin, GstElement * sink, GstPad * srcpad)
/* could not link this stream */
capsstr = gst_caps_to_string (gst_pad_get_caps (srcpad));
g_warning ("could not link %s", capsstr);
g_warning ("could not link %s: %d", capsstr, res);
g_free (capsstr);
gst_bin_remove (GST_BIN (play_bin), sink);

View file

@ -173,34 +173,30 @@ gst_stream_info_init (GstStreamInfo * stream_info)
}
static gboolean
cb_probe (GstProbe * probe, GstMiniObject ** data, gpointer user_data)
cb_probe (GstPad * pad, GstEvent * e, gpointer user_data)
{
GstStreamInfo *info = user_data;
if (GST_IS_EVENT (*data)) {
GstEvent *e = GST_EVENT (*data);
if (GST_EVENT_TYPE (e) == GST_EVENT_TAG) {
gchar *codec; //, *lang;
GstTagList *list = gst_event_tag_get_list (e);
if (GST_EVENT_TYPE (e) == GST_EVENT_TAG) {
gchar *codec; //, *lang;
GstTagList *list = gst_event_tag_get_list (e);
if (gst_tag_list_get_string (list, GST_TAG_VIDEO_CODEC, &codec)) {
g_free (info->codec);
info->codec = codec;
g_object_notify (G_OBJECT (info), "codec");
} else if (gst_tag_list_get_string (list, GST_TAG_AUDIO_CODEC, &codec)) {
g_free (info->codec);
info->codec = codec;
g_object_notify (G_OBJECT (info), "codec");
}
#if 0
if (gst_tag_list_get_string (list, GST_TAG_LANGUAGE_CODE, &lang)) {
g_free (info->langcode);
info->langcode = lang;
g_object_notify (G_OBJECT (info), "language-code");
}
#endif
if (gst_tag_list_get_string (list, GST_TAG_VIDEO_CODEC, &codec)) {
g_free (info->codec);
info->codec = codec;
g_object_notify (G_OBJECT (info), "codec");
} else if (gst_tag_list_get_string (list, GST_TAG_AUDIO_CODEC, &codec)) {
g_free (info->codec);
info->codec = codec;
g_object_notify (G_OBJECT (info), "codec");
}
#if 0
if (gst_tag_list_get_string (list, GST_TAG_LANGUAGE_CODE, &lang)) {
g_free (info->langcode);
info->langcode = lang;
g_object_notify (G_OBJECT (info), "language-code");
}
#endif
}
return TRUE;
@ -216,10 +212,8 @@ gst_stream_info_new (GstObject * object,
gst_object_ref (object);
if (GST_IS_PAD (object)) {
GstProbe *probe;
probe = gst_probe_new (FALSE, cb_probe, info);
gst_pad_add_probe (GST_PAD_CAST (object), probe);
gst_pad_add_event_probe (GST_PAD_CAST (object),
G_CALLBACK (cb_probe), info);
}
info->object = object;
info->type = type;