gst/playback/: Implement group-switch signal for use in apps to clear metadata cache, clean up subtitle, add suburi p...

Original commit message from CVS:
* gst/playback/gstplaybasebin.c: (gst_play_base_bin_class_init),
(gst_play_base_bin_init), (gst_play_base_bin_dispose),
(probe_triggered), (new_decoded_pad), (gen_source_element),
(gst_play_base_bin_set_property), (gst_play_base_bin_get_property):
* gst/playback/gstplaybasebin.h:
* gst/playback/gstplaybin.c: (gst_play_bin_class_init),
(gst_play_bin_init), (group_switch), (remove_sinks), (setup_sinks),
(gst_play_bin_change_state):
Implement group-switch signal for use in apps to clear metadata
cache, clean up subtitle, add suburi property instead of # hack,
some error-out fixes.
This commit is contained in:
Ronald S. Bultje 2005-01-11 12:03:24 +00:00
parent e63860b014
commit b92916a2bf
4 changed files with 70 additions and 15 deletions

View file

@ -1,3 +1,17 @@
2005-01-11 Ronald S. Bultje <rbultje@ronald.bitfreak.net>
* gst/playback/gstplaybasebin.c: (gst_play_base_bin_class_init),
(gst_play_base_bin_init), (gst_play_base_bin_dispose),
(probe_triggered), (new_decoded_pad), (gen_source_element),
(gst_play_base_bin_set_property), (gst_play_base_bin_get_property):
* gst/playback/gstplaybasebin.h:
* gst/playback/gstplaybin.c: (gst_play_bin_class_init),
(gst_play_bin_init), (group_switch), (remove_sinks), (setup_sinks),
(gst_play_bin_change_state):
Implement group-switch signal for use in apps to clear metadata
cache, clean up subtitle, add suburi property instead of # hack,
some error-out fixes.
2005-01-11 Ronald S. Bultje <rbultje@ronald.bitfreak.net>
* ext/vorbis/vorbisdec.c: (vorbis_dec_chain):

View file

