2 * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
3 * Copyright (C) <2003> David Schleef <ds@schleef.org>
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
15 * You should have received a copy of the GNU Library General Public
16 * License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 * Boston, MA 02111-1307, USA.
21 /* portions derived from:
23 * pangoft2topgm.c: Example program to view a UTF-8 encoding file
24 * using Pango to render result.
26 * Copyright (C) 1999 Red Hat Software
27 * Copyright (C) 2001 Sun Microsystems
31 * This file was (probably) generated from gsttimeoverlay.c,
32 * gsttimeoverlay.c,v 1.7 2003/11/08 02:48:59 dschleef Exp
39 /*#define DEBUG_ENABLED */
40 #include <gsttimeoverlay.h>
43 #include <pango/pango.h>
44 #include <pango/pangoft2.h>
47 /* GstTimeoverlay signals and args */
60 static void gst_timeoverlay_base_init (gpointer g_class);
61 static void gst_timeoverlay_class_init (gpointer g_class, gpointer class_data);
62 static void gst_timeoverlay_init (GTypeInstance * instance, gpointer g_class);
64 static void gst_timeoverlay_set_property (GObject * object, guint prop_id,
65 const GValue * value, GParamSpec * pspec);
66 static void gst_timeoverlay_get_property (GObject * object, guint prop_id,
67 GValue * value, GParamSpec * pspec);
69 static void gst_timeoverlay_planar411 (GstVideofilter * videofilter, void *dest,
71 static void gst_timeoverlay_setup (GstVideofilter * videofilter);
74 gst_timeoverlay_get_type (void)
76 static GType timeoverlay_type = 0;
78 if (!timeoverlay_type) {
79 static const GTypeInfo timeoverlay_info = {
80 sizeof (GstTimeoverlayClass),
81 gst_timeoverlay_base_init,
83 gst_timeoverlay_class_init,
86 sizeof (GstTimeoverlay),
91 timeoverlay_type = g_type_register_static (GST_TYPE_VIDEOFILTER,
92 "GstTimeoverlay", &timeoverlay_info, 0);
94 return timeoverlay_type;
97 static GstVideofilterFormat gst_timeoverlay_formats[] = {
98 {"I420", 12, gst_timeoverlay_planar411,},
103 gst_timeoverlay_base_init (gpointer g_class)
105 static GstElementDetails timeoverlay_details =
106 GST_ELEMENT_DETAILS ("Time Overlay",
107 "Filter/Editor/Video",
108 "Overlays the time on a video stream",
109 "David Schleef <ds@schleef.org>");
110 GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
111 GstVideofilterClass *videofilter_class = GST_VIDEOFILTER_CLASS (g_class);
114 gst_element_class_set_details (element_class, &timeoverlay_details);
116 for (i = 0; i < G_N_ELEMENTS (gst_timeoverlay_formats); i++) {
117 gst_videofilter_class_add_format (videofilter_class,
118 gst_timeoverlay_formats + i);
121 gst_videofilter_class_add_pad_templates (GST_VIDEOFILTER_CLASS (g_class));
125 gst_timeoverlay_class_init (gpointer g_class, gpointer class_data)
127 GObjectClass *gobject_class;
128 GstVideofilterClass *videofilter_class;
130 gobject_class = G_OBJECT_CLASS (g_class);
131 videofilter_class = GST_VIDEOFILTER_CLASS (g_class);
134 g_object_class_install_property (gobject_class, ARG_METHOD,
135 g_param_spec_enum ("method", "method", "method",
136 GST_TYPE_TIMEOVERLAY_METHOD, GST_TIMEOVERLAY_METHOD_1,
140 gobject_class->set_property = gst_timeoverlay_set_property;
141 gobject_class->get_property = gst_timeoverlay_get_property;
143 videofilter_class->setup = gst_timeoverlay_setup;
147 gst_timeoverlay_init (GTypeInstance * instance, gpointer g_class)
149 GstTimeoverlay *timeoverlay = GST_TIMEOVERLAY (instance);
150 GstVideofilter *videofilter;
152 GST_DEBUG ("gst_timeoverlay_init");
154 videofilter = GST_VIDEOFILTER (timeoverlay);
160 gst_timeoverlay_set_property (GObject * object, guint prop_id,
161 const GValue * value, GParamSpec * pspec)
165 g_return_if_fail (GST_IS_TIMEOVERLAY (object));
166 src = GST_TIMEOVERLAY (object);
168 GST_DEBUG ("gst_timeoverlay_set_property");
172 src->method = g_value_get_enum (value);
181 gst_timeoverlay_get_property (GObject * object, guint prop_id, GValue * value,
186 g_return_if_fail (GST_IS_TIMEOVERLAY (object));
187 src = GST_TIMEOVERLAY (object);
192 g_value_set_enum (value, src->method);
196 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
202 plugin_init (GstPlugin * plugin)
204 if (!gst_library_load ("gstvideofilter"))
207 return gst_element_register (plugin, "timeoverlay", GST_RANK_NONE,
208 GST_TYPE_TIMEOVERLAY);
211 GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
214 "Time overlay", plugin_init, VERSION, GST_LICENSE, GST_PACKAGE, GST_ORIGIN)
216 static void gst_timeoverlay_setup (GstVideofilter * videofilter)
218 GstTimeoverlay *timeoverlay;
219 PangoFontDescription *font_description;
220 PangoContext *context;
222 g_return_if_fail (GST_IS_TIMEOVERLAY (videofilter));
223 timeoverlay = GST_TIMEOVERLAY (videofilter);
225 /* if any setup needs to be done, do it here */
227 /* what does this affect? */
228 context = pango_ft2_get_context (100, 100);
230 pango_context_set_language (context, pango_language_from_string ("en_US"));
231 pango_context_set_base_dir (context, PANGO_DIRECTION_LTR);
233 font_description = pango_font_description_new ();
234 pango_font_description_set_family (font_description, g_strdup ("Monospace"));
235 pango_font_description_set_style (font_description, PANGO_STYLE_NORMAL);
236 pango_font_description_set_variant (font_description, PANGO_VARIANT_NORMAL);
237 pango_font_description_set_weight (font_description, PANGO_WEIGHT_NORMAL);
238 pango_font_description_set_stretch (font_description, PANGO_STRETCH_NORMAL);
239 pango_font_description_set_size (font_description, 12 * PANGO_SCALE);
241 pango_context_set_font_description (context, font_description);
243 timeoverlay->context = context;
244 timeoverlay->font_description = font_description;
249 gst_timeoverlay_print_smpte_time (guint64 time)
257 x = rint ((time + 500000) * 1e-6);
259 hours = floor (x / (60 * 60 * 1000));
260 x -= hours * 60 * 60 * 1000;
261 minutes = floor (x / (60 * 1000));
262 x -= minutes * 60 * 1000;
263 seconds = floor (x / (1000));
267 return g_strdup_printf ("%02d:%02d:%02d.%03d", hours, minutes, seconds, ms);
271 gst_timeoverlay_planar411 (GstVideofilter * videofilter, void *dest, void *src)
273 GstTimeoverlay *timeoverlay;
276 PangoRectangle logical_rect;
278 int b_height, b_width;
283 g_return_if_fail (GST_IS_TIMEOVERLAY (videofilter));
284 timeoverlay = GST_TIMEOVERLAY (videofilter);
286 width = gst_videofilter_get_input_width (videofilter);
287 height = gst_videofilter_get_input_height (videofilter);
289 width = gst_videofilter_get_input_width (videofilter);
290 height = gst_videofilter_get_input_height (videofilter);
292 layout = pango_layout_new (timeoverlay->context);
294 gst_timeoverlay_print_smpte_time (GST_BUFFER_TIMESTAMP (videofilter->
296 pango_layout_set_text (layout, string, strlen (string));
299 pango_layout_set_alignment (layout, PANGO_ALIGN_LEFT);
300 pango_layout_set_width (layout, -1);
302 pango_layout_get_extents (layout, NULL, &logical_rect);
303 b_height = PANGO_PIXELS (logical_rect.height);
304 b_width = PANGO_PIXELS (logical_rect.width);
308 memcpy (dest, src, videofilter->from_buf_size);
310 for (i = 0; i < b_height; i++) {
311 memset (dest + i * width, 0, b_width);
313 for (i = 0; i < b_height / 2; i++) {
314 memset (dest + width * height + i * (width / 2), 128, b_width / 2);
315 memset (dest + width * height + (width / 2) * (height / 2) +
316 i * (width / 2), 128, b_width / 2);
318 bitmap.rows = b_height;
319 bitmap.width = b_width;
320 bitmap.pitch = width;
321 bitmap.buffer = dest;
322 bitmap.num_grays = 256;
323 bitmap.pixel_mode = ft_pixel_mode_grays;
325 pango_ft2_render_layout (&bitmap, layout, 0, 0);