playbin2, playsink, subtitleoverlay: Set subtitle encoding properly

For this add subtitle encoding properties to playsink and subtitleoverlay
and update the values in the containing elements.

Also update the font description in textoverlay or the used renderer
element if it is changed during playback.

Fixes bug #610310.
This commit is contained in:
Sebastian Dröge 2010-02-21 19:52:45 +01:00
parent 1b41c2696d
commit ff21fe1d25
5 changed files with 131 additions and 33 deletions

View file

@ -372,7 +372,6 @@ struct _GstPlayBin
gint current_video; /* the currently selected stream */
gint current_audio; /* the currently selected stream */
gint current_text; /* the currently selected stream */
gchar *encoding; /* subtitle encoding */
guint64 buffer_duration; /* When buffering, the max buffer duration (ns) */
guint buffer_size; /* When buffering, the max buffer size (bytes) */
@ -1184,8 +1183,6 @@ gst_play_bin_init (GstPlayBin * playbin)
g_signal_connect (playbin->playsink, "notify::mute",
G_CALLBACK (notify_mute_cb), playbin);
playbin->encoding = g_strdup (DEFAULT_SUBTITLE_ENCODING);
playbin->current_video = DEFAULT_CURRENT_VIDEO;
playbin->current_audio = DEFAULT_CURRENT_AUDIO;
playbin->current_text = DEFAULT_CURRENT_TEXT;
@ -1214,7 +1211,6 @@ gst_play_bin_finalize (GObject * object)
gst_object_unref (playbin->text_sink);
g_value_array_free (playbin->elements);
g_free (playbin->encoding);
g_mutex_free (playbin->lock);
g_mutex_free (playbin->dyn_lock);
g_mutex_free (playbin->elements_lock);
@ -1713,27 +1709,6 @@ no_channels:
}
}
static void
gst_play_bin_set_encoding (GstPlayBin * playbin, const gchar * encoding)
{
GstElement *elem;
GST_PLAY_BIN_LOCK (playbin);
g_free (playbin->encoding);
playbin->encoding = g_strdup (encoding);
/* set subtitles on all current and next decodebins. */
if ((elem = playbin->groups[0].uridecodebin))
g_object_set (G_OBJECT (elem), "subtitle-encoding", encoding, NULL);
if ((elem = playbin->groups[0].suburidecodebin))
g_object_set (G_OBJECT (elem), "subtitle-encoding", encoding, NULL);
if ((elem = playbin->groups[1].uridecodebin))
g_object_set (G_OBJECT (elem), "subtitle-encoding", encoding, NULL);
if ((elem = playbin->groups[1].suburidecodebin))
g_object_set (G_OBJECT (elem), "subtitle-encoding", encoding, NULL);
GST_PLAY_BIN_UNLOCK (playbin);
}
static void
gst_play_bin_set_sink (GstPlayBin * playbin, GstElement ** elem,
const gchar * dbg, GstElement * sink)
@ -1784,7 +1759,8 @@ gst_play_bin_set_property (GObject * object, guint prop_id,
gst_play_bin_set_current_text_stream (playbin, g_value_get_int (value));
break;
case PROP_SUBTITLE_ENCODING:
gst_play_bin_set_encoding (playbin, g_value_get_string (value));
gst_play_sink_set_subtitle_encoding (playbin->playsink,
g_value_get_string (value));
break;
case PROP_VIDEO_SINK:
gst_play_bin_set_sink (playbin, &playbin->video_sink, "video",
@ -1943,7 +1919,8 @@ gst_play_bin_get_property (GObject * object, guint prop_id, GValue * value,
break;
case PROP_SUBTITLE_ENCODING:
GST_PLAY_BIN_LOCK (playbin);
g_value_set_string (value, playbin->encoding);
g_value_take_string (value,
gst_play_sink_get_subtitle_encoding (playbin->playsink));
GST_PLAY_BIN_UNLOCK (playbin);
break;
case PROP_VIDEO_SINK:
@ -3185,8 +3162,6 @@ activate_group (GstPlayBin * playbin, GstSourceGroup * group, GstState target)
else
g_object_set (uridecodebin, "download", FALSE, NULL);
/* configure subtitle encoding */
g_object_set (uridecodebin, "subtitle-encoding", playbin->encoding, NULL);
/* configure uri */
g_object_set (uridecodebin, "uri", group->uri, NULL);
/* configure buffering of demuxed/parsed data */
@ -3250,9 +3225,6 @@ activate_group (GstPlayBin * playbin, GstSourceGroup * group, GstState target)
/* configure connection speed */
g_object_set (suburidecodebin, "connection-speed",
playbin->connection_speed, NULL);
/* configure subtitle encoding */
g_object_set (suburidecodebin, "subtitle-encoding", playbin->encoding,
NULL);
/* configure uri */
g_object_set (suburidecodebin, "uri", group->suburi, NULL);

View file

@ -146,6 +146,7 @@ struct _GstPlaySink
gdouble volume;
gboolean mute;
gchar *font_desc; /* font description */
gchar *subtitle_encoding; /* subtitle encoding */
guint connection_speed; /* connection speed in bits/sec (0 = unknown) */
gint count;
gboolean volume_changed; /* volume/mute changed while no audiochain */
@ -192,6 +193,7 @@ enum
PROP_MUTE,
PROP_VOLUME,
PROP_FONT_DESC,
PROP_SUBTITLE_ENCODING,
PROP_VIS_PLUGIN,
PROP_LAST
};
@ -274,6 +276,13 @@ gst_play_sink_class_init (GstPlaySinkClass * klass)
"Pango font description of font "
"to be used for subtitle rendering", NULL,
G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS));
g_object_class_install_property (gobject_klass, PROP_SUBTITLE_ENCODING,
g_param_spec_string ("subtitle-encoding", "subtitle encoding",
"Encoding to assume if input subtitles are not in UTF-8 encoding. "
"If not set, the GST_SUBTITLE_ENCODING environment variable will "
"be checked for an encoding to use. If that is not set either, "
"ISO-8859-15 will be assumed.", NULL,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
g_object_class_install_property (gobject_klass, PROP_VIS_PLUGIN,
g_param_spec_object ("vis-plugin", "Vis plugin",
"the visualization element to use (NULL = default)",
@ -323,6 +332,7 @@ gst_play_sink_init (GstPlaySink * playsink)
playsink->text_sink = NULL;
playsink->volume = 1.0;
playsink->font_desc = NULL;
playsink->subtitle_encoding = NULL;
playsink->flags = DEFAULT_FLAGS;
g_static_rec_mutex_init (&playsink->lock);
@ -398,6 +408,9 @@ gst_play_sink_dispose (GObject * object)
g_free (playsink->font_desc);
playsink->font_desc = NULL;
g_free (playsink->subtitle_encoding);
playsink->subtitle_encoding = NULL;
G_OBJECT_CLASS (gst_play_sink_parent_class)->dispose (object);
}
@ -1250,6 +1263,10 @@ gen_text_chain (GstPlaySink * playsink)
g_object_set (G_OBJECT (chain->overlay), "font-desc",
playsink->font_desc, NULL);
}
if (playsink->subtitle_encoding) {
g_object_set (G_OBJECT (chain->overlay), "subtitle-encoding",
playsink->subtitle_encoding, NULL);
}
gst_element_link_pads (chain->queue, "src", chain->overlay,
"video_sink");
@ -2158,6 +2175,41 @@ gst_play_sink_get_font_desc (GstPlaySink * playsink)
return result;
}
void
gst_play_sink_set_subtitle_encoding (GstPlaySink * playsink,
const gchar * encoding)
{
GstPlayTextChain *chain;
GST_PLAY_SINK_LOCK (playsink);
chain = (GstPlayTextChain *) playsink->textchain;
g_free (playsink->subtitle_encoding);
playsink->subtitle_encoding = g_strdup (encoding);
if (chain && chain->overlay) {
g_object_set (chain->overlay, "subtitle-encoding", encoding, NULL);
}
GST_PLAY_SINK_UNLOCK (playsink);
}
gchar *
gst_play_sink_get_subtitle_encoding (GstPlaySink * playsink)
{
gchar *result = NULL;
GstPlayTextChain *chain;
GST_PLAY_SINK_LOCK (playsink);
chain = (GstPlayTextChain *) playsink->textchain;
if (chain && chain->overlay) {
g_object_get (chain->overlay, "subtitle-encoding", &result, NULL);
playsink->subtitle_encoding = g_strdup (result);
} else {
result = g_strdup (playsink->subtitle_encoding);
}
GST_PLAY_SINK_UNLOCK (playsink);
return result;
}
/**
* gst_play_sink_get_last_frame:
* @playsink: a #GstPlaySink
@ -2648,6 +2700,10 @@ gst_play_sink_set_property (GObject * object, guint prop_id,
case PROP_FONT_DESC:
gst_play_sink_set_font_desc (playsink, g_value_get_string (value));
break;
case PROP_SUBTITLE_ENCODING:
gst_play_sink_set_subtitle_encoding (playsink,
g_value_get_string (value));
break;
case PROP_VIS_PLUGIN:
gst_play_sink_set_vis_plugin (playsink, g_value_get_object (value));
break;
@ -2676,6 +2732,10 @@ gst_play_sink_get_property (GObject * object, guint prop_id,
case PROP_FONT_DESC:
g_value_take_string (value, gst_play_sink_get_font_desc (playsink));
break;
case PROP_SUBTITLE_ENCODING:
g_value_take_string (value,
gst_play_sink_get_subtitle_encoding (playsink));
break;
case PROP_VIS_PLUGIN:
g_value_take_object (value, gst_play_sink_get_vis_plugin (playsink));
break;

View file

@ -88,6 +88,8 @@ GstPlayFlags gst_play_sink_get_flags (GstPlaySink * playsink);
void gst_play_sink_set_font_desc (GstPlaySink *playsink, const gchar * desc);
gchar * gst_play_sink_get_font_desc (GstPlaySink *playsink);
void gst_play_sink_set_subtitle_encoding (GstPlaySink *playsink, const gchar * encoding);
gchar * gst_play_sink_get_subtitle_encoding (GstPlaySink *playsink);
GstBuffer * gst_play_sink_get_last_frame (GstPlaySink * playsink);

View file

@ -75,7 +75,8 @@ enum
{
PROP_0,
PROP_SILENT,
PROP_FONT_DESC
PROP_FONT_DESC,
PROP_SUBTITLE_ENCODING
};
GST_BOILERPLATE (GstSubtitleOverlay, gst_subtitle_overlay, GstBin,
@ -136,6 +137,11 @@ gst_subtitle_overlay_finalize (GObject * object)
self->font_desc = NULL;
}
if (self->encoding) {
g_free (self->encoding);
self->encoding = NULL;
}
G_OBJECT_CLASS (parent_class)->finalize (object);
}
@ -656,6 +662,27 @@ _get_silent_property (GstElement * element, gboolean * invert)
return NULL;
}
static gboolean
_has_subtitle_encoding_property (GstElement * element)
{
GParamSpec *pspec;
pspec =
g_object_class_find_property (G_OBJECT_GET_CLASS (element),
"subtitle-encoding");
return (pspec && pspec->value_type == G_TYPE_STRING);
}
static gboolean
_has_font_desc_property (GstElement * element)
{
GParamSpec *pspec;
pspec =
g_object_class_find_property (G_OBJECT_GET_CLASS (element), "font-desc");
return (pspec && pspec->value_type == G_TYPE_STRING);
}
static void
_pad_blocked_cb (GstPad * pad, gboolean blocked, gpointer user_data)
{
@ -849,6 +876,9 @@ _pad_blocked_cb (GstPad * pad, gboolean blocked, gpointer user_data)
gst_object_unref (video_peer);
}
if (_has_subtitle_encoding_property (self->parser))
g_object_set (self->parser, "subtitle-encoding", self->encoding, NULL);
/* Try to set video fps on the parser */
gst_subtitle_overlay_set_fps (self);
@ -1049,6 +1079,11 @@ _pad_blocked_cb (GstPad * pad, gboolean blocked, gpointer user_data)
} else {
self->silent_property =
_get_silent_property (element, &self->silent_property_invert);
if (_has_subtitle_encoding_property (self->renderer))
g_object_set (self->renderer, "subtitle-encoding", self->encoding,
NULL);
if (_has_font_desc_property (self->renderer))
g_object_set (self->renderer, "font-desc", self->font_desc, NULL);
}
/* First link everything internally */
@ -1408,6 +1443,11 @@ gst_subtitle_overlay_get_property (GObject * object, guint prop_id,
g_value_set_string (value, self->font_desc);
GST_SUBTITLE_OVERLAY_UNLOCK (self);
break;
case PROP_SUBTITLE_ENCODING:
GST_SUBTITLE_OVERLAY_LOCK (self);
g_value_set_string (value, self->encoding);
GST_SUBTITLE_OVERLAY_UNLOCK (self);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@ -1449,6 +1489,21 @@ gst_subtitle_overlay_set_property (GObject * object, guint prop_id,
GST_SUBTITLE_OVERLAY_LOCK (self);
g_free (self->font_desc);
self->font_desc = g_value_dup_string (value);
if (self->overlay)
g_object_set (self->overlay, "font-desc", self->font_desc, NULL);
else if (self->renderer && _has_font_desc_property (self->renderer))
g_object_set (self->renderer, "font-desc", self->font_desc, NULL);
GST_SUBTITLE_OVERLAY_UNLOCK (self);
break;
case PROP_SUBTITLE_ENCODING:
GST_SUBTITLE_OVERLAY_LOCK (self);
g_free (self->encoding);
self->encoding = g_value_dup_string (value);
if (self->renderer && _has_subtitle_encoding_property (self->renderer))
g_object_set (self->renderer, "subtitle-encoding", self->encoding,
NULL);
if (self->parser && _has_subtitle_encoding_property (self->parser))
g_object_set (self->parser, "subtitle-encoding", self->encoding, NULL);
GST_SUBTITLE_OVERLAY_UNLOCK (self);
break;
default:
@ -1500,6 +1555,14 @@ gst_subtitle_overlay_class_init (GstSubtitleOverlayClass * klass)
"to be used for subtitle rendering", NULL,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
g_object_class_install_property (gobject_class, PROP_SUBTITLE_ENCODING,
g_param_spec_string ("subtitle-encoding", "subtitle encoding",
"Encoding to assume if input subtitles are not in UTF-8 encoding. "
"If not set, the GST_SUBTITLE_ENCODING environment variable will "
"be checked for an encoding to use. If that is not set either, "
"ISO-8859-15 will be assumed.", NULL,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
element_class->change_state =
GST_DEBUG_FUNCPTR (gst_subtitle_overlay_change_state);

View file

@ -62,6 +62,7 @@ struct _GstSubtitleOverlay
gboolean silent;
gchar *font_desc;
gchar *encoding;
/* < private > */
gboolean do_async;