GstPlayChain chain;
GstPad *sinkpad;
GstElement *queue;
- GstElement *filter;
GstElement *conv;
GstElement *volume; /* element with the volume property */
gboolean sink_volume; /* if the volume was provided by the sink */
GstPlayChain chain;
GstPad *sinkpad;
GstElement *queue;
- GstElement *filter;
GstElement *conv;
GstElement *sink;
gboolean async;
/* properties */
GstElement *audio_sink;
GstElement *video_sink;
- GstElement *audio_filter;
- GstElement *video_filter;
GstElement *visualisation;
GstElement *text_sink;
gdouble volume;
PROP_TEXT_SINK,
PROP_SEND_EVENT_MODE,
PROP_FORCE_ASPECT_RATIO,
- PROP_VIDEO_FILTER,
- PROP_AUDIO_FILTER,
PROP_LAST
};
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
/**
- * GstPlaySink:video-filter:
- *
- * Set the video filter element/bin to use. Will apply on a best-effort basis
- * unless GST_PLAY_FLAG_FORCE_FILTERS is set. playsink must be in
- * %GST_STATE_NULL
- */
- g_object_class_install_property (gobject_klass, PROP_VIDEO_SINK,
- g_param_spec_object ("video-filter", "Video filter",
- "the video filter(s) to apply, if possible",
- GST_TYPE_ELEMENT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
- /**
- * GstPlaySink:audio-filter:
- *
- * Set the audio filter element/bin to use. Will apply on a best-effort basis
- * unless GST_PLAY_FLAG_FORCE_FILTERS is set. playsink must be in
- * %GST_STATE_NULL
- */
- g_object_class_install_property (gobject_klass, PROP_AUDIO_FILTER,
- g_param_spec_object ("audio-filter", "Audio filter",
- "the audio filter(s) to apply, if possible",
- GST_TYPE_ELEMENT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
- /**
* GstPlaySink:video-sink:
*
* Set the used video sink element. NULL will use the default sink. playsink
playsink = GST_PLAY_SINK (object);
- if (playsink->audio_filter != NULL) {
- gst_element_set_state (playsink->audio_filter, GST_STATE_NULL);
- gst_object_unref (playsink->audio_filter);
- playsink->audio_filter = NULL;
- }
- if (playsink->video_filter != NULL) {
- gst_element_set_state (playsink->video_filter, GST_STATE_NULL);
- gst_object_unref (playsink->video_filter);
- playsink->video_filter = NULL;
- }
if (playsink->audio_sink != NULL) {
gst_element_set_state (playsink->audio_sink, GST_STATE_NULL);
gst_object_unref (playsink->audio_sink);
return result;
}
-void
-gst_play_sink_set_filter (GstPlaySink * playsink, GstPlaySinkType type,
- GstElement * filter)
-{
- GstElement **elem = NULL, *old = NULL;
-
- GST_LOG_OBJECT (playsink,
- "Setting filter %" GST_PTR_FORMAT " as filter type %d", filter, type);
-
- GST_PLAY_SINK_LOCK (playsink);
- switch (type) {
- case GST_PLAY_SINK_TYPE_AUDIO:
- case GST_PLAY_SINK_TYPE_AUDIO_RAW:
- elem = &playsink->audio_filter;
- break;
- case GST_PLAY_SINK_TYPE_VIDEO:
- case GST_PLAY_SINK_TYPE_VIDEO_RAW:
- elem = &playsink->video_filter;
- break;
- default:
- break;
- }
- if (elem) {
- old = *elem;
- if (filter)
- gst_object_ref_sink (filter);
- *elem = filter;
- }
- GST_PLAY_SINK_UNLOCK (playsink);
-
- if (old) {
- /* Set the old filter to NULL if it is not used any longer */
- if (old != filter && !GST_OBJECT_PARENT (old))
- gst_element_set_state (old, GST_STATE_NULL);
- gst_object_unref (old);
- }
-}
-
-GstElement *
-gst_play_sink_get_filter (GstPlaySink * playsink, GstPlaySinkType type)
-{
- GstElement *result = NULL;
- GstElement *elem = NULL, *chainp = NULL;
-
- GST_PLAY_SINK_LOCK (playsink);
- switch (type) {
- case GST_PLAY_SINK_TYPE_AUDIO_RAW:
- {
- GstPlayAudioChain *chain;
- if ((chain = (GstPlayAudioChain *) playsink->audiochain))
- chainp = chain->filter;
- elem = playsink->audio_filter;
- break;
- }
- case GST_PLAY_SINK_TYPE_VIDEO_RAW:
- {
- GstPlayVideoChain *chain;
- if ((chain = (GstPlayVideoChain *) playsink->videochain))
- chainp = chain->filter;
- elem = playsink->video_filter;
- break;
- }
- default:
- break;
- }
- if (chainp) {
- /* we have an active chain with a filter, get the filter */
- result = gst_object_ref (chainp);
- }
- /* nothing found, return last configured filter */
- if (result == NULL && elem)
- result = gst_object_ref (elem);
- GST_PLAY_SINK_UNLOCK (playsink);
-
- return result;
-}
-
static GstPadProbeReturn
gst_play_sink_vis_blocked (GstPad * tee_pad, GstPadProbeInfo * info,
gpointer user_data)
/* make the element (bin) that contains the elements needed to perform
* video display.
*
- * +------------------------------------------------------------------------+
- * | vbin |
- * | +--------+ +-------+ +----------+ +----------+ +---------+ |
- * | | filter | | queue | |colorspace| |videoscale| |videosink| |
- * | +-sink src-sink src-sink src-sink src-sink | |
- * | | +--------+ +-------+ +----------+ +----------+ +---------+ |
- * sink-+ |
- * +------------------------------------------------------------------------+
+ * +------------------------------------------------------------+
+ * | vbin |
+ * | +-------+ +----------+ +----------+ +---------+ |
+ * | | queue | |colorspace| |videoscale| |videosink| |
+ * | +-sink src-sink src-sink src-sink | |
+ * | | +-------+ +----------+ +----------+ +---------+ |
+ * sink-+ |
+ * +------------------------------------------------------------+
*
*/
static GstPlayVideoChain *
}
}
- head = chain->sink;
- prev = NULL;
-
- /* add the video filter first, so everything is working with post-filter
- * samples */
- chain->filter = gst_play_sink_get_filter (playsink,
- GST_PLAY_SINK_TYPE_VIDEO_RAW);
- if (chain->filter) {
- if (!raw) {
- if (playsink->flags & GST_PLAY_FLAG_FORCE_FILTERS) {
- goto filter_with_nonraw;
- } else {
- GST_DEBUG_OBJECT (playsink,
- "skipping video filter since we're not raw");
- }
- } else {
- GST_DEBUG_OBJECT (playsink, "adding video filter");
- gst_bin_add (bin, chain->filter);
- head = prev = chain->filter;
- }
- }
-
/* decouple decoder from sink, this improves playback quite a lot since the
* decoder can continue while the sink blocks for synchronisation. We don't
* need a lot of buffers as this consumes a lot of memory and we don't want
GST_ELEMENT_WARNING (playsink, CORE, MISSING_PLUGIN,
(_("Missing element '%s' - check your GStreamer installation."),
"queue"), ("video rendering might be suboptimal"));
+ head = chain->sink;
+ prev = NULL;
} else {
g_object_set (G_OBJECT (chain->queue), "max-size-buffers", 3,
"max-size-bytes", 0, "max-size-time", (gint64) 0, "silent", TRUE, NULL);
gst_bin_add (bin, chain->queue);
- if (prev) {
- if (!gst_element_link_pads_full (prev, "src", chain->queue, "sink",
- GST_PAD_LINK_CHECK_TEMPLATE_CAPS))
- goto link_failed;
- } else {
- head = chain->queue;
- }
- prev = chain->queue;
+ head = prev = chain->queue;
}
GST_OBJECT_LOCK (playsink);
{
GST_ELEMENT_ERROR (playsink, CORE, PAD,
(NULL), ("Failed to configure the video sink."));
- goto cleanup;
+ /* checking sink made it READY */
+ gst_element_set_state (chain->sink, GST_STATE_NULL);
+ /* Remove chain from the bin to allow reuse later */
+ gst_bin_remove (bin, chain->sink);
+ free_chain ((GstPlayChain *) chain);
+ return NULL;
}
-filter_with_nonraw:
- {
- GST_ELEMENT_ERROR (playsink, CORE, NEGOTIATION,
- (NULL), ("Cannot apply video-filter on non-raw stream"));
- goto cleanup;
- }
-cleanup:
- /* checking sink made it READY */
- gst_element_set_state (chain->sink, GST_STATE_NULL);
- /* Remove chain from the bin to allow reuse later */
- gst_bin_remove (bin, chain->sink);
- free_chain ((GstPlayChain *) chain);
- return NULL;
}
static gboolean
chain = playsink->videochain;
- /* if we have a filter, and raw-ness changed, we have to force a rebuild */
- if (chain->filter && chain->chain.raw != raw)
- return FALSE;
-
chain->chain.raw = raw;
/* if the chain was active we don't do anything */
* We add a tee as the first element so that we can link the visualisation chain
* to it when requested.
*
- * +--------------------------------------------------------------+
- * | abin |
- * | +----------+ +--------+ +---------+ +-----------+ |
- * | | filter | | queue | | convbin | | audiosink | |
- * | +-sink src-sink src-sink src-sink | |
- * | | +----------+ +--------+ +---------+ +-----------+ |
- * sink-+ |
- * +--------------------------------------------------------------+
+ * +------------------------------------------------+
+ * | abin |
+ * | +---------+ +---------+ +-----------+ |
+ * | | queue | | convbin | | audiosink | |
+ * | +-sink src-sink src-sink | |
+ * | | +---------+ +---------+ +-----------+ |
+ * sink-+ |
+ * +------------------------------------------------+
*/
static GstPlayAudioChain *
gen_audio_chain (GstPlaySink * playsink, gboolean raw)
gst_object_ref_sink (bin);
gst_bin_add (bin, chain->sink);
- head = chain->sink;
- prev = NULL;
-
- /* add the audio filter first, so everything is working with post-filter
- * samples */
- chain->filter = gst_play_sink_get_filter (playsink,
- GST_PLAY_SINK_TYPE_AUDIO_RAW);
- if (chain->filter) {
- if (!raw) {
- if (playsink->flags & GST_PLAY_FLAG_FORCE_FILTERS) {
- goto filter_with_nonraw;
- } else {
- GST_DEBUG_OBJECT (playsink,
- "skipping video filter since we're not raw");
- }
- } else {
- GST_DEBUG_OBJECT (playsink, "adding video filter");
- gst_bin_add (bin, chain->filter);
- head = prev = chain->filter;
- }
- }
-
/* we have to add a queue when we need to decouple for the video sink in
* visualisations and for streamsynchronizer */
GST_DEBUG_OBJECT (playsink, "adding audio queue");
GST_ELEMENT_WARNING (playsink, CORE, MISSING_PLUGIN,
(_("Missing element '%s' - check your GStreamer installation."),
"queue"), ("audio playback and visualizations might not work"));
+ head = chain->sink;
+ prev = NULL;
} else {
g_object_set (chain->queue, "silent", TRUE, NULL);
gst_bin_add (bin, chain->queue);
- if (prev) {
- if (!gst_element_link_pads_full (prev, "src", chain->queue, "sink",
- GST_PAD_LINK_CHECK_TEMPLATE_CAPS))
- goto link_failed;
- } else {
- head = chain->queue;
- }
- prev = chain->queue;
+ prev = head = chain->queue;
}
/* find ts-offset element */
{
GST_ELEMENT_ERROR (playsink, CORE, PAD,
(NULL), ("Failed to configure the audio sink."));
- goto cleanup;
+ /* checking sink made it READY */
+ gst_element_set_state (chain->sink, GST_STATE_NULL);
+ /* Remove chain from the bin to allow reuse later */
+ gst_bin_remove (bin, chain->sink);
+ free_chain ((GstPlayChain *) chain);
+ return NULL;
}
-filter_with_nonraw:
- {
- GST_ELEMENT_ERROR (playsink, CORE, NEGOTIATION,
- (NULL), ("Cannot apply video-filter on non-raw stream"));
- goto cleanup;
- }
-cleanup:
- /* checking sink made it READY */
- gst_element_set_state (chain->sink, GST_STATE_NULL);
- /* Remove chain from the bin to allow reuse later */
- gst_bin_remove (bin, chain->sink);
- free_chain ((GstPlayChain *) chain);
- return NULL;
}
static gboolean
chain = playsink->audiochain;
conv = GST_PLAY_SINK_AUDIO_CONVERT_CAST (chain->conv);
- /* if we have a filter, and raw-ness changed, we have to force a rebuild */
- if (chain->filter && chain->chain.raw != raw)
- return FALSE;
-
chain->chain.raw = raw;
/* if the chain was active we don't do anything */
/* unlink the old plugin and unghost the pad */
gst_pad_unlink (playsink->vischain->vispeerpad,
playsink->vischain->vissinkpad);
- gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (playsink->vischain->
- srcpad), NULL);
+ gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (playsink->
+ vischain->srcpad), NULL);
/* set the old plugin to NULL and remove */
gst_element_set_state (playsink->vischain->vis, GST_STATE_NULL);
/* link pads */
gst_pad_link_full (playsink->vischain->vispeerpad,
playsink->vischain->vissinkpad, GST_PAD_LINK_CHECK_NOTHING);
- gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (playsink->vischain->
- srcpad), playsink->vischain->vissrcpad);
+ gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (playsink->
+ vischain->srcpad), playsink->vischain->vissrcpad);
} else {
srcpad =
gst_element_get_static_pad (playsink->vischain->chain.bin, "src");
(playsink->video_pad)));
if (blocked && playsink->video_block_id == 0) {
if (playsink->vis_pad_block_id)
- gst_pad_remove_probe (((GstPlayVisChain *) playsink->vischain)->
- blockpad, playsink->vis_pad_block_id);
+ gst_pad_remove_probe (((GstPlayVisChain *) playsink->
+ vischain)->blockpad, playsink->vis_pad_block_id);
playsink->vis_pad_block_id = 0;
playsink->video_block_id =
(playsink->audio_pad)));
if (blocked && playsink->audio_block_id == 0) {
if (playsink->vis_pad_block_id)
- gst_pad_remove_probe (((GstPlayVisChain *) playsink->vischain)->
- blockpad, playsink->vis_pad_block_id);
+ gst_pad_remove_probe (((GstPlayVisChain *) playsink->
+ vischain)->blockpad, playsink->vis_pad_block_id);
playsink->vis_pad_block_id = 0;
playsink->audio_block_id =
sinkpad_blocked_cb, playsink, NULL);
} else if (!blocked && playsink->audio_block_id) {
if (playsink->vis_pad_block_id)
- gst_pad_remove_probe (((GstPlayVisChain *) playsink->vischain)->
- blockpad, playsink->vis_pad_block_id);
+ gst_pad_remove_probe (((GstPlayVisChain *) playsink->
+ vischain)->blockpad, playsink->vis_pad_block_id);
playsink->vis_pad_block_id = 0;
gst_pad_remove_probe (opad, playsink->audio_block_id);
(playsink->text_pad)));
if (blocked && playsink->text_block_id == 0) {
if (playsink->vis_pad_block_id)
- gst_pad_remove_probe (((GstPlayVisChain *) playsink->vischain)->
- blockpad, playsink->vis_pad_block_id);
+ gst_pad_remove_probe (((GstPlayVisChain *) playsink->
+ vischain)->blockpad, playsink->vis_pad_block_id);
playsink->vis_pad_block_id = 0;
playsink->text_block_id =
GST_PAD_CAST (gst_proxy_pad_get_internal (GST_PROXY_PAD (res)));
if (playsink->vis_pad_block_id)
- gst_pad_remove_probe (((GstPlayVisChain *) playsink->vischain)->
- blockpad, playsink->vis_pad_block_id);
+ gst_pad_remove_probe (((GstPlayVisChain *) playsink->
+ vischain)->blockpad, playsink->vis_pad_block_id);
playsink->vis_pad_block_id = 0;
*block_id =
audio_set_blocked (playsink, FALSE);
text_set_blocked (playsink, FALSE);
if (playsink->vis_pad_block_id)
- gst_pad_remove_probe (((GstPlayVisChain *) playsink->vischain)->
- blockpad, playsink->vis_pad_block_id);
+ gst_pad_remove_probe (((GstPlayVisChain *) playsink->
+ vischain)->blockpad, playsink->vis_pad_block_id);
playsink->vis_pad_block_id = 0;
GST_PLAY_SINK_UNLOCK (playsink);
case PROP_AV_OFFSET:
gst_play_sink_set_av_offset (playsink, g_value_get_int64 (value));
break;
- case PROP_VIDEO_FILTER:
- gst_play_sink_set_filter (playsink, GST_PLAY_SINK_TYPE_VIDEO,
- g_value_get_object (value));
- break;
- case PROP_AUDIO_FILTER:
- gst_play_sink_set_filter (playsink, GST_PLAY_SINK_TYPE_AUDIO,
- g_value_get_object (value));
- break;
case PROP_VIDEO_SINK:
gst_play_sink_set_sink (playsink, GST_PLAY_SINK_TYPE_VIDEO,
g_value_get_object (value));
case PROP_AV_OFFSET:
g_value_set_int64 (value, gst_play_sink_get_av_offset (playsink));
break;
- case PROP_VIDEO_FILTER:
- g_value_take_object (value, gst_play_sink_get_filter (playsink,
- GST_PLAY_SINK_TYPE_VIDEO));
- break;
- case PROP_AUDIO_FILTER:
- g_value_take_object (value, gst_play_sink_get_filter (playsink,
- GST_PLAY_SINK_TYPE_AUDIO));
- break;
case PROP_VIDEO_SINK:
g_value_take_object (value, gst_play_sink_get_sink (playsink,
GST_PLAY_SINK_TYPE_VIDEO));