mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-17 03:35:21 +00:00
gst/playback/gstplay-marshal.list: Added marshal for streamselector Tags.
Original commit message from CVS: * gst/playback/gstplay-marshal.list: Added marshal for streamselector Tags. * gst/playback/gstplaybasebin.c: (set_active_source): Streamselector now selects pads based on the pad object instead of its name. * gst/playback/gstplaybin2.c: (gst_play_bin_class_init), (init_group), (gst_play_bin_init), (get_group), (get_tags), (gst_play_bin_get_video_tags), (gst_play_bin_get_audio_tags), (gst_play_bin_get_text_tags), (gst_play_bin_set_current_video_stream), (gst_play_bin_set_current_audio_stream), (gst_play_bin_set_current_text_stream), (gst_play_bin_set_property), (gst_play_bin_get_property), (pad_added_cb), (pad_removed_cb), (autoplug_select_cb): Remove option to mute streams with the current-a/v/t property, we have this functionality in the flags. Add signals to notify when the number of A/V/T channels changed. Add action signals to get tags for the A/V/T streams. Implement setting the current A/V/T stream. Rearrange some things to simplify stream selection. Implement volume. * gst/playback/gstplaysink.c: (gst_play_sink_set_volume), (gst_play_sink_get_volume), (gst_play_sink_set_property), (gst_play_sink_get_property), (gen_video_chain), (gen_audio_chain), (activate_vis), (gst_play_sink_reconfigure): * gst/playback/gstplaysink.h: Add and implement volume setting methods. * gst/playback/gststreamselector.c: (gst_selector_pad_class_init), (gst_selector_pad_finalize), (gst_selector_pad_get_property), (gst_selector_pad_event), (gst_stream_selector_class_init), (gst_stream_selector_init), (gst_stream_selector_finalize), (gst_stream_selector_set_property), (gst_stream_selector_get_property), (gst_stream_selector_get_linked_pad), (gst_stream_selector_request_new_pad): * gst/playback/gststreamselector.h: Add pad properties for tags and status of pads. Keep tags on pads. Make active pad selection based on pad object instead of name.
This commit is contained in:
parent
fcb1b6634b
commit
c8bb67d0ca
9 changed files with 579 additions and 87 deletions
46
ChangeLog
46
ChangeLog
|
@ -1,3 +1,49 @@
|
|||
2008-02-08 Wim Taymans <wim.taymans@collabora.co.uk>
|
||||
|
||||
* gst/playback/gstplay-marshal.list:
|
||||
Added marshal for streamselector Tags.
|
||||
|
||||
* gst/playback/gstplaybasebin.c: (set_active_source):
|
||||
Streamselector now selects pads based on the pad object instead of its
|
||||
name.
|
||||
|
||||
* gst/playback/gstplaybin2.c: (gst_play_bin_class_init),
|
||||
(init_group), (gst_play_bin_init), (get_group), (get_tags),
|
||||
(gst_play_bin_get_video_tags), (gst_play_bin_get_audio_tags),
|
||||
(gst_play_bin_get_text_tags),
|
||||
(gst_play_bin_set_current_video_stream),
|
||||
(gst_play_bin_set_current_audio_stream),
|
||||
(gst_play_bin_set_current_text_stream),
|
||||
(gst_play_bin_set_property), (gst_play_bin_get_property),
|
||||
(pad_added_cb), (pad_removed_cb), (autoplug_select_cb):
|
||||
Remove option to mute streams with the current-a/v/t property, we have
|
||||
this functionality in the flags.
|
||||
Add signals to notify when the number of A/V/T channels changed.
|
||||
Add action signals to get tags for the A/V/T streams.
|
||||
Implement setting the current A/V/T stream.
|
||||
Rearrange some things to simplify stream selection.
|
||||
Implement volume.
|
||||
|
||||
* gst/playback/gstplaysink.c: (gst_play_sink_set_volume),
|
||||
(gst_play_sink_get_volume), (gst_play_sink_set_property),
|
||||
(gst_play_sink_get_property), (gen_video_chain), (gen_audio_chain),
|
||||
(activate_vis), (gst_play_sink_reconfigure):
|
||||
* gst/playback/gstplaysink.h:
|
||||
Add and implement volume setting methods.
|
||||
|
||||
* gst/playback/gststreamselector.c: (gst_selector_pad_class_init),
|
||||
(gst_selector_pad_finalize), (gst_selector_pad_get_property),
|
||||
(gst_selector_pad_event), (gst_stream_selector_class_init),
|
||||
(gst_stream_selector_init), (gst_stream_selector_finalize),
|
||||
(gst_stream_selector_set_property),
|
||||
(gst_stream_selector_get_property),
|
||||
(gst_stream_selector_get_linked_pad),
|
||||
(gst_stream_selector_request_new_pad):
|
||||
* gst/playback/gststreamselector.h:
|
||||
Add pad properties for tags and status of pads.
|
||||
Keep tags on pads.
|
||||
Make active pad selection based on pad object instead of name.
|
||||
|
||||
2008-02-08 Stefan Kost <ensonic@users.sf.net>
|
||||
|
||||
* configure.ac:
|
||||
|
|
2
common
2
common
|
@ -1 +1 @@
|
|||
Subproject commit aa24bcc28323422b29ba41874a4a98b6b6ddf63a
|
||||
Subproject commit 961bb6bd997d7c8da6058534e86b4a1361c0fcea
|
|
@ -5,3 +5,4 @@ VOID:OBJECT,BOOLEAN
|
|||
ENUM:OBJECT,OBJECT,BOXED
|
||||
ENUM:OBJECT,OBJECT,OBJECT
|
||||
BOXED:OBJECT,OBJECT,BOXED
|
||||
BOXED:INT
|
||||
|
|
|
@ -2443,8 +2443,7 @@ set_active_source (GstPlayBaseBin * play_base_bin,
|
|||
"pb_sel_pad"));
|
||||
|
||||
if (sel && sel_pad != NULL) {
|
||||
g_object_set (G_OBJECT (sel), "active-pad", GST_PAD_NAME (sel_pad),
|
||||
NULL);
|
||||
g_object_set (G_OBJECT (sel), "active-pad", sel_pad, NULL);
|
||||
}
|
||||
|
||||
have_active = TRUE;
|
||||
|
@ -2463,7 +2462,7 @@ set_active_source (GstPlayBaseBin * play_base_bin,
|
|||
|
||||
if (!have_active) {
|
||||
GST_LOG ("Muting group type: %d", type);
|
||||
g_object_set (sel, "active-pad", "", NULL);
|
||||
g_object_set (sel, "active-pad", NULL, NULL);
|
||||
} else {
|
||||
GST_LOG ("Unmuting group type: %d", type);
|
||||
}
|
||||
|
|
|
@ -249,6 +249,7 @@
|
|||
#include <gst/pbutils/pbutils.h>
|
||||
|
||||
#include "gstplay-enum.h"
|
||||
#include "gstplay-marshal.h"
|
||||
#include "gstplaysink.h"
|
||||
#include "gstfactorylists.h"
|
||||
#include "gststreaminfo.h"
|
||||
|
@ -277,7 +278,7 @@ struct _GstSourceSelect
|
|||
GstPlaySinkType type; /* the sink pad type of the selector */
|
||||
|
||||
GstElement *selector; /* the selector */
|
||||
gint current; /* the currently selected stream */
|
||||
GPtrArray *channels;
|
||||
GstPad *srcpad; /* the source pad of the selector */
|
||||
GstPad *sinkpad; /* the sinkpad of the sink when the selector is linked */
|
||||
};
|
||||
|
@ -298,6 +299,10 @@ struct _GstSourceGroup
|
|||
GstElement *source;
|
||||
gchar *subencoding; /* encoding to propagate to the subtitle elements */
|
||||
|
||||
GPtrArray *video_channels; /* links to selector pads */
|
||||
GPtrArray *audio_channels; /* links to selector pads */
|
||||
GPtrArray *text_channels; /* links to selector pads */
|
||||
|
||||
/* uridecodebins for uri and subtitle uri */
|
||||
GstElement *uridecodebin;
|
||||
GstElement *suburidecodebin;
|
||||
|
@ -319,6 +324,9 @@ struct _GstPlayBin
|
|||
|
||||
/* properties */
|
||||
guint connection_speed; /* connection speed in bits/sec (0 = unknown) */
|
||||
gint current_video; /* the currently selected stream */
|
||||
gint current_audio; /* the currently selected stream */
|
||||
gint current_text; /* the currently selected stream */
|
||||
|
||||
/* our play sink */
|
||||
GstPlaySink *playsink;
|
||||
|
@ -330,7 +338,15 @@ struct _GstPlayBinClass
|
|||
{
|
||||
GstPipelineClass parent_class;
|
||||
|
||||
void (*about_to_finish) (void);
|
||||
void (*about_to_finish) (GstPlayBin * playbin);
|
||||
|
||||
void (*video_changed) (GstPlayBin * playbin);
|
||||
void (*audio_changed) (GstPlayBin * playbin);
|
||||
void (*text_changed) (GstPlayBin * playbin);
|
||||
|
||||
GstTagList *(*get_video_tags) (GstPlayBin * playbin, gint stream);
|
||||
GstTagList *(*get_audio_tags) (GstPlayBin * playbin, gint stream);
|
||||
GstTagList *(*get_text_tags) (GstPlayBin * playbin, gint stream);
|
||||
};
|
||||
|
||||
/* props */
|
||||
|
@ -381,6 +397,12 @@ enum
|
|||
enum
|
||||
{
|
||||
SIGNAL_ABOUT_TO_FINISH,
|
||||
SIGNAL_VIDEO_CHANGED,
|
||||
SIGNAL_AUDIO_CHANGED,
|
||||
SIGNAL_TEXT_CHANGED,
|
||||
SIGNAL_GET_VIDEO_TAGS,
|
||||
SIGNAL_GET_AUDIO_TAGS,
|
||||
SIGNAL_GET_TEXT_TAGS,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
|
@ -398,6 +420,13 @@ static GstStateChangeReturn gst_play_bin_change_state (GstElement * element,
|
|||
|
||||
static void gst_play_bin_handle_message (GstBin * bin, GstMessage * message);
|
||||
|
||||
static GstStructure *gst_play_bin_get_video_tags (GstPlayBin * playbin,
|
||||
gint stream);
|
||||
static GstStructure *gst_play_bin_get_audio_tags (GstPlayBin * playbin,
|
||||
gint stream);
|
||||
static GstStructure *gst_play_bin_get_text_tags (GstPlayBin * playbin,
|
||||
gint stream);
|
||||
|
||||
static gboolean setup_next_source (GstPlayBin * playbin);
|
||||
|
||||
static GstElementClass *parent_class;
|
||||
|
@ -495,13 +524,11 @@ gst_play_bin_class_init (GstPlayBinClass * klass)
|
|||
*
|
||||
* Get or set the currently playing video stream. By default the first video
|
||||
* stream with data is played.
|
||||
*
|
||||
* Setting this property to -2 will disable the video stream.
|
||||
*/
|
||||
g_object_class_install_property (gobject_klass, PROP_CURRENT_VIDEO,
|
||||
g_param_spec_int ("current-video", "Current Video",
|
||||
"Currently playing video stream (-1 = auto, -2 = none)",
|
||||
-2, G_MAXINT, -1, G_PARAM_READWRITE));
|
||||
"Currently playing video stream (-1 = auto)",
|
||||
-1, G_MAXINT, -1, G_PARAM_READWRITE));
|
||||
/**
|
||||
* GstPlayBin:n-audio
|
||||
*
|
||||
|
@ -515,13 +542,11 @@ gst_play_bin_class_init (GstPlayBinClass * klass)
|
|||
*
|
||||
* Get or set the currently playing audio stream. By default the first audio
|
||||
* stream with data is played.
|
||||
*
|
||||
* Setting this property to -2 will disable the audio stream.
|
||||
*/
|
||||
g_object_class_install_property (gobject_klass, PROP_CURRENT_AUDIO,
|
||||
g_param_spec_int ("current-audio", "Current audio",
|
||||
"Currently playing audio stream (-1 = none, -2 = none)",
|
||||
-2, G_MAXINT, -1, G_PARAM_READWRITE));
|
||||
"Currently playing audio stream (-1 = auto)",
|
||||
-1, G_MAXINT, -1, G_PARAM_READWRITE));
|
||||
/**
|
||||
* GstPlayBin:n-text
|
||||
*
|
||||
|
@ -533,15 +558,13 @@ gst_play_bin_class_init (GstPlayBinClass * klass)
|
|||
/**
|
||||
* GstPlayBin:current-text
|
||||
*
|
||||
* Get or set the currently playing subtitle stream. By default the first audio
|
||||
* stream with data is played.
|
||||
*
|
||||
* Setting this property to -2 will disable the text stream.
|
||||
* Get or set the currently playing subtitle stream. By default the first
|
||||
* subtitle stream with data is played.
|
||||
*/
|
||||
g_object_class_install_property (gobject_klass, PROP_CURRENT_TEXT,
|
||||
g_param_spec_int ("current-text", "Current Text",
|
||||
"Currently playing text stream (-1 = none, -2 = none)",
|
||||
-2, G_MAXINT, -1, G_PARAM_READWRITE));
|
||||
"Currently playing text stream (-1 = auto)",
|
||||
-1, G_MAXINT, -1, G_PARAM_READWRITE));
|
||||
|
||||
g_object_class_install_property (gobject_klass, PROP_SUBTITLE_ENCODING,
|
||||
g_param_spec_string ("subtitle-encoding", "subtitle encoding",
|
||||
|
@ -582,6 +605,7 @@ gst_play_bin_class_init (GstPlayBinClass * klass)
|
|||
0, G_MAXUINT, DEFAULT_CONNECTION_SPEED, G_PARAM_READWRITE));
|
||||
/**
|
||||
* GstPlayBin::about-to-finish:
|
||||
* @playbin: a #GstPlayBin
|
||||
*
|
||||
* This signal is emitted when the current uri is about to finish. You can
|
||||
* set the next-uri and next-suburi to make sure that playback continues.
|
||||
|
@ -592,6 +616,99 @@ gst_play_bin_class_init (GstPlayBinClass * klass)
|
|||
G_STRUCT_OFFSET (GstPlayBinClass, about_to_finish), NULL, NULL,
|
||||
gst_marshal_VOID__VOID, G_TYPE_NONE, 0, G_TYPE_NONE);
|
||||
|
||||
/**
|
||||
* GstPlayBin::video-changed
|
||||
* @playbin: a #GstPlayBin
|
||||
*
|
||||
* This signal is emited whenever the number or order of the video
|
||||
* streams has changed. The application will most likely want to select
|
||||
* a new video stream.
|
||||
*/
|
||||
gst_play_bin_signals[SIGNAL_VIDEO_CHANGED] =
|
||||
g_signal_new ("video-changed", G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (GstPlayBinClass, video_changed), NULL, NULL,
|
||||
gst_marshal_VOID__VOID, G_TYPE_NONE, 0, G_TYPE_NONE);
|
||||
/**
|
||||
* GstPlayBin::audio-changed
|
||||
* @playbin: a #GstPlayBin
|
||||
*
|
||||
* This signal is emited whenever the number or order of the audio
|
||||
* streams has changed. The application will most likely want to select
|
||||
* a new audio stream.
|
||||
*/
|
||||
gst_play_bin_signals[SIGNAL_AUDIO_CHANGED] =
|
||||
g_signal_new ("audio-changed", G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (GstPlayBinClass, audio_changed), NULL, NULL,
|
||||
gst_marshal_VOID__VOID, G_TYPE_NONE, 0, G_TYPE_NONE);
|
||||
/**
|
||||
* GstPlayBin::text-changed
|
||||
* @playbin: a #GstPlayBin
|
||||
*
|
||||
* This signal is emited whenever the number or order of the text
|
||||
* streams has changed. The application will most likely want to select
|
||||
* a new text stream.
|
||||
*/
|
||||
gst_play_bin_signals[SIGNAL_TEXT_CHANGED] =
|
||||
g_signal_new ("text-changed", G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (GstPlayBinClass, text_changed), NULL, NULL,
|
||||
gst_marshal_VOID__VOID, G_TYPE_NONE, 0, G_TYPE_NONE);
|
||||
|
||||
/**
|
||||
* GstPlayBin::get-video-tags
|
||||
* @playbin: a #GstPlayBin
|
||||
* @stream: a video stream number
|
||||
*
|
||||
* Action signal to retrieve the tags of a specific video stream number.
|
||||
* This information can be used to select a stream.
|
||||
*
|
||||
* Returns: a GstTagList with tags or NULL when the stream number does not
|
||||
* exist.
|
||||
*/
|
||||
gst_play_bin_signals[SIGNAL_GET_VIDEO_TAGS] =
|
||||
g_signal_new ("get-video-tags", G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
|
||||
G_STRUCT_OFFSET (GstPlayBinClass, get_video_tags), NULL, NULL,
|
||||
gst_play_marshal_BOXED__INT, GST_TYPE_TAG_LIST, 1, G_TYPE_INT);
|
||||
/**
|
||||
* GstPlayBin::get-audio-tags
|
||||
* @playbin: a #GstPlayBin
|
||||
* @stream: an audio stream number
|
||||
*
|
||||
* Action signal to retrieve the tags of a specific audio stream number.
|
||||
* This information can be used to select a stream.
|
||||
*
|
||||
* Returns: a GstTagList with tags or NULL when the stream number does not
|
||||
* exist.
|
||||
*/
|
||||
gst_play_bin_signals[SIGNAL_GET_AUDIO_TAGS] =
|
||||
g_signal_new ("get-audio-tags", G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
|
||||
G_STRUCT_OFFSET (GstPlayBinClass, get_audio_tags), NULL, NULL,
|
||||
gst_play_marshal_BOXED__INT, GST_TYPE_TAG_LIST, 1, G_TYPE_INT);
|
||||
/**
|
||||
* GstPlayBin::get-text-tags
|
||||
* @playbin: a #GstPlayBin
|
||||
* @stream: a text stream number
|
||||
*
|
||||
* Action signal to retrieve the tags of a specific text stream number.
|
||||
* This information can be used to select a stream.
|
||||
*
|
||||
* Returns: a GstTagList with tags or NULL when the stream number does not
|
||||
* exist.
|
||||
*/
|
||||
gst_play_bin_signals[SIGNAL_GET_TEXT_TAGS] =
|
||||
g_signal_new ("get-text-tags", G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
|
||||
G_STRUCT_OFFSET (GstPlayBinClass, get_text_tags), NULL, NULL,
|
||||
gst_play_marshal_BOXED__INT, GST_TYPE_TAG_LIST, 1, G_TYPE_INT);
|
||||
|
||||
klass->get_video_tags = gst_play_bin_get_video_tags;
|
||||
klass->get_audio_tags = gst_play_bin_get_audio_tags;
|
||||
klass->get_text_tags = gst_play_bin_get_text_tags;
|
||||
|
||||
gst_element_class_set_details (gstelement_klass, &gst_play_bin_details);
|
||||
|
||||
gstelement_klass->change_state =
|
||||
|
@ -604,18 +721,27 @@ gst_play_bin_class_init (GstPlayBinClass * klass)
|
|||
static void
|
||||
init_group (GstPlayBin * playbin, GstSourceGroup * group)
|
||||
{
|
||||
/* store the array for the different channels */
|
||||
group->video_channels = g_ptr_array_new ();
|
||||
group->audio_channels = g_ptr_array_new ();
|
||||
group->text_channels = g_ptr_array_new ();
|
||||
/* init selectors */
|
||||
group->playbin = playbin;
|
||||
group->selector[0].media = "audio/x-raw-";
|
||||
group->selector[0].type = GST_PLAY_SINK_TYPE_AUDIO_RAW;
|
||||
group->selector[0].channels = group->audio_channels;
|
||||
group->selector[1].media = "audio/";
|
||||
group->selector[1].type = GST_PLAY_SINK_TYPE_AUDIO;
|
||||
group->selector[1].channels = group->audio_channels;
|
||||
group->selector[2].media = "video/x-raw-";
|
||||
group->selector[2].type = GST_PLAY_SINK_TYPE_VIDEO_RAW;
|
||||
group->selector[2].channels = group->video_channels;
|
||||
group->selector[3].media = "video/";
|
||||
group->selector[3].type = GST_PLAY_SINK_TYPE_VIDEO;
|
||||
group->selector[3].channels = group->video_channels;
|
||||
group->selector[4].media = "text/";
|
||||
group->selector[4].type = GST_PLAY_SINK_TYPE_TEXT;
|
||||
group->selector[4].channels = group->text_channels;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -639,7 +765,9 @@ gst_play_bin_init (GstPlayBin * playbin)
|
|||
gst_bin_add (GST_BIN_CAST (playbin), GST_ELEMENT_CAST (playbin->playsink));
|
||||
gst_play_sink_set_flags (playbin->playsink, DEFAULT_FLAGS);
|
||||
|
||||
/* get the caps */
|
||||
playbin->current_video = DEFAULT_CURRENT_VIDEO;
|
||||
playbin->current_audio = DEFAULT_CURRENT_AUDIO;
|
||||
playbin->current_text = DEFAULT_CURRENT_TEXT;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -698,6 +826,202 @@ done:
|
|||
GST_OBJECT_UNLOCK (playbin);
|
||||
}
|
||||
|
||||
/* get the currently playing group or if nothing is playing, the next
|
||||
* group. Must be called with the LOCK. */
|
||||
static GstSourceGroup *
|
||||
get_group (GstPlayBin * playbin)
|
||||
{
|
||||
GstSourceGroup *result;
|
||||
|
||||
if (!(result = playbin->curr_group))
|
||||
result = playbin->next_group;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static GstTagList *
|
||||
get_tags (GstPlayBin * playbin, GPtrArray * channels, gint stream)
|
||||
{
|
||||
GstTagList *result;
|
||||
GstPad *sinkpad;
|
||||
|
||||
if (!channels || channels->len < stream)
|
||||
return NULL;
|
||||
|
||||
sinkpad = g_ptr_array_index (channels, stream);
|
||||
g_object_get (sinkpad, "tags", &result, NULL);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static GstTagList *
|
||||
gst_play_bin_get_video_tags (GstPlayBin * playbin, gint stream)
|
||||
{
|
||||
GstTagList *result;
|
||||
GstSourceGroup *group;
|
||||
|
||||
GST_OBJECT_LOCK (playbin);
|
||||
group = get_group (playbin);
|
||||
result = get_tags (playbin, group->video_channels, stream);
|
||||
GST_OBJECT_UNLOCK (playbin);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static GstTagList *
|
||||
gst_play_bin_get_audio_tags (GstPlayBin * playbin, gint stream)
|
||||
{
|
||||
GstTagList *result;
|
||||
GstSourceGroup *group;
|
||||
|
||||
GST_OBJECT_LOCK (playbin);
|
||||
group = get_group (playbin);
|
||||
result = get_tags (playbin, group->audio_channels, stream);
|
||||
GST_OBJECT_UNLOCK (playbin);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static GstTagList *
|
||||
gst_play_bin_get_text_tags (GstPlayBin * playbin, gint stream)
|
||||
{
|
||||
GstTagList *result;
|
||||
GstSourceGroup *group;
|
||||
|
||||
GST_OBJECT_LOCK (playbin);
|
||||
group = get_group (playbin);
|
||||
result = get_tags (playbin, group->text_channels, stream);
|
||||
GST_OBJECT_UNLOCK (playbin);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_play_bin_set_current_video_stream (GstPlayBin * playbin, gint stream)
|
||||
{
|
||||
GstSourceGroup *group;
|
||||
GPtrArray *channels;
|
||||
GstPad *sinkpad;
|
||||
|
||||
GST_OBJECT_LOCK (playbin);
|
||||
group = get_group (playbin);
|
||||
if (!(channels = group->video_channels))
|
||||
goto no_channels;
|
||||
|
||||
if (stream == -1 || channels->len < stream) {
|
||||
sinkpad = NULL;
|
||||
} else {
|
||||
/* take channel from selected stream */
|
||||
sinkpad = g_ptr_array_index (channels, stream);
|
||||
}
|
||||
|
||||
if (sinkpad)
|
||||
gst_object_ref (sinkpad);
|
||||
GST_OBJECT_UNLOCK (playbin);
|
||||
|
||||
if (sinkpad) {
|
||||
GstObject *selector;
|
||||
|
||||
if ((selector = gst_pad_get_parent (sinkpad))) {
|
||||
/* activate the selected pad */
|
||||
g_object_set (selector, "active-pad", sinkpad, NULL);
|
||||
gst_object_unref (selector);
|
||||
}
|
||||
gst_object_unref (sinkpad);
|
||||
}
|
||||
return TRUE;
|
||||
|
||||
no_channels:
|
||||
{
|
||||
GST_OBJECT_UNLOCK (playbin);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_play_bin_set_current_audio_stream (GstPlayBin * playbin, gint stream)
|
||||
{
|
||||
GstSourceGroup *group;
|
||||
GPtrArray *channels;
|
||||
GstPad *sinkpad;
|
||||
|
||||
GST_OBJECT_LOCK (playbin);
|
||||
group = get_group (playbin);
|
||||
if (!(channels = group->audio_channels))
|
||||
goto no_channels;
|
||||
|
||||
if (stream == -1 || channels->len < stream) {
|
||||
sinkpad = NULL;
|
||||
} else {
|
||||
/* take channel from selected stream */
|
||||
sinkpad = g_ptr_array_index (channels, stream);
|
||||
}
|
||||
|
||||
if (sinkpad)
|
||||
gst_object_ref (sinkpad);
|
||||
GST_OBJECT_UNLOCK (playbin);
|
||||
|
||||
if (sinkpad) {
|
||||
GstObject *selector;
|
||||
|
||||
if ((selector = gst_pad_get_parent (sinkpad))) {
|
||||
/* activate the selected pad */
|
||||
g_object_set (selector, "active-pad", sinkpad, NULL);
|
||||
gst_object_unref (selector);
|
||||
}
|
||||
gst_object_unref (sinkpad);
|
||||
}
|
||||
return TRUE;
|
||||
|
||||
no_channels:
|
||||
{
|
||||
GST_OBJECT_UNLOCK (playbin);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_play_bin_set_current_text_stream (GstPlayBin * playbin, gint stream)
|
||||
{
|
||||
GstSourceGroup *group;
|
||||
GPtrArray *channels;
|
||||
GstPad *sinkpad;
|
||||
|
||||
GST_OBJECT_LOCK (playbin);
|
||||
group = get_group (playbin);
|
||||
if (!(channels = group->text_channels))
|
||||
goto no_channels;
|
||||
|
||||
if (stream == -1 || channels->len < stream) {
|
||||
sinkpad = NULL;
|
||||
} else {
|
||||
/* take channel from selected stream */
|
||||
sinkpad = g_ptr_array_index (channels, stream);
|
||||
}
|
||||
|
||||
if (sinkpad)
|
||||
gst_object_ref (sinkpad);
|
||||
GST_OBJECT_UNLOCK (playbin);
|
||||
|
||||
if (sinkpad) {
|
||||
GstObject *selector;
|
||||
|
||||
if ((selector = gst_pad_get_parent (sinkpad))) {
|
||||
/* activate the selected pad */
|
||||
g_object_set (selector, "active-pad", sinkpad, NULL);
|
||||
gst_object_unref (selector);
|
||||
}
|
||||
gst_object_unref (sinkpad);
|
||||
}
|
||||
return TRUE;
|
||||
|
||||
no_channels:
|
||||
{
|
||||
GST_OBJECT_UNLOCK (playbin);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gst_play_bin_set_property (GObject * object, guint prop_id,
|
||||
const GValue * value, GParamSpec * pspec)
|
||||
|
@ -717,10 +1041,13 @@ gst_play_bin_set_property (GObject * object, guint prop_id,
|
|||
gst_play_sink_set_flags (playbin->playsink, g_value_get_flags (value));
|
||||
break;
|
||||
case PROP_CURRENT_VIDEO:
|
||||
gst_play_bin_set_current_video_stream (playbin, g_value_get_int (value));
|
||||
break;
|
||||
case PROP_CURRENT_AUDIO:
|
||||
gst_play_bin_set_current_audio_stream (playbin, g_value_get_int (value));
|
||||
break;
|
||||
case PROP_CURRENT_TEXT:
|
||||
gst_play_bin_set_current_text_stream (playbin, g_value_get_int (value));
|
||||
break;
|
||||
case PROP_SUBTITLE_ENCODING:
|
||||
break;
|
||||
|
@ -731,6 +1058,7 @@ gst_play_bin_set_property (GObject * object, guint prop_id,
|
|||
case PROP_VIS_PLUGIN:
|
||||
break;
|
||||
case PROP_VOLUME:
|
||||
gst_play_sink_set_volume (playbin->playsink, g_value_get_double (value));
|
||||
break;
|
||||
case PROP_FONT_DESC:
|
||||
break;
|
||||
|
@ -745,32 +1073,6 @@ gst_play_bin_set_property (GObject * object, guint prop_id,
|
|||
}
|
||||
}
|
||||
|
||||
/* get the currently playing group or if nothing is playing, the next
|
||||
* group. Must be called with the LOCK. */
|
||||
static GstSourceGroup *
|
||||
get_group (GstPlayBin * playbin)
|
||||
{
|
||||
GstSourceGroup *result;
|
||||
|
||||
if (!(result = playbin->curr_group))
|
||||
result = playbin->next_group;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static gint
|
||||
get_n_pads (GstSourceSelect * select)
|
||||
{
|
||||
gint res;
|
||||
|
||||
if (select->selector == NULL)
|
||||
return 0;
|
||||
|
||||
g_object_get (select->selector, "n-pads", &res, NULL);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_play_bin_get_property (GObject * object, guint prop_id, GValue * value,
|
||||
GParamSpec * pspec)
|
||||
|
@ -808,37 +1110,53 @@ gst_play_bin_get_property (GObject * object, guint prop_id, GValue * value,
|
|||
case PROP_N_VIDEO:
|
||||
{
|
||||
GstSourceGroup *group;
|
||||
gint n_rawvideo, n_video;
|
||||
gint n_video;
|
||||
|
||||
GST_OBJECT_LOCK (playbin);
|
||||
group = get_group (playbin);
|
||||
n_rawvideo = get_n_pads (&group->selector[2]);
|
||||
n_video = get_n_pads (&group->selector[3]);
|
||||
g_value_set_int (value, n_rawvideo + n_video);
|
||||
n_video = (group->video_channels ? group->video_channels->len : 0);
|
||||
g_value_set_int (value, n_video);
|
||||
GST_OBJECT_UNLOCK (playbin);
|
||||
break;
|
||||
}
|
||||
case PROP_CURRENT_VIDEO:
|
||||
GST_OBJECT_LOCK (playbin);
|
||||
g_value_set_int (value, playbin->current_video);
|
||||
GST_OBJECT_UNLOCK (playbin);
|
||||
break;
|
||||
case PROP_N_AUDIO:
|
||||
{
|
||||
GstSourceGroup *group;
|
||||
gint n_rawaudio, n_audio;
|
||||
gint n_audio;
|
||||
|
||||
GST_OBJECT_LOCK (playbin);
|
||||
group = get_group (playbin);
|
||||
n_rawaudio = get_n_pads (&group->selector[0]);
|
||||
n_audio = get_n_pads (&group->selector[1]);
|
||||
g_value_set_int (value, n_rawaudio + n_audio);
|
||||
n_audio = (group->audio_channels ? group->audio_channels->len : 0);
|
||||
g_value_set_int (value, n_audio);
|
||||
GST_OBJECT_UNLOCK (playbin);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case PROP_CURRENT_AUDIO:
|
||||
GST_OBJECT_LOCK (playbin);
|
||||
g_value_set_int (value, playbin->current_audio);
|
||||
GST_OBJECT_UNLOCK (playbin);
|
||||
break;
|
||||
case PROP_N_TEXT:
|
||||
{
|
||||
GstSourceGroup *group;
|
||||
gint n_text;
|
||||
|
||||
GST_OBJECT_LOCK (playbin);
|
||||
group = get_group (playbin);
|
||||
n_text = (group->text_channels ? group->text_channels->len : 0);
|
||||
g_value_set_int (value, n_text);
|
||||
GST_OBJECT_UNLOCK (playbin);
|
||||
break;
|
||||
}
|
||||
case PROP_CURRENT_TEXT:
|
||||
GST_OBJECT_LOCK (playbin);
|
||||
g_value_set_int (value, playbin->current_text);
|
||||
GST_OBJECT_UNLOCK (playbin);
|
||||
break;
|
||||
case PROP_SUBTITLE_ENCODING:
|
||||
break;
|
||||
|
@ -849,6 +1167,7 @@ gst_play_bin_get_property (GObject * object, guint prop_id, GValue * value,
|
|||
case PROP_VIS_PLUGIN:
|
||||
break;
|
||||
case PROP_VOLUME:
|
||||
g_value_set_double (value, gst_play_sink_get_volume (playbin->playsink));
|
||||
break;
|
||||
case PROP_FRAME:
|
||||
break;
|
||||
|
@ -929,6 +1248,9 @@ pad_added_cb (GstElement * decodebin, GstPad * pad, GstSourceGroup * group)
|
|||
if (select == NULL)
|
||||
goto unknown_type;
|
||||
|
||||
/* store the selector for the pad */
|
||||
g_object_set_data (G_OBJECT (pad), "playbin2.select", select);
|
||||
|
||||
if (select->selector == NULL) {
|
||||
/* no selector, create one */
|
||||
GST_DEBUG_OBJECT (playbin, "creating new selector");
|
||||
|
@ -948,12 +1270,16 @@ pad_added_cb (GstElement * decodebin, GstPad * pad, GstSourceGroup * group)
|
|||
if ((sinkpad = gst_element_get_request_pad (select->selector, "sink%d"))) {
|
||||
GST_DEBUG_OBJECT (playbin, "got pad %s:%s from selector",
|
||||
GST_DEBUG_PAD_NAME (sinkpad));
|
||||
|
||||
/* store the pad in the array */
|
||||
g_ptr_array_add (select->channels, sinkpad);
|
||||
|
||||
res = gst_pad_link (pad, sinkpad);
|
||||
if (GST_PAD_LINK_FAILED (res))
|
||||
goto link_failed;
|
||||
|
||||
/* store selector pad so we can release it */
|
||||
g_object_set_data (G_OBJECT (pad), "playbin2.selector", sinkpad);
|
||||
g_object_set_data (G_OBJECT (pad), "playbin2.sinkpad", sinkpad);
|
||||
}
|
||||
GST_DEBUG_OBJECT (playbin, "linked pad %s:%s to selector %p",
|
||||
GST_DEBUG_PAD_NAME (pad), select->selector);
|
||||
|
@ -990,15 +1316,20 @@ pad_removed_cb (GstElement * decodebin, GstPad * pad, GstSourceGroup * group)
|
|||
GstPlayBin *playbin;
|
||||
GstPad *peer;
|
||||
GstElement *selector;
|
||||
GstSourceSelect *select;
|
||||
|
||||
playbin = group->playbin;
|
||||
|
||||
GST_DEBUG_OBJECT (playbin,
|
||||
"pad %s:%s removed from group %p", GST_DEBUG_PAD_NAME (pad), group);
|
||||
|
||||
if ((select = g_object_get_data (G_OBJECT (pad), "playbin2.select"))) {
|
||||
/* remove the pad from the array */
|
||||
g_ptr_array_remove (select->channels, pad);
|
||||
}
|
||||
|
||||
/* get the selector sinkpad */
|
||||
peer = g_object_get_data (G_OBJECT (pad), "playbin2.selector");
|
||||
if (!peer)
|
||||
if (!(peer = g_object_get_data (G_OBJECT (pad), "playbin2.sinkpad")))
|
||||
goto not_linked;
|
||||
|
||||
/* unlink the pad now (can fail, the pad is unlinked before it's removed) */
|
||||
|
|
|
@ -33,7 +33,6 @@ GST_DEBUG_CATEGORY_STATIC (gst_play_sink_debug);
|
|||
#define GST_CAT_DEFAULT gst_play_sink_debug
|
||||
|
||||
#define VOLUME_MAX_DOUBLE 10.0
|
||||
#define CONNECTION_SPEED_DEFAULT 0
|
||||
|
||||
/* holds the common data fields for the audio and video pipelines. We keep them
|
||||
* in a structure to more easily have all the info available. */
|
||||
|
@ -519,6 +518,39 @@ gst_play_sink_set_vis_plugin (GstPlaySink * playsink,
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
gst_play_sink_set_volume (GstPlaySink * playsink, gdouble volume)
|
||||
{
|
||||
GstPlayAudioChain *chain;
|
||||
|
||||
GST_PLAY_SINK_LOCK (playsink);
|
||||
playsink->volume = volume;
|
||||
chain = (GstPlayAudioChain *) playsink->audiochain;
|
||||
if (chain && chain->volume) {
|
||||
g_object_set (chain->volume, "volume", volume, NULL);
|
||||
}
|
||||
GST_PLAY_SINK_UNLOCK (playsink);
|
||||
}
|
||||
|
||||
gdouble
|
||||
gst_play_sink_get_volume (GstPlaySink * playsink)
|
||||
{
|
||||
gdouble result;
|
||||
GstPlayAudioChain *chain;
|
||||
|
||||
GST_PLAY_SINK_LOCK (playsink);
|
||||
chain = (GstPlayAudioChain *) playsink->audiochain;
|
||||
if (chain && chain->volume) {
|
||||
g_object_get (chain->volume, "volume", &result, NULL);
|
||||
playsink->volume = result;
|
||||
} else {
|
||||
result = playsink->volume;
|
||||
}
|
||||
GST_PLAY_SINK_UNLOCK (playsink);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_play_sink_set_property (GObject * object, guint prop_id,
|
||||
const GValue * value, GParamSpec * pspec)
|
||||
|
@ -538,9 +570,7 @@ gst_play_sink_set_property (GObject * object, guint prop_id,
|
|||
gst_play_sink_set_vis_plugin (playsink, g_value_get_object (value));
|
||||
break;
|
||||
case PROP_VOLUME:
|
||||
GST_OBJECT_LOCK (playsink);
|
||||
playsink->volume = g_value_get_double (value);
|
||||
GST_OBJECT_UNLOCK (playsink);
|
||||
gst_play_sink_set_volume (playsink, g_value_get_double (value));
|
||||
break;
|
||||
case PROP_FONT_DESC:
|
||||
GST_OBJECT_LOCK (playsink);
|
||||
|
@ -583,9 +613,7 @@ gst_play_sink_get_property (GObject * object, guint prop_id, GValue * value,
|
|||
GST_OBJECT_UNLOCK (playsink);
|
||||
break;
|
||||
case PROP_VOLUME:
|
||||
GST_OBJECT_LOCK (playsink);
|
||||
g_value_set_double (value, playsink->volume);
|
||||
GST_OBJECT_UNLOCK (playsink);
|
||||
g_value_set_double (value, gst_play_sink_get_volume (playsink));
|
||||
break;
|
||||
case PROP_FRAME:
|
||||
{
|
||||
|
@ -914,8 +942,11 @@ gen_audio_chain (GstPlaySink * playsink, gboolean raw)
|
|||
|
||||
res = gst_element_link_pads (chain->conv, "src", chain->resample, "sink");
|
||||
|
||||
/* FIXME check if the sink has the volume property */
|
||||
|
||||
if (playsink->flags & GST_PLAY_FLAG_SOFT_VOLUME) {
|
||||
chain->volume = gst_element_factory_make ("volume", "volume");
|
||||
/* configure with the latest volume */
|
||||
g_object_set (G_OBJECT (chain->volume), "volume", playsink->volume, NULL);
|
||||
gst_bin_add (bin, chain->volume);
|
||||
|
||||
|
|
|
@ -69,6 +69,9 @@ void gst_play_sink_set_video_sink (GstPlaySink * playsink, GstElemen
|
|||
void gst_play_sink_set_audio_sink (GstPlaySink * playsink, GstElement * sink);
|
||||
void gst_play_sink_set_vis_plugin (GstPlaySink * playsink, GstElement * vis);
|
||||
|
||||
void gst_play_sink_set_volume (GstPlaySink *playsink, gdouble volume);
|
||||
gdouble gst_play_sink_get_volume (GstPlaySink *playsink);
|
||||
|
||||
gboolean gst_play_sink_set_flags (GstPlaySink * playsink, GstPlayFlags flags);
|
||||
GstPlayFlags gst_play_sink_get_flags (GstPlaySink * playsink);
|
||||
|
||||
|
|
|
@ -91,6 +91,7 @@ struct _GstSelectorPad
|
|||
gboolean eos;
|
||||
gboolean segment_pending;
|
||||
GstSegment segment;
|
||||
GstTagList *tags;
|
||||
};
|
||||
|
||||
struct _GstSelectorPadClass
|
||||
|
@ -102,6 +103,9 @@ static void gst_selector_pad_class_init (GstSelectorPadClass * klass);
|
|||
static void gst_selector_pad_init (GstSelectorPad * pad);
|
||||
static void gst_selector_pad_finalize (GObject * object);
|
||||
|
||||
static void gst_selector_pad_get_property (GObject * object,
|
||||
guint prop_id, GValue * value, GParamSpec * pspec);
|
||||
|
||||
static GstPadClass *selector_pad_parent_class = NULL;
|
||||
|
||||
static void gst_selector_pad_reset (GstSelectorPad * pad);
|
||||
|
@ -112,6 +116,14 @@ static GstFlowReturn gst_selector_pad_chain (GstPad * pad, GstBuffer * buf);
|
|||
static GstFlowReturn gst_selector_pad_bufferalloc (GstPad * pad,
|
||||
guint64 offset, guint size, GstCaps * caps, GstBuffer ** buf);
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_PAD_0,
|
||||
PROP_PAD_TAGS,
|
||||
PROP_PAD_ACTIVE,
|
||||
PROP_PAD_LAST
|
||||
};
|
||||
|
||||
static GType
|
||||
gst_selector_pad_get_type (void)
|
||||
{
|
||||
|
@ -147,6 +159,17 @@ gst_selector_pad_class_init (GstSelectorPadClass * klass)
|
|||
selector_pad_parent_class = g_type_class_peek_parent (klass);
|
||||
|
||||
gobject_class->finalize = gst_selector_pad_finalize;
|
||||
gobject_class->get_property =
|
||||
GST_DEBUG_FUNCPTR (gst_selector_pad_get_property);
|
||||
|
||||
g_object_class_install_property (gobject_class, PROP_PAD_TAGS,
|
||||
g_param_spec_boxed ("tags", "Tags",
|
||||
"The currently active tags on the pad", GST_TYPE_TAG_LIST,
|
||||
G_PARAM_READABLE));
|
||||
|
||||
g_object_class_install_property (gobject_class, PROP_PAD_ACTIVE,
|
||||
g_param_spec_boolean ("active", "Active",
|
||||
"If the pad is currently active", FALSE, G_PARAM_READABLE));
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -162,9 +185,42 @@ gst_selector_pad_finalize (GObject * object)
|
|||
|
||||
pad = GST_SELECTOR_PAD_CAST (object);
|
||||
|
||||
if (pad->tags)
|
||||
gst_tag_list_free (pad->tags);
|
||||
|
||||
G_OBJECT_CLASS (selector_pad_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_selector_pad_get_property (GObject * object,
|
||||
guint prop_id, GValue * value, GParamSpec * pspec)
|
||||
{
|
||||
GstSelectorPad *pad;
|
||||
|
||||
pad = GST_SELECTOR_PAD (object);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_PAD_TAGS:
|
||||
GST_OBJECT_LOCK (object);
|
||||
g_value_set_boxed (value, pad->tags);
|
||||
GST_OBJECT_UNLOCK (object);
|
||||
break;
|
||||
case PROP_PAD_ACTIVE:
|
||||
{
|
||||
GstStreamSelector *sel;
|
||||
|
||||
sel = GST_STREAM_SELECTOR (gst_pad_get_parent (pad));
|
||||
g_value_set_boolean (value, gst_stream_selector_is_active_sinkpad (sel,
|
||||
GST_PAD_CAST (pad)));
|
||||
gst_object_unref (sel);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gst_selector_pad_reset (GstSelectorPad * pad)
|
||||
{
|
||||
|
@ -232,6 +288,21 @@ gst_selector_pad_event (GstPad * pad, GstEvent * event)
|
|||
selpad->segment_pending = TRUE;
|
||||
break;
|
||||
}
|
||||
case GST_EVENT_TAG:
|
||||
{
|
||||
GstTagList *tags;
|
||||
|
||||
GST_OBJECT_LOCK (selpad);
|
||||
if (selpad->tags)
|
||||
gst_tag_list_free (selpad->tags);
|
||||
gst_event_parse_tag (event, &tags);
|
||||
if (tags)
|
||||
tags = gst_tag_list_copy (tags);
|
||||
selpad->tags = tags;
|
||||
GST_DEBUG_OBJECT (sel, "received tags %" GST_PTR_FORMAT, selpad->tags);
|
||||
GST_OBJECT_UNLOCK (selpad);
|
||||
break;
|
||||
}
|
||||
case GST_EVENT_EOS:
|
||||
selpad->eos = TRUE;
|
||||
break;
|
||||
|
@ -364,19 +435,24 @@ ignore:
|
|||
}
|
||||
|
||||
static void gst_stream_selector_dispose (GObject * object);
|
||||
static void gst_stream_selector_finalize (GObject * object);
|
||||
|
||||
static void gst_stream_selector_init (GstStreamSelector * sel);
|
||||
static void gst_stream_selector_base_init (GstStreamSelectorClass * klass);
|
||||
static void gst_stream_selector_class_init (GstStreamSelectorClass * klass);
|
||||
|
||||
static void gst_stream_selector_set_property (GObject * object,
|
||||
guint prop_id, const GValue * value, GParamSpec * pspec);
|
||||
static void gst_stream_selector_get_property (GObject * object,
|
||||
guint prop_id, GValue * value, GParamSpec * pspec);
|
||||
|
||||
static GstPad *gst_stream_selector_request_new_pad (GstElement * element,
|
||||
GstPadTemplate * templ, const gchar * unused);
|
||||
static void gst_stream_selector_release_pad (GstElement * element,
|
||||
GstPad * pad);
|
||||
static GList *gst_stream_selector_get_linked_pads (GstPad * pad);
|
||||
static GstCaps *gst_stream_selector_getcaps (GstPad * pad);
|
||||
|
||||
static GstElementClass *parent_class = NULL;
|
||||
|
||||
GType
|
||||
|
@ -427,17 +503,19 @@ gst_stream_selector_class_init (GstStreamSelectorClass * klass)
|
|||
parent_class = g_type_class_peek_parent (klass);
|
||||
|
||||
gobject_class->dispose = gst_stream_selector_dispose;
|
||||
gobject_class->finalize = gst_stream_selector_finalize;
|
||||
|
||||
gobject_class->set_property =
|
||||
GST_DEBUG_FUNCPTR (gst_stream_selector_set_property);
|
||||
gobject_class->get_property =
|
||||
GST_DEBUG_FUNCPTR (gst_stream_selector_get_property);
|
||||
|
||||
g_object_class_install_property (gobject_class, PROP_N_PADS,
|
||||
g_param_spec_int ("n-pads", "Number of Pads",
|
||||
"The number of sink pads", 0, G_MAXINT, 0, G_PARAM_READABLE));
|
||||
g_param_spec_uint ("n-pads", "Number of Pads",
|
||||
"The number of sink pads", 0, G_MAXUINT, 0, G_PARAM_READABLE));
|
||||
g_object_class_install_property (gobject_class, PROP_ACTIVE_PAD,
|
||||
g_param_spec_string ("active-pad", "Active pad",
|
||||
"Name of the currently" " active sink pad", NULL, G_PARAM_READWRITE));
|
||||
g_param_spec_object ("active-pad", "Active Pad",
|
||||
"The currently active sink pad", GST_TYPE_PAD, G_PARAM_READWRITE));
|
||||
|
||||
gstelement_class->request_new_pad = gst_stream_selector_request_new_pad;
|
||||
gstelement_class->release_pad = gst_stream_selector_release_pad;
|
||||
|
@ -453,9 +531,8 @@ gst_stream_selector_init (GstStreamSelector * sel)
|
|||
GST_DEBUG_FUNCPTR (gst_stream_selector_getcaps));
|
||||
gst_element_add_pad (GST_ELEMENT (sel), sel->srcpad);
|
||||
/* sinkpad management */
|
||||
sel->active_sinkpad = NULL;
|
||||
sel->padcount = 0;
|
||||
sel->n_pads = 0;
|
||||
sel->active_sinkpad = NULL;
|
||||
gst_segment_init (&sel->segment, GST_FORMAT_UNDEFINED);
|
||||
}
|
||||
|
||||
|
@ -472,6 +549,16 @@ gst_stream_selector_dispose (GObject * object)
|
|||
G_OBJECT_CLASS (parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_stream_selector_finalize (GObject * object)
|
||||
{
|
||||
GstStreamSelector *sel;
|
||||
|
||||
sel = GST_STREAM_SELECTOR (object);
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_stream_selector_set_property (GObject * object, guint prop_id,
|
||||
const GValue * value, GParamSpec * pspec)
|
||||
|
@ -479,13 +566,13 @@ gst_stream_selector_set_property (GObject * object, guint prop_id,
|
|||
GstStreamSelector *sel = GST_STREAM_SELECTOR (object);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_ACTIVE_PAD:{
|
||||
const gchar *pad_name = g_value_get_string (value);
|
||||
case PROP_ACTIVE_PAD:
|
||||
{
|
||||
GstPad *pad = NULL;
|
||||
GstPad **active_pad_p;
|
||||
|
||||
if (strcmp (pad_name, "") != 0)
|
||||
pad = gst_element_get_pad (GST_ELEMENT (object), pad_name);
|
||||
pad = g_value_get_object (value);
|
||||
|
||||
GST_OBJECT_LOCK (object);
|
||||
if (pad != sel->active_sinkpad) {
|
||||
GstSelectorPad *selpad;
|
||||
|
@ -504,8 +591,6 @@ gst_stream_selector_set_property (GObject * object, guint prop_id,
|
|||
}
|
||||
}
|
||||
GST_OBJECT_UNLOCK (object);
|
||||
if (pad)
|
||||
gst_object_unref (pad);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
@ -523,16 +608,12 @@ gst_stream_selector_get_property (GObject * object, guint prop_id,
|
|||
switch (prop_id) {
|
||||
case PROP_N_PADS:
|
||||
GST_OBJECT_LOCK (object);
|
||||
g_value_set_int (value, sel->n_pads);
|
||||
g_value_set_uint (value, sel->n_pads);
|
||||
GST_OBJECT_UNLOCK (object);
|
||||
break;
|
||||
case PROP_ACTIVE_PAD:{
|
||||
GST_OBJECT_LOCK (object);
|
||||
if (sel->active_sinkpad != NULL) {
|
||||
g_value_take_string (value, gst_pad_get_name (sel->active_sinkpad));
|
||||
} else {
|
||||
g_value_set_string (value, "");
|
||||
}
|
||||
g_value_set_object (value, sel->active_sinkpad);
|
||||
GST_OBJECT_UNLOCK (object);
|
||||
break;
|
||||
}
|
||||
|
@ -549,6 +630,7 @@ gst_stream_selector_get_linked_pad (GstPad * pad, gboolean strict)
|
|||
GstPad *otherpad = NULL;
|
||||
|
||||
sel = GST_STREAM_SELECTOR (gst_pad_get_parent (pad));
|
||||
|
||||
GST_OBJECT_LOCK (sel);
|
||||
if (pad == sel->srcpad)
|
||||
otherpad = sel->active_sinkpad;
|
||||
|
@ -653,10 +735,10 @@ gst_stream_selector_request_new_pad (GstElement * element,
|
|||
GST_LOG_OBJECT (sel, "Creating new pad %d", sel->padcount);
|
||||
GST_OBJECT_LOCK (sel);
|
||||
name = g_strdup_printf ("sink%d", sel->padcount++);
|
||||
sel->n_pads++;
|
||||
sinkpad = g_object_new (GST_TYPE_SELECTOR_PAD,
|
||||
"name", name, "direction", templ->direction, "template", templ, NULL);
|
||||
g_free (name);
|
||||
sel->n_pads++;
|
||||
GST_OBJECT_UNLOCK (sel);
|
||||
|
||||
gst_pad_set_event_function (sinkpad,
|
||||
|
|
|
@ -44,10 +44,9 @@ struct _GstStreamSelector {
|
|||
|
||||
GstPad *srcpad;
|
||||
|
||||
guint padcount;
|
||||
|
||||
GstPad *active_sinkpad;
|
||||
guint n_pads;
|
||||
guint padcount;
|
||||
|
||||
GstSegment segment;
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue