playsink: Use subtitleoverlay for subtitles
This commit is contained in:
parent
c92559a9cb
commit
c0828e55b6
@ -97,6 +97,7 @@ typedef struct
|
|||||||
GstElement *overlay;
|
GstElement *overlay;
|
||||||
GstPad *videosinkpad;
|
GstPad *videosinkpad;
|
||||||
GstPad *textsinkpad;
|
GstPad *textsinkpad;
|
||||||
|
GstPad *textsinkpad_target;
|
||||||
GstPad *srcpad; /* outgoing srcpad, used to connect to the next
|
GstPad *srcpad; /* outgoing srcpad, used to connect to the next
|
||||||
* chain */
|
* chain */
|
||||||
GstElement *sink; /* custom sink to receive subtitle buffers */
|
GstElement *sink; /* custom sink to receive subtitle buffers */
|
||||||
@ -1137,14 +1138,16 @@ setup_video_chain (GstPlaySink * playsink, gboolean raw, gboolean async,
|
|||||||
|
|
||||||
/* make an element for playback of video with subtitles embedded.
|
/* make an element for playback of video with subtitles embedded.
|
||||||
*
|
*
|
||||||
* +----------------------------------------------+
|
* +-------------------------------+
|
||||||
* | tbin +-------------+ |
|
* | tbin |
|
||||||
* | +-----+ | textoverlay | |
|
* | +-----------------+ |
|
||||||
* | | csp | +--video_sink | |
|
* | | subtitleoverlay | |
|
||||||
* sink-------sink src+ +-text_sink src--+ |
|
* video----video_sink | |
|
||||||
* | +-----+ | +-------------+ +-- src
|
* | | src--src
|
||||||
* text_sink-------------+ |
|
* text-----text_sink | |
|
||||||
* +----------------------------------------------+
|
* | +-----------------+ |
|
||||||
|
* +-------------------------------+
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
static GstPlayTextChain *
|
static GstPlayTextChain *
|
||||||
gen_text_chain (GstPlaySink * playsink)
|
gen_text_chain (GstPlaySink * playsink)
|
||||||
@ -1205,49 +1208,24 @@ gen_text_chain (GstPlaySink * playsink)
|
|||||||
|
|
||||||
if (textsinkpad == NULL) {
|
if (textsinkpad == NULL) {
|
||||||
if (!(playsink->flags & GST_PLAY_FLAG_NATIVE_VIDEO)) {
|
if (!(playsink->flags & GST_PLAY_FLAG_NATIVE_VIDEO)) {
|
||||||
/* no custom sink, try to setup the colorspace and textoverlay elements */
|
chain->overlay =
|
||||||
chain->conv = gst_element_factory_make ("ffmpegcolorspace", "tconv");
|
gst_element_factory_make ("subtitleoverlay", "suboverlay");
|
||||||
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"), ("subtitle rendering might fail"));
|
|
||||||
} else {
|
|
||||||
gst_bin_add (bin, chain->conv);
|
|
||||||
videosinkpad = gst_element_get_static_pad (chain->conv, "sink");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
chain->overlay = gst_element_factory_make ("textoverlay", "overlay");
|
|
||||||
if (chain->overlay == NULL) {
|
if (chain->overlay == NULL) {
|
||||||
post_missing_element_message (playsink, "textoverlay");
|
post_missing_element_message (playsink, "subtitleoverlay");
|
||||||
GST_ELEMENT_WARNING (playsink, CORE, MISSING_PLUGIN,
|
GST_ELEMENT_WARNING (playsink, CORE, MISSING_PLUGIN,
|
||||||
(_("Missing element '%s' - check your GStreamer installation."),
|
(_("Missing element '%s' - check your GStreamer installation."),
|
||||||
"textoverlay"), ("subtitle rendering disabled"));
|
"subtitleoverlay"), ("subtitle rendering disabled"));
|
||||||
} else {
|
} else {
|
||||||
gst_bin_add (bin, chain->overlay);
|
gst_bin_add (bin, chain->overlay);
|
||||||
|
|
||||||
/* Set some parameters */
|
|
||||||
g_object_set (G_OBJECT (chain->overlay),
|
|
||||||
"halign", "center", "valign", "bottom", NULL);
|
|
||||||
if (playsink->font_desc) {
|
if (playsink->font_desc) {
|
||||||
g_object_set (G_OBJECT (chain->overlay), "font-desc",
|
g_object_set (G_OBJECT (chain->overlay), "font-desc",
|
||||||
playsink->font_desc, NULL);
|
playsink->font_desc, NULL);
|
||||||
}
|
}
|
||||||
g_object_set (G_OBJECT (chain->overlay), "wait-text", FALSE, NULL);
|
|
||||||
|
|
||||||
textsinkpad = gst_element_get_static_pad (chain->overlay, "text_sink");
|
|
||||||
|
|
||||||
|
textsinkpad =
|
||||||
|
gst_element_get_static_pad (chain->overlay, "subtitle_sink");
|
||||||
srcpad = gst_element_get_static_pad (chain->overlay, "src");
|
srcpad = gst_element_get_static_pad (chain->overlay, "src");
|
||||||
|
|
||||||
if (videosinkpad) {
|
|
||||||
/* if we had a videosinkpad, we had a converter and we can link it, we
|
|
||||||
* know that this will work */
|
|
||||||
gst_element_link_pads (chain->conv, "src", chain->overlay,
|
|
||||||
"video_sink");
|
|
||||||
} else {
|
|
||||||
/* no videopad, expose our own video pad then */
|
|
||||||
videosinkpad =
|
videosinkpad =
|
||||||
gst_element_get_static_pad (chain->overlay, "video_sink");
|
gst_element_get_static_pad (chain->overlay, "video_sink");
|
||||||
}
|
}
|
||||||
@ -1255,8 +1233,8 @@ gen_text_chain (GstPlaySink * playsink)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (videosinkpad == NULL) {
|
if (videosinkpad == NULL) {
|
||||||
/* if we still don't have a videosink, we don't have a converter nor an
|
/* if we still don't have a videosink, we don't have an overlay. the only
|
||||||
* overlay. the only thing we can do is insert an identity and ghost the src
|
* thing we can do is insert an identity and ghost the src
|
||||||
* and sink pads. */
|
* and sink pads. */
|
||||||
chain->conv = gst_element_factory_make ("identity", "tidentity");
|
chain->conv = gst_element_factory_make ("identity", "tidentity");
|
||||||
g_object_set (chain->conv, "signal-handoffs", FALSE, NULL);
|
g_object_set (chain->conv, "signal-handoffs", FALSE, NULL);
|
||||||
@ -1264,13 +1242,6 @@ gen_text_chain (GstPlaySink * playsink)
|
|||||||
gst_bin_add (bin, chain->conv);
|
gst_bin_add (bin, chain->conv);
|
||||||
srcpad = gst_element_get_static_pad (chain->conv, "src");
|
srcpad = gst_element_get_static_pad (chain->conv, "src");
|
||||||
videosinkpad = gst_element_get_static_pad (chain->conv, "sink");
|
videosinkpad = gst_element_get_static_pad (chain->conv, "sink");
|
||||||
} else {
|
|
||||||
/* we have a videosink but maybe not a srcpad because there was no
|
|
||||||
* overlay */
|
|
||||||
if (srcpad == NULL) {
|
|
||||||
/* ghost the source pad of the converter then */
|
|
||||||
srcpad = gst_element_get_static_pad (chain->conv, "src");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* expose the ghostpads */
|
/* expose the ghostpads */
|
||||||
@ -1281,6 +1252,7 @@ gen_text_chain (GstPlaySink * playsink)
|
|||||||
}
|
}
|
||||||
if (textsinkpad) {
|
if (textsinkpad) {
|
||||||
chain->textsinkpad = gst_ghost_pad_new ("text_sink", textsinkpad);
|
chain->textsinkpad = gst_ghost_pad_new ("text_sink", textsinkpad);
|
||||||
|
chain->textsinkpad_target = textsinkpad;
|
||||||
gst_object_unref (textsinkpad);
|
gst_object_unref (textsinkpad);
|
||||||
gst_element_add_pad (chain->chain.bin, chain->textsinkpad);
|
gst_element_add_pad (chain->chain.bin, chain->textsinkpad);
|
||||||
}
|
}
|
||||||
@ -2016,16 +1988,27 @@ gst_play_sink_reconfigure (GstPlaySink * playsink)
|
|||||||
playsink->textchain = gen_text_chain (playsink);
|
playsink->textchain = gen_text_chain (playsink);
|
||||||
}
|
}
|
||||||
if (playsink->textchain) {
|
if (playsink->textchain) {
|
||||||
|
GstPad *target;
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (playsink, "adding text chain");
|
GST_DEBUG_OBJECT (playsink, "adding text chain");
|
||||||
add_chain (GST_PLAY_CHAIN (playsink->textchain), TRUE);
|
add_chain (GST_PLAY_CHAIN (playsink->textchain), TRUE);
|
||||||
|
|
||||||
|
if (!(target =
|
||||||
|
gst_ghost_pad_get_target (GST_GHOST_PAD_CAST
|
||||||
|
(playsink->textchain->textsinkpad)))) {
|
||||||
|
target = gst_object_ref (playsink->textchain->textsinkpad_target);
|
||||||
|
gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (playsink->
|
||||||
|
textchain->textsinkpad), target);
|
||||||
|
}
|
||||||
|
gst_object_unref (target);
|
||||||
|
|
||||||
gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (playsink->text_pad),
|
gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (playsink->text_pad),
|
||||||
playsink->textchain->textsinkpad);
|
playsink->textchain->textsinkpad);
|
||||||
gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (playsink->video_pad),
|
gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (playsink->video_pad),
|
||||||
playsink->textchain->videosinkpad);
|
playsink->textchain->videosinkpad);
|
||||||
gst_pad_link (playsink->textchain->srcpad, playsink->videochain->sinkpad);
|
gst_pad_link (playsink->textchain->srcpad, playsink->videochain->sinkpad);
|
||||||
|
|
||||||
activate_chain (GST_PLAY_CHAIN (playsink->textchain), TRUE);
|
activate_chain (GST_PLAY_CHAIN (playsink->textchain), TRUE);
|
||||||
if (playsink->textchain->overlay)
|
|
||||||
g_object_set (playsink->textchain->overlay, "silent", FALSE, NULL);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
GST_DEBUG_OBJECT (playsink, "no text needed");
|
GST_DEBUG_OBJECT (playsink, "no text needed");
|
||||||
@ -2039,8 +2022,8 @@ gst_play_sink_reconfigure (GstPlaySink * playsink)
|
|||||||
} else {
|
} else {
|
||||||
/* we have a chain and a textpad, turn the subtitles off */
|
/* we have a chain and a textpad, turn the subtitles off */
|
||||||
GST_DEBUG_OBJECT (playsink, "turning off the text");
|
GST_DEBUG_OBJECT (playsink, "turning off the text");
|
||||||
if (playsink->textchain->overlay)
|
gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (playsink->
|
||||||
g_object_set (playsink->textchain->overlay, "silent", TRUE, NULL);
|
textchain->textsinkpad), NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!need_video && playsink->video_pad)
|
if (!need_video && playsink->video_pad)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user