mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-06-06 07:28:53 +00:00
gst/playback/: Reuse the audio and video bins.
Original commit message from CVS: * gst/playback/gstdecodebin.c: (gst_decode_bin_class_init), (gst_decode_bin_init), (find_compatibles), (close_pad_link), (try_to_link_1), (no_more_pads), (close_link), (type_found): * gst/playback/gstplaybasebin.c: (gst_play_base_bin_class_init), (unknown_type), (gst_play_base_bin_remove_element), (gst_play_base_bin_link_stream): * gst/playback/gstplaybasebin.h: * gst/playback/gstplaybin.c: (gst_play_bin_init), (gst_play_bin_set_property), (gen_video_element), (gen_audio_element), (setup_sinks): * gst/playback/gststreaminfo.c: (gst_stream_type_get_type), (gst_stream_info_get_type), (gst_stream_info_class_init), (gst_stream_info_init), (gst_stream_info_new), (gst_stream_info_dispose), (stream_info_mute_pad), (gst_stream_info_set_property), (gst_stream_info_get_property): * gst/playback/gststreaminfo.h: Reuse the audio and video bins. Some internal cleanups in the stream selection code.
This commit is contained in:
parent
18fff8755d
commit
a85131e7ca
7 changed files with 155 additions and 89 deletions
21
ChangeLog
21
ChangeLog
|
@ -1,3 +1,24 @@
|
||||||
|
2004-10-08 Wim Taymans <wim@fluendo.com>
|
||||||
|
|
||||||
|
* gst/playback/gstdecodebin.c: (gst_decode_bin_class_init),
|
||||||
|
(gst_decode_bin_init), (find_compatibles), (close_pad_link),
|
||||||
|
(try_to_link_1), (no_more_pads), (close_link), (type_found):
|
||||||
|
* gst/playback/gstplaybasebin.c: (gst_play_base_bin_class_init),
|
||||||
|
(unknown_type), (gst_play_base_bin_remove_element),
|
||||||
|
(gst_play_base_bin_link_stream):
|
||||||
|
* gst/playback/gstplaybasebin.h:
|
||||||
|
* gst/playback/gstplaybin.c: (gst_play_bin_init),
|
||||||
|
(gst_play_bin_set_property), (gen_video_element),
|
||||||
|
(gen_audio_element), (setup_sinks):
|
||||||
|
* gst/playback/gststreaminfo.c: (gst_stream_type_get_type),
|
||||||
|
(gst_stream_info_get_type), (gst_stream_info_class_init),
|
||||||
|
(gst_stream_info_init), (gst_stream_info_new),
|
||||||
|
(gst_stream_info_dispose), (stream_info_mute_pad),
|
||||||
|
(gst_stream_info_set_property), (gst_stream_info_get_property):
|
||||||
|
* gst/playback/gststreaminfo.h:
|
||||||
|
Reuse the audio and video bins.
|
||||||
|
Some internal cleanups in the stream selection code.
|
||||||
|
|
||||||
2004-10-08 Julien MOUTTE <julien@moutte.net>
|
2004-10-08 Julien MOUTTE <julien@moutte.net>
|
||||||
|
|
||||||
* sys/ximage/ximagesink.c: (gst_ximagesink_sink_link),
|
* sys/ximage/ximagesink.c: (gst_ximagesink_sink_link),
|
||||||
|
|
|
@ -73,7 +73,7 @@ struct _GstDecodeBinClass
|
||||||
/* signal we fire when a new pad has been decoded into raw audio/video */
|
/* signal we fire when a new pad has been decoded into raw audio/video */
|
||||||
void (*new_decoded_pad) (GstElement * element, GstPad * pad, gboolean last);
|
void (*new_decoded_pad) (GstElement * element, GstPad * pad, gboolean last);
|
||||||
/* signal fired when we found a pad that we cannot decode */
|
/* signal fired when we found a pad that we cannot decode */
|
||||||
void (*unknown_type) (GstElement * element, GstCaps * caps);
|
void (*unknown_type) (GstElement * element, GstPad * pad, GstCaps * caps);
|
||||||
};
|
};
|
||||||
|
|
||||||
/* props */
|
/* props */
|
||||||
|
@ -187,7 +187,8 @@ gst_decode_bin_class_init (GstDecodeBinClass * klass)
|
||||||
gst_decode_bin_signals[SIGNAL_UNKNOWN_TYPE] =
|
gst_decode_bin_signals[SIGNAL_UNKNOWN_TYPE] =
|
||||||
g_signal_new ("unknown-type", G_TYPE_FROM_CLASS (klass),
|
g_signal_new ("unknown-type", G_TYPE_FROM_CLASS (klass),
|
||||||
G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstDecodeBinClass, unknown_type),
|
G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstDecodeBinClass, unknown_type),
|
||||||
NULL, NULL, gst_marshal_VOID__OBJECT, G_TYPE_NONE, 1, GST_TYPE_CAPS);
|
NULL, NULL, gst_marshal_VOID__POINTER_OBJECT, G_TYPE_NONE, 2,
|
||||||
|
GST_TYPE_PAD, GST_TYPE_CAPS);
|
||||||
|
|
||||||
gobject_klass->dispose = GST_DEBUG_FUNCPTR (gst_decode_bin_dispose);
|
gobject_klass->dispose = GST_DEBUG_FUNCPTR (gst_decode_bin_dispose);
|
||||||
|
|
||||||
|
@ -374,9 +375,9 @@ close_pad_link (GstElement * element, GstPad * pad, GstCaps * caps,
|
||||||
|
|
||||||
/* the caps is empty, this means the pad has no type, we can only
|
/* the caps is empty, this means the pad has no type, we can only
|
||||||
* decide to fire the unknown_type signal. */
|
* decide to fire the unknown_type signal. */
|
||||||
if (gst_caps_is_empty (caps)) {
|
if (caps == NULL || gst_caps_is_empty (caps)) {
|
||||||
g_signal_emit (G_OBJECT (decode_bin),
|
g_signal_emit (G_OBJECT (decode_bin),
|
||||||
gst_decode_bin_signals[SIGNAL_UNKNOWN_TYPE], 0, caps);
|
gst_decode_bin_signals[SIGNAL_UNKNOWN_TYPE], 0, pad, caps);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -423,15 +424,13 @@ close_pad_link (GstElement * element, GstPad * pad, GstCaps * caps,
|
||||||
/* no compatible elements, fire the unknown_type signal, we cannot go
|
/* no compatible elements, fire the unknown_type signal, we cannot go
|
||||||
* on */
|
* on */
|
||||||
g_signal_emit (G_OBJECT (decode_bin),
|
g_signal_emit (G_OBJECT (decode_bin),
|
||||||
gst_decode_bin_signals[SIGNAL_UNKNOWN_TYPE], 0, caps);
|
gst_decode_bin_signals[SIGNAL_UNKNOWN_TYPE], 0, pad, caps);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try_to_link_1 (decode_bin, pad, to_try);
|
try_to_link_1 (decode_bin, pad, to_try);
|
||||||
} else {
|
} else {
|
||||||
GST_LOG_OBJECT (element, "multiple possibilities, delaying");
|
GST_LOG_OBJECT (element, "multiple possibilities, delaying");
|
||||||
g_warning ("multiple possibilities, delaying");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* given a list of element factories, try to link one of the factories
|
/* given a list of element factories, try to link one of the factories
|
||||||
|
|
|
@ -136,11 +136,6 @@ gst_play_base_bin_class_init (GstPlayBaseBinClass * klass)
|
||||||
GST_DEBUG_CATEGORY_INIT (gst_play_base_bin_debug, "playbasebin", 0,
|
GST_DEBUG_CATEGORY_INIT (gst_play_base_bin_debug, "playbasebin", 0,
|
||||||
"playbasebin");
|
"playbasebin");
|
||||||
|
|
||||||
gst_play_base_bin_signals[MUTE_STREAM_SIGNAL] =
|
|
||||||
g_signal_new ("mute-stream", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
|
|
||||||
G_STRUCT_OFFSET (GstPlayBaseBinClass, mute_stream),
|
|
||||||
NULL, NULL, gst_marshal_VOID__OBJECT_POINTER, G_TYPE_NONE, 2,
|
|
||||||
G_TYPE_OBJECT, G_TYPE_BOOLEAN);
|
|
||||||
gst_play_base_bin_signals[LINK_STREAM_SIGNAL] =
|
gst_play_base_bin_signals[LINK_STREAM_SIGNAL] =
|
||||||
g_signal_new ("link-stream", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
|
g_signal_new ("link-stream", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
|
||||||
G_STRUCT_OFFSET (GstPlayBaseBinClass, link_stream),
|
G_STRUCT_OFFSET (GstPlayBaseBinClass, link_stream),
|
||||||
|
@ -162,7 +157,6 @@ gst_play_base_bin_class_init (GstPlayBaseBinClass * klass)
|
||||||
gstbin_klass->remove_element =
|
gstbin_klass->remove_element =
|
||||||
GST_DEBUG_FUNCPTR (gst_play_base_bin_remove_element);
|
GST_DEBUG_FUNCPTR (gst_play_base_bin_remove_element);
|
||||||
|
|
||||||
klass->mute_stream = gst_play_base_bin_mute_stream;
|
|
||||||
klass->link_stream = gst_play_base_bin_link_stream;
|
klass->link_stream = gst_play_base_bin_link_stream;
|
||||||
klass->unlink_stream = gst_play_base_bin_unlink_stream;
|
klass->unlink_stream = gst_play_base_bin_unlink_stream;
|
||||||
}
|
}
|
||||||
|
@ -256,13 +250,19 @@ remove_prerolls (GstPlayBaseBin * play_base_bin)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
unknown_type (GstElement * element, GstCaps * caps,
|
unknown_type (GstElement * element, GstPad * pad, GstCaps * caps,
|
||||||
GstPlayBaseBin * play_base_bin)
|
GstPlayBaseBin * play_base_bin)
|
||||||
{
|
{
|
||||||
gchar *capsstr = gst_caps_to_string (caps);
|
gchar *capsstr;
|
||||||
|
GstStreamInfo *info;
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
/* add the stream to the list */
|
||||||
|
info = gst_stream_info_new (pad, GST_STREAM_TYPE_UNKNOWN, NULL);
|
||||||
|
play_base_bin->streaminfo = g_list_append (play_base_bin->streaminfo, info);
|
||||||
|
|
||||||
g_free (capsstr);
|
g_free (capsstr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -683,6 +683,9 @@ gst_play_base_bin_remove_element (GstBin * bin, GstElement * element)
|
||||||
if (!thread) {
|
if (!thread) {
|
||||||
g_warning ("cannot find element to remove");
|
g_warning ("cannot find element to remove");
|
||||||
} else {
|
} else {
|
||||||
|
/* we remove the element from the thread first so that the
|
||||||
|
* state is not affected when someone holds a reference to it */
|
||||||
|
gst_bin_remove (GST_BIN (thread), element);
|
||||||
element = thread;
|
element = thread;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -739,63 +742,6 @@ gst_play_base_bin_found_tag (GstElement * element,
|
||||||
gst_object_unref (parent);
|
gst_object_unref (parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
play_base_bin_mute_pad (GstPlayBaseBin * play_base_bin,
|
|
||||||
GstPad * pad, gboolean mute)
|
|
||||||
{
|
|
||||||
GList *int_links;
|
|
||||||
gboolean activate = !mute;
|
|
||||||
gchar *debug_str = (activate ? "activate" : "inactivate");
|
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (play_base_bin, "%s %s:%s", debug_str,
|
|
||||||
GST_DEBUG_PAD_NAME (pad));
|
|
||||||
gst_pad_set_active (pad, activate);
|
|
||||||
|
|
||||||
for (int_links = gst_pad_get_internal_links (pad);
|
|
||||||
int_links; int_links = g_list_next (int_links)) {
|
|
||||||
GstPad *pad = GST_PAD (int_links->data);
|
|
||||||
GstPad *peer = gst_pad_get_peer (pad);
|
|
||||||
GstElement *peer_elem = gst_pad_get_parent (peer);
|
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (play_base_bin, "%s internal pad %s:%s",
|
|
||||||
debug_str, GST_DEBUG_PAD_NAME (pad));
|
|
||||||
|
|
||||||
gst_pad_set_active (pad, activate);
|
|
||||||
|
|
||||||
if (peer_elem->numsrcpads == 1) {
|
|
||||||
GST_DEBUG_OBJECT (play_base_bin, "recursing element %s on pad %s:%s",
|
|
||||||
gst_element_get_name (peer_elem), GST_DEBUG_PAD_NAME (peer));
|
|
||||||
play_base_bin_mute_pad (play_base_bin, peer, mute);
|
|
||||||
} else {
|
|
||||||
GST_DEBUG_OBJECT (play_base_bin, "%s final pad %s:%s",
|
|
||||||
debug_str, GST_DEBUG_PAD_NAME (peer));
|
|
||||||
gst_pad_set_active (peer, activate);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* muting a stream follows the flow downstream and dis/enables all
|
|
||||||
* pads it encounters until an element with more than one source pad
|
|
||||||
* (a demuxer or equivalent) is met.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
gst_play_base_bin_mute_stream (GstPlayBaseBin * play_base_bin,
|
|
||||||
GstStreamInfo * info, gboolean mute)
|
|
||||||
{
|
|
||||||
GST_DEBUG ("mute stream");
|
|
||||||
|
|
||||||
g_return_if_fail (play_base_bin != NULL);
|
|
||||||
g_return_if_fail (GST_IS_PLAY_BASE_BIN (play_base_bin));
|
|
||||||
g_return_if_fail (info != NULL);
|
|
||||||
g_return_if_fail (GST_IS_STREAM_INFO (info));
|
|
||||||
|
|
||||||
/* check if info contains a pad */
|
|
||||||
if (info->pad == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
play_base_bin_mute_pad (play_base_bin, info->pad, mute);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
gst_play_base_bin_link_stream (GstPlayBaseBin * play_base_bin,
|
gst_play_base_bin_link_stream (GstPlayBaseBin * play_base_bin,
|
||||||
GstStreamInfo * info, GstPad * pad)
|
GstStreamInfo * info, GstPad * pad)
|
||||||
|
@ -821,7 +767,7 @@ gst_play_base_bin_link_stream (GstPlayBaseBin * play_base_bin,
|
||||||
if (info) {
|
if (info) {
|
||||||
if (!gst_pad_link (info->pad, pad)) {
|
if (!gst_pad_link (info->pad, pad)) {
|
||||||
GST_DEBUG ("could not link");
|
GST_DEBUG ("could not link");
|
||||||
gst_play_base_bin_mute_stream (play_base_bin, info, TRUE);
|
g_object_set (G_OBJECT (info), "mute", TRUE, NULL);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
GST_DEBUG ("could not find pad to link");
|
GST_DEBUG ("could not find pad to link");
|
||||||
|
|
|
@ -66,9 +66,6 @@ struct _GstPlayBaseBin {
|
||||||
struct _GstPlayBaseBinClass {
|
struct _GstPlayBaseBinClass {
|
||||||
GstBinClass parent_class;
|
GstBinClass parent_class;
|
||||||
|
|
||||||
void (*mute_stream) (GstPlayBaseBin *play_base_bin,
|
|
||||||
GstStreamInfo *info,
|
|
||||||
gboolean mute);
|
|
||||||
void (*link_stream) (GstPlayBaseBin *play_base_bin,
|
void (*link_stream) (GstPlayBaseBin *play_base_bin,
|
||||||
GstStreamInfo *info,
|
GstStreamInfo *info,
|
||||||
GstPad *pad);
|
GstPad *pad);
|
||||||
|
@ -83,9 +80,6 @@ const GList* gst_play_base_bin_get_streaminfo (GstPlayBaseBin *play_base_bin);
|
||||||
gint gst_play_base_bin_get_nstreams_of_type (GstPlayBaseBin *play_base_bin,
|
gint gst_play_base_bin_get_nstreams_of_type (GstPlayBaseBin *play_base_bin,
|
||||||
GstStreamType type);
|
GstStreamType type);
|
||||||
|
|
||||||
void gst_play_base_bin_mute_stream (GstPlayBaseBin *play_base_bin,
|
|
||||||
GstStreamInfo *info,
|
|
||||||
gboolean mute);
|
|
||||||
void gst_play_base_bin_link_stream (GstPlayBaseBin *play_base_bin,
|
void gst_play_base_bin_link_stream (GstPlayBaseBin *play_base_bin,
|
||||||
GstStreamInfo *info,
|
GstStreamInfo *info,
|
||||||
GstPad *pad);
|
GstPad *pad);
|
||||||
|
|
|
@ -48,11 +48,13 @@ struct _GstPlayBin
|
||||||
GstElement *video_sink;
|
GstElement *video_sink;
|
||||||
GstElement *visualisation;
|
GstElement *visualisation;
|
||||||
GstElement *volume_element;
|
GstElement *volume_element;
|
||||||
float volume;
|
gfloat volume;
|
||||||
|
|
||||||
GList *sinks;
|
GList *sinks;
|
||||||
|
|
||||||
GList *seekables;
|
GList *seekables;
|
||||||
|
|
||||||
|
GHashTable *cache;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GstPlayBinClass
|
struct _GstPlayBinClass
|
||||||
|
@ -194,6 +196,7 @@ gst_play_bin_init (GstPlayBin * play_bin)
|
||||||
play_bin->volume = 1.0;
|
play_bin->volume = 1.0;
|
||||||
play_bin->seekables = NULL;
|
play_bin->seekables = NULL;
|
||||||
play_bin->sinks = NULL;
|
play_bin->sinks = NULL;
|
||||||
|
play_bin->cache = g_hash_table_new (g_str_hash, g_str_equal);
|
||||||
|
|
||||||
GST_FLAG_SET (play_bin, GST_BIN_SELF_SCHEDULABLE);
|
GST_FLAG_SET (play_bin, GST_BIN_SELF_SCHEDULABLE);
|
||||||
}
|
}
|
||||||
|
@ -222,11 +225,31 @@ gst_play_bin_set_property (GObject * object, guint prop_id,
|
||||||
|
|
||||||
switch (prop_id) {
|
switch (prop_id) {
|
||||||
case ARG_VIDEO_SINK:
|
case ARG_VIDEO_SINK:
|
||||||
|
{
|
||||||
|
GstElement *element;
|
||||||
|
|
||||||
play_bin->video_sink = g_value_get_object (value);
|
play_bin->video_sink = g_value_get_object (value);
|
||||||
|
|
||||||
|
element = g_hash_table_lookup (play_bin->cache, "vbin");
|
||||||
|
if (element != NULL) {
|
||||||
|
g_hash_table_remove (play_bin->cache, "vbin");
|
||||||
|
g_object_unref (G_OBJECT (element));
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case ARG_AUDIO_SINK:
|
case ARG_AUDIO_SINK:
|
||||||
|
{
|
||||||
|
GstElement *element;
|
||||||
|
|
||||||
play_bin->audio_sink = g_value_get_object (value);
|
play_bin->audio_sink = g_value_get_object (value);
|
||||||
|
|
||||||
|
element = g_hash_table_lookup (play_bin->cache, "abin");
|
||||||
|
if (element != NULL) {
|
||||||
|
g_hash_table_remove (play_bin->cache, "abin");
|
||||||
|
g_object_unref (G_OBJECT (element));
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case ARG_VIS_PLUGIN:
|
case ARG_VIS_PLUGIN:
|
||||||
play_bin->visualisation = g_value_get_object (value);
|
play_bin->visualisation = g_value_get_object (value);
|
||||||
break;
|
break;
|
||||||
|
@ -281,6 +304,13 @@ gen_video_element (GstPlayBin * play_bin)
|
||||||
GstElement *scale;
|
GstElement *scale;
|
||||||
GstElement *sink;
|
GstElement *sink;
|
||||||
|
|
||||||
|
element = g_hash_table_lookup (play_bin->cache, "vbin");
|
||||||
|
if (element != NULL) {
|
||||||
|
g_object_ref (G_OBJECT (element));
|
||||||
|
sink = gst_bin_get_by_name (GST_BIN (element), "sink");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
element = gst_bin_new ("vbin");
|
element = gst_bin_new ("vbin");
|
||||||
conv = gst_element_factory_make ("ffmpegcolorspace", "vconv");
|
conv = gst_element_factory_make ("ffmpegcolorspace", "vconv");
|
||||||
scale = gst_element_factory_make ("videoscale", "vscale");
|
scale = gst_element_factory_make ("videoscale", "vscale");
|
||||||
|
@ -291,8 +321,6 @@ gen_video_element (GstPlayBin * play_bin)
|
||||||
sink = gst_element_factory_make ("ximagesink", "sink");
|
sink = gst_element_factory_make ("ximagesink", "sink");
|
||||||
}
|
}
|
||||||
|
|
||||||
play_bin->seekables = g_list_append (play_bin->seekables, sink);
|
|
||||||
|
|
||||||
gst_bin_add (GST_BIN (element), conv);
|
gst_bin_add (GST_BIN (element), conv);
|
||||||
gst_bin_add (GST_BIN (element), scale);
|
gst_bin_add (GST_BIN (element), scale);
|
||||||
gst_bin_add (GST_BIN (element), sink);
|
gst_bin_add (GST_BIN (element), sink);
|
||||||
|
@ -304,6 +332,13 @@ gen_video_element (GstPlayBin * play_bin)
|
||||||
|
|
||||||
gst_element_set_state (element, GST_STATE_READY);
|
gst_element_set_state (element, GST_STATE_READY);
|
||||||
|
|
||||||
|
/* ref before adding to the cache */
|
||||||
|
g_object_ref (G_OBJECT (element));
|
||||||
|
g_hash_table_insert (play_bin->cache, "vbin", element);
|
||||||
|
|
||||||
|
done:
|
||||||
|
play_bin->seekables = g_list_append (play_bin->seekables, sink);
|
||||||
|
|
||||||
return element;
|
return element;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -316,6 +351,12 @@ gen_audio_element (GstPlayBin * play_bin)
|
||||||
GstElement *volume;
|
GstElement *volume;
|
||||||
GstElement *scale;
|
GstElement *scale;
|
||||||
|
|
||||||
|
element = g_hash_table_lookup (play_bin->cache, "abin");
|
||||||
|
if (element != NULL) {
|
||||||
|
g_object_ref (G_OBJECT (element));
|
||||||
|
sink = gst_bin_get_by_name (GST_BIN (element), "sink");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
element = gst_bin_new ("abin");
|
element = gst_bin_new ("abin");
|
||||||
conv = gst_element_factory_make ("audioconvert", "aconv");
|
conv = gst_element_factory_make ("audioconvert", "aconv");
|
||||||
scale = gst_element_factory_make ("audioscale", "ascale");
|
scale = gst_element_factory_make ("audioscale", "ascale");
|
||||||
|
@ -331,8 +372,6 @@ gen_audio_element (GstPlayBin * play_bin)
|
||||||
sink = gst_element_factory_make ("osssink", "sink");
|
sink = gst_element_factory_make ("osssink", "sink");
|
||||||
}
|
}
|
||||||
|
|
||||||
play_bin->seekables = g_list_prepend (play_bin->seekables, sink);
|
|
||||||
|
|
||||||
gst_bin_add (GST_BIN (element), conv);
|
gst_bin_add (GST_BIN (element), conv);
|
||||||
gst_bin_add (GST_BIN (element), scale);
|
gst_bin_add (GST_BIN (element), scale);
|
||||||
gst_bin_add (GST_BIN (element), volume);
|
gst_bin_add (GST_BIN (element), volume);
|
||||||
|
@ -347,6 +386,13 @@ gen_audio_element (GstPlayBin * play_bin)
|
||||||
|
|
||||||
gst_element_set_state (element, GST_STATE_READY);
|
gst_element_set_state (element, GST_STATE_READY);
|
||||||
|
|
||||||
|
/* ref before adding to the cache */
|
||||||
|
g_object_ref (G_OBJECT (element));
|
||||||
|
g_hash_table_insert (play_bin->cache, "abin", element);
|
||||||
|
|
||||||
|
done:
|
||||||
|
play_bin->seekables = g_list_prepend (play_bin->seekables, sink);
|
||||||
|
|
||||||
return element;
|
return element;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -380,7 +426,7 @@ setup_sinks (GstPlayBin * play_bin)
|
||||||
|
|
||||||
for (s = streaminfo; s; s = g_list_next (s)) {
|
for (s = streaminfo; s; s = g_list_next (s)) {
|
||||||
GObject *obj = G_OBJECT (s->data);
|
GObject *obj = G_OBJECT (s->data);
|
||||||
int type;
|
gint type;
|
||||||
GstPad *srcpad, *sinkpad;
|
GstPad *srcpad, *sinkpad;
|
||||||
GstElement *sink = NULL;
|
GstElement *sink = NULL;
|
||||||
gboolean res;
|
gboolean res;
|
||||||
|
@ -431,8 +477,7 @@ setup_sinks (GstPlayBin * play_bin)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (mute) {
|
if (mute) {
|
||||||
gst_play_base_bin_mute_stream (GST_PLAY_BASE_BIN (play_bin),
|
g_object_set (G_OBJECT (obj), "mute", TRUE, NULL);
|
||||||
GST_STREAM_INFO (obj), TRUE);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,14 +32,18 @@ enum
|
||||||
ARG_PAD,
|
ARG_PAD,
|
||||||
ARG_TYPE,
|
ARG_TYPE,
|
||||||
ARG_DECODER,
|
ARG_DECODER,
|
||||||
|
ARG_MUTE,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* signals */
|
/* signals */
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
|
SIGNAL_MUTED,
|
||||||
LAST_SIGNAL
|
LAST_SIGNAL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static guint gst_stream_info_signals[LAST_SIGNAL] = { 0 };
|
||||||
|
|
||||||
#define GST_TYPE_STREAM_TYPE (gst_stream_type_get_type())
|
#define GST_TYPE_STREAM_TYPE (gst_stream_type_get_type())
|
||||||
static GType
|
static GType
|
||||||
gst_stream_type_get_type (void)
|
gst_stream_type_get_type (void)
|
||||||
|
@ -89,7 +93,6 @@ gst_stream_info_get_type (void)
|
||||||
(GInstanceInitFunc) gst_stream_info_init,
|
(GInstanceInitFunc) gst_stream_info_init,
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
gst_stream_info_type = g_type_register_static (G_TYPE_OBJECT,
|
gst_stream_info_type = g_type_register_static (G_TYPE_OBJECT,
|
||||||
"GstStreamInfo", &gst_stream_info_info, 0);
|
"GstStreamInfo", &gst_stream_info_info, 0);
|
||||||
}
|
}
|
||||||
|
@ -118,6 +121,14 @@ gst_stream_info_class_init (GstStreamInfoClass * klass)
|
||||||
g_object_class_install_property (gobject_klass, ARG_DECODER,
|
g_object_class_install_property (gobject_klass, ARG_DECODER,
|
||||||
g_param_spec_string ("decoder", "Decoder",
|
g_param_spec_string ("decoder", "Decoder",
|
||||||
"The decoder used to decode the stream", NULL, G_PARAM_READABLE));
|
"The decoder used to decode the stream", NULL, G_PARAM_READABLE));
|
||||||
|
g_object_class_install_property (gobject_klass, ARG_MUTE,
|
||||||
|
g_param_spec_boolean ("mute", "Mute", "Mute or unmute this stream", FALSE,
|
||||||
|
G_PARAM_READWRITE));
|
||||||
|
|
||||||
|
gst_stream_info_signals[SIGNAL_MUTED] =
|
||||||
|
g_signal_new ("muted", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
|
||||||
|
G_STRUCT_OFFSET (GstStreamInfoClass, muted), NULL, NULL,
|
||||||
|
gst_marshal_VOID__BOOLEAN, G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
|
||||||
|
|
||||||
gobject_klass->dispose = GST_DEBUG_FUNCPTR (gst_stream_info_dispose);
|
gobject_klass->dispose = GST_DEBUG_FUNCPTR (gst_stream_info_dispose);
|
||||||
}
|
}
|
||||||
|
@ -129,6 +140,7 @@ gst_stream_info_init (GstStreamInfo * stream_info)
|
||||||
stream_info->pad = NULL;
|
stream_info->pad = NULL;
|
||||||
stream_info->type = GST_STREAM_TYPE_UNKNOWN;
|
stream_info->type = GST_STREAM_TYPE_UNKNOWN;
|
||||||
stream_info->decoder = NULL;
|
stream_info->decoder = NULL;
|
||||||
|
stream_info->mute = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
GstStreamInfo *
|
GstStreamInfo *
|
||||||
|
@ -163,6 +175,39 @@ gst_stream_info_dispose (GObject * object)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
stream_info_mute_pad (GstStreamInfo * stream_info, GstPad * pad, gboolean mute)
|
||||||
|
{
|
||||||
|
GList *int_links;
|
||||||
|
gboolean activate = !mute;
|
||||||
|
gchar *debug_str = (activate ? "activate" : "inactivate");
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (stream_info, "%s %s:%s", debug_str,
|
||||||
|
GST_DEBUG_PAD_NAME (pad));
|
||||||
|
gst_pad_set_active (pad, activate);
|
||||||
|
|
||||||
|
for (int_links = gst_pad_get_internal_links (pad);
|
||||||
|
int_links; int_links = g_list_next (int_links)) {
|
||||||
|
GstPad *pad = GST_PAD (int_links->data);
|
||||||
|
GstPad *peer = gst_pad_get_peer (pad);
|
||||||
|
GstElement *peer_elem = gst_pad_get_parent (peer);
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (stream_info, "%s internal pad %s:%s",
|
||||||
|
debug_str, GST_DEBUG_PAD_NAME (pad));
|
||||||
|
|
||||||
|
gst_pad_set_active (pad, activate);
|
||||||
|
|
||||||
|
if (peer_elem->numsrcpads == 1) {
|
||||||
|
GST_DEBUG_OBJECT (stream_info, "recursing element %s on pad %s:%s",
|
||||||
|
gst_element_get_name (peer_elem), GST_DEBUG_PAD_NAME (peer));
|
||||||
|
stream_info_mute_pad (stream_info, peer, mute);
|
||||||
|
} else {
|
||||||
|
GST_DEBUG_OBJECT (stream_info, "%s final pad %s:%s",
|
||||||
|
debug_str, GST_DEBUG_PAD_NAME (peer));
|
||||||
|
gst_pad_set_active (peer, activate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_stream_info_set_property (GObject * object, guint prop_id,
|
gst_stream_info_set_property (GObject * object, guint prop_id,
|
||||||
|
@ -175,6 +220,16 @@ gst_stream_info_set_property (GObject * object, guint prop_id,
|
||||||
stream_info = GST_STREAM_INFO (object);
|
stream_info = GST_STREAM_INFO (object);
|
||||||
|
|
||||||
switch (prop_id) {
|
switch (prop_id) {
|
||||||
|
case ARG_MUTE:
|
||||||
|
{
|
||||||
|
gboolean new_mute = g_value_get_boolean (value);
|
||||||
|
|
||||||
|
if (new_mute != stream_info->mute) {
|
||||||
|
stream_info->mute = new_mute;
|
||||||
|
stream_info_mute_pad (stream_info, stream_info->pad, new_mute);
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
@ -201,6 +256,9 @@ gst_stream_info_get_property (GObject * object, guint prop_id, GValue * value,
|
||||||
case ARG_DECODER:
|
case ARG_DECODER:
|
||||||
g_value_set_string (value, stream_info->decoder);
|
g_value_set_string (value, stream_info->decoder);
|
||||||
break;
|
break;
|
||||||
|
case ARG_MUTE:
|
||||||
|
g_value_set_boolean (value, stream_info->mute);
|
||||||
|
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;
|
||||||
|
|
|
@ -47,17 +47,20 @@ struct _GstStreamInfo {
|
||||||
GstPad *pad;
|
GstPad *pad;
|
||||||
GstStreamType type;
|
GstStreamType type;
|
||||||
gchar *decoder;
|
gchar *decoder;
|
||||||
|
gboolean mute;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GstStreamInfoClass {
|
struct _GstStreamInfoClass {
|
||||||
GObjectClass parent_class;
|
GObjectClass parent_class;
|
||||||
|
|
||||||
|
/* signals */
|
||||||
|
void (*muted) (GstStreamInfo *info, gboolean mute);
|
||||||
};
|
};
|
||||||
|
|
||||||
GType gst_stream_info_get_type (void);
|
GType gst_stream_info_get_type (void);
|
||||||
|
|
||||||
GstStreamInfo* gst_stream_info_new (GstPad *pad, GstStreamType type, gchar *decoder);
|
GstStreamInfo* gst_stream_info_new (GstPad *pad, GstStreamType type, gchar *decoder);
|
||||||
|
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* __GST_STREAMINFO_H__ */
|
#endif /* __GST_STREAMINFO_H__ */
|
||||||
|
|
Loading…
Reference in a new issue