9a3b292ed3cd4e5e01c06650c793d4d1ee43b71d
[platform/upstream/gst-plugins-good.git] / ext / pango / gsttimeoverlay.c
1 /* GStreamer
2  * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
3  * Copyright (C) <2003> David Schleef <ds@schleef.org>
4  *
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.
9  *
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.
14  *
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.
19  */
20
21 /* portions derived from:
22  * Pango
23  * pangoft2topgm.c: Example program to view a UTF-8 encoding file
24  *                  using Pango to render result.
25  *
26  * Copyright (C) 1999 Red Hat Software
27  * Copyright (C) 2001 Sun Microsystems
28  */
29
30 /*
31  * This file was (probably) generated from gsttimeoverlay.c,
32  * gsttimeoverlay.c,v 1.7 2003/11/08 02:48:59 dschleef Exp 
33  */
34
35 #ifdef HAVE_CONFIG_H
36 #include "config.h"
37 #endif
38
39 /*#define DEBUG_ENABLED */
40 #include <gsttimeoverlay.h>
41 #include <string.h>
42 #include <math.h>
43 #include <pango/pango.h>
44 #include <pango/pangoft2.h>
45
46
47 /* GstTimeoverlay signals and args */
48 enum {
49   /* FILL ME */
50   LAST_SIGNAL
51 };
52
53 enum {
54   ARG_0,
55   /* FILL ME */
56 };
57
58 static void     gst_timeoverlay_base_init       (gpointer g_class);
59 static void     gst_timeoverlay_class_init      (gpointer g_class, gpointer class_data);
60 static void     gst_timeoverlay_init            (GTypeInstance *instance, gpointer g_class);
61
62 static void     gst_timeoverlay_set_property            (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
63 static void     gst_timeoverlay_get_property            (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
64
65 static void gst_timeoverlay_planar411(GstVideofilter *videofilter, void *dest, void *src);
66 static void gst_timeoverlay_setup(GstVideofilter *videofilter);
67
68 GType
69 gst_timeoverlay_get_type (void)
70 {
71   static GType timeoverlay_type = 0;
72
73   if (!timeoverlay_type) {
74     static const GTypeInfo timeoverlay_info = {
75       sizeof(GstTimeoverlayClass),
76       gst_timeoverlay_base_init,
77       NULL,
78       gst_timeoverlay_class_init,
79       NULL,
80       NULL,
81       sizeof(GstTimeoverlay),
82       0,
83       gst_timeoverlay_init,
84     };
85     timeoverlay_type = g_type_register_static(GST_TYPE_VIDEOFILTER,
86         "GstTimeoverlay", &timeoverlay_info, 0);
87   }
88   return timeoverlay_type;
89 }
90
91 static GstVideofilterFormat gst_timeoverlay_formats[] = {
92   { "I420", 12, gst_timeoverlay_planar411, },
93 };
94
95   
96 static void
97 gst_timeoverlay_base_init (gpointer g_class)
98 {
99   static GstElementDetails timeoverlay_details = GST_ELEMENT_DETAILS (
100     "Time Overlay",
101     "Filter/Editor/Video",
102     "Overlays the time on a video stream",
103     "David Schleef <ds@schleef.org>"
104   );
105   GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
106   GstVideofilterClass *videofilter_class = GST_VIDEOFILTER_CLASS (g_class);
107   int i;
108   
109   gst_element_class_set_details (element_class, &timeoverlay_details);
110
111   for(i=0;i<G_N_ELEMENTS(gst_timeoverlay_formats);i++){
112     gst_videofilter_class_add_format(videofilter_class,
113         gst_timeoverlay_formats + i);
114   }
115
116   gst_videofilter_class_add_pad_templates (GST_VIDEOFILTER_CLASS (g_class));
117 }
118
119 static void
120 gst_timeoverlay_class_init (gpointer g_class, gpointer class_data)
121 {
122   GObjectClass *gobject_class;
123   GstVideofilterClass *videofilter_class;
124
125   gobject_class = G_OBJECT_CLASS (g_class);
126   videofilter_class = GST_VIDEOFILTER_CLASS (g_class);
127
128 #if 0
129   g_object_class_install_property(gobject_class, ARG_METHOD,
130       g_param_spec_enum("method","method","method",
131       GST_TYPE_TIMEOVERLAY_METHOD, GST_TIMEOVERLAY_METHOD_1,
132       G_PARAM_READWRITE));
133 #endif
134
135   gobject_class->set_property = gst_timeoverlay_set_property;
136   gobject_class->get_property = gst_timeoverlay_get_property;
137
138   videofilter_class->setup = gst_timeoverlay_setup;
139 }
140
141 static void
142 gst_timeoverlay_init (GTypeInstance *instance, gpointer g_class)
143 {
144   GstTimeoverlay *timeoverlay = GST_TIMEOVERLAY (instance);
145   GstVideofilter *videofilter;
146
147   GST_DEBUG("gst_timeoverlay_init");
148
149   videofilter = GST_VIDEOFILTER(timeoverlay);
150
151   /* do stuff */
152 }
153
154 static void
155 gst_timeoverlay_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
156 {
157   GstTimeoverlay *src;
158
159   /* it's not null if we got it, but it might not be ours */
160   g_return_if_fail(GST_IS_TIMEOVERLAY(object));
161   src = GST_TIMEOVERLAY(object);
162
163   GST_DEBUG("gst_timeoverlay_set_property");
164   switch (prop_id) {
165 #if 0
166     case ARG_METHOD:
167       src->method = g_value_get_enum (value);
168       break;
169 #endif
170     default:
171       break;
172   }
173 }
174
175 static void
176 gst_timeoverlay_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
177 {
178   GstTimeoverlay *src;
179
180   /* it's not null if we got it, but it might not be ours */
181   g_return_if_fail(GST_IS_TIMEOVERLAY(object));
182   src = GST_TIMEOVERLAY(object);
183
184   switch (prop_id) {
185 #if 0
186     case ARG_METHOD:
187       g_value_set_enum (value, src->method);
188       break;
189 #endif
190     default:
191       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
192       break;
193   }
194 }
195
196 static gboolean plugin_init (GstPlugin *plugin)
197 {
198   if(!gst_library_load("gstvideofilter"))
199     return FALSE;
200
201   return gst_element_register (plugin, "timeoverlay", GST_RANK_NONE,
202       GST_TYPE_TIMEOVERLAY);
203 }
204
205 GST_PLUGIN_DEFINE (
206   GST_VERSION_MAJOR,
207   GST_VERSION_MINOR,
208   "timeoverlay",
209   "Time overlay",
210   plugin_init,
211   VERSION,
212   GST_LICENSE,
213   GST_PACKAGE,
214   GST_ORIGIN
215 )
216
217 static void gst_timeoverlay_setup(GstVideofilter *videofilter)
218 {
219   GstTimeoverlay *timeoverlay;
220   PangoFontDescription *font_description;
221   PangoContext *context;
222
223   g_return_if_fail(GST_IS_TIMEOVERLAY(videofilter));
224   timeoverlay = GST_TIMEOVERLAY(videofilter);
225
226   /* if any setup needs to be done, do it here */
227
228   /* what does this affect? */
229   context = pango_ft2_get_context (100, 100);
230
231   pango_context_set_language (context, pango_language_from_string ("en_US"));
232   pango_context_set_base_dir (context, PANGO_DIRECTION_LTR);
233
234   font_description = pango_font_description_new ();
235   pango_font_description_set_family (font_description, g_strdup ("Monospace"));
236   pango_font_description_set_style (font_description, PANGO_STYLE_NORMAL);
237   pango_font_description_set_variant (font_description, PANGO_VARIANT_NORMAL);
238   pango_font_description_set_weight (font_description, PANGO_WEIGHT_NORMAL);
239   pango_font_description_set_stretch (font_description, PANGO_STRETCH_NORMAL);
240   pango_font_description_set_size (font_description, 12 * PANGO_SCALE);
241
242   pango_context_set_font_description (context, font_description);
243
244   timeoverlay->context = context;
245   timeoverlay->font_description = font_description;
246
247 }
248
249 static char *gst_timeoverlay_print_smpte_time(guint64 time)
250 {
251   int hours;
252   int minutes;
253   int seconds;
254   int ms;
255   double x;
256
257   x = rint((time + 500000)*1e-6);
258
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));
264   x -= seconds*1000;
265   ms = rint(x);
266
267   return g_strdup_printf("%02d:%02d:%02d.%03d",hours,minutes,seconds,ms);
268 }
269
270 static void gst_timeoverlay_planar411(GstVideofilter *videofilter,
271     void *dest, void *src)
272 {
273   GstTimeoverlay *timeoverlay;
274   int width;
275   int height;
276   PangoRectangle logical_rect;
277   PangoLayout *layout;
278   int b_height, b_width;
279   FT_Bitmap bitmap;
280   char *string;
281   int i;
282
283   g_return_if_fail(GST_IS_TIMEOVERLAY(videofilter));
284   timeoverlay = GST_TIMEOVERLAY(videofilter);
285
286   width = gst_videofilter_get_input_width(videofilter);
287   height = gst_videofilter_get_input_height(videofilter);
288
289   width = gst_videofilter_get_input_width(videofilter);
290   height = gst_videofilter_get_input_height(videofilter);
291
292   layout = pango_layout_new (timeoverlay->context);
293   string = gst_timeoverlay_print_smpte_time(GST_BUFFER_TIMESTAMP(videofilter->in_buf));
294   pango_layout_set_text (layout, string, strlen(string));
295   g_free(string);
296
297   pango_layout_set_alignment (layout, PANGO_ALIGN_LEFT);
298   pango_layout_set_width (layout, -1);
299
300   pango_layout_get_extents (layout, NULL, &logical_rect);
301   b_height = PANGO_PIXELS (logical_rect.height);
302   b_width = PANGO_PIXELS (logical_rect.width);
303
304   //hheight = 20;
305
306   memcpy(dest, src, videofilter->from_buf_size);
307
308   for(i=0;i<b_height;i++){
309     memset(dest + i*width, 0, b_width);
310   }
311   for(i=0;i<b_height/2;i++){
312     memset(dest + width*height + i*(width/2), 128, b_width/2);
313     memset(dest + width*height + (width/2)*(height/2) + i*(width/2), 128,
314        b_width/2);
315   }
316   bitmap.rows = b_height;
317   bitmap.width = b_width;
318   bitmap.pitch = width;
319   bitmap.buffer = dest;
320   bitmap.num_grays = 256;
321   bitmap.pixel_mode = ft_pixel_mode_grays;
322
323   pango_ft2_render_layout (&bitmap, layout, 0, 0);
324 }
325