@ -36,6 +36,7 @@ enum
{
ARG_0,
ARG_URI,
ARG_SUBURI,
ARG_THREADED,
ARG_NSTREAMS,
ARG_QUEUE_SIZE,
@ -52,6 +53,7 @@ enum
SETUP_OUTPUT_PADS_SIGNAL,
REMOVED_OUTPUT_PAD_SIGNAL,
BUFFERING_SIGNAL,
GROUP_SWITCH_SIGNAL,
LINK_STREAM_SIGNAL,
UNLINK_STREAM_SIGNAL,
LAST_SIGNAL
@ -136,6 +138,9 @@ gst_play_base_bin_class_init (GstPlayBaseBinClass * klass)
g_object_class_install_property (gobject_klass, ARG_URI,
g_param_spec_string ("uri", "URI", "URI of the media to play",
NULL, G_PARAM_READWRITE));
g_object_class_install_property (gobject_klass, ARG_SUBURI,
g_param_spec_string ("suburi", ".sub-URI", "Optional URI of a subtitle",
NULL, G_PARAM_READWRITE));
g_object_class_install_property (gobject_klass, ARG_NSTREAMS,
g_param_spec_int ("nstreams", "NStreams", "number of streams",
0, G_MAXINT, 0, G_PARAM_READABLE));
@ -182,6 +187,11 @@ gst_play_base_bin_class_init (GstPlayBaseBinClass * klass)
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstPlayBaseBinClass, buffering),
NULL, NULL, g_cclosure_marshal_VOID__INT, G_TYPE_NONE, 1, G_TYPE_INT);
gst_play_base_bin_signals[GROUP_SWITCH_SIGNAL] =
g_signal_new ("group-switch", G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstPlayBaseBinClass, group_switch),
NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
/* action signals */
gst_play_base_bin_signals[LINK_STREAM_SIGNAL] =
@ -215,6 +225,7 @@ static void
gst_play_base_bin_init (GstPlayBaseBin * play_base_bin)
{
play_base_bin->uri = NULL;
play_base_bin->suburi = NULL;
play_base_bin->need_rebuild = TRUE;
play_base_bin->source = NULL;
play_base_bin->decoder = NULL;
@ -239,6 +250,8 @@ gst_play_base_bin_dispose (GObject * object)
play_base_bin = GST_PLAY_BASE_BIN (object);
g_free (play_base_bin->uri);
play_base_bin->uri = NULL;
g_free (play_base_bin->suburi);
play_base_bin->suburi = NULL;
if (G_OBJECT_CLASS (parent_class)->dispose) {
G_OBJECT_CLASS (parent_class)->dispose (object);
@ -639,6 +652,8 @@ probe_triggered (GstProbe * probe, GstData ** data, gpointer user_data)
gst_element_set_state (play_base_bin->thread, GST_STATE_PAUSED);
/* ok, get rid of the current group then */
group_destroy (group);
g_signal_emit (play_base_bin,
gst_play_base_bin_signals[GROUP_SWITCH_SIGNAL], 0);
/* removing the current group brings the next group
* active */
play_base_bin->queued_groups =
@ -764,8 +779,9 @@ new_decoded_pad (GstElement * element, GstPad * pad, gboolean last,
/* first see if this pad has interesting caps */
caps = gst_pad_get_caps (pad);
if (caps == NULL || gst_caps_is_empty (caps)) {
g_warning ("no type on pad %s:%s", GST_DEBUG_PAD_NAME (pad));
if (caps == NULL || gst_caps_is_empty (caps) || gst_caps_is_any (caps)) {
g_warning ("no type on pad %s:%s",
GST_DEBUG_PAD_NAME (GST_PAD_REALIZE (pad)));
if (caps)
gst_caps_free (caps);
return;
@ -964,24 +980,20 @@ gen_source_element (GstPlayBaseBin * play_base_bin, GstElement ** subbin)
GstElement *source, *queue, *bin;
GstProbe *probe;
gboolean is_stream;
gchar **src, *uri;
/* stip subtitle from uri */
src = g_strsplit (play_base_bin->uri, "#", 2);
if (!src[0])
if (!play_base_bin->uri)
return NULL;
if (src[1]) {
if (play_base_bin->suburi) {
/* subtitle specified */
*subbin = setup_subtitle (play_base_bin, src[1]);
*subbin = setup_subtitle (play_base_bin, play_base_bin->suburi);
} else {
/* no subtitle specified */
*subbin = NULL;
}
uri = src[0];
src[0] = NULL;
g_strfreev (src);
source = gst_element_make_from_uri (GST_URI_SRC, uri, "source");
source = gst_element_make_from_uri (GST_URI_SRC, play_base_bin->uri,
"source");
if (!source)
return NULL;
@ -1399,6 +1411,19 @@ gst_play_base_bin_set_property (GObject * object, guint prop_id,
}
break;
}
case ARG_SUBURI:{
const gchar *suburi = g_value_get_string (value);
if ((!suburi && !play_base_bin->suburi) ||
(suburi && play_base_bin->suburi &&
!strcmp (play_base_bin->suburi, suburi)))
return;
g_free (play_base_bin->suburi);
play_base_bin->suburi = g_strdup (suburi);
GST_DEBUG ("setting new .sub uri to %s", suburi);
play_base_bin->need_rebuild = TRUE;
break;
}
case ARG_QUEUE_SIZE:
play_base_bin->queue_size = g_value_get_uint64 (value);
break;
@ -1434,6 +1459,9 @@ gst_play_base_bin_get_property (GObject * object, guint prop_id, GValue * value,
case ARG_URI:
g_value_set_string (value, play_base_bin->uri);
break;
case ARG_SUBURI:
g_value_set_string (value, play_base_bin->suburi);
break;
case ARG_NSTREAMS:
{
GstPlayBaseGroup *group = get_active_group (play_base_bin);

View file

@ -72,7 +72,7 @@ struct _GstPlayBaseBin {
/* internal thread */
GstElement *thread;
gchar *uri;
gchar *uri, *suburi;
GstElement *source;
GstElement *decoder;
GstElement *subtitle; /* additional filesrc ! subparse bin */
@ -100,6 +100,7 @@ struct _GstPlayBaseBinClass {
* 100: buf=full (overrun) - will flush head of cache (latency) */
void (*buffering) (GstPlayBaseBin *play_base_bin,
gint percentage);
void (*group_switch) (GstPlayBaseBin *play_base_bin);
/* action signals */
gboolean (*link_stream) (GstPlayBaseBin *play_base_bin,

View file

@ -62,6 +62,9 @@ struct _GstPlayBin
/* our cache for the sinks */
GHashTable *cache;
/* boolean to see if we're currently switching groups */
gboolean group_switch;
};
struct _GstPlayBinClass
@ -90,6 +93,7 @@ static void gst_play_bin_class_init (GstPlayBinClass * klass);
static void gst_play_bin_init (GstPlayBin * play_bin);
static void gst_play_bin_dispose (GObject * object);
static void group_switch (GstPlayBaseBin * play_base_bin);
static void setup_sinks (GstPlayBaseBin * play_base_bin);
static void remove_sinks (GstPlayBin * play_bin);
@ -202,6 +206,7 @@ gst_play_bin_class_init (GstPlayBinClass * klass)
gstelement_klass->query = GST_DEBUG_FUNCPTR (gst_play_bin_query);
playbasebin_klass->setup_output_pads = setup_sinks;
playbasebin_klass->group_switch = group_switch;
}
static void
@ -217,6 +222,7 @@ gst_play_bin_init (GstPlayBin * play_bin)
play_bin->frame = NULL;
play_bin->cache = g_hash_table_new_full (g_str_hash, g_str_equal,
NULL, (GDestroyNotify) gst_object_unref);
play_bin->group_switch = FALSE;
/* no iterate is needed */
GST_FLAG_SET (play_bin, GST_BIN_SELF_SCHEDULABLE);
@ -615,6 +621,13 @@ gen_vis_element (GstPlayBin * play_bin)
return element;
}
/* set for group switch */
static void
group_switch (GstPlayBaseBin * play_base_bin)
{
GST_PLAY_BIN (play_base_bin)->group_switch = TRUE;
}
/* get rid of all installed sinks */
static void
remove_sinks (GstPlayBin * play_bin)
@ -624,6 +637,7 @@ remove_sinks (GstPlayBin * play_bin)
GstElement *element;
GST_DEBUG ("removesinks");
play_bin->group_switch = FALSE;
element = g_hash_table_lookup (play_bin->cache, "abin");
if (element != NULL) {
parent = gst_element_get_parent (element);
@ -755,7 +769,6 @@ setup_sinks (GstPlayBaseBin * play_base_bin)
} else {
sink = gen_audio_element (play_bin);
}
//gst_element_link (group->type[GST_STREAM_TYPE_AUDIO - 1].preroll, sink);
add_sink (play_bin, sink,
gst_element_get_pad (group->type[GST_STREAM_TYPE_AUDIO - 1].preroll,
"src"));
@ -776,7 +789,6 @@ setup_sinks (GstPlayBaseBin * play_base_bin)
} else {
sink = gen_video_element (play_bin);
}
//gst_element_link (group->type[GST_STREAM_TYPE_VIDEO - 1].preroll, sink);
add_sink (play_bin, sink,
gst_element_get_pad (group->type[GST_STREAM_TYPE_VIDEO - 1].preroll,
"src"));
@ -802,7 +814,7 @@ gst_play_bin_change_state (GstElement * element)
case GST_STATE_PLAYING_TO_PAUSED:
/* Set audio sink state to NULL to release the sound device,
* but only if we own it (else we might be in chain-transition). */
if (play_bin->audio_sink != NULL &&
if (play_bin->audio_sink != NULL && !play_bin->group_switch &&
GST_STATE (play_bin->audio_sink) == GST_STATE_PAUSED) {
gst_element_set_state (play_bin->audio_sink, GST_STATE_NULL);
}