mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-25 09:40:37 +00:00
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:
parent
e63860b014
commit
b92916a2bf
4 changed files with 70 additions and 15 deletions
14
ChangeLog
14
ChangeLog
|
@ -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>
|
2005-01-11 Ronald S. Bultje <rbultje@ronald.bitfreak.net>
|
||||||
|
|
||||||
* ext/vorbis/vorbisdec.c: (vorbis_dec_chain):
|
* ext/vorbis/vorbisdec.c: (vorbis_dec_chain):
|
||||||
|
|
|
@ -36,6 +36,7 @@ enum
|
||||||
{
|
{
|
||||||
ARG_0,
|
ARG_0,
|
||||||
ARG_URI,
|
ARG_URI,
|
||||||
|
ARG_SUBURI,
|
||||||
ARG_THREADED,
|
ARG_THREADED,
|
||||||
ARG_NSTREAMS,
|
ARG_NSTREAMS,
|
||||||
ARG_QUEUE_SIZE,
|
ARG_QUEUE_SIZE,
|
||||||
|
@ -52,6 +53,7 @@ enum
|
||||||
SETUP_OUTPUT_PADS_SIGNAL,
|
SETUP_OUTPUT_PADS_SIGNAL,
|
||||||
REMOVED_OUTPUT_PAD_SIGNAL,
|
REMOVED_OUTPUT_PAD_SIGNAL,
|
||||||
BUFFERING_SIGNAL,
|
BUFFERING_SIGNAL,
|
||||||
|
GROUP_SWITCH_SIGNAL,
|
||||||
LINK_STREAM_SIGNAL,
|
LINK_STREAM_SIGNAL,
|
||||||
UNLINK_STREAM_SIGNAL,
|
UNLINK_STREAM_SIGNAL,
|
||||||
LAST_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_object_class_install_property (gobject_klass, ARG_URI,
|
||||||
g_param_spec_string ("uri", "URI", "URI of the media to play",
|
g_param_spec_string ("uri", "URI", "URI of the media to play",
|
||||||
NULL, G_PARAM_READWRITE));
|
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_object_class_install_property (gobject_klass, ARG_NSTREAMS,
|
||||||
g_param_spec_int ("nstreams", "NStreams", "number of streams",
|
g_param_spec_int ("nstreams", "NStreams", "number of streams",
|
||||||
0, G_MAXINT, 0, G_PARAM_READABLE));
|
0, G_MAXINT, 0, G_PARAM_READABLE));
|
||||||
|
@ -182,6 +187,11 @@ gst_play_base_bin_class_init (GstPlayBaseBinClass * klass)
|
||||||
G_SIGNAL_RUN_LAST,
|
G_SIGNAL_RUN_LAST,
|
||||||
G_STRUCT_OFFSET (GstPlayBaseBinClass, buffering),
|
G_STRUCT_OFFSET (GstPlayBaseBinClass, buffering),
|
||||||
NULL, NULL, g_cclosure_marshal_VOID__INT, G_TYPE_NONE, 1, G_TYPE_INT);
|
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 */
|
/* action signals */
|
||||||
gst_play_base_bin_signals[LINK_STREAM_SIGNAL] =
|
gst_play_base_bin_signals[LINK_STREAM_SIGNAL] =
|
||||||
|
@ -215,6 +225,7 @@ static void
|
||||||
gst_play_base_bin_init (GstPlayBaseBin * play_base_bin)
|
gst_play_base_bin_init (GstPlayBaseBin * play_base_bin)
|
||||||
{
|
{
|
||||||
play_base_bin->uri = NULL;
|
play_base_bin->uri = NULL;
|
||||||
|
play_base_bin->suburi = NULL;
|
||||||
play_base_bin->need_rebuild = TRUE;
|
play_base_bin->need_rebuild = TRUE;
|
||||||
play_base_bin->source = NULL;
|
play_base_bin->source = NULL;
|
||||||
play_base_bin->decoder = 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);
|
play_base_bin = GST_PLAY_BASE_BIN (object);
|
||||||
g_free (play_base_bin->uri);
|
g_free (play_base_bin->uri);
|
||||||
play_base_bin->uri = NULL;
|
play_base_bin->uri = NULL;
|
||||||
|
g_free (play_base_bin->suburi);
|
||||||
|
play_base_bin->suburi = NULL;
|
||||||
|
|
||||||
if (G_OBJECT_CLASS (parent_class)->dispose) {
|
if (G_OBJECT_CLASS (parent_class)->dispose) {
|
||||||
G_OBJECT_CLASS (parent_class)->dispose (object);
|
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);
|
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);
|
||||||
|
g_signal_emit (play_base_bin,
|
||||||
|
gst_play_base_bin_signals[GROUP_SWITCH_SIGNAL], 0);
|
||||||
/* removing the current group brings the next group
|
/* removing the current group brings the next group
|
||||||
* active */
|
* active */
|
||||||
play_base_bin->queued_groups =
|
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 */
|
/* first see if this pad has interesting caps */
|
||||||
caps = gst_pad_get_caps (pad);
|
caps = gst_pad_get_caps (pad);
|
||||||
if (caps == NULL || gst_caps_is_empty (caps)) {
|
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 (pad));
|
g_warning ("no type on pad %s:%s",
|
||||||
|
GST_DEBUG_PAD_NAME (GST_PAD_REALIZE (pad)));
|
||||||
if (caps)
|
if (caps)
|
||||||
gst_caps_free (caps);
|
gst_caps_free (caps);
|
||||||
return;
|
return;
|
||||||
|
@ -964,24 +980,20 @@ gen_source_element (GstPlayBaseBin * play_base_bin, GstElement ** subbin)
|
||||||
GstElement *source, *queue, *bin;
|
GstElement *source, *queue, *bin;
|
||||||
GstProbe *probe;
|
GstProbe *probe;
|
||||||
gboolean is_stream;
|
gboolean is_stream;
|
||||||
gchar **src, *uri;
|
|
||||||
|
|
||||||
/* stip subtitle from uri */
|
/* stip subtitle from uri */
|
||||||
src = g_strsplit (play_base_bin->uri, "#", 2);
|
if (!play_base_bin->uri)
|
||||||
if (!src[0])
|
|
||||||
return NULL;
|
return NULL;
|
||||||
if (src[1]) {
|
if (play_base_bin->suburi) {
|
||||||
/* subtitle specified */
|
/* subtitle specified */
|
||||||
*subbin = setup_subtitle (play_base_bin, src[1]);
|
*subbin = setup_subtitle (play_base_bin, play_base_bin->suburi);
|
||||||
} else {
|
} else {
|
||||||
/* no subtitle specified */
|
/* no subtitle specified */
|
||||||
*subbin = NULL;
|
*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)
|
if (!source)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
@ -1399,6 +1411,19 @@ gst_play_base_bin_set_property (GObject * object, guint prop_id,
|
||||||
}
|
}
|
||||||
break;
|
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:
|
case ARG_QUEUE_SIZE:
|
||||||
play_base_bin->queue_size = g_value_get_uint64 (value);
|
play_base_bin->queue_size = g_value_get_uint64 (value);
|
||||||
break;
|
break;
|
||||||
|
@ -1434,6 +1459,9 @@ gst_play_base_bin_get_property (GObject * object, guint prop_id, GValue * value,
|
||||||
case ARG_URI:
|
case ARG_URI:
|
||||||
g_value_set_string (value, play_base_bin->uri);
|
g_value_set_string (value, play_base_bin->uri);
|
||||||
break;
|
break;
|
||||||
|
case ARG_SUBURI:
|
||||||
|
g_value_set_string (value, play_base_bin->suburi);
|
||||||
|
break;
|
||||||
case ARG_NSTREAMS:
|
case ARG_NSTREAMS:
|
||||||
{
|
{
|
||||||
GstPlayBaseGroup *group = get_active_group (play_base_bin);
|
GstPlayBaseGroup *group = get_active_group (play_base_bin);
|
||||||
|
|
|
@ -72,7 +72,7 @@ struct _GstPlayBaseBin {
|
||||||
|
|
||||||
/* internal thread */
|
/* internal thread */
|
||||||
GstElement *thread;
|
GstElement *thread;
|
||||||
gchar *uri;
|
gchar *uri, *suburi;
|
||||||
GstElement *source;
|
GstElement *source;
|
||||||
GstElement *decoder;
|
GstElement *decoder;
|
||||||
GstElement *subtitle; /* additional filesrc ! subparse bin */
|
GstElement *subtitle; /* additional filesrc ! subparse bin */
|
||||||
|
@ -100,6 +100,7 @@ struct _GstPlayBaseBinClass {
|
||||||
* 100: buf=full (overrun) - will flush head of cache (latency) */
|
* 100: buf=full (overrun) - will flush head of cache (latency) */
|
||||||
void (*buffering) (GstPlayBaseBin *play_base_bin,
|
void (*buffering) (GstPlayBaseBin *play_base_bin,
|
||||||
gint percentage);
|
gint percentage);
|
||||||
|
void (*group_switch) (GstPlayBaseBin *play_base_bin);
|
||||||
|
|
||||||
/* action signals */
|
/* action signals */
|
||||||
gboolean (*link_stream) (GstPlayBaseBin *play_base_bin,
|
gboolean (*link_stream) (GstPlayBaseBin *play_base_bin,
|
||||||
|
|
|
@ -62,6 +62,9 @@ struct _GstPlayBin
|
||||||
|
|
||||||
/* our cache for the sinks */
|
/* our cache for the sinks */
|
||||||
GHashTable *cache;
|
GHashTable *cache;
|
||||||
|
|
||||||
|
/* boolean to see if we're currently switching groups */
|
||||||
|
gboolean group_switch;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GstPlayBinClass
|
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_init (GstPlayBin * play_bin);
|
||||||
static void gst_play_bin_dispose (GObject * object);
|
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 setup_sinks (GstPlayBaseBin * play_base_bin);
|
||||||
static void remove_sinks (GstPlayBin * play_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);
|
gstelement_klass->query = GST_DEBUG_FUNCPTR (gst_play_bin_query);
|
||||||
|
|
||||||
playbasebin_klass->setup_output_pads = setup_sinks;
|
playbasebin_klass->setup_output_pads = setup_sinks;
|
||||||
|
playbasebin_klass->group_switch = group_switch;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -217,6 +222,7 @@ gst_play_bin_init (GstPlayBin * play_bin)
|
||||||
play_bin->frame = NULL;
|
play_bin->frame = NULL;
|
||||||
play_bin->cache = g_hash_table_new_full (g_str_hash, g_str_equal,
|
play_bin->cache = g_hash_table_new_full (g_str_hash, g_str_equal,
|
||||||
NULL, (GDestroyNotify) gst_object_unref);
|
NULL, (GDestroyNotify) gst_object_unref);
|
||||||
|
play_bin->group_switch = FALSE;
|
||||||
|
|
||||||
/* no iterate is needed */
|
/* no iterate is needed */
|
||||||
GST_FLAG_SET (play_bin, GST_BIN_SELF_SCHEDULABLE);
|
GST_FLAG_SET (play_bin, GST_BIN_SELF_SCHEDULABLE);
|
||||||
|
@ -615,6 +621,13 @@ gen_vis_element (GstPlayBin * play_bin)
|
||||||
return element;
|
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 */
|
/* get rid of all installed sinks */
|
||||||
static void
|
static void
|
||||||
remove_sinks (GstPlayBin * play_bin)
|
remove_sinks (GstPlayBin * play_bin)
|
||||||
|
@ -624,6 +637,7 @@ remove_sinks (GstPlayBin * play_bin)
|
||||||
GstElement *element;
|
GstElement *element;
|
||||||
|
|
||||||
GST_DEBUG ("removesinks");
|
GST_DEBUG ("removesinks");
|
||||||
|
play_bin->group_switch = FALSE;
|
||||||
element = g_hash_table_lookup (play_bin->cache, "abin");
|
element = g_hash_table_lookup (play_bin->cache, "abin");
|
||||||
if (element != NULL) {
|
if (element != NULL) {
|
||||||
parent = gst_element_get_parent (element);
|
parent = gst_element_get_parent (element);
|
||||||
|
@ -755,7 +769,6 @@ setup_sinks (GstPlayBaseBin * play_base_bin)
|
||||||
} else {
|
} else {
|
||||||
sink = gen_audio_element (play_bin);
|
sink = gen_audio_element (play_bin);
|
||||||
}
|
}
|
||||||
//gst_element_link (group->type[GST_STREAM_TYPE_AUDIO - 1].preroll, sink);
|
|
||||||
add_sink (play_bin, sink,
|
add_sink (play_bin, sink,
|
||||||
gst_element_get_pad (group->type[GST_STREAM_TYPE_AUDIO - 1].preroll,
|
gst_element_get_pad (group->type[GST_STREAM_TYPE_AUDIO - 1].preroll,
|
||||||
"src"));
|
"src"));
|
||||||
|
@ -776,7 +789,6 @@ setup_sinks (GstPlayBaseBin * play_base_bin)
|
||||||
} else {
|
} else {
|
||||||
sink = gen_video_element (play_bin);
|
sink = gen_video_element (play_bin);
|
||||||
}
|
}
|
||||||
//gst_element_link (group->type[GST_STREAM_TYPE_VIDEO - 1].preroll, sink);
|
|
||||||
add_sink (play_bin, sink,
|
add_sink (play_bin, sink,
|
||||||
gst_element_get_pad (group->type[GST_STREAM_TYPE_VIDEO - 1].preroll,
|
gst_element_get_pad (group->type[GST_STREAM_TYPE_VIDEO - 1].preroll,
|
||||||
"src"));
|
"src"));
|
||||||
|
@ -802,7 +814,7 @@ gst_play_bin_change_state (GstElement * element)
|
||||||
case GST_STATE_PLAYING_TO_PAUSED:
|
case GST_STATE_PLAYING_TO_PAUSED:
|
||||||
/* Set audio sink state to NULL to release the sound device,
|
/* Set audio sink state to NULL to release the sound device,
|
||||||
* but only if we own it (else we might be in chain-transition). */
|
* 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_STATE (play_bin->audio_sink) == GST_STATE_PAUSED) {
|
||||||
gst_element_set_state (play_bin->audio_sink, GST_STATE_NULL);
|
gst_element_set_state (play_bin->audio_sink, GST_STATE_NULL);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue