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):
Debug.
* sys/v4l/v4lsrc_calls.c: (gst_v4lsrc_grab_frame):
{
ARG_0,
ARG_URI,
+ ARG_SUBURI,
ARG_THREADED,
ARG_NSTREAMS,
ARG_QUEUE_SIZE,
SETUP_OUTPUT_PADS_SIGNAL,
REMOVED_OUTPUT_PAD_SIGNAL,
BUFFERING_SIGNAL,
+ GROUP_SWITCH_SIGNAL,
LINK_STREAM_SIGNAL,
UNLINK_STREAM_SIGNAL,
LAST_SIGNAL
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));
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] =
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;
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);
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 =
/* 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;
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;
}
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;
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);
/* our cache for the sinks */
GHashTable *cache;
+
+ /* boolean to see if we're currently switching groups */
+ gboolean group_switch;
};
struct _GstPlayBinClass
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);
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
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);
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)
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);
} 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"));
} 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"));
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);
}