playbin2/playsink: Remove everything related to subpicture streams
These will soon be handled the same way as subtitle streams.
This commit is contained in:
parent
dcc109bd9a
commit
ced1b8f897
@ -286,7 +286,6 @@ struct _GstSourceGroup
|
|||||||
GPtrArray *video_channels; /* links to selector pads */
|
GPtrArray *video_channels; /* links to selector pads */
|
||||||
GPtrArray *audio_channels; /* links to selector pads */
|
GPtrArray *audio_channels; /* links to selector pads */
|
||||||
GPtrArray *text_channels; /* links to selector pads */
|
GPtrArray *text_channels; /* links to selector pads */
|
||||||
GPtrArray *subp_channels; /* links to selector pads */
|
|
||||||
|
|
||||||
GstElement *audio_sink; /* autoplugged audio and video sinks */
|
GstElement *audio_sink; /* autoplugged audio and video sinks */
|
||||||
GstElement *video_sink;
|
GstElement *video_sink;
|
||||||
@ -383,7 +382,6 @@ struct _GstPlayBin
|
|||||||
|
|
||||||
GstElement *audio_sink; /* configured audio sink, or NULL */
|
GstElement *audio_sink; /* configured audio sink, or NULL */
|
||||||
GstElement *video_sink; /* configured video sink, or NULL */
|
GstElement *video_sink; /* configured video sink, or NULL */
|
||||||
GstElement *subpic_sink; /* configured subpicture sink, or NULL */
|
|
||||||
GstElement *text_sink; /* configured text sink, or NULL */
|
GstElement *text_sink; /* configured text sink, or NULL */
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -436,7 +434,6 @@ struct _GstPlayBinClass
|
|||||||
#define DEFAULT_VIDEO_SINK NULL
|
#define DEFAULT_VIDEO_SINK NULL
|
||||||
#define DEFAULT_VIS_PLUGIN NULL
|
#define DEFAULT_VIS_PLUGIN NULL
|
||||||
#define DEFAULT_TEXT_SINK NULL
|
#define DEFAULT_TEXT_SINK NULL
|
||||||
#define DEFAULT_SUBPIC_SINK NULL
|
|
||||||
#define DEFAULT_VOLUME 1.0
|
#define DEFAULT_VOLUME 1.0
|
||||||
#define DEFAULT_MUTE FALSE
|
#define DEFAULT_MUTE FALSE
|
||||||
#define DEFAULT_FRAME NULL
|
#define DEFAULT_FRAME NULL
|
||||||
@ -463,7 +460,6 @@ enum
|
|||||||
PROP_VIDEO_SINK,
|
PROP_VIDEO_SINK,
|
||||||
PROP_VIS_PLUGIN,
|
PROP_VIS_PLUGIN,
|
||||||
PROP_TEXT_SINK,
|
PROP_TEXT_SINK,
|
||||||
PROP_SUBPIC_SINK,
|
|
||||||
PROP_VOLUME,
|
PROP_VOLUME,
|
||||||
PROP_MUTE,
|
PROP_MUTE,
|
||||||
PROP_FRAME,
|
PROP_FRAME,
|
||||||
@ -742,10 +738,6 @@ gst_play_bin_class_init (GstPlayBinClass * klass)
|
|||||||
g_param_spec_object ("text-sink", "Text plugin",
|
g_param_spec_object ("text-sink", "Text plugin",
|
||||||
"the text output element to use (NULL = default textoverlay)",
|
"the text output element to use (NULL = default textoverlay)",
|
||||||
GST_TYPE_ELEMENT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
GST_TYPE_ELEMENT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||||
g_object_class_install_property (gobject_klass, PROP_SUBPIC_SINK,
|
|
||||||
g_param_spec_object ("subpic-sink", "Subpicture plugin",
|
|
||||||
"the subpicture output element to use (NULL = default dvdspu)",
|
|
||||||
GST_TYPE_ELEMENT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GstPlayBin2:volume:
|
* GstPlayBin2:volume:
|
||||||
@ -1046,7 +1038,6 @@ init_group (GstPlayBin * playbin, GstSourceGroup * group)
|
|||||||
group->video_channels = g_ptr_array_new ();
|
group->video_channels = g_ptr_array_new ();
|
||||||
group->audio_channels = g_ptr_array_new ();
|
group->audio_channels = g_ptr_array_new ();
|
||||||
group->text_channels = g_ptr_array_new ();
|
group->text_channels = g_ptr_array_new ();
|
||||||
group->subp_channels = g_ptr_array_new ();
|
|
||||||
group->lock = g_mutex_new ();
|
group->lock = g_mutex_new ();
|
||||||
/* init selectors. The selector is found by finding the first prefix that
|
/* init selectors. The selector is found by finding the first prefix that
|
||||||
* matches the media. */
|
* matches the media. */
|
||||||
@ -1060,19 +1051,16 @@ init_group (GstPlayBin * playbin, GstSourceGroup * group)
|
|||||||
group->selector[1].media_list[0] = "audio/";
|
group->selector[1].media_list[0] = "audio/";
|
||||||
group->selector[1].type = GST_PLAY_SINK_TYPE_AUDIO;
|
group->selector[1].type = GST_PLAY_SINK_TYPE_AUDIO;
|
||||||
group->selector[1].channels = group->audio_channels;
|
group->selector[1].channels = group->audio_channels;
|
||||||
group->selector[2].media_list[0] = "video/x-raw-";
|
group->selector[2].media_list[0] = "text/";
|
||||||
group->selector[2].type = GST_PLAY_SINK_TYPE_VIDEO_RAW;
|
group->selector[2].media_list[1] = "video/x-dvd-subpicture";
|
||||||
group->selector[2].channels = group->video_channels;
|
group->selector[2].type = GST_PLAY_SINK_TYPE_TEXT;
|
||||||
group->selector[3].media_list[0] = "video/x-dvd-subpicture";
|
group->selector[2].channels = group->text_channels;
|
||||||
group->selector[3].media_list[1] = "subpicture/x-pgs";
|
group->selector[3].media_list[0] = "video/x-raw-";
|
||||||
group->selector[3].type = GST_PLAY_SINK_TYPE_SUBPIC;
|
group->selector[3].type = GST_PLAY_SINK_TYPE_VIDEO_RAW;
|
||||||
group->selector[3].channels = group->subp_channels;
|
group->selector[3].channels = group->video_channels;
|
||||||
group->selector[4].media_list[0] = "video/";
|
group->selector[4].media_list[0] = "video/";
|
||||||
group->selector[4].type = GST_PLAY_SINK_TYPE_VIDEO;
|
group->selector[4].type = GST_PLAY_SINK_TYPE_VIDEO;
|
||||||
group->selector[4].channels = group->video_channels;
|
group->selector[4].channels = group->video_channels;
|
||||||
group->selector[5].media_list[0] = "text/";
|
|
||||||
group->selector[5].type = GST_PLAY_SINK_TYPE_TEXT;
|
|
||||||
group->selector[5].channels = group->text_channels;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -1082,7 +1070,6 @@ free_group (GstPlayBin * playbin, GstSourceGroup * group)
|
|||||||
g_ptr_array_free (group->video_channels, TRUE);
|
g_ptr_array_free (group->video_channels, TRUE);
|
||||||
g_ptr_array_free (group->audio_channels, TRUE);
|
g_ptr_array_free (group->audio_channels, TRUE);
|
||||||
g_ptr_array_free (group->text_channels, TRUE);
|
g_ptr_array_free (group->text_channels, TRUE);
|
||||||
g_ptr_array_free (group->subp_channels, TRUE);
|
|
||||||
g_mutex_free (group->lock);
|
g_mutex_free (group->lock);
|
||||||
if (group->audio_sink)
|
if (group->audio_sink)
|
||||||
gst_object_unref (group->audio_sink);
|
gst_object_unref (group->audio_sink);
|
||||||
@ -1178,8 +1165,6 @@ gst_play_bin_finalize (GObject * object)
|
|||||||
gst_object_unref (playbin->audio_sink);
|
gst_object_unref (playbin->audio_sink);
|
||||||
if (playbin->text_sink)
|
if (playbin->text_sink)
|
||||||
gst_object_unref (playbin->text_sink);
|
gst_object_unref (playbin->text_sink);
|
||||||
if (playbin->subpic_sink)
|
|
||||||
gst_object_unref (playbin->subpic_sink);
|
|
||||||
|
|
||||||
g_value_array_free (playbin->elements);
|
g_value_array_free (playbin->elements);
|
||||||
g_free (playbin->encoding);
|
g_free (playbin->encoding);
|
||||||
@ -1632,10 +1617,6 @@ gst_play_bin_set_property (GObject * object, guint prop_id,
|
|||||||
gst_play_bin_set_sink (playbin, &playbin->text_sink, "text",
|
gst_play_bin_set_sink (playbin, &playbin->text_sink, "text",
|
||||||
g_value_get_object (value));
|
g_value_get_object (value));
|
||||||
break;
|
break;
|
||||||
case PROP_SUBPIC_SINK:
|
|
||||||
gst_play_bin_set_sink (playbin, &playbin->subpic_sink, "subpicture",
|
|
||||||
g_value_get_object (value));
|
|
||||||
break;
|
|
||||||
case PROP_VOLUME:
|
case PROP_VOLUME:
|
||||||
gst_play_sink_set_volume (playbin->playsink, g_value_get_double (value));
|
gst_play_sink_set_volume (playbin->playsink, g_value_get_double (value));
|
||||||
break;
|
break;
|
||||||
@ -1799,11 +1780,6 @@ gst_play_bin_get_property (GObject * object, guint prop_id, GValue * value,
|
|||||||
gst_play_bin_get_current_sink (playbin, &playbin->text_sink,
|
gst_play_bin_get_current_sink (playbin, &playbin->text_sink,
|
||||||
"text", GST_PLAY_SINK_TYPE_TEXT));
|
"text", GST_PLAY_SINK_TYPE_TEXT));
|
||||||
break;
|
break;
|
||||||
case PROP_SUBPIC_SINK:
|
|
||||||
g_value_take_object (value,
|
|
||||||
gst_play_bin_get_current_sink (playbin, &playbin->subpic_sink,
|
|
||||||
"subpicture", GST_PLAY_SINK_TYPE_SUBPIC));
|
|
||||||
break;
|
|
||||||
case PROP_VOLUME:
|
case PROP_VOLUME:
|
||||||
g_value_set_double (value, gst_play_sink_get_volume (playbin->playsink));
|
g_value_set_double (value, gst_play_sink_get_volume (playbin->playsink));
|
||||||
break;
|
break;
|
||||||
@ -1841,7 +1817,7 @@ gst_play_bin_get_property (GObject * object, guint prop_id, GValue * value,
|
|||||||
/* mime types we are not handling on purpose right now, don't post a
|
/* mime types we are not handling on purpose right now, don't post a
|
||||||
* missing-plugin message for these */
|
* missing-plugin message for these */
|
||||||
static const gchar *blacklisted_mimes[] = {
|
static const gchar *blacklisted_mimes[] = {
|
||||||
"video/x-dvd-subpicture", "subpicture/x-pgs", NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -2198,7 +2174,6 @@ pad_added_cb (GstElement * decodebin, GstPad * pad, GstSourceGroup * group)
|
|||||||
g_object_set (sinkpad, "always-ok", always_ok, NULL);
|
g_object_set (sinkpad, "always-ok", always_ok, NULL);
|
||||||
signal = SIGNAL_TEXT_CHANGED;
|
signal = SIGNAL_TEXT_CHANGED;
|
||||||
break;
|
break;
|
||||||
case GST_PLAY_SINK_TYPE_SUBPIC:
|
|
||||||
default:
|
default:
|
||||||
signal = -1;
|
signal = -1;
|
||||||
}
|
}
|
||||||
@ -2388,8 +2363,6 @@ no_more_pads_cb (GstElement * decodebin, GstSourceGroup * group)
|
|||||||
}
|
}
|
||||||
gst_play_sink_set_sink (playbin->playsink, GST_PLAY_SINK_TYPE_TEXT,
|
gst_play_sink_set_sink (playbin->playsink, GST_PLAY_SINK_TYPE_TEXT,
|
||||||
playbin->text_sink);
|
playbin->text_sink);
|
||||||
gst_play_sink_set_sink (playbin->playsink, GST_PLAY_SINK_TYPE_SUBPIC,
|
|
||||||
playbin->subpic_sink);
|
|
||||||
GST_SOURCE_GROUP_UNLOCK (group);
|
GST_SOURCE_GROUP_UNLOCK (group);
|
||||||
|
|
||||||
GST_LOG_OBJECT (playbin, "reconfigure sink");
|
GST_LOG_OBJECT (playbin, "reconfigure sink");
|
||||||
|
@ -104,20 +104,6 @@ typedef struct
|
|||||||
GstElement *sink; /* custom sink to receive subtitle buffers */
|
GstElement *sink; /* custom sink to receive subtitle buffers */
|
||||||
} GstPlayTextChain;
|
} GstPlayTextChain;
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
GstPlayChain chain;
|
|
||||||
GstPad *sinkpad;
|
|
||||||
GstElement *queue;
|
|
||||||
GstElement *conv;
|
|
||||||
GstElement *overlay;
|
|
||||||
GstPad *videosinkpad;
|
|
||||||
GstPad *subpsinkpad;
|
|
||||||
GstPad *srcpad; /* outgoing srcpad, used to connect to the next
|
|
||||||
* chain */
|
|
||||||
GstElement *sink; /* custom sink to receive subpicture buffers */
|
|
||||||
} GstPlaySubpChain;
|
|
||||||
|
|
||||||
#define GST_PLAY_SINK_GET_LOCK(playsink) (&((GstPlaySink *)playsink)->lock)
|
#define GST_PLAY_SINK_GET_LOCK(playsink) (&((GstPlaySink *)playsink)->lock)
|
||||||
#define GST_PLAY_SINK_LOCK(playsink) g_static_rec_mutex_lock (GST_PLAY_SINK_GET_LOCK (playsink))
|
#define GST_PLAY_SINK_LOCK(playsink) g_static_rec_mutex_lock (GST_PLAY_SINK_GET_LOCK (playsink))
|
||||||
#define GST_PLAY_SINK_UNLOCK(playsink) g_static_rec_mutex_unlock (GST_PLAY_SINK_GET_LOCK (playsink))
|
#define GST_PLAY_SINK_UNLOCK(playsink) g_static_rec_mutex_unlock (GST_PLAY_SINK_GET_LOCK (playsink))
|
||||||
@ -138,7 +124,6 @@ struct _GstPlaySink
|
|||||||
GstPlayVideoChain *videochain;
|
GstPlayVideoChain *videochain;
|
||||||
GstPlayVisChain *vischain;
|
GstPlayVisChain *vischain;
|
||||||
GstPlayTextChain *textchain;
|
GstPlayTextChain *textchain;
|
||||||
GstPlaySubpChain *subpchain;
|
|
||||||
|
|
||||||
/* audio */
|
/* audio */
|
||||||
GstPad *audio_pad;
|
GstPad *audio_pad;
|
||||||
@ -153,15 +138,12 @@ struct _GstPlaySink
|
|||||||
gboolean video_pad_raw;
|
gboolean video_pad_raw;
|
||||||
/* text */
|
/* text */
|
||||||
GstPad *text_pad;
|
GstPad *text_pad;
|
||||||
/* subpictures */
|
|
||||||
GstPad *subp_pad;
|
|
||||||
|
|
||||||
/* properties */
|
/* properties */
|
||||||
GstElement *audio_sink;
|
GstElement *audio_sink;
|
||||||
GstElement *video_sink;
|
GstElement *video_sink;
|
||||||
GstElement *visualisation;
|
GstElement *visualisation;
|
||||||
GstElement *text_sink;
|
GstElement *text_sink;
|
||||||
GstElement *subp_sink;
|
|
||||||
gfloat volume;
|
gfloat volume;
|
||||||
gboolean mute;
|
gboolean mute;
|
||||||
gchar *font_desc; /* font description */
|
gchar *font_desc; /* font description */
|
||||||
@ -202,13 +184,6 @@ static GstStaticPadTemplate texttemplate = GST_STATIC_PAD_TEMPLATE ("text_sink",
|
|||||||
GST_PAD_SINK,
|
GST_PAD_SINK,
|
||||||
GST_PAD_REQUEST,
|
GST_PAD_REQUEST,
|
||||||
GST_STATIC_CAPS_ANY);
|
GST_STATIC_CAPS_ANY);
|
||||||
static GstStaticPadTemplate subpictemplate =
|
|
||||||
GST_STATIC_PAD_TEMPLATE ("subpic_sink",
|
|
||||||
GST_PAD_SINK,
|
|
||||||
GST_PAD_REQUEST,
|
|
||||||
GST_STATIC_CAPS_ANY);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* props */
|
/* props */
|
||||||
enum
|
enum
|
||||||
@ -326,8 +301,6 @@ gst_play_sink_class_init (GstPlaySinkClass * klass)
|
|||||||
gst_static_pad_template_get (&videotemplate));
|
gst_static_pad_template_get (&videotemplate));
|
||||||
gst_element_class_add_pad_template (gstelement_klass,
|
gst_element_class_add_pad_template (gstelement_klass,
|
||||||
gst_static_pad_template_get (&texttemplate));
|
gst_static_pad_template_get (&texttemplate));
|
||||||
gst_element_class_add_pad_template (gstelement_klass,
|
|
||||||
gst_static_pad_template_get (&subpictemplate));
|
|
||||||
gst_element_class_set_details (gstelement_klass, &gst_play_sink_details);
|
gst_element_class_set_details (gstelement_klass, &gst_play_sink_details);
|
||||||
|
|
||||||
gstelement_klass->change_state =
|
gstelement_klass->change_state =
|
||||||
@ -466,9 +439,6 @@ gst_play_sink_set_sink (GstPlaySink * playsink, GstPlaySinkType type,
|
|||||||
case GST_PLAY_SINK_TYPE_TEXT:
|
case GST_PLAY_SINK_TYPE_TEXT:
|
||||||
elem = &playsink->text_sink;
|
elem = &playsink->text_sink;
|
||||||
break;
|
break;
|
||||||
case GST_PLAY_SINK_TYPE_SUBPIC:
|
|
||||||
elem = &playsink->subp_sink;
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -516,14 +486,6 @@ gst_play_sink_get_sink (GstPlaySink * playsink, GstPlaySinkType type)
|
|||||||
elem = playsink->text_sink;
|
elem = playsink->text_sink;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case GST_PLAY_SINK_TYPE_SUBPIC:
|
|
||||||
{
|
|
||||||
GstPlaySubpChain *chain;
|
|
||||||
if ((chain = (GstPlaySubpChain *) playsink->subpchain))
|
|
||||||
chainp = chain->sink;
|
|
||||||
elem = playsink->subp_sink;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -947,7 +909,7 @@ gen_video_chain (GstPlaySink * playsink, gboolean raw, gboolean async,
|
|||||||
GstPlayVideoChain *chain;
|
GstPlayVideoChain *chain;
|
||||||
GstBin *bin;
|
GstBin *bin;
|
||||||
GstPad *pad;
|
GstPad *pad;
|
||||||
GstElement *head, *prev, *elem = NULL;
|
GstElement *head = NULL, *prev = NULL, *elem = NULL;
|
||||||
|
|
||||||
chain = g_new0 (GstPlayVideoChain, 1);
|
chain = g_new0 (GstPlayVideoChain, 1);
|
||||||
chain->chain.playsink = playsink;
|
chain->chain.playsink = playsink;
|
||||||
@ -976,6 +938,7 @@ gen_video_chain (GstPlaySink * playsink, gboolean raw, gboolean async,
|
|||||||
}
|
}
|
||||||
if (chain->sink == NULL)
|
if (chain->sink == NULL)
|
||||||
goto no_sinks;
|
goto no_sinks;
|
||||||
|
head = chain->sink;
|
||||||
|
|
||||||
/* if we can disable async behaviour of the sink, we can avoid adding a
|
/* if we can disable async behaviour of the sink, we can avoid adding a
|
||||||
* queue for the audio chain. */
|
* queue for the audio chain. */
|
||||||
@ -1274,134 +1237,6 @@ gen_text_chain (GstPlaySink * playsink)
|
|||||||
return chain;
|
return chain;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* make an element for playback of video with subpictures embedded.
|
|
||||||
*
|
|
||||||
* +--------------------------------------------------------+
|
|
||||||
* | pbin +-------------+ |
|
|
||||||
* | +-------+ +-----+ | dvdspu | |
|
|
||||||
* | | queue | | csp | +---video | |
|
|
||||||
* sink----sink src--sink src+ +-subpicture src--+ |
|
|
||||||
* | +-------+ +-----+ | +-------------+ +-- src
|
|
||||||
* subpicture----------------------+ |
|
|
||||||
* +--------------------------------------------------------+
|
|
||||||
*/
|
|
||||||
static GstPlaySubpChain *
|
|
||||||
gen_subp_chain (GstPlaySink * playsink)
|
|
||||||
{
|
|
||||||
GstPlaySubpChain *chain;
|
|
||||||
GstBin *bin;
|
|
||||||
GstElement *elem, *head;
|
|
||||||
GstPad *videosinkpad, *subpsinkpad, *srcpad;
|
|
||||||
|
|
||||||
chain = g_new0 (GstPlaySubpChain, 1);
|
|
||||||
chain->chain.playsink = playsink;
|
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (playsink, "making subpicture chain %p", chain);
|
|
||||||
|
|
||||||
chain->chain.bin = gst_bin_new ("pbin");
|
|
||||||
bin = GST_BIN_CAST (chain->chain.bin);
|
|
||||||
gst_object_ref_sink (bin);
|
|
||||||
|
|
||||||
subpsinkpad = srcpad = NULL;
|
|
||||||
|
|
||||||
/* first try to hook the text pad to the custom sink */
|
|
||||||
if (playsink->subp_sink) {
|
|
||||||
GST_DEBUG_OBJECT (playsink, "trying configured subpsink");
|
|
||||||
chain->sink = try_element (playsink, playsink->text_sink, FALSE);
|
|
||||||
if (chain->sink) {
|
|
||||||
elem = gst_play_sink_find_property_sinks (playsink, chain->sink, "async");
|
|
||||||
if (elem) {
|
|
||||||
/* make sure the sparse subtitles don't participate in the preroll */
|
|
||||||
g_object_set (elem, "async", FALSE, NULL);
|
|
||||||
/* we have a custom sink, this will be our subpsinkpad */
|
|
||||||
subpsinkpad = gst_element_get_static_pad (chain->sink, "sink");
|
|
||||||
if (subpsinkpad) {
|
|
||||||
/* we're all fine now and we can add the sink to the chain */
|
|
||||||
GST_DEBUG_OBJECT (playsink, "adding custom text sink");
|
|
||||||
gst_bin_add (bin, chain->sink);
|
|
||||||
} else {
|
|
||||||
GST_WARNING_OBJECT (playsink,
|
|
||||||
"can't find a sink pad on custom text sink");
|
|
||||||
gst_object_unref (chain->sink);
|
|
||||||
chain->sink = NULL;
|
|
||||||
}
|
|
||||||
/* try to set sync to true but it's no biggie when we can't */
|
|
||||||
if ((elem =
|
|
||||||
gst_play_sink_find_property_sinks (playsink, chain->sink,
|
|
||||||
"sync")))
|
|
||||||
g_object_set (elem, "sync", TRUE, NULL);
|
|
||||||
} else {
|
|
||||||
GST_WARNING_OBJECT (playsink,
|
|
||||||
"can't find async property in custom text sink");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (subpsinkpad == NULL) {
|
|
||||||
GST_ELEMENT_WARNING (playsink, CORE, MISSING_PLUGIN,
|
|
||||||
(_("Custom text sink element is not usable.")),
|
|
||||||
("fallback to default dvdspu overlay"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* make a little queue */
|
|
||||||
chain->queue = gst_element_factory_make ("queue", "vqueue");
|
|
||||||
g_object_set (G_OBJECT (chain->queue), "max-size-buffers", 3,
|
|
||||||
"max-size-bytes", 0, "max-size-time", (gint64) 0, NULL);
|
|
||||||
gst_bin_add (bin, chain->queue);
|
|
||||||
head = chain->queue;
|
|
||||||
|
|
||||||
/* video goes into the queue */
|
|
||||||
videosinkpad = gst_element_get_static_pad (chain->queue, "sink");
|
|
||||||
|
|
||||||
if (subpsinkpad == NULL) {
|
|
||||||
if (!(playsink->flags & GST_PLAY_FLAG_NATIVE_VIDEO)) {
|
|
||||||
/* no custom sink, try to setup the colorspace and textoverlay elements */
|
|
||||||
chain->conv = gst_element_factory_make ("ffmpegcolorspace", "tconv");
|
|
||||||
if (chain->conv == NULL) {
|
|
||||||
/* not really needed, it might work without colorspace */
|
|
||||||
post_missing_element_message (playsink, "ffmpegcolorspace");
|
|
||||||
GST_ELEMENT_WARNING (playsink, CORE, MISSING_PLUGIN,
|
|
||||||
(_("Missing element '%s' - check your GStreamer installation."),
|
|
||||||
"ffmpegcolorspace"), ("subpicture rendering might fail"));
|
|
||||||
} else {
|
|
||||||
gst_bin_add (bin, chain->conv);
|
|
||||||
gst_element_link_pads (head, "src", chain->conv, "sink");
|
|
||||||
head = chain->conv;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
chain->overlay = gst_element_factory_make ("dvdspu", "spuoverlay");
|
|
||||||
if (chain->overlay == NULL) {
|
|
||||||
post_missing_element_message (playsink, "dvdspu");
|
|
||||||
GST_ELEMENT_WARNING (playsink, CORE, MISSING_PLUGIN,
|
|
||||||
(_("Missing element '%s' - check your GStreamer installation."),
|
|
||||||
"dvdspu"), ("subpicture rendering disabled"));
|
|
||||||
} else {
|
|
||||||
gst_bin_add (bin, chain->overlay);
|
|
||||||
/* Set some parameters */
|
|
||||||
subpsinkpad = gst_element_get_static_pad (chain->overlay, "subpicture");
|
|
||||||
/* link to the next element */
|
|
||||||
gst_element_link_pads (head, "src", chain->overlay, "video");
|
|
||||||
head = chain->overlay;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
srcpad = gst_element_get_static_pad (head, "src");
|
|
||||||
chain->srcpad = gst_ghost_pad_new ("src", srcpad);
|
|
||||||
gst_object_unref (srcpad);
|
|
||||||
gst_element_add_pad (chain->chain.bin, chain->srcpad);
|
|
||||||
|
|
||||||
/* expose the ghostpads */
|
|
||||||
chain->videosinkpad = gst_ghost_pad_new ("sink", videosinkpad);
|
|
||||||
gst_object_unref (videosinkpad);
|
|
||||||
gst_element_add_pad (chain->chain.bin, chain->videosinkpad);
|
|
||||||
|
|
||||||
if (subpsinkpad) {
|
|
||||||
chain->subpsinkpad = gst_ghost_pad_new ("subpicture", subpsinkpad);
|
|
||||||
gst_object_unref (subpsinkpad);
|
|
||||||
gst_element_add_pad (chain->chain.bin, chain->subpsinkpad);
|
|
||||||
}
|
|
||||||
return chain;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
notify_volume_cb (GObject * object, GParamSpec * pspec, GstPlaySink * playsink)
|
notify_volume_cb (GObject * object, GParamSpec * pspec, GstPlaySink * playsink)
|
||||||
{
|
{
|
||||||
@ -1873,12 +1708,12 @@ gboolean
|
|||||||
gst_play_sink_reconfigure (GstPlaySink * playsink)
|
gst_play_sink_reconfigure (GstPlaySink * playsink)
|
||||||
{
|
{
|
||||||
GstPlayFlags flags;
|
GstPlayFlags flags;
|
||||||
gboolean need_audio, need_video, need_vis, need_text, need_subp;
|
gboolean need_audio, need_video, need_vis, need_text;
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (playsink, "reconfiguring");
|
GST_DEBUG_OBJECT (playsink, "reconfiguring");
|
||||||
|
|
||||||
/* assume we need nothing */
|
/* assume we need nothing */
|
||||||
need_audio = need_video = need_vis = need_text = need_subp = FALSE;
|
need_audio = need_video = need_vis = need_text = FALSE;
|
||||||
|
|
||||||
GST_PLAY_SINK_LOCK (playsink);
|
GST_PLAY_SINK_LOCK (playsink);
|
||||||
GST_OBJECT_LOCK (playsink);
|
GST_OBJECT_LOCK (playsink);
|
||||||
@ -1887,7 +1722,7 @@ gst_play_sink_reconfigure (GstPlaySink * playsink)
|
|||||||
GST_OBJECT_UNLOCK (playsink);
|
GST_OBJECT_UNLOCK (playsink);
|
||||||
|
|
||||||
/* figure out which components we need */
|
/* figure out which components we need */
|
||||||
if (flags & GST_PLAY_FLAG_TEXT && (playsink->text_pad || playsink->subp_pad)) {
|
if (flags & GST_PLAY_FLAG_TEXT && playsink->text_pad) {
|
||||||
/* we have a text_pad and we need text rendering, in this case we need a
|
/* we have a text_pad and we need text rendering, in this case we need a
|
||||||
* video_pad to combine the video with the text */
|
* video_pad to combine the video with the text */
|
||||||
if (!playsink->video_pad)
|
if (!playsink->video_pad)
|
||||||
@ -1896,13 +1731,7 @@ gst_play_sink_reconfigure (GstPlaySink * playsink)
|
|||||||
/* we have subtitles and we are requested to show it, we also need to show
|
/* we have subtitles and we are requested to show it, we also need to show
|
||||||
* video in this case. */
|
* video in this case. */
|
||||||
need_video = TRUE;
|
need_video = TRUE;
|
||||||
need_text = (playsink->text_pad != NULL);
|
need_text = TRUE;
|
||||||
need_subp = (playsink->subp_pad != NULL);
|
|
||||||
|
|
||||||
/* we can't handle both of them yet (FIXME: wouldn't it be better to just
|
|
||||||
* pick one and ignore the other then instead of erroring out?) */
|
|
||||||
if (need_text && need_subp)
|
|
||||||
goto subs_and_text;
|
|
||||||
} else if (flags & GST_PLAY_FLAG_VIDEO && playsink->video_pad) {
|
} else if (flags & GST_PLAY_FLAG_VIDEO && playsink->video_pad) {
|
||||||
/* we have video and we are requested to show it */
|
/* we have video and we are requested to show it */
|
||||||
need_video = TRUE;
|
need_video = TRUE;
|
||||||
@ -2040,42 +1869,6 @@ gst_play_sink_reconfigure (GstPlaySink * playsink)
|
|||||||
gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (playsink->text_pad), NULL);
|
gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (playsink->text_pad), NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (need_subp && playsink->videochain) {
|
|
||||||
GST_DEBUG_OBJECT (playsink, "adding subpicture");
|
|
||||||
if (!playsink->subpchain) {
|
|
||||||
GST_DEBUG_OBJECT (playsink, "creating subpicture chain");
|
|
||||||
playsink->subpchain = gen_subp_chain (playsink);
|
|
||||||
}
|
|
||||||
if (playsink->subpchain) {
|
|
||||||
GST_DEBUG_OBJECT (playsink, "adding subp chain");
|
|
||||||
add_chain (GST_PLAY_CHAIN (playsink->subpchain), TRUE);
|
|
||||||
gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (playsink->subp_pad),
|
|
||||||
playsink->subpchain->subpsinkpad);
|
|
||||||
gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (playsink->video_pad),
|
|
||||||
playsink->subpchain->videosinkpad);
|
|
||||||
gst_pad_link (playsink->subpchain->srcpad, playsink->videochain->sinkpad);
|
|
||||||
activate_chain (GST_PLAY_CHAIN (playsink->subpchain), TRUE);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
GST_DEBUG_OBJECT (playsink, "no subpicture needed");
|
|
||||||
/* we have no subpicture or we are requested to not show them */
|
|
||||||
if (playsink->subpchain) {
|
|
||||||
if (playsink->subp_pad == NULL) {
|
|
||||||
/* no subpicture pad, remove the chain entirely */
|
|
||||||
GST_DEBUG_OBJECT (playsink, "removing subp chain");
|
|
||||||
add_chain (GST_PLAY_CHAIN (playsink->subpchain), FALSE);
|
|
||||||
activate_chain (GST_PLAY_CHAIN (playsink->subpchain), FALSE);
|
|
||||||
} else {
|
|
||||||
/* we have a chain and a subpicture pad, turn the subtitles off */
|
|
||||||
GST_DEBUG_OBJECT (playsink, "turning off the subp");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!need_video && playsink->video_pad)
|
|
||||||
gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (playsink->video_pad), NULL);
|
|
||||||
if (playsink->subp_pad)
|
|
||||||
gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (playsink->subp_pad), NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (need_audio) {
|
if (need_audio) {
|
||||||
gboolean raw, queue;
|
gboolean raw, queue;
|
||||||
|
|
||||||
@ -2201,14 +1994,6 @@ subs_but_no_video:
|
|||||||
GST_PLAY_SINK_UNLOCK (playsink);
|
GST_PLAY_SINK_UNLOCK (playsink);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
subs_and_text:
|
|
||||||
{
|
|
||||||
GST_ELEMENT_ERROR (playsink, STREAM, FORMAT,
|
|
||||||
(_("Can't display both text subtitles and subpictures.")),
|
|
||||||
("Have text pad and subpicture pad"));
|
|
||||||
GST_PLAY_SINK_UNLOCK (playsink);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -2419,15 +2204,6 @@ gst_play_sink_request_pad (GstPlaySink * playsink, GstPlaySinkType type)
|
|||||||
created = TRUE;
|
created = TRUE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case GST_PLAY_SINK_TYPE_SUBPIC:
|
|
||||||
GST_LOG_OBJECT (playsink, "ghosting subpicture pad");
|
|
||||||
if (!playsink->subp_pad) {
|
|
||||||
playsink->subp_pad =
|
|
||||||
gst_ghost_pad_new_no_target ("subp_sink", GST_PAD_SINK);
|
|
||||||
created = TRUE;
|
|
||||||
}
|
|
||||||
res = playsink->subp_pad;
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
res = NULL;
|
res = NULL;
|
||||||
break;
|
break;
|
||||||
@ -2475,8 +2251,6 @@ gst_play_sink_request_new_pad (GstElement * element, GstPadTemplate * templ,
|
|||||||
type = GST_PLAY_SINK_TYPE_VIDEO_RAW;
|
type = GST_PLAY_SINK_TYPE_VIDEO_RAW;
|
||||||
else if (!strcmp (tplname, "text_sink"))
|
else if (!strcmp (tplname, "text_sink"))
|
||||||
type = GST_PLAY_SINK_TYPE_TEXT;
|
type = GST_PLAY_SINK_TYPE_TEXT;
|
||||||
else if (!strcmp (tplname, "subpicsink"))
|
|
||||||
type = GST_PLAY_SINK_TYPE_SUBPIC;
|
|
||||||
else
|
else
|
||||||
goto unknown_template;
|
goto unknown_template;
|
||||||
|
|
||||||
@ -2503,8 +2277,6 @@ gst_play_sink_release_pad (GstPlaySink * playsink, GstPad * pad)
|
|||||||
res = &playsink->audio_pad;
|
res = &playsink->audio_pad;
|
||||||
} else if (pad == playsink->text_pad) {
|
} else if (pad == playsink->text_pad) {
|
||||||
res = &playsink->text_pad;
|
res = &playsink->text_pad;
|
||||||
} else if (pad == playsink->subp_pad) {
|
|
||||||
res = &playsink->subp_pad;
|
|
||||||
} else {
|
} else {
|
||||||
/* try to release the given pad anyway, these could be the FLUSHING pads. */
|
/* try to release the given pad anyway, these could be the FLUSHING pads. */
|
||||||
res = &pad;
|
res = &pad;
|
||||||
@ -2578,7 +2350,7 @@ gst_play_sink_handle_message (GstBin * bin, GstMessage * message)
|
|||||||
|
|
||||||
/* Send an event to our sinks until one of them works; don't then send to the
|
/* Send an event to our sinks until one of them works; don't then send to the
|
||||||
* remaining sinks (unlike GstBin)
|
* remaining sinks (unlike GstBin)
|
||||||
* Special case: If a subpicture or text sink is set we need to send the event
|
* Special case: If a text sink is set we need to send the event
|
||||||
* to them in case it's source is different from the a/v stream's source.
|
* to them in case it's source is different from the a/v stream's source.
|
||||||
*/
|
*/
|
||||||
static gboolean
|
static gboolean
|
||||||
@ -2595,15 +2367,6 @@ gst_play_sink_send_event_to_sink (GstPlaySink * playsink, GstEvent * event)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (playsink->subpchain && playsink->subpchain->sink) {
|
|
||||||
gst_event_ref (event);
|
|
||||||
if ((res = gst_element_send_event (playsink->subpchain->chain.bin, event))) {
|
|
||||||
GST_DEBUG_OBJECT (playsink, "Sent event succesfully to subpicture sink");
|
|
||||||
} else {
|
|
||||||
GST_DEBUG_OBJECT (playsink, "Event failed when sent to subpicture sink");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (playsink->videochain) {
|
if (playsink->videochain) {
|
||||||
gst_event_ref (event);
|
gst_event_ref (event);
|
||||||
if ((res = gst_element_send_event (playsink->videochain->chain.bin, event))) {
|
if ((res = gst_element_send_event (playsink->videochain->chain.bin, event))) {
|
||||||
@ -2757,10 +2520,6 @@ gst_play_sink_change_state (GstElement * element, GstStateChange transition)
|
|||||||
activate_chain (GST_PLAY_CHAIN (playsink->textchain), FALSE);
|
activate_chain (GST_PLAY_CHAIN (playsink->textchain), FALSE);
|
||||||
add_chain (GST_PLAY_CHAIN (playsink->textchain), FALSE);
|
add_chain (GST_PLAY_CHAIN (playsink->textchain), FALSE);
|
||||||
}
|
}
|
||||||
if (playsink->subpchain) {
|
|
||||||
activate_chain (GST_PLAY_CHAIN (playsink->subpchain), FALSE);
|
|
||||||
add_chain (GST_PLAY_CHAIN (playsink->subpchain), FALSE);
|
|
||||||
}
|
|
||||||
do_async_done (playsink);
|
do_async_done (playsink);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -46,7 +46,6 @@ G_BEGIN_DECLS
|
|||||||
* @GST_PLAY_SINK_TYPE_VIDEO: a non-raw video pad
|
* @GST_PLAY_SINK_TYPE_VIDEO: a non-raw video pad
|
||||||
* @GST_PLAY_SINK_TYPE_VIDEO_RAW: a raw video pad
|
* @GST_PLAY_SINK_TYPE_VIDEO_RAW: a raw video pad
|
||||||
* @GST_PLAY_SINK_TYPE_TEXT: a raw text pad
|
* @GST_PLAY_SINK_TYPE_TEXT: a raw text pad
|
||||||
* @GST_PLAY_SINK_TYPE_SUBPIC: a subpicture pad
|
|
||||||
* @GST_PLAY_SINK_TYPE_LAST: the last type
|
* @GST_PLAY_SINK_TYPE_LAST: the last type
|
||||||
* @GST_PLAY_SINK_TYPE_FLUSHING: a flushing pad, used when shutting down
|
* @GST_PLAY_SINK_TYPE_FLUSHING: a flushing pad, used when shutting down
|
||||||
*
|
*
|
||||||
@ -58,11 +57,10 @@ typedef enum {
|
|||||||
GST_PLAY_SINK_TYPE_VIDEO = 2,
|
GST_PLAY_SINK_TYPE_VIDEO = 2,
|
||||||
GST_PLAY_SINK_TYPE_VIDEO_RAW = 3,
|
GST_PLAY_SINK_TYPE_VIDEO_RAW = 3,
|
||||||
GST_PLAY_SINK_TYPE_TEXT = 4,
|
GST_PLAY_SINK_TYPE_TEXT = 4,
|
||||||
GST_PLAY_SINK_TYPE_SUBPIC = 5,
|
GST_PLAY_SINK_TYPE_LAST = 5,
|
||||||
GST_PLAY_SINK_TYPE_LAST = 6,
|
|
||||||
|
|
||||||
/* this is a dummy pad */
|
/* this is a dummy pad */
|
||||||
GST_PLAY_SINK_TYPE_FLUSHING = 7
|
GST_PLAY_SINK_TYPE_FLUSHING = 6
|
||||||
} GstPlaySinkType;
|
} GstPlaySinkType;
|
||||||
|
|
||||||
typedef struct _GstPlaySink GstPlaySink;
|
typedef struct _GstPlaySink GstPlaySink;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user