mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-02 21:48:55 +00:00
gst/playback/: Updated README.
Original commit message from CVS: * gst/playback/README: * gst/playback/gstplaybasebin.c: (group_destroy), (group_is_muted), (add_stream), (unknown_type), (add_element_stream), (no_more_pads), (probe_triggered), (preroll_unlinked), (new_decoded_pad), (gst_play_base_bin_change_state), (gst_play_base_bin_found_tag): * gst/playback/gstplaybin.c: (gen_vis_element), (remove_sinks), (setup_sinks): * gst/playback/gststreaminfo.c: (gst_stream_info_set_mute), (gst_stream_info_is_mute), (gst_stream_info_set_property): * gst/playback/gststreaminfo.h: Updated README. Only switch groups if all streams have muted (EOSed). Send Tags in sync with the stream playback instead of in the playback/preroll phase. Some cleanups, free the fakesrc elements.
This commit is contained in:
parent
1eaa518961
commit
b398d11af9
6 changed files with 177 additions and 61 deletions
18
ChangeLog
18
ChangeLog
|
@ -1,3 +1,21 @@
|
||||||
|
2004-11-09 Wim Taymans <wim@fluendo.com>
|
||||||
|
|
||||||
|
* gst/playback/README:
|
||||||
|
* gst/playback/gstplaybasebin.c: (group_destroy), (group_is_muted),
|
||||||
|
(add_stream), (unknown_type), (add_element_stream), (no_more_pads),
|
||||||
|
(probe_triggered), (preroll_unlinked), (new_decoded_pad),
|
||||||
|
(gst_play_base_bin_change_state), (gst_play_base_bin_found_tag):
|
||||||
|
* gst/playback/gstplaybin.c: (gen_vis_element), (remove_sinks),
|
||||||
|
(setup_sinks):
|
||||||
|
* gst/playback/gststreaminfo.c: (gst_stream_info_set_mute),
|
||||||
|
(gst_stream_info_is_mute), (gst_stream_info_set_property):
|
||||||
|
* gst/playback/gststreaminfo.h:
|
||||||
|
Updated README.
|
||||||
|
Only switch groups if all streams have muted (EOSed).
|
||||||
|
Send Tags in sync with the stream playback instead of in
|
||||||
|
the playback/preroll phase.
|
||||||
|
Some cleanups, free the fakesrc elements.
|
||||||
|
|
||||||
2004-11-09 Benjamin Otte <in7y118@public.uni-hamburg.de>
|
2004-11-09 Benjamin Otte <in7y118@public.uni-hamburg.de>
|
||||||
|
|
||||||
* ext/alsa/gstalsa.c: (gst_alsa_get_caps_internal):
|
* ext/alsa/gstalsa.c: (gst_alsa_get_caps_internal):
|
||||||
|
|
|
@ -43,7 +43,6 @@ baseplaybin:
|
||||||
- reuse, cleanup in ready state
|
- reuse, cleanup in ready state
|
||||||
- when the first pad is closed, it's possible that another dynamic element is
|
- when the first pad is closed, it's possible that another dynamic element is
|
||||||
added somewhere so that we need a queue for the first pad as well.
|
added somewhere so that we need a queue for the first pad as well.
|
||||||
- make sure we get EOS on all pads in a group before commiting the next group.
|
|
||||||
|
|
||||||
playbin:
|
playbin:
|
||||||
|
|
||||||
|
@ -59,7 +58,6 @@ playbin:
|
||||||
- be smarter about replugging the sinks instead of removing them and readding them.
|
- be smarter about replugging the sinks instead of removing them and readding them.
|
||||||
- Do not crap out when the audio device is in use.
|
- Do not crap out when the audio device is in use.
|
||||||
|
|
||||||
|
|
||||||
general
|
general
|
||||||
|
|
||||||
TODO
|
TODO
|
||||||
|
|
|
@ -262,6 +262,7 @@ group_destroy (GstPlayBaseGroup * group)
|
||||||
GstElement *element = GST_ELEMENT (prerolls->data);
|
GstElement *element = GST_ELEMENT (prerolls->data);
|
||||||
GstPad *pad;
|
GstPad *pad;
|
||||||
guint sig_id;
|
guint sig_id;
|
||||||
|
GstElement *fakesrc;
|
||||||
|
|
||||||
/* have to unlink the unlink handler first because else we
|
/* have to unlink the unlink handler first because else we
|
||||||
* are going to link an element in the finalize handler */
|
* are going to link an element in the finalize handler */
|
||||||
|
@ -275,10 +276,20 @@ group_destroy (GstPlayBaseGroup * group)
|
||||||
g_object_set_data (G_OBJECT (pad), "unlinked_id", GINT_TO_POINTER (0));
|
g_object_set_data (G_OBJECT (pad), "unlinked_id", GINT_TO_POINTER (0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* remove any fakesrc elements for this preroll element */
|
||||||
|
fakesrc = (GstElement *) g_object_get_data (G_OBJECT (element), "fakesrc");
|
||||||
|
if (fakesrc != NULL) {
|
||||||
|
GST_LOG ("removing fakesrc");
|
||||||
|
gst_bin_remove (GST_BIN (play_base_bin->thread), fakesrc);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if the group is currently being played, we have to remove the element
|
||||||
|
* from the thread */
|
||||||
if (get_active_group (play_base_bin) == group) {
|
if (get_active_group (play_base_bin) == group) {
|
||||||
GST_LOG ("removing preroll element %s", gst_element_get_name (element));
|
GST_LOG ("removing preroll element %s", gst_element_get_name (element));
|
||||||
gst_bin_remove (GST_BIN (play_base_bin->thread), element);
|
gst_bin_remove (GST_BIN (play_base_bin->thread), element);
|
||||||
} else {
|
} else {
|
||||||
|
/* else we can just unref it */
|
||||||
gst_object_unref (GST_OBJECT (element));
|
gst_object_unref (GST_OBJECT (element));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -336,6 +347,22 @@ group_commit (GstPlayBaseBin * play_base_bin)
|
||||||
g_mutex_unlock (play_base_bin->group_lock);
|
g_mutex_unlock (play_base_bin->group_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* check if there are streams in the group that are not muted */
|
||||||
|
static gboolean
|
||||||
|
group_is_muted (GstPlayBaseGroup * group)
|
||||||
|
{
|
||||||
|
GList *infos;
|
||||||
|
|
||||||
|
for (infos = group->streaminfo; infos; infos = g_list_next (infos)) {
|
||||||
|
GstStreamInfo *info = GST_STREAM_INFO (infos->data);
|
||||||
|
|
||||||
|
/* if we find a non muded group we can return FALSE */
|
||||||
|
if (!info->mute)
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
/* this signal will be fired when one of the queues with raw
|
/* this signal will be fired when one of the queues with raw
|
||||||
* data is filled. This means that the group building stage is over
|
* data is filled. This means that the group building stage is over
|
||||||
* and playback of the new queued group should start */
|
* and playback of the new queued group should start */
|
||||||
|
@ -400,11 +427,13 @@ remove_groups (GstPlayBaseBin * play_base_bin)
|
||||||
/* Add/remove a single stream to current building group.
|
/* Add/remove a single stream to current building group.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
add_stream (GstPlayBaseBin * play_base_bin, GstStreamInfo * info)
|
add_stream (GstPlayBaseGroup * group, GstStreamInfo * info)
|
||||||
{
|
{
|
||||||
GstPlayBaseGroup *group = get_building_group (play_base_bin);
|
GST_DEBUG ("add stream to group %p", group);
|
||||||
|
|
||||||
|
/* keep ref to the group */
|
||||||
|
g_object_set_data (G_OBJECT (info), "group", group);
|
||||||
|
|
||||||
GST_DEBUG ("add stream to building group %p", group);
|
|
||||||
group->streaminfo = g_list_append (group->streaminfo, info);
|
group->streaminfo = g_list_append (group->streaminfo, info);
|
||||||
switch (info->type) {
|
switch (info->type) {
|
||||||
case GST_STREAM_TYPE_AUDIO:
|
case GST_STREAM_TYPE_AUDIO:
|
||||||
|
@ -428,6 +457,7 @@ unknown_type (GstElement * element, GstPad * pad, GstCaps * caps,
|
||||||
{
|
{
|
||||||
gchar *capsstr;
|
gchar *capsstr;
|
||||||
GstStreamInfo *info;
|
GstStreamInfo *info;
|
||||||
|
GstPlayBaseGroup *group = get_building_group (play_base_bin);
|
||||||
|
|
||||||
capsstr = gst_caps_to_string (caps);
|
capsstr = gst_caps_to_string (caps);
|
||||||
g_warning ("don't know how to handle %s", capsstr);
|
g_warning ("don't know how to handle %s", capsstr);
|
||||||
|
@ -436,7 +466,7 @@ unknown_type (GstElement * element, GstPad * pad, GstCaps * caps,
|
||||||
info = gst_stream_info_new (GST_OBJECT (pad), GST_STREAM_TYPE_UNKNOWN,
|
info = gst_stream_info_new (GST_OBJECT (pad), GST_STREAM_TYPE_UNKNOWN,
|
||||||
NULL, caps);
|
NULL, caps);
|
||||||
info->origin = GST_OBJECT (pad);
|
info->origin = GST_OBJECT (pad);
|
||||||
add_stream (play_base_bin, info);
|
add_stream (group, info);
|
||||||
|
|
||||||
g_free (capsstr);
|
g_free (capsstr);
|
||||||
}
|
}
|
||||||
|
@ -450,13 +480,14 @@ static void
|
||||||
add_element_stream (GstElement * element, GstPlayBaseBin * play_base_bin)
|
add_element_stream (GstElement * element, GstPlayBaseBin * play_base_bin)
|
||||||
{
|
{
|
||||||
GstStreamInfo *info;
|
GstStreamInfo *info;
|
||||||
|
GstPlayBaseGroup *group = get_building_group (play_base_bin);
|
||||||
|
|
||||||
/* add the stream to the list */
|
/* add the stream to the list */
|
||||||
info =
|
info =
|
||||||
gst_stream_info_new (GST_OBJECT (element), GST_STREAM_TYPE_ELEMENT,
|
gst_stream_info_new (GST_OBJECT (element), GST_STREAM_TYPE_ELEMENT,
|
||||||
NULL, NULL);
|
NULL, NULL);
|
||||||
info->origin = GST_OBJECT (element);
|
info->origin = GST_OBJECT (element);
|
||||||
add_stream (play_base_bin, info);
|
add_stream (group, info);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* when the decoder element signals that no more pads will be generated, we
|
/* when the decoder element signals that no more pads will be generated, we
|
||||||
|
@ -467,31 +498,45 @@ no_more_pads (GstElement * element, GstPlayBaseBin * play_base_bin)
|
||||||
{
|
{
|
||||||
/* setup phase */
|
/* setup phase */
|
||||||
GST_DEBUG ("no more pads");
|
GST_DEBUG ("no more pads");
|
||||||
|
/* we can commit this group for playback now */
|
||||||
group_commit (play_base_bin);
|
group_commit (play_base_bin);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
probe_triggered (GstProbe * probe, GstData ** data, gpointer user_data)
|
probe_triggered (GstProbe * probe, GstData ** data, gpointer user_data)
|
||||||
{
|
{
|
||||||
GstPlayBaseGroup *group = (GstPlayBaseGroup *) user_data;
|
GstPlayBaseGroup *group;
|
||||||
GstPlayBaseBin *play_base_bin = group->bin;
|
GstPlayBaseBin *play_base_bin;
|
||||||
|
GstStreamInfo *info = GST_STREAM_INFO (user_data);
|
||||||
|
|
||||||
|
group = (GstPlayBaseGroup *) g_object_get_data (G_OBJECT (info), "group");
|
||||||
|
play_base_bin = group->bin;
|
||||||
|
|
||||||
if (GST_IS_EVENT (*data)) {
|
if (GST_IS_EVENT (*data)) {
|
||||||
GstEvent *event = GST_EVENT (*data);
|
GstEvent *event = GST_EVENT (*data);
|
||||||
|
|
||||||
if (GST_EVENT_TYPE (event) == GST_EVENT_EOS) {
|
if (GST_EVENT_TYPE (event) == GST_EVENT_EOS) {
|
||||||
gint queued;
|
gboolean have_left;
|
||||||
|
|
||||||
GST_DEBUG ("probe got EOS in group %p", group);
|
GST_DEBUG ("probe got EOS in group %p", group);
|
||||||
|
|
||||||
/* FIXME there might be more streams in this group that need
|
/* mute this stream */
|
||||||
* to go to EOS before we can switch to the next group. So
|
g_object_set (G_OBJECT (info), "mute", TRUE, NULL);
|
||||||
* here we should mark the stream as EOSed and decide if all
|
|
||||||
* streams have EOSed before continuing. */
|
|
||||||
|
|
||||||
/* see if we have some more groups left to play */
|
/* see if we have some more groups left to play */
|
||||||
queued = g_list_length (play_base_bin->queued_groups);
|
have_left = (g_list_length (play_base_bin->queued_groups) > 1);
|
||||||
if (queued > 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);
|
||||||
|
/* remove the EOS if we have something left */
|
||||||
|
return !have_left;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (have_left) {
|
||||||
gst_element_set_state (play_base_bin->thread, GST_STATE_PAUSED);
|
gst_element_set_state (play_base_bin->thread, GST_STATE_PAUSED);
|
||||||
/* ok, get rid of the current group then */
|
/* ok, get rid of the current group then */
|
||||||
group_destroy (group);
|
group_destroy (group);
|
||||||
|
@ -512,6 +557,27 @@ probe_triggered (GstProbe * probe, GstData ** data, gpointer user_data)
|
||||||
/* get rid of the EOS event */
|
/* get rid of the EOS event */
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
} else if (GST_EVENT_TYPE (event) == GST_EVENT_TAG) {
|
||||||
|
GstTagList *taglist;
|
||||||
|
GstObject *source;
|
||||||
|
|
||||||
|
/* ref some to be sure.. */
|
||||||
|
gst_event_ref (event);
|
||||||
|
gst_object_ref (GST_OBJECT (play_base_bin));
|
||||||
|
taglist = gst_event_tag_get_list (event);
|
||||||
|
/* now try to find the source of this tag */
|
||||||
|
source = event->src;
|
||||||
|
if (source == NULL || !GST_IS_ELEMENT (source)) {
|
||||||
|
/* no source, just use playbasebin then. This happens almost
|
||||||
|
* all the time, it seems the source is never filled in... */
|
||||||
|
source = GST_OBJECT (play_base_bin);
|
||||||
|
}
|
||||||
|
/* emit the signal now */
|
||||||
|
g_signal_emit_by_name (G_OBJECT (play_base_bin),
|
||||||
|
"found-tag", source, taglist);
|
||||||
|
/* and unref */
|
||||||
|
gst_object_unref (GST_OBJECT (play_base_bin));
|
||||||
|
gst_event_unref (event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -525,9 +591,10 @@ static void
|
||||||
preroll_unlinked (GstPad * pad, GstPad * peerpad,
|
preroll_unlinked (GstPad * pad, GstPad * peerpad,
|
||||||
GstPlayBaseBin * play_base_bin)
|
GstPlayBaseBin * play_base_bin)
|
||||||
{
|
{
|
||||||
GstElement *fakesrc;
|
GstElement *fakesrc, *queue;
|
||||||
guint sig_id;
|
guint sig_id;
|
||||||
|
|
||||||
|
/* make a fakesrc that will just emit one EOS */
|
||||||
fakesrc = gst_element_factory_make ("fakesrc", NULL);
|
fakesrc = gst_element_factory_make ("fakesrc", NULL);
|
||||||
g_object_set (G_OBJECT (fakesrc), "num_buffers", 0, NULL);
|
g_object_set (G_OBJECT (fakesrc), "num_buffers", 0, NULL);
|
||||||
|
|
||||||
|
@ -536,8 +603,13 @@ preroll_unlinked (GstPad * pad, GstPad * peerpad,
|
||||||
gst_pad_link (gst_element_get_pad (fakesrc, "src"), pad);
|
gst_pad_link (gst_element_get_pad (fakesrc, "src"), pad);
|
||||||
gst_bin_add (GST_BIN (play_base_bin->thread), fakesrc);
|
gst_bin_add (GST_BIN (play_base_bin->thread), fakesrc);
|
||||||
|
|
||||||
sig_id = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (pad), "unlinked_id"));
|
/* keep track of these patch elements */
|
||||||
|
queue = GST_ELEMENT (gst_object_get_parent (GST_OBJECT (pad)));
|
||||||
|
g_object_set_data (G_OBJECT (queue), "fakesrc", fakesrc);
|
||||||
|
|
||||||
|
/* now unlink the unlinked signal so that it is not called again when
|
||||||
|
* we destroy the queue */
|
||||||
|
sig_id = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (pad), "unlinked_id"));
|
||||||
if (sig_id != 0) {
|
if (sig_id != 0) {
|
||||||
g_signal_handler_disconnect (G_OBJECT (pad), sig_id);
|
g_signal_handler_disconnect (G_OBJECT (pad), sig_id);
|
||||||
g_object_set_data (G_OBJECT (pad), "unlinked_id", GINT_TO_POINTER (0));
|
g_object_set_data (G_OBJECT (pad), "unlinked_id", GINT_TO_POINTER (0));
|
||||||
|
@ -627,15 +699,15 @@ new_decoded_pad (GstElement * element, GstPad * pad, gboolean last,
|
||||||
|
|
||||||
gst_element_set_state (new_element, GST_STATE_PAUSED);
|
gst_element_set_state (new_element, GST_STATE_PAUSED);
|
||||||
}
|
}
|
||||||
/* install a probe so that we know when this group has ended */
|
|
||||||
probe = gst_probe_new (FALSE, probe_triggered, group);
|
|
||||||
|
|
||||||
gst_pad_add_probe (GST_PAD_REALIZE (srcpad), probe);
|
|
||||||
|
|
||||||
/* add the stream to the list */
|
/* add the stream to the list */
|
||||||
info = gst_stream_info_new (GST_OBJECT (srcpad), type, NULL, caps);
|
info = gst_stream_info_new (GST_OBJECT (srcpad), type, NULL, caps);
|
||||||
info->origin = GST_OBJECT (pad);
|
info->origin = GST_OBJECT (pad);
|
||||||
add_stream (play_base_bin, info);
|
add_stream (group, info);
|
||||||
|
|
||||||
|
/* install a probe so that we know when this group has ended */
|
||||||
|
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 (GST_PAD_REALIZE (srcpad), probe);
|
||||||
|
|
||||||
/* signal the no more pads after adding the stream */
|
/* signal the no more pads after adding the stream */
|
||||||
if (last)
|
if (last)
|
||||||
|
@ -1181,27 +1253,38 @@ gst_play_base_bin_error (GstElement * element,
|
||||||
gst_object_unref (parent);
|
gst_object_unref (parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* this code does not do anything usefull as it catches the tags
|
||||||
|
* in the preroll and playback stage so that it is very difficult
|
||||||
|
* to link them to the actual playback point.
|
||||||
|
*
|
||||||
|
* An alternative codepath can be found in the probe_triggered function
|
||||||
|
* where the tag is signaled when it is found inside the stream. The
|
||||||
|
* drawback is that we don't know the source anymore at that point because
|
||||||
|
* the event->src field appears to be left empty most of the time...
|
||||||
|
*/
|
||||||
static void
|
static void
|
||||||
gst_play_base_bin_found_tag (GstElement * element,
|
gst_play_base_bin_found_tag (GstElement * element,
|
||||||
GstElement * _source, const GstTagList * taglist, gpointer data)
|
GstElement * _source, const GstTagList * taglist, gpointer data)
|
||||||
{
|
{
|
||||||
GstObject *source, *parent;
|
GstObject *source;
|
||||||
|
GstPlayBaseBin *play_base_bin;
|
||||||
|
|
||||||
source = GST_OBJECT (_source);
|
source = GST_OBJECT (_source);
|
||||||
parent = GST_OBJECT (data);
|
play_base_bin = GST_PLAY_BASE_BIN (data);
|
||||||
|
|
||||||
/* tell ourselves */
|
/* tell ourselves */
|
||||||
gst_object_ref (source);
|
gst_object_ref (source);
|
||||||
gst_object_ref (parent);
|
gst_object_ref (GST_OBJECT (play_base_bin));
|
||||||
GST_DEBUG ("forwarding taglist %p from %s to %s", taglist,
|
GST_DEBUG ("forwarding taglist %p from %s to %s", taglist,
|
||||||
GST_ELEMENT_NAME (source), GST_OBJECT_NAME (parent));
|
GST_ELEMENT_NAME (source), GST_OBJECT_NAME (play_base_bin));
|
||||||
|
|
||||||
g_signal_emit_by_name (G_OBJECT (parent), "found-tag", source, taglist);
|
/* this would signal completely out-of-band */
|
||||||
|
//g_signal_emit_by_name (G_OBJECT (play_base_bin), "found-tag", source, taglist);
|
||||||
|
|
||||||
GST_DEBUG ("forwarded taglist %p from %s to %s", taglist,
|
GST_DEBUG ("forwarded taglist %p from %s to %s", taglist,
|
||||||
GST_ELEMENT_NAME (source), GST_OBJECT_NAME (parent));
|
GST_ELEMENT_NAME (source), GST_OBJECT_NAME (play_base_bin));
|
||||||
gst_object_unref (source);
|
gst_object_unref (source);
|
||||||
gst_object_unref (parent);
|
gst_object_unref (GST_OBJECT (play_base_bin));
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
|
|
|
@ -491,8 +491,6 @@ gen_vis_element (GstPlayBin * play_bin)
|
||||||
gst_element_add_ghost_pad (element,
|
gst_element_add_ghost_pad (element,
|
||||||
gst_element_get_pad (tee, "sink"), "sink");
|
gst_element_get_pad (tee, "sink"), "sink");
|
||||||
|
|
||||||
//gst_element_set_state (element, GST_STATE_READY);
|
|
||||||
|
|
||||||
return element;
|
return element;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -231,12 +231,36 @@ stream_info_mute_pad (GstStreamInfo * stream_info, GstPad * pad, gboolean mute)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
gst_stream_info_set_mute (GstStreamInfo * stream_info, gboolean mute)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (GST_IS_STREAM_INFO (stream_info), FALSE);
|
||||||
|
|
||||||
|
if (stream_info->type == GST_STREAM_TYPE_ELEMENT) {
|
||||||
|
g_warning ("cannot mute element stream");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mute != stream_info->mute) {
|
||||||
|
stream_info->mute = mute;
|
||||||
|
stream_info_mute_pad (stream_info, GST_PAD (stream_info->object), mute);
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
gst_stream_info_is_mute (GstStreamInfo * stream_info)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (GST_IS_STREAM_INFO (stream_info), TRUE);
|
||||||
|
|
||||||
|
return stream_info->mute;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_stream_info_set_property (GObject * object, guint prop_id,
|
gst_stream_info_set_property (GObject * object, guint prop_id,
|
||||||
const GValue * value, GParamSpec * pspec)
|
const GValue * value, GParamSpec * pspec)
|
||||||
{
|
{
|
||||||
GstStreamInfo *stream_info;
|
GstStreamInfo *stream_info;
|
||||||
gboolean new_mute;
|
|
||||||
|
|
||||||
g_return_if_fail (GST_IS_STREAM_INFO (object));
|
g_return_if_fail (GST_IS_STREAM_INFO (object));
|
||||||
|
|
||||||
|
@ -244,20 +268,8 @@ gst_stream_info_set_property (GObject * object, guint prop_id,
|
||||||
|
|
||||||
switch (prop_id) {
|
switch (prop_id) {
|
||||||
case ARG_MUTE:
|
case ARG_MUTE:
|
||||||
{
|
gst_stream_info_set_mute (stream_info, g_value_get_boolean (value));
|
||||||
if (stream_info->type == GST_STREAM_TYPE_ELEMENT) {
|
|
||||||
g_warning ("cannot mute element stream");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
new_mute = g_value_get_boolean (value);
|
|
||||||
|
|
||||||
if (new_mute != stream_info->mute) {
|
|
||||||
stream_info->mute = new_mute;
|
|
||||||
stream_info_mute_pad (stream_info, GST_PAD (stream_info->object),
|
|
||||||
new_mute);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -36,21 +36,23 @@ typedef struct _GstStreamInfoClass GstStreamInfoClass;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
GST_STREAM_TYPE_UNKNOWN = 0,
|
GST_STREAM_TYPE_UNKNOWN = 0,
|
||||||
GST_STREAM_TYPE_AUDIO = 1,
|
GST_STREAM_TYPE_AUDIO = 1, /* an audio stream */
|
||||||
GST_STREAM_TYPE_VIDEO = 2,
|
GST_STREAM_TYPE_VIDEO = 2, /* a video stream */
|
||||||
GST_STREAM_TYPE_TEXT = 3,
|
GST_STREAM_TYPE_TEXT = 3, /* a subtitle/text stream */
|
||||||
GST_STREAM_TYPE_ELEMENT = 4,
|
GST_STREAM_TYPE_ELEMENT = 4, /* stream handled by an element */
|
||||||
} GstStreamType;
|
} GstStreamType;
|
||||||
|
|
||||||
struct _GstStreamInfo {
|
struct _GstStreamInfo {
|
||||||
GObject parent;
|
GObject parent;
|
||||||
|
|
||||||
GstObject *object;
|
GstObject *object; /* pad/element providing/handling this stream */
|
||||||
GstStreamType type;
|
GstStreamType type; /* the type of the provided stream */
|
||||||
gchar *decoder;
|
gchar *decoder; /* string describing the decoder */
|
||||||
gboolean mute;
|
gboolean mute; /* is the stream muted or not */
|
||||||
GstObject *origin;
|
GstObject *origin; /* the real object providing this stream, this can
|
||||||
GstCaps *caps;
|
be different from the object as the object can be
|
||||||
|
a queue pad, inserted for preroll. */
|
||||||
|
GstCaps *caps; /* the caps of the stream */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GstStreamInfoClass {
|
struct _GstStreamInfoClass {
|
||||||
|
@ -62,10 +64,15 @@ struct _GstStreamInfoClass {
|
||||||
|
|
||||||
GType gst_stream_info_get_type (void);
|
GType gst_stream_info_get_type (void);
|
||||||
|
|
||||||
GstStreamInfo* gst_stream_info_new (GstObject *object,
|
GstStreamInfo* gst_stream_info_new (GstObject *object,
|
||||||
GstStreamType type,
|
GstStreamType type,
|
||||||
const gchar *decoder,
|
const gchar *decoder,
|
||||||
const GstCaps *caps);
|
const GstCaps *caps);
|
||||||
|
|
||||||
|
gboolean gst_stream_info_set_mute (GstStreamInfo *stream_info,
|
||||||
|
gboolean mute);
|
||||||
|
gboolean gst_stream_info_is_mute (GstStreamInfo *stream_info);
|
||||||
|
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue