mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 04:01:08 +00:00
pango: Create one context per instance and remove class mutex
PangoCairo is thread-safe as long as the context and fontmap are not shared between threads. Previously each subclass had its own context and a class mutex for this reason, but apart from hurting performance this was also not completely safe yet: the same fontmap might've been used by different classes from different threads as the thread-default fontmap (at time of class initialization) was used.
This commit is contained in:
parent
6024b8e46b
commit
2ace14f613
6 changed files with 62 additions and 94 deletions
|
@ -258,7 +258,6 @@ gst_base_text_overlay_scale_mode_get_type (void)
|
|||
#define GST_BASE_TEXT_OVERLAY_BROADCAST(ov)(g_cond_broadcast (GST_BASE_TEXT_OVERLAY_GET_COND (ov)))
|
||||
|
||||
static GstElementClass *parent_class = NULL;
|
||||
static void gst_base_text_overlay_base_init (gpointer g_class);
|
||||
static void gst_base_text_overlay_class_init (GstBaseTextOverlayClass * klass);
|
||||
static void gst_base_text_overlay_init (GstBaseTextOverlay * overlay,
|
||||
GstBaseTextOverlayClass * klass);
|
||||
|
@ -318,7 +317,7 @@ gst_base_text_overlay_get_type (void)
|
|||
if (g_once_init_enter ((gsize *) & type)) {
|
||||
static const GTypeInfo info = {
|
||||
sizeof (GstBaseTextOverlayClass),
|
||||
(GBaseInitFunc) gst_base_text_overlay_base_init,
|
||||
(GBaseInitFunc) NULL,
|
||||
NULL,
|
||||
(GClassInitFunc) gst_base_text_overlay_class_init,
|
||||
NULL,
|
||||
|
@ -343,25 +342,6 @@ gst_base_text_overlay_get_text (GstBaseTextOverlay * overlay,
|
|||
return g_strdup (overlay->default_text);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_base_text_overlay_base_init (gpointer g_class)
|
||||
{
|
||||
GstBaseTextOverlayClass *klass = GST_BASE_TEXT_OVERLAY_CLASS (g_class);
|
||||
PangoFontMap *fontmap;
|
||||
|
||||
/* Only lock for the subclasses here, the base class
|
||||
* doesn't have this mutex yet and it's not necessary
|
||||
* here */
|
||||
if (klass->pango_lock)
|
||||
g_mutex_lock (klass->pango_lock);
|
||||
fontmap = pango_cairo_font_map_get_default ();
|
||||
klass->pango_context =
|
||||
pango_font_map_create_context (PANGO_FONT_MAP (fontmap));
|
||||
pango_context_set_base_gravity (klass->pango_context, PANGO_GRAVITY_SOUTH);
|
||||
if (klass->pango_lock)
|
||||
g_mutex_unlock (klass->pango_lock);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_base_text_overlay_class_init (GstBaseTextOverlayClass * klass)
|
||||
{
|
||||
|
@ -385,9 +365,6 @@ gst_base_text_overlay_class_init (GstBaseTextOverlayClass * klass)
|
|||
gstelement_class->change_state =
|
||||
GST_DEBUG_FUNCPTR (gst_base_text_overlay_change_state);
|
||||
|
||||
klass->pango_lock = g_slice_new (GMutex);
|
||||
g_mutex_init (klass->pango_lock);
|
||||
|
||||
klass->get_text = gst_base_text_overlay_get_text;
|
||||
|
||||
g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_TEXT,
|
||||
|
@ -682,6 +659,11 @@ gst_base_text_overlay_finalize (GObject * object)
|
|||
overlay->text_buffer = NULL;
|
||||
}
|
||||
|
||||
if (overlay->pango_context) {
|
||||
g_object_unref (overlay->pango_context);
|
||||
overlay->pango_context = NULL;
|
||||
}
|
||||
|
||||
g_mutex_clear (&overlay->lock);
|
||||
g_cond_clear (&overlay->cond);
|
||||
|
||||
|
@ -694,6 +676,13 @@ gst_base_text_overlay_init (GstBaseTextOverlay * overlay,
|
|||
{
|
||||
GstPadTemplate *template;
|
||||
PangoFontDescription *desc;
|
||||
PangoFontMap *fontmap;
|
||||
|
||||
fontmap = pango_cairo_font_map_new ();
|
||||
overlay->pango_context =
|
||||
pango_font_map_create_context (PANGO_FONT_MAP (fontmap));
|
||||
g_object_unref (fontmap);
|
||||
pango_context_set_base_gravity (overlay->pango_context, PANGO_GRAVITY_SOUTH);
|
||||
|
||||
/* video sink */
|
||||
template = gst_static_pad_template_get (&video_sink_template_factory);
|
||||
|
@ -736,13 +725,8 @@ gst_base_text_overlay_init (GstBaseTextOverlay * overlay,
|
|||
GST_DEBUG_FUNCPTR (gst_base_text_overlay_src_query));
|
||||
gst_element_add_pad (GST_ELEMENT (overlay), overlay->srcpad);
|
||||
|
||||
g_mutex_lock (GST_BASE_TEXT_OVERLAY_GET_CLASS (overlay)->pango_lock);
|
||||
overlay->layout =
|
||||
pango_layout_new (GST_BASE_TEXT_OVERLAY_GET_CLASS
|
||||
(overlay)->pango_context);
|
||||
desc =
|
||||
pango_context_get_font_description (GST_BASE_TEXT_OVERLAY_GET_CLASS
|
||||
(overlay)->pango_context);
|
||||
overlay->layout = pango_layout_new (overlay->pango_context);
|
||||
desc = pango_context_get_font_description (overlay->pango_context);
|
||||
gst_base_text_overlay_adjust_values_with_fontdesc (overlay, desc);
|
||||
|
||||
overlay->color = DEFAULT_PROP_COLOR;
|
||||
|
@ -803,7 +787,6 @@ gst_base_text_overlay_init (GstBaseTextOverlay * overlay,
|
|||
g_mutex_init (&overlay->lock);
|
||||
g_cond_init (&overlay->cond);
|
||||
gst_segment_init (&overlay->segment, GST_FORMAT_TIME);
|
||||
g_mutex_unlock (GST_BASE_TEXT_OVERLAY_GET_CLASS (overlay)->pango_lock);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1101,7 +1084,6 @@ gst_base_text_overlay_set_property (GObject * object, guint prop_id,
|
|||
const gchar *fontdesc_str;
|
||||
|
||||
fontdesc_str = g_value_get_string (value);
|
||||
g_mutex_lock (GST_BASE_TEXT_OVERLAY_GET_CLASS (overlay)->pango_lock);
|
||||
desc = pango_font_description_from_string (fontdesc_str);
|
||||
if (desc) {
|
||||
GST_LOG_OBJECT (overlay, "font description set: %s", fontdesc_str);
|
||||
|
@ -1112,7 +1094,6 @@ gst_base_text_overlay_set_property (GObject * object, guint prop_id,
|
|||
GST_WARNING_OBJECT (overlay, "font description parse failed: %s",
|
||||
fontdesc_str);
|
||||
}
|
||||
g_mutex_unlock (GST_BASE_TEXT_OVERLAY_GET_CLASS (overlay)->pango_lock);
|
||||
break;
|
||||
}
|
||||
case PROP_COLOR:
|
||||
|
@ -1132,10 +1113,8 @@ gst_base_text_overlay_set_property (GObject * object, guint prop_id,
|
|||
break;
|
||||
case PROP_LINE_ALIGNMENT:
|
||||
overlay->line_align = g_value_get_enum (value);
|
||||
g_mutex_lock (GST_BASE_TEXT_OVERLAY_GET_CLASS (overlay)->pango_lock);
|
||||
pango_layout_set_alignment (overlay->layout,
|
||||
(PangoAlignment) overlay->line_align);
|
||||
g_mutex_unlock (GST_BASE_TEXT_OVERLAY_GET_CLASS (overlay)->pango_lock);
|
||||
break;
|
||||
case PROP_WAIT_TEXT:
|
||||
overlay->wait_text = g_value_get_boolean (value);
|
||||
|
@ -1149,10 +1128,8 @@ gst_base_text_overlay_set_property (GObject * object, guint prop_id,
|
|||
overlay->valign = GST_BASE_TEXT_OVERLAY_VALIGN_TOP;
|
||||
overlay->halign = GST_BASE_TEXT_OVERLAY_HALIGN_RIGHT;
|
||||
overlay->line_align = GST_BASE_TEXT_OVERLAY_LINE_ALIGN_LEFT;
|
||||
g_mutex_lock (GST_BASE_TEXT_OVERLAY_GET_CLASS (overlay)->pango_lock);
|
||||
pango_layout_set_alignment (overlay->layout,
|
||||
(PangoAlignment) overlay->line_align);
|
||||
g_mutex_unlock (GST_BASE_TEXT_OVERLAY_GET_CLASS (overlay)->pango_lock);
|
||||
}
|
||||
break;
|
||||
case PROP_SCALE_MODE:
|
||||
|
@ -1262,14 +1239,12 @@ gst_base_text_overlay_get_property (GObject * object, guint prop_id,
|
|||
{
|
||||
const PangoFontDescription *desc;
|
||||
|
||||
g_mutex_lock (GST_BASE_TEXT_OVERLAY_GET_CLASS (overlay)->pango_lock);
|
||||
desc = pango_layout_get_font_description (overlay->layout);
|
||||
if (!desc)
|
||||
g_value_set_string (value, "");
|
||||
else {
|
||||
g_value_take_string (value, pango_font_description_to_string (desc));
|
||||
}
|
||||
g_mutex_unlock (GST_BASE_TEXT_OVERLAY_GET_CLASS (overlay)->pango_lock);
|
||||
break;
|
||||
}
|
||||
case PROP_TEXT_X:
|
||||
|
@ -1755,8 +1730,6 @@ gst_base_text_overlay_render_pangocairo (GstBaseTextOverlay * overlay,
|
|||
GstBuffer *buffer;
|
||||
GstMapInfo map;
|
||||
|
||||
g_mutex_lock (GST_BASE_TEXT_OVERLAY_GET_CLASS (overlay)->pango_lock);
|
||||
|
||||
if (overlay->auto_adjust_size) {
|
||||
/* 640 pixel is default */
|
||||
scalef_x = scalef_y = (double) (overlay->width) / DEFAULT_SCALE_BASIS;
|
||||
|
@ -1918,14 +1891,12 @@ gst_base_text_overlay_render_pangocairo (GstBaseTextOverlay * overlay,
|
|||
scalef_y *= overlay->render_scale;
|
||||
|
||||
if (width <= 0 || height <= 0) {
|
||||
g_mutex_unlock (GST_BASE_TEXT_OVERLAY_GET_CLASS (overlay)->pango_lock);
|
||||
GST_DEBUG_OBJECT (overlay,
|
||||
"Overlay is outside video frame. Skipping text rendering");
|
||||
return;
|
||||
}
|
||||
|
||||
if (unscaled_height <= 0 || unscaled_width <= 0) {
|
||||
g_mutex_unlock (GST_BASE_TEXT_OVERLAY_GET_CLASS (overlay)->pango_lock);
|
||||
GST_DEBUG_OBJECT (overlay,
|
||||
"Overlay is outside video frame. Skipping text rendering");
|
||||
return;
|
||||
|
@ -2057,7 +2028,6 @@ gst_base_text_overlay_render_pangocairo (GstBaseTextOverlay * overlay,
|
|||
overlay->text_width = width;
|
||||
if (height != 0)
|
||||
overlay->text_height = height;
|
||||
g_mutex_unlock (GST_BASE_TEXT_OVERLAY_GET_CLASS (overlay)->pango_lock);
|
||||
|
||||
gst_base_text_overlay_set_composition (overlay);
|
||||
}
|
||||
|
|
|
@ -144,6 +144,8 @@ struct _GstBaseTextOverlay {
|
|||
GstPad *text_sinkpad;
|
||||
GstPad *srcpad;
|
||||
|
||||
PangoContext *pango_context;
|
||||
|
||||
GstSegment segment;
|
||||
GstSegment text_segment;
|
||||
GstBuffer *text_buffer;
|
||||
|
@ -232,9 +234,6 @@ struct _GstBaseTextOverlay {
|
|||
struct _GstBaseTextOverlayClass {
|
||||
GstElementClass parent_class;
|
||||
|
||||
PangoContext *pango_context;
|
||||
GMutex *pango_lock;
|
||||
|
||||
gchar * (*get_text) (GstBaseTextOverlay *overlay, GstBuffer *video_frame);
|
||||
};
|
||||
|
||||
|
|
|
@ -138,8 +138,6 @@ gst_clock_overlay_class_init (GstClockOverlayClass * klass)
|
|||
GObjectClass *gobject_class;
|
||||
GstElementClass *gstelement_class;
|
||||
GstBaseTextOverlayClass *gsttextoverlay_class;
|
||||
PangoContext *context;
|
||||
PangoFontDescription *font_description;
|
||||
|
||||
gobject_class = (GObjectClass *) klass;
|
||||
gstelement_class = (GstElementClass *) klass;
|
||||
|
@ -160,23 +158,6 @@ gst_clock_overlay_class_init (GstClockOverlayClass * klass)
|
|||
g_param_spec_string ("time-format", "Date/Time Format",
|
||||
"Format to use for time and date value, as in strftime.",
|
||||
DEFAULT_PROP_TIMEFORMAT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
g_mutex_lock (gsttextoverlay_class->pango_lock);
|
||||
context = gsttextoverlay_class->pango_context;
|
||||
|
||||
pango_context_set_language (context, pango_language_from_string ("en_US"));
|
||||
pango_context_set_base_dir (context, PANGO_DIRECTION_LTR);
|
||||
|
||||
font_description = pango_font_description_new ();
|
||||
pango_font_description_set_family_static (font_description, "Monospace");
|
||||
pango_font_description_set_style (font_description, PANGO_STYLE_NORMAL);
|
||||
pango_font_description_set_variant (font_description, PANGO_VARIANT_NORMAL);
|
||||
pango_font_description_set_weight (font_description, PANGO_WEIGHT_NORMAL);
|
||||
pango_font_description_set_stretch (font_description, PANGO_STRETCH_NORMAL);
|
||||
pango_font_description_set_size (font_description, 18 * PANGO_SCALE);
|
||||
pango_context_set_font_description (context, font_description);
|
||||
pango_font_description_free (font_description);
|
||||
g_mutex_unlock (gsttextoverlay_class->pango_lock);
|
||||
}
|
||||
|
||||
|
||||
|
@ -197,6 +178,8 @@ static void
|
|||
gst_clock_overlay_init (GstClockOverlay * overlay)
|
||||
{
|
||||
GstBaseTextOverlay *textoverlay;
|
||||
PangoContext *context;
|
||||
PangoFontDescription *font_description;
|
||||
|
||||
textoverlay = GST_BASE_TEXT_OVERLAY (overlay);
|
||||
|
||||
|
@ -204,8 +187,22 @@ gst_clock_overlay_init (GstClockOverlay * overlay)
|
|||
textoverlay->halign = GST_BASE_TEXT_OVERLAY_HALIGN_LEFT;
|
||||
|
||||
overlay->format = g_strdup (DEFAULT_PROP_TIMEFORMAT);
|
||||
}
|
||||
|
||||
context = textoverlay->pango_context;
|
||||
|
||||
pango_context_set_language (context, pango_language_from_string ("en_US"));
|
||||
pango_context_set_base_dir (context, PANGO_DIRECTION_LTR);
|
||||
|
||||
font_description = pango_font_description_new ();
|
||||
pango_font_description_set_family_static (font_description, "Monospace");
|
||||
pango_font_description_set_style (font_description, PANGO_STYLE_NORMAL);
|
||||
pango_font_description_set_variant (font_description, PANGO_VARIANT_NORMAL);
|
||||
pango_font_description_set_weight (font_description, PANGO_WEIGHT_NORMAL);
|
||||
pango_font_description_set_stretch (font_description, PANGO_STRETCH_NORMAL);
|
||||
pango_font_description_set_size (font_description, 18 * PANGO_SCALE);
|
||||
pango_context_set_font_description (context, font_description);
|
||||
pango_font_description_free (font_description);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_clock_overlay_set_property (GObject * object, guint prop_id,
|
||||
|
|
|
@ -177,7 +177,6 @@ gst_text_render_class_init (GstTextRenderClass * klass)
|
|||
{
|
||||
GObjectClass *gobject_class;
|
||||
GstElementClass *gstelement_class;
|
||||
PangoFontMap *fontmap;
|
||||
|
||||
gobject_class = (GObjectClass *) klass;
|
||||
gstelement_class = (GstElementClass *) klass;
|
||||
|
@ -199,9 +198,6 @@ gst_text_render_class_init (GstTextRenderClass * klass)
|
|||
"David Schleef <ds@schleef.org>, "
|
||||
"GStreamer maintainers <gstreamer-devel@lists.freedesktop.org>");
|
||||
|
||||
fontmap = pango_cairo_font_map_get_default ();
|
||||
klass->pango_context =
|
||||
pango_font_map_create_context (PANGO_FONT_MAP (fontmap));
|
||||
g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_FONT_DESC,
|
||||
g_param_spec_string ("font-desc", "font description",
|
||||
"Pango font description of font "
|
||||
|
@ -631,6 +627,9 @@ gst_text_render_finalize (GObject * object)
|
|||
if (render->layout)
|
||||
g_object_unref (render->layout);
|
||||
|
||||
if (render->pango_context)
|
||||
g_object_unref (render->pango_context);
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
|
@ -638,6 +637,7 @@ static void
|
|||
gst_text_render_init (GstTextRender * render)
|
||||
{
|
||||
GstPadTemplate *template;
|
||||
PangoFontMap *fontmap;
|
||||
|
||||
/* sink */
|
||||
template = gst_static_pad_template_get (&sink_template_factory);
|
||||
|
@ -657,9 +657,13 @@ gst_text_render_init (GstTextRender * render)
|
|||
|
||||
gst_element_add_pad (GST_ELEMENT (render), render->srcpad);
|
||||
|
||||
fontmap = pango_cairo_font_map_new ();
|
||||
render->pango_context =
|
||||
pango_font_map_create_context (PANGO_FONT_MAP (fontmap));
|
||||
g_object_unref (fontmap);
|
||||
|
||||
render->line_align = DEFAULT_PROP_LINE_ALIGNMENT;
|
||||
render->layout =
|
||||
pango_layout_new (GST_TEXT_RENDER_GET_CLASS (render)->pango_context);
|
||||
render->layout = pango_layout_new (render->pango_context);
|
||||
pango_layout_set_alignment (render->layout,
|
||||
(PangoAlignment) render->line_align);
|
||||
|
||||
|
|
|
@ -83,6 +83,8 @@ struct _GstTextRender {
|
|||
gint baseline_y;
|
||||
gboolean use_ARGB;
|
||||
|
||||
PangoContext *pango_context;
|
||||
|
||||
GstTextRenderVAlign valign;
|
||||
GstTextRenderHAlign halign;
|
||||
GstTextRenderLineAlign line_align;
|
||||
|
@ -95,8 +97,6 @@ struct _GstTextRender {
|
|||
|
||||
struct _GstTextRenderClass {
|
||||
GstElementClass parent_class;
|
||||
|
||||
PangoContext *pango_context;
|
||||
};
|
||||
|
||||
GType gst_text_render_get_type(void) G_GNUC_CONST;
|
||||
|
|
|
@ -172,8 +172,6 @@ gst_time_overlay_class_init (GstTimeOverlayClass * klass)
|
|||
GstElementClass *gstelement_class;
|
||||
GstBaseTextOverlayClass *gsttextoverlay_class;
|
||||
GObjectClass *gobject_class;
|
||||
PangoContext *context;
|
||||
PangoFontDescription *font_description;
|
||||
|
||||
gsttextoverlay_class = (GstBaseTextOverlayClass *) klass;
|
||||
gstelement_class = (GstElementClass *) klass;
|
||||
|
@ -193,9 +191,23 @@ gst_time_overlay_class_init (GstTimeOverlayClass * klass)
|
|||
g_param_spec_enum ("time-mode", "Time Mode", "What time to show",
|
||||
GST_TYPE_TIME_OVERLAY_TIME_LINE, DEFAULT_TIME_LINE,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
}
|
||||
|
||||
g_mutex_lock (gsttextoverlay_class->pango_lock);
|
||||
context = gsttextoverlay_class->pango_context;
|
||||
static void
|
||||
gst_time_overlay_init (GstTimeOverlay * overlay)
|
||||
{
|
||||
GstBaseTextOverlay *textoverlay;
|
||||
PangoContext *context;
|
||||
PangoFontDescription *font_description;
|
||||
|
||||
textoverlay = GST_BASE_TEXT_OVERLAY (overlay);
|
||||
|
||||
textoverlay->valign = GST_BASE_TEXT_OVERLAY_VALIGN_TOP;
|
||||
textoverlay->halign = GST_BASE_TEXT_OVERLAY_HALIGN_LEFT;
|
||||
|
||||
overlay->time_line = DEFAULT_TIME_LINE;
|
||||
|
||||
context = textoverlay->pango_context;
|
||||
|
||||
pango_context_set_language (context, pango_language_from_string ("en_US"));
|
||||
pango_context_set_base_dir (context, PANGO_DIRECTION_LTR);
|
||||
|
@ -209,20 +221,6 @@ gst_time_overlay_class_init (GstTimeOverlayClass * klass)
|
|||
pango_font_description_set_size (font_description, 18 * PANGO_SCALE);
|
||||
pango_context_set_font_description (context, font_description);
|
||||
pango_font_description_free (font_description);
|
||||
g_mutex_unlock (gsttextoverlay_class->pango_lock);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_time_overlay_init (GstTimeOverlay * overlay)
|
||||
{
|
||||
GstBaseTextOverlay *textoverlay;
|
||||
|
||||
textoverlay = GST_BASE_TEXT_OVERLAY (overlay);
|
||||
|
||||
textoverlay->valign = GST_BASE_TEXT_OVERLAY_VALIGN_TOP;
|
||||
textoverlay->halign = GST_BASE_TEXT_OVERLAY_HALIGN_LEFT;
|
||||
|
||||
overlay->time_line = DEFAULT_TIME_LINE;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
Loading…
Reference in a new issue