mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-23 00:36:51 +00:00
playbin3: Cleanup and refactor combiner sourcecombine
* Remove fields no longer used, or that can be replaced by smaller code * Rename "channels" to a more meaningful "input pads" * Directly handle/use combiner pads in the combiners instead of on the playbin3 main structure Remove the corresponding combiner sinkpad whenever a uridecodebin3 source pad goes away * If used, store the corresponding combiner sink pad in the SourcePad helper structure Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/2384>
This commit is contained in:
parent
8870f59a07
commit
53bb864244
3 changed files with 80 additions and 102 deletions
|
@ -253,8 +253,6 @@ typedef struct _GstSourceGroup GstSourceGroup;
|
||||||
typedef struct _GstSourceCombine GstSourceCombine;
|
typedef struct _GstSourceCombine GstSourceCombine;
|
||||||
typedef struct _SourcePad SourcePad;
|
typedef struct _SourcePad SourcePad;
|
||||||
|
|
||||||
typedef GstCaps *(*SourceCombineGetMediaCapsFunc) (void);
|
|
||||||
|
|
||||||
/* GstSourceCombine controls all the information regarding a certain
|
/* GstSourceCombine controls all the information regarding a certain
|
||||||
* media type.
|
* media type.
|
||||||
*
|
*
|
||||||
|
@ -262,13 +260,10 @@ typedef GstCaps *(*SourceCombineGetMediaCapsFunc) (void);
|
||||||
*/
|
*/
|
||||||
struct _GstSourceCombine
|
struct _GstSourceCombine
|
||||||
{
|
{
|
||||||
const gchar *media_type; /* the media type for the combiner */
|
|
||||||
SourceCombineGetMediaCapsFunc get_media_caps; /* more complex caps for the combiner */
|
|
||||||
GstPlaySinkType type; /* the sink pad type of the combiner */
|
|
||||||
GstStreamType stream_type; /* The GstStreamType of the combiner */
|
GstStreamType stream_type; /* The GstStreamType of the combiner */
|
||||||
|
|
||||||
GstElement *combiner; /* the combiner */
|
GstElement *combiner; /* the combiner */
|
||||||
GPtrArray *channels; /* Array of GstPad ? */
|
GPtrArray *inputpads; /* Array of sink request GstPad of the combiner */
|
||||||
|
|
||||||
GstPad *srcpad; /* the source pad of the combiner */
|
GstPad *srcpad; /* the source pad of the combiner */
|
||||||
GstPad *sinkpad; /* the sinkpad of the sink when the combiner
|
GstPad *sinkpad; /* the sinkpad of the sink when the combiner
|
||||||
|
@ -305,7 +300,6 @@ static const gchar *stream_type_names[] = {
|
||||||
(s) & GST_STREAM_TYPE_TEXT ? "text " : ""
|
(s) & GST_STREAM_TYPE_TEXT ? "text " : ""
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#if 0 /* AUTOPLUG DISABLED */
|
#if 0 /* AUTOPLUG DISABLED */
|
||||||
static void avelements_free (gpointer data);
|
static void avelements_free (gpointer data);
|
||||||
static GSequence *avelements_create (GstPlayBin3 * playbin,
|
static GSequence *avelements_create (GstPlayBin3 * playbin,
|
||||||
|
@ -327,6 +321,7 @@ struct _SourcePad
|
||||||
{
|
{
|
||||||
GstPad *pad; /* The controlled pad */
|
GstPad *pad; /* The controlled pad */
|
||||||
GstStreamType stream_type; /* stream type of the controlled pad */
|
GstStreamType stream_type; /* stream type of the controlled pad */
|
||||||
|
GstPad *combine_sinkpad; /* Combiner request sinkpad linked to pad */
|
||||||
gulong event_probe_id;
|
gulong event_probe_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -441,9 +436,6 @@ struct _GstPlayBin3
|
||||||
GstSourceGroup *curr_group; /* pointer to the currently playing group */
|
GstSourceGroup *curr_group; /* pointer to the currently playing group */
|
||||||
GstSourceGroup *next_group; /* pointer to the next group */
|
GstSourceGroup *next_group; /* pointer to the next group */
|
||||||
|
|
||||||
/* Array of GstPad controlled by each combiner */
|
|
||||||
GPtrArray *channels[PLAYBIN_STREAM_LAST]; /* links to combiner pads */
|
|
||||||
|
|
||||||
/* combiners for different streams */
|
/* combiners for different streams */
|
||||||
GstSourceCombine combiner[PLAYBIN_STREAM_LAST];
|
GstSourceCombine combiner[PLAYBIN_STREAM_LAST];
|
||||||
|
|
||||||
|
@ -1096,32 +1088,18 @@ do_async_done (GstPlayBin3 * playbin)
|
||||||
static void
|
static void
|
||||||
init_combiners (GstPlayBin3 * playbin)
|
init_combiners (GstPlayBin3 * playbin)
|
||||||
{
|
{
|
||||||
gint i;
|
|
||||||
|
|
||||||
/* store the array for the different channels */
|
|
||||||
for (i = 0; i < PLAYBIN_STREAM_LAST; i++)
|
|
||||||
playbin->channels[i] = g_ptr_array_new ();
|
|
||||||
|
|
||||||
playbin->combiner[PLAYBIN_STREAM_AUDIO].media_type = "audio";
|
|
||||||
playbin->combiner[PLAYBIN_STREAM_AUDIO].type = GST_PLAY_SINK_TYPE_AUDIO;
|
|
||||||
playbin->combiner[PLAYBIN_STREAM_AUDIO].stream_type = GST_STREAM_TYPE_AUDIO;
|
playbin->combiner[PLAYBIN_STREAM_AUDIO].stream_type = GST_STREAM_TYPE_AUDIO;
|
||||||
playbin->combiner[PLAYBIN_STREAM_AUDIO].channels = playbin->channels[0];
|
playbin->combiner[PLAYBIN_STREAM_AUDIO].inputpads = g_ptr_array_new ();
|
||||||
playbin->combiner[PLAYBIN_STREAM_AUDIO].streams =
|
playbin->combiner[PLAYBIN_STREAM_AUDIO].streams =
|
||||||
g_ptr_array_new_with_free_func ((GDestroyNotify) gst_object_unref);
|
g_ptr_array_new_with_free_func ((GDestroyNotify) gst_object_unref);
|
||||||
|
|
||||||
playbin->combiner[PLAYBIN_STREAM_VIDEO].media_type = "video";
|
|
||||||
playbin->combiner[PLAYBIN_STREAM_VIDEO].type = GST_PLAY_SINK_TYPE_VIDEO;
|
|
||||||
playbin->combiner[PLAYBIN_STREAM_VIDEO].stream_type = GST_STREAM_TYPE_VIDEO;
|
playbin->combiner[PLAYBIN_STREAM_VIDEO].stream_type = GST_STREAM_TYPE_VIDEO;
|
||||||
playbin->combiner[PLAYBIN_STREAM_VIDEO].channels = playbin->channels[1];
|
playbin->combiner[PLAYBIN_STREAM_VIDEO].inputpads = g_ptr_array_new ();
|
||||||
playbin->combiner[PLAYBIN_STREAM_VIDEO].streams =
|
playbin->combiner[PLAYBIN_STREAM_VIDEO].streams =
|
||||||
g_ptr_array_new_with_free_func ((GDestroyNotify) gst_object_unref);
|
g_ptr_array_new_with_free_func ((GDestroyNotify) gst_object_unref);
|
||||||
|
|
||||||
playbin->combiner[PLAYBIN_STREAM_TEXT].media_type = "text";
|
|
||||||
playbin->combiner[PLAYBIN_STREAM_TEXT].get_media_caps =
|
|
||||||
gst_subtitle_overlay_create_factory_caps;
|
|
||||||
playbin->combiner[PLAYBIN_STREAM_TEXT].type = GST_PLAY_SINK_TYPE_TEXT;
|
|
||||||
playbin->combiner[PLAYBIN_STREAM_TEXT].stream_type = GST_STREAM_TYPE_TEXT;
|
playbin->combiner[PLAYBIN_STREAM_TEXT].stream_type = GST_STREAM_TYPE_TEXT;
|
||||||
playbin->combiner[PLAYBIN_STREAM_TEXT].channels = playbin->channels[2];
|
playbin->combiner[PLAYBIN_STREAM_TEXT].inputpads = g_ptr_array_new ();
|
||||||
playbin->combiner[PLAYBIN_STREAM_TEXT].streams =
|
playbin->combiner[PLAYBIN_STREAM_TEXT].streams =
|
||||||
g_ptr_array_new_with_free_func ((GDestroyNotify) gst_object_unref);
|
g_ptr_array_new_with_free_func ((GDestroyNotify) gst_object_unref);
|
||||||
}
|
}
|
||||||
|
@ -1183,7 +1161,8 @@ update_combiner_info (GstPlayBin3 * playbin, GstStreamCollection * collection)
|
||||||
for (i = 0; i < 2; i++) { \
|
for (i = 0; i < 2; i++) { \
|
||||||
GstSourceGroup *group = &playbin->groups[i]; \
|
GstSourceGroup *group = &playbin->groups[i]; \
|
||||||
\
|
\
|
||||||
GST_DEBUG ("GstSourceGroup #%d (%s)", i, (group == playbin->curr_group) ? "current" : (group == playbin->next_group) ? "next" : "unused"); \
|
GST_DEBUG ("GstSourceGroup #%d (%s) : %s", i, (group == playbin->curr_group) ? "current" : (group == playbin->next_group) ? "next" : "unused", \
|
||||||
|
group->uridecodebin ? GST_ELEMENT_NAME (group->uridecodebin) : "NULL" ); \
|
||||||
GST_DEBUG (" valid:%d , active:%d , playing:%d", group->valid, group->active, group->playing); \
|
GST_DEBUG (" valid:%d , active:%d , playing:%d", group->valid, group->active, group->playing); \
|
||||||
GST_DEBUG (" uri:%s", group->uri); \
|
GST_DEBUG (" uri:%s", group->uri); \
|
||||||
GST_DEBUG (" suburi:%s", group->suburi); \
|
GST_DEBUG (" suburi:%s", group->suburi); \
|
||||||
|
@ -1380,16 +1359,12 @@ static void
|
||||||
gst_play_bin3_finalize (GObject * object)
|
gst_play_bin3_finalize (GObject * object)
|
||||||
{
|
{
|
||||||
GstPlayBin3 *playbin;
|
GstPlayBin3 *playbin;
|
||||||
gint i;
|
|
||||||
|
|
||||||
playbin = GST_PLAY_BIN3 (object);
|
playbin = GST_PLAY_BIN3 (object);
|
||||||
|
|
||||||
free_group (playbin, &playbin->groups[0]);
|
free_group (playbin, &playbin->groups[0]);
|
||||||
free_group (playbin, &playbin->groups[1]);
|
free_group (playbin, &playbin->groups[1]);
|
||||||
|
|
||||||
for (i = 0; i < PLAYBIN_STREAM_LAST; i++)
|
|
||||||
g_ptr_array_free (playbin->channels[i], TRUE);
|
|
||||||
|
|
||||||
/* Setting states to NULL is safe here because playsink
|
/* Setting states to NULL is safe here because playsink
|
||||||
* will already be gone and none of these sinks will be
|
* will already be gone and none of these sinks will be
|
||||||
* a child of playsink
|
* a child of playsink
|
||||||
|
@ -1421,8 +1396,11 @@ gst_play_bin3_finalize (GObject * object)
|
||||||
}
|
}
|
||||||
|
|
||||||
g_ptr_array_free (playbin->combiner[PLAYBIN_STREAM_AUDIO].streams, TRUE);
|
g_ptr_array_free (playbin->combiner[PLAYBIN_STREAM_AUDIO].streams, TRUE);
|
||||||
|
g_ptr_array_free (playbin->combiner[PLAYBIN_STREAM_AUDIO].inputpads, TRUE);
|
||||||
g_ptr_array_free (playbin->combiner[PLAYBIN_STREAM_VIDEO].streams, TRUE);
|
g_ptr_array_free (playbin->combiner[PLAYBIN_STREAM_VIDEO].streams, TRUE);
|
||||||
|
g_ptr_array_free (playbin->combiner[PLAYBIN_STREAM_VIDEO].inputpads, TRUE);
|
||||||
g_ptr_array_free (playbin->combiner[PLAYBIN_STREAM_TEXT].streams, TRUE);
|
g_ptr_array_free (playbin->combiner[PLAYBIN_STREAM_TEXT].streams, TRUE);
|
||||||
|
g_ptr_array_free (playbin->combiner[PLAYBIN_STREAM_TEXT].inputpads, TRUE);
|
||||||
|
|
||||||
if (playbin->elements)
|
if (playbin->elements)
|
||||||
gst_plugin_feature_list_free (playbin->elements);
|
gst_plugin_feature_list_free (playbin->elements);
|
||||||
|
@ -1594,7 +1572,6 @@ gst_play_bin3_set_current_stream (GstPlayBin3 * playbin,
|
||||||
gboolean * flush_marker)
|
gboolean * flush_marker)
|
||||||
{
|
{
|
||||||
GstSourceCombine *combine;
|
GstSourceCombine *combine;
|
||||||
GPtrArray *channels;
|
|
||||||
GstPad *sinkpad;
|
GstPad *sinkpad;
|
||||||
|
|
||||||
GST_PLAY_BIN3_LOCK (playbin);
|
GST_PLAY_BIN3_LOCK (playbin);
|
||||||
|
@ -1604,7 +1581,6 @@ gst_play_bin3_set_current_stream (GstPlayBin3 * playbin,
|
||||||
playbin->do_stream_selections = TRUE;
|
playbin->do_stream_selections = TRUE;
|
||||||
|
|
||||||
combine = playbin->combiner + stream_type;
|
combine = playbin->combiner + stream_type;
|
||||||
channels = playbin->channels[stream_type];
|
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (playbin, "Changing current %s stream %d -> %d",
|
GST_DEBUG_OBJECT (playbin, "Changing current %s stream %d -> %d",
|
||||||
stream_type_names[stream_type], *current_value, stream);
|
stream_type_names[stream_type], *current_value, stream);
|
||||||
|
@ -1621,14 +1597,14 @@ gst_play_bin3_set_current_stream (GstPlayBin3 * playbin,
|
||||||
|
|
||||||
if (!combine->has_active_pad)
|
if (!combine->has_active_pad)
|
||||||
goto no_active_pad;
|
goto no_active_pad;
|
||||||
if (channels == NULL)
|
if (combine->inputpads == NULL)
|
||||||
goto no_channels;
|
goto no_channels;
|
||||||
|
|
||||||
if (stream == -1 || channels->len <= stream) {
|
if (stream == -1 || combine->inputpads->len <= stream) {
|
||||||
sinkpad = NULL;
|
sinkpad = NULL;
|
||||||
} else {
|
} else {
|
||||||
/* take channel from selected stream */
|
/* take combiner sink pad for selected stream */
|
||||||
sinkpad = g_ptr_array_index (channels, stream);
|
sinkpad = g_ptr_array_index (combine->inputpads, stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sinkpad)
|
if (sinkpad)
|
||||||
|
@ -1676,7 +1652,8 @@ no_active_pad:
|
||||||
no_channels:
|
no_channels:
|
||||||
{
|
{
|
||||||
GST_PLAY_BIN3_UNLOCK (playbin);
|
GST_PLAY_BIN3_UNLOCK (playbin);
|
||||||
GST_DEBUG_OBJECT (playbin, "can't switch video, we have no channels");
|
GST_DEBUG_OBJECT (playbin,
|
||||||
|
"can't switch stream, we have no combiner input pad");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2607,8 +2584,7 @@ gst_play_bin3_deep_element_added (GstBin * playbin, GstBin * sub_bin,
|
||||||
|
|
||||||
/* Returns current stream number, or -1 if none has been selected yet */
|
/* Returns current stream number, or -1 if none has been selected yet */
|
||||||
static int
|
static int
|
||||||
get_current_stream_number (GstPlayBin3 * playbin, GstSourceCombine * combine,
|
get_current_stream_number (GstPlayBin3 * playbin, GstSourceCombine * combine)
|
||||||
GPtrArray * channels)
|
|
||||||
{
|
{
|
||||||
/* Internal API cleanup would make this easier... */
|
/* Internal API cleanup would make this easier... */
|
||||||
int i;
|
int i;
|
||||||
|
@ -2622,8 +2598,8 @@ get_current_stream_number (GstPlayBin3 * playbin, GstSourceCombine * combine,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < channels->len; i++) {
|
for (i = 0; i < combine->inputpads->len; i++) {
|
||||||
pad = g_ptr_array_index (channels, i);
|
pad = g_ptr_array_index (combine->inputpads, i);
|
||||||
if ((combiner = gst_pad_get_parent (pad))) {
|
if ((combiner = gst_pad_get_parent (pad))) {
|
||||||
g_object_get (combiner, "active-pad", ¤t, NULL);
|
g_object_get (combiner, "active-pad", ¤t, NULL);
|
||||||
gst_object_unref (combiner);
|
gst_object_unref (combiner);
|
||||||
|
@ -2647,7 +2623,6 @@ combiner_active_pad_changed (GObject * combiner, GParamSpec * pspec,
|
||||||
GstPlayBin3 * playbin)
|
GstPlayBin3 * playbin)
|
||||||
{
|
{
|
||||||
GstSourceCombine *combine = NULL;
|
GstSourceCombine *combine = NULL;
|
||||||
GPtrArray *channels = NULL;
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
GST_PLAY_BIN3_LOCK (playbin);
|
GST_PLAY_BIN3_LOCK (playbin);
|
||||||
|
@ -2655,7 +2630,6 @@ combiner_active_pad_changed (GObject * combiner, GParamSpec * pspec,
|
||||||
for (i = 0; i < PLAYBIN_STREAM_LAST; i++) {
|
for (i = 0; i < PLAYBIN_STREAM_LAST; i++) {
|
||||||
if (combiner == G_OBJECT (playbin->combiner[i].combiner)) {
|
if (combiner == G_OBJECT (playbin->combiner[i].combiner)) {
|
||||||
combine = &playbin->combiner[i];
|
combine = &playbin->combiner[i];
|
||||||
channels = playbin->channels[i];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2665,10 +2639,9 @@ combiner_active_pad_changed (GObject * combiner, GParamSpec * pspec,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (combine->type) {
|
switch (combine->stream_type) {
|
||||||
case GST_PLAY_SINK_TYPE_VIDEO:
|
case GST_STREAM_TYPE_VIDEO:
|
||||||
playbin->current_video = get_current_stream_number (playbin,
|
playbin->current_video = get_current_stream_number (playbin, combine);
|
||||||
combine, channels);
|
|
||||||
|
|
||||||
if (playbin->video_pending_flush_finish) {
|
if (playbin->video_pending_flush_finish) {
|
||||||
playbin->video_pending_flush_finish = FALSE;
|
playbin->video_pending_flush_finish = FALSE;
|
||||||
|
@ -2677,9 +2650,8 @@ combiner_active_pad_changed (GObject * combiner, GParamSpec * pspec,
|
||||||
"playsink-custom-video-flush-finish");
|
"playsink-custom-video-flush-finish");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case GST_PLAY_SINK_TYPE_AUDIO:
|
case GST_STREAM_TYPE_AUDIO:
|
||||||
playbin->current_audio = get_current_stream_number (playbin,
|
playbin->current_audio = get_current_stream_number (playbin, combine);
|
||||||
combine, channels);
|
|
||||||
|
|
||||||
if (playbin->audio_pending_flush_finish) {
|
if (playbin->audio_pending_flush_finish) {
|
||||||
playbin->audio_pending_flush_finish = FALSE;
|
playbin->audio_pending_flush_finish = FALSE;
|
||||||
|
@ -2688,9 +2660,8 @@ combiner_active_pad_changed (GObject * combiner, GParamSpec * pspec,
|
||||||
"playsink-custom-audio-flush-finish");
|
"playsink-custom-audio-flush-finish");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case GST_PLAY_SINK_TYPE_TEXT:
|
case GST_STREAM_TYPE_TEXT:
|
||||||
playbin->current_text = get_current_stream_number (playbin,
|
playbin->current_text = get_current_stream_number (playbin, combine);
|
||||||
combine, channels);
|
|
||||||
|
|
||||||
if (playbin->text_pending_flush_finish) {
|
if (playbin->text_pending_flush_finish) {
|
||||||
playbin->text_pending_flush_finish = FALSE;
|
playbin->text_pending_flush_finish = FALSE;
|
||||||
|
@ -2833,7 +2804,7 @@ _decodebin_event_probe (GstPad * pad, GstPadProbeInfo * info, gpointer udata)
|
||||||
|
|
||||||
static void
|
static void
|
||||||
control_source_pad (GstSourceGroup * group, GstPad * pad,
|
control_source_pad (GstSourceGroup * group, GstPad * pad,
|
||||||
GstStreamType stream_type)
|
GstPad * combine_pad, GstStreamType stream_type)
|
||||||
{
|
{
|
||||||
SourcePad *sourcepad = g_slice_new0 (SourcePad);
|
SourcePad *sourcepad = g_slice_new0 (SourcePad);
|
||||||
|
|
||||||
|
@ -2842,6 +2813,7 @@ control_source_pad (GstSourceGroup * group, GstPad * pad,
|
||||||
gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM,
|
gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM,
|
||||||
_decodebin_event_probe, group, NULL);
|
_decodebin_event_probe, group, NULL);
|
||||||
sourcepad->stream_type = stream_type;
|
sourcepad->stream_type = stream_type;
|
||||||
|
sourcepad->combine_sinkpad = combine_pad;
|
||||||
group->source_pads = g_list_append (group->source_pads, sourcepad);
|
group->source_pads = g_list_append (group->source_pads, sourcepad);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2856,13 +2828,13 @@ remove_combiner (GstPlayBin3 * playbin, GstSourceCombine * combine)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Go over all sink pads and release them ! */
|
/* Go over all sink pads and release them ! */
|
||||||
for (n = 0; n < combine->channels->len; n++) {
|
for (n = 0; n < combine->inputpads->len; n++) {
|
||||||
GstPad *sinkpad = g_ptr_array_index (combine->channels, n);
|
GstPad *sinkpad = g_ptr_array_index (combine->inputpads, n);
|
||||||
|
|
||||||
gst_element_release_request_pad (combine->combiner, sinkpad);
|
gst_element_release_request_pad (combine->combiner, sinkpad);
|
||||||
gst_object_unref (sinkpad);
|
gst_object_unref (sinkpad);
|
||||||
}
|
}
|
||||||
g_ptr_array_set_size (combine->channels, 0);
|
g_ptr_array_set_size (combine->inputpads, 0);
|
||||||
|
|
||||||
gst_element_set_state (combine->combiner, GST_STATE_NULL);
|
gst_element_set_state (combine->combiner, GST_STATE_NULL);
|
||||||
gst_bin_remove (GST_BIN_CAST (playbin), combine->combiner);
|
gst_bin_remove (GST_BIN_CAST (playbin), combine->combiner);
|
||||||
|
@ -2894,7 +2866,9 @@ create_combiner (GstPlayBin3 * playbin, GstSourceCombine * combine)
|
||||||
gchar *concat_name;
|
gchar *concat_name;
|
||||||
GST_DEBUG_OBJECT (playbin,
|
GST_DEBUG_OBJECT (playbin,
|
||||||
"No custom combiner requested, using 'concat' element");
|
"No custom combiner requested, using 'concat' element");
|
||||||
concat_name = g_strdup_printf ("%s-concat", combine->media_type);
|
concat_name =
|
||||||
|
g_strdup_printf ("%s-concat",
|
||||||
|
gst_stream_type_get_name (combine->stream_type));
|
||||||
combine->combiner = gst_element_factory_make ("concat", concat_name);
|
combine->combiner = gst_element_factory_make ("concat", concat_name);
|
||||||
g_object_set (combine->combiner, "adjust-base", FALSE, NULL);
|
g_object_set (combine->combiner, "adjust-base", FALSE, NULL);
|
||||||
g_free (concat_name);
|
g_free (concat_name);
|
||||||
|
@ -2922,11 +2896,12 @@ create_combiner (GstPlayBin3 * playbin, GstSourceCombine * combine)
|
||||||
gst_element_sync_state_with_parent (combine->combiner);
|
gst_element_sync_state_with_parent (combine->combiner);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static GstPad *
|
||||||
combiner_control_pad (GstPlayBin3 * playbin, GstSourceCombine * combine,
|
combiner_control_pad (GstPlayBin3 * playbin, GstSourceCombine * combine,
|
||||||
GstPad * srcpad)
|
GstPad * srcpad)
|
||||||
{
|
{
|
||||||
GstPadLinkReturn res;
|
GstPadLinkReturn res;
|
||||||
|
GstPad *combine_pad = NULL;
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (playbin, "srcpad %" GST_PTR_FORMAT, srcpad);
|
GST_DEBUG_OBJECT (playbin, "srcpad %" GST_PTR_FORMAT, srcpad);
|
||||||
|
|
||||||
|
@ -2943,7 +2918,7 @@ combiner_control_pad (GstPlayBin3 * playbin, GstSourceCombine * combine,
|
||||||
/* store the pad in the array */
|
/* store the pad in the array */
|
||||||
GST_DEBUG_OBJECT (playbin, "pad %" GST_PTR_FORMAT " added to array",
|
GST_DEBUG_OBJECT (playbin, "pad %" GST_PTR_FORMAT " added to array",
|
||||||
sinkpad);
|
sinkpad);
|
||||||
g_ptr_array_add (combine->channels, sinkpad);
|
g_ptr_array_add (combine->inputpads, sinkpad);
|
||||||
|
|
||||||
res = gst_pad_link (srcpad, sinkpad);
|
res = gst_pad_link (srcpad, sinkpad);
|
||||||
if (GST_PAD_LINK_FAILED (res))
|
if (GST_PAD_LINK_FAILED (res))
|
||||||
|
@ -2952,7 +2927,7 @@ combiner_control_pad (GstPlayBin3 * playbin, GstSourceCombine * combine,
|
||||||
GST_DEBUG_OBJECT (playbin,
|
GST_DEBUG_OBJECT (playbin,
|
||||||
"linked pad %" GST_PTR_FORMAT " to combiner %" GST_PTR_FORMAT, srcpad,
|
"linked pad %" GST_PTR_FORMAT " to combiner %" GST_PTR_FORMAT, srcpad,
|
||||||
combine->combiner);
|
combine->combiner);
|
||||||
|
combine_pad = sinkpad;
|
||||||
} else {
|
} else {
|
||||||
GST_LOG_OBJECT (playbin, "combine->sinkpad:%" GST_PTR_FORMAT,
|
GST_LOG_OBJECT (playbin, "combine->sinkpad:%" GST_PTR_FORMAT,
|
||||||
combine->sinkpad);
|
combine->sinkpad);
|
||||||
|
@ -2968,61 +2943,39 @@ combiner_control_pad (GstPlayBin3 * playbin, GstSourceCombine * combine,
|
||||||
goto failed_sinkpad_link;
|
goto failed_sinkpad_link;
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return combine_pad;
|
||||||
|
|
||||||
/* Failure cases */
|
/* Failure cases */
|
||||||
request_pad_failed:
|
request_pad_failed:
|
||||||
GST_ELEMENT_ERROR (playbin, CORE, PAD,
|
GST_ELEMENT_ERROR (playbin, CORE, PAD,
|
||||||
("Internal playbin error."),
|
("Internal playbin error."),
|
||||||
("Failed to get request pad from combiner %p.", combine->combiner));
|
("Failed to get request pad from combiner %p.", combine->combiner));
|
||||||
return FALSE;
|
return NULL;
|
||||||
|
|
||||||
|
|
||||||
sinkpad_already_linked:
|
sinkpad_already_linked:
|
||||||
GST_ELEMENT_ERROR (playbin, CORE, PAD,
|
GST_ELEMENT_ERROR (playbin, CORE, PAD,
|
||||||
("Internal playbin error."), ("playsink pad already used !"));
|
("Internal playbin error."), ("playsink pad already used !"));
|
||||||
return FALSE;
|
return NULL;
|
||||||
|
|
||||||
failed_sinkpad_link:
|
failed_sinkpad_link:
|
||||||
GST_ELEMENT_ERROR (playbin, CORE, PAD,
|
GST_ELEMENT_ERROR (playbin, CORE, PAD,
|
||||||
("Internal playbin error."),
|
("Internal playbin error."),
|
||||||
("Failed to link pad to sink. Error %d", res));
|
("Failed to link pad to sink. Error %d", res));
|
||||||
return FALSE;
|
return NULL;
|
||||||
|
|
||||||
failed_combiner_link:
|
failed_combiner_link:
|
||||||
GST_ELEMENT_ERROR (playbin, CORE, PAD,
|
GST_ELEMENT_ERROR (playbin, CORE, PAD,
|
||||||
("Internal playbin error."),
|
("Internal playbin error."),
|
||||||
("Failed to link pad to combiner. Error %d", res));
|
("Failed to link pad to combiner. Error %d", res));
|
||||||
return FALSE;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
combiner_release_pad (GstPlayBin3 * playbin, GstSourceCombine * combine,
|
|
||||||
GstPad * pad)
|
|
||||||
{
|
|
||||||
if (combine->combiner) {
|
|
||||||
GstPad *peer = gst_pad_get_peer (pad);
|
|
||||||
|
|
||||||
if (peer) {
|
|
||||||
GST_DEBUG_OBJECT (playbin, "Removing combiner pad %" GST_PTR_FORMAT,
|
|
||||||
peer);
|
|
||||||
g_ptr_array_remove (combine->channels, peer);
|
|
||||||
|
|
||||||
gst_element_release_request_pad (combine->combiner, peer);
|
|
||||||
gst_object_unref (peer);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
/* Release direct link if present */
|
|
||||||
if (combine->sinkpad) {
|
|
||||||
GST_DEBUG_OBJECT (playbin, "Unlinking pad from playsink sinkpad");
|
|
||||||
gst_pad_unlink (pad, combine->sinkpad);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Call after pad was unlinked from (potential) combiner */
|
/* Call after pad was unlinked from (potential) combiner */
|
||||||
static void
|
static void
|
||||||
release_source_pad (GstPlayBin3 * playbin, GstSourceGroup * group, GstPad * pad)
|
release_source_pad (GstPlayBin3 * playbin, GstSourceGroup * group,
|
||||||
|
GstSourceCombine * combine, GstPad * pad)
|
||||||
{
|
{
|
||||||
SourcePad *sourcepad;
|
SourcePad *sourcepad;
|
||||||
GList *tmp;
|
GList *tmp;
|
||||||
|
@ -3039,6 +2992,12 @@ release_source_pad (GstPlayBin3 * playbin, GstSourceGroup * group, GstPad * pad)
|
||||||
sourcepad->event_probe_id = 0;
|
sourcepad->event_probe_id = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (sourcepad->combine_sinkpad) {
|
||||||
|
gst_element_release_request_pad (combine->combiner,
|
||||||
|
sourcepad->combine_sinkpad);
|
||||||
|
g_ptr_array_remove (combine->inputpads, sourcepad->combine_sinkpad);
|
||||||
|
}
|
||||||
|
|
||||||
/* Remove from list of controlled pads and check again for EOS status */
|
/* Remove from list of controlled pads and check again for EOS status */
|
||||||
group->source_pads = g_list_remove (group->source_pads, sourcepad);
|
group->source_pads = g_list_remove (group->source_pads, sourcepad);
|
||||||
g_slice_free (SourcePad, sourcepad);
|
g_slice_free (SourcePad, sourcepad);
|
||||||
|
@ -3061,6 +3020,7 @@ pad_added_cb (GstElement * uridecodebin, GstPad * pad, GstSourceGroup * group)
|
||||||
gint pb_stream_type = -1;
|
gint pb_stream_type = -1;
|
||||||
gchar *pad_name;
|
gchar *pad_name;
|
||||||
GstPlayBin3 *playbin = group->playbin;
|
GstPlayBin3 *playbin = group->playbin;
|
||||||
|
GstPad *combine_pad;
|
||||||
|
|
||||||
GST_PLAY_BIN3_SHUTDOWN_LOCK (playbin, shutdown);
|
GST_PLAY_BIN3_SHUTDOWN_LOCK (playbin, shutdown);
|
||||||
|
|
||||||
|
@ -3091,9 +3051,9 @@ pad_added_cb (GstElement * uridecodebin, GstPad * pad, GstSourceGroup * group)
|
||||||
GST_PLAY_BIN3_LOCK (playbin);
|
GST_PLAY_BIN3_LOCK (playbin);
|
||||||
combine = &playbin->combiner[pb_stream_type];
|
combine = &playbin->combiner[pb_stream_type];
|
||||||
|
|
||||||
combiner_control_pad (playbin, combine, pad);
|
combine_pad = combiner_control_pad (playbin, combine, pad);
|
||||||
|
|
||||||
control_source_pad (group, pad, combine->stream_type);
|
control_source_pad (group, pad, combine_pad, combine->stream_type);
|
||||||
|
|
||||||
/* Update present stream_types and check whether we should post a pending about-to-finish */
|
/* Update present stream_types and check whether we should post a pending about-to-finish */
|
||||||
group->present_stream_types |= combine->stream_type;
|
group->present_stream_types |= combine->stream_type;
|
||||||
|
@ -3145,8 +3105,7 @@ pad_removed_cb (GstElement * decodebin, GstPad * pad, GstSourceGroup * group)
|
||||||
else
|
else
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
combiner_release_pad (playbin, combine, pad);
|
release_source_pad (playbin, group, combine, pad);
|
||||||
release_source_pad (playbin, group, pad);
|
|
||||||
|
|
||||||
done:
|
done:
|
||||||
GST_PLAY_BIN3_UNLOCK (playbin);
|
GST_PLAY_BIN3_UNLOCK (playbin);
|
||||||
|
@ -3207,16 +3166,17 @@ reconfigure_output (GstPlayBin3 * playbin)
|
||||||
combine->stream_type;
|
combine->stream_type;
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (playbin, "Stream type status: '%s' %s %s",
|
GST_DEBUG_OBJECT (playbin, "Stream type status: '%s' %s %s",
|
||||||
combine->media_type, is_selected ? "selected" : "NOT selected",
|
gst_stream_type_get_name (combine->stream_type),
|
||||||
|
is_selected ? "selected" : "NOT selected",
|
||||||
is_active ? "active" : "NOT active");
|
is_active ? "active" : "NOT active");
|
||||||
/* FIXME : Remove asserts below once enough testing has been done */
|
/* FIXME : Remove asserts below once enough testing has been done */
|
||||||
|
|
||||||
if (is_selected && is_active) {
|
if (is_selected && is_active) {
|
||||||
GST_DEBUG_OBJECT (playbin, "Stream type '%s' already active",
|
GST_DEBUG_OBJECT (playbin, "Stream type '%s' already active",
|
||||||
combine->media_type);
|
gst_stream_type_get_name (combine->stream_type));
|
||||||
} else if (is_active && !is_selected) {
|
} else if (is_active && !is_selected) {
|
||||||
GST_DEBUG_OBJECT (playbin, "Stream type '%s' is no longer requested",
|
GST_DEBUG_OBJECT (playbin, "Stream type '%s' is no longer requested",
|
||||||
combine->media_type);
|
gst_stream_type_get_name (combine->stream_type));
|
||||||
|
|
||||||
/* Unlink combiner from sink */
|
/* Unlink combiner from sink */
|
||||||
if (combine->srcpad) {
|
if (combine->srcpad) {
|
||||||
|
@ -3240,7 +3200,7 @@ reconfigure_output (GstPlayBin3 * playbin)
|
||||||
remove_combiner (playbin, combine);
|
remove_combiner (playbin, combine);
|
||||||
} else if (!is_active && is_selected) {
|
} else if (!is_active && is_selected) {
|
||||||
GST_DEBUG_OBJECT (playbin, "Stream type '%s' is now requested",
|
GST_DEBUG_OBJECT (playbin, "Stream type '%s' is now requested",
|
||||||
combine->media_type);
|
gst_stream_type_get_name (combine->stream_type));
|
||||||
|
|
||||||
/* If we are shutting down, do *not* add more combiners */
|
/* If we are shutting down, do *not* add more combiners */
|
||||||
if (g_atomic_int_get (&playbin->shutdown))
|
if (g_atomic_int_get (&playbin->shutdown))
|
||||||
|
@ -3250,14 +3210,15 @@ reconfigure_output (GstPlayBin3 * playbin)
|
||||||
|
|
||||||
/* Request playsink sink pad */
|
/* Request playsink sink pad */
|
||||||
combine->sinkpad =
|
combine->sinkpad =
|
||||||
gst_play_sink_request_pad (playbin->playsink, combine->type);
|
gst_play_sink_request_pad (playbin->playsink,
|
||||||
|
gst_play_sink_type_from_stream_type (combine->stream_type));
|
||||||
gst_object_ref (combine->sinkpad);
|
gst_object_ref (combine->sinkpad);
|
||||||
/* Create combiner if needed and link it */
|
/* Create combiner if needed and link it */
|
||||||
create_combiner (playbin, combine);
|
create_combiner (playbin, combine);
|
||||||
if (combine->combiner) {
|
if (combine->combiner) {
|
||||||
res = gst_pad_link (combine->srcpad, combine->sinkpad);
|
res = gst_pad_link (combine->srcpad, combine->sinkpad);
|
||||||
GST_DEBUG_OBJECT (playbin, "linked type %s, result: %d",
|
GST_DEBUG_OBJECT (playbin, "linked type %s, result: %d",
|
||||||
combine->media_type, res);
|
gst_stream_type_get_name (combine->stream_type), res);
|
||||||
if (res != GST_PAD_LINK_OK) {
|
if (res != GST_PAD_LINK_OK) {
|
||||||
GST_ELEMENT_ERROR (playbin, CORE, PAD,
|
GST_ELEMENT_ERROR (playbin, CORE, PAD,
|
||||||
("Internal playbin error."),
|
("Internal playbin error."),
|
||||||
|
|
|
@ -5596,3 +5596,18 @@ gst_play_sink_colorbalance_init (gpointer g_iface, gpointer g_iface_data)
|
||||||
iface->get_value = gst_play_sink_colorbalance_get_value;
|
iface->get_value = gst_play_sink_colorbalance_get_value;
|
||||||
iface->get_balance_type = gst_play_sink_colorbalance_get_balance_type;
|
iface->get_balance_type = gst_play_sink_colorbalance_get_balance_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GstPlaySinkType
|
||||||
|
gst_play_sink_type_from_stream_type (GstStreamType stream_type)
|
||||||
|
{
|
||||||
|
switch (stream_type) {
|
||||||
|
case GST_STREAM_TYPE_AUDIO:
|
||||||
|
return GST_PLAY_SINK_TYPE_AUDIO;
|
||||||
|
case GST_STREAM_TYPE_VIDEO:
|
||||||
|
return GST_PLAY_SINK_TYPE_VIDEO;
|
||||||
|
case GST_STREAM_TYPE_TEXT:
|
||||||
|
return GST_PLAY_SINK_TYPE_TEXT;
|
||||||
|
default:
|
||||||
|
return GST_PLAY_SINK_TYPE_LAST;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -101,6 +101,8 @@ GstSample * gst_play_sink_convert_sample (GstPlaySink * playsink, GstCaps
|
||||||
|
|
||||||
gboolean gst_play_sink_reconfigure (GstPlaySink * playsink);
|
gboolean gst_play_sink_reconfigure (GstPlaySink * playsink);
|
||||||
|
|
||||||
|
GstPlaySinkType gst_play_sink_type_from_stream_type (GstStreamType stream_type);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* __GST_PLAY_SINK_H__ */
|
#endif /* __GST_PLAY_SINK_H__ */
|
||||||
|
|
Loading…
Reference in a new issue