diff options
Diffstat (limited to 'ext/pango/gsttimeoverlay.c')
-rw-r--r-- | ext/pango/gsttimeoverlay.c | 313 |
1 files changed, 58 insertions, 255 deletions
diff --git a/ext/pango/gsttimeoverlay.c b/ext/pango/gsttimeoverlay.c index 7ad0807a..b756172b 100644 --- a/ext/pango/gsttimeoverlay.c +++ b/ext/pango/gsttimeoverlay.c @@ -1,6 +1,6 @@ /* GStreamer * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu> - * Copyright (C) <2003> David Schleef <ds@schleef.org> + * Copyright (C) <2005> Tim-Philipp Müller <tim@centricular.net> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -18,215 +18,99 @@ * Boston, MA 02111-1307, USA. */ -/* portions derived from: - * Pango - * pangoft2topgm.c: Example program to view a UTF-8 encoding file - * using Pango to render result. - * - * Copyright (C) 1999 Red Hat Software - * Copyright (C) 2001 Sun Microsystems - */ - -/* - * This file was (probably) generated from gsttimeoverlay.c, - * gsttimeoverlay.c,v 1.7 2003/11/08 02:48:59 dschleef Exp - */ - #ifdef HAVE_CONFIG_H #include "config.h" #endif -/*#define DEBUG_ENABLED */ -#include <gsttimeoverlay.h> -#include <string.h> -#include <math.h> -#include <pango/pango.h> -#include <pango/pangoft2.h> - - -/* GstTimeoverlay signals and args */ -enum -{ - /* FILL ME */ - LAST_SIGNAL -}; +#include <gst/video/video.h> -enum -{ - ARG_0 - /* FILL ME */ -}; - -static void gst_timeoverlay_base_init (gpointer g_class); -static void gst_timeoverlay_class_init (gpointer g_class, gpointer class_data); -static void gst_timeoverlay_init (GTypeInstance * instance, gpointer g_class); +#include <gsttimeoverlay.h> -static void gst_timeoverlay_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec); -static void gst_timeoverlay_get_property (GObject * object, guint prop_id, - GValue * value, GParamSpec * pspec); +static GstElementDetails time_overlay_details = +GST_ELEMENT_DETAILS ("Time Overlay", + "Filter/Editor/Video", + "Overlays the time on a video stream", + "Tim-Philipp Müller <tim@centricular.net>"); -static void gst_timeoverlay_planar411 (GstVideofilter * videofilter, void *dest, - void *src); -static void gst_timeoverlay_setup (GstVideofilter * videofilter); +GST_BOILERPLATE (GstTimeOverlay, gst_time_overlay, GstTextOverlay, + GST_TYPE_TEXT_OVERLAY) -GType -gst_timeoverlay_get_type (void) + static void gst_time_overlay_base_init (gpointer g_class) { - static GType timeoverlay_type = 0; - - if (!timeoverlay_type) { - static const GTypeInfo timeoverlay_info = { - sizeof (GstTimeoverlayClass), - gst_timeoverlay_base_init, - NULL, - gst_timeoverlay_class_init, - NULL, - NULL, - sizeof (GstTimeoverlay), - 0, - gst_timeoverlay_init, - }; + GstElementClass *element_class = GST_ELEMENT_CLASS (g_class); - timeoverlay_type = g_type_register_static (GST_TYPE_VIDEOFILTER, - "GstTimeoverlay", &timeoverlay_info, 0); - } - return timeoverlay_type; + gst_element_class_set_details (element_class, &time_overlay_details); } -static GstVideofilterFormat gst_timeoverlay_formats[] = { - {"I420", 12, gst_timeoverlay_planar411,}, -}; - - -static void -gst_timeoverlay_base_init (gpointer g_class) +static gchar * +gst_time_overlay_render_time (GstTimeOverlay * overlay, GstClockTime time) { - static GstElementDetails timeoverlay_details = - GST_ELEMENT_DETAILS ("Time Overlay", - "Filter/Editor/Video", - "Overlays the time on a video stream", - "David Schleef <ds@schleef.org>"); - GstElementClass *element_class = GST_ELEMENT_CLASS (g_class); - GstVideofilterClass *videofilter_class = GST_VIDEOFILTER_CLASS (g_class); - int i; + guint hours, mins, secs, msecs; - gst_element_class_set_details (element_class, &timeoverlay_details); + if (!GST_CLOCK_TIME_IS_VALID (time)) + return g_strdup (""); - for (i = 0; i < G_N_ELEMENTS (gst_timeoverlay_formats); i++) { - gst_videofilter_class_add_format (videofilter_class, - gst_timeoverlay_formats + i); - } + hours = (guint) (time / (GST_SECOND * 60 * 60)); + mins = (guint) ((time / (GST_SECOND * 60)) % 60); + secs = (guint) ((time / GST_SECOND) % 60); + msecs = (guint) ((time % GST_SECOND) / (1000 * 1000)); - gst_videofilter_class_add_pad_templates (GST_VIDEOFILTER_CLASS (g_class)); + return g_strdup_printf ("%u:%02u:%02u.%03u", hours, mins, secs, msecs); } -static void -gst_timeoverlay_class_init (gpointer g_class, gpointer class_data) +static gchar * +gst_time_overlay_get_text (GstTextOverlay * overlay, GstBuffer * video_frame) { - GObjectClass *gobject_class; - GstVideofilterClass *videofilter_class; + GstClockTime time = GST_BUFFER_TIMESTAMP (video_frame); + gchar *time_str, *txt, *ret; - gobject_class = G_OBJECT_CLASS (g_class); - videofilter_class = GST_VIDEOFILTER_CLASS (g_class); + overlay->need_render = TRUE; -#if 0 - g_object_class_install_property (gobject_class, ARG_METHOD, - g_param_spec_enum ("method", "method", "method", - GST_TYPE_TIMEOVERLAY_METHOD, GST_TIMEOVERLAY_METHOD_1, - G_PARAM_READWRITE)); -#endif + if (!GST_CLOCK_TIME_IS_VALID (time)) { + GST_DEBUG ("buffer without valid timestamp"); + return g_strdup (""); + } - gobject_class->set_property = gst_timeoverlay_set_property; - gobject_class->get_property = gst_timeoverlay_get_property; + GST_DEBUG ("buffer with timestamp %" GST_TIME_FORMAT, GST_TIME_ARGS (time)); - videofilter_class->setup = gst_timeoverlay_setup; -} + GST_OBJECT_LOCK (overlay); + txt = g_strdup (overlay->default_text); + GST_OBJECT_UNLOCK (overlay); -static void -gst_timeoverlay_init (GTypeInstance * instance, gpointer g_class) -{ - GstTimeoverlay *timeoverlay = GST_TIMEOVERLAY (instance); - GstVideofilter *videofilter; - - GST_DEBUG ("gst_timeoverlay_init"); + time_str = gst_time_overlay_render_time (GST_TIME_OVERLAY (overlay), time); + if (txt != NULL && *txt != '\0') { + ret = g_strdup_printf ("%s %s", txt, time_str); + } else { + ret = time_str; + time_str = NULL; + } - videofilter = GST_VIDEOFILTER (timeoverlay); + g_free (txt); + g_free (time_str); - /* do stuff */ + return ret; } static void -gst_timeoverlay_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec) +gst_time_overlay_class_init (GstTimeOverlayClass * klass) { - GstTimeoverlay *src; + GstTextOverlayClass *gsttextoverlay_class; - g_return_if_fail (GST_IS_TIMEOVERLAY (object)); - src = GST_TIMEOVERLAY (object); + gsttextoverlay_class = (GstTextOverlayClass *) klass; - GST_DEBUG ("gst_timeoverlay_set_property"); - switch (prop_id) { -#if 0 - case ARG_METHOD: - src->method = g_value_get_enum (value); - break; -#endif - default: - break; - } + gsttextoverlay_class->get_text = gst_time_overlay_get_text; } static void -gst_timeoverlay_get_property (GObject * object, guint prop_id, GValue * value, - GParamSpec * pspec) +gst_time_overlay_init (GstTimeOverlay * overlay, GstTimeOverlayClass * klass) { - GstTimeoverlay *src; - - g_return_if_fail (GST_IS_TIMEOVERLAY (object)); - src = GST_TIMEOVERLAY (object); - - switch (prop_id) { -#if 0 - case ARG_METHOD: - g_value_set_enum (value, src->method); - break; -#endif - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static gboolean -plugin_init (GstPlugin * plugin) -{ - if (!gst_library_load ("gstvideofilter")) - return FALSE; - - return gst_element_register (plugin, "timeoverlay", GST_RANK_NONE, - GST_TYPE_TIMEOVERLAY); -} - -GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, - GST_VERSION_MINOR, - "timeoverlay", - "Time overlay", plugin_init, VERSION, GST_LICENSE, GST_PACKAGE_NAME, - GST_PACKAGE_ORIGIN) - - static void gst_timeoverlay_setup (GstVideofilter * videofilter) -{ - GstTimeoverlay *timeoverlay; PangoFontDescription *font_description; + GstTextOverlay *textoverlay; PangoContext *context; - g_return_if_fail (GST_IS_TIMEOVERLAY (videofilter)); - timeoverlay = GST_TIMEOVERLAY (videofilter); - - /* if any setup needs to be done, do it here */ + textoverlay = GST_TEXT_OVERLAY (overlay); - /* what does this affect? */ - context = pango_ft2_get_context (100, 100); + context = GST_TEXT_OVERLAY_CLASS (klass)->pango_context; pango_context_set_language (context, pango_language_from_string ("en_US")); pango_context_set_base_dir (context, PANGO_DIRECTION_LTR); @@ -237,91 +121,10 @@ GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, 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, 12 * PANGO_SCALE); - + pango_font_description_set_size (font_description, 18 * PANGO_SCALE); pango_context_set_font_description (context, font_description); + pango_font_description_free (font_description); - timeoverlay->context = context; - timeoverlay->font_description = font_description; - -} - -static char * -gst_timeoverlay_print_smpte_time (guint64 time) -{ - int hours; - int minutes; - int seconds; - int ms; - double x; - - x = rint ((time + 500000) * 1e-6); - - hours = floor (x / (60 * 60 * 1000)); - x -= hours * 60 * 60 * 1000; - minutes = floor (x / (60 * 1000)); - x -= minutes * 60 * 1000; - seconds = floor (x / (1000)); - x -= seconds * 1000; - ms = rint (x); - - return g_strdup_printf ("%02d:%02d:%02d.%03d", hours, minutes, seconds, ms); -} - -static void -gst_timeoverlay_planar411 (GstVideofilter * videofilter, void *dest, void *src) -{ - GstTimeoverlay *timeoverlay; - int width; - int height; - PangoRectangle logical_rect; - PangoLayout *layout; - int b_height, b_width; - FT_Bitmap bitmap; - char *string; - int i; - - g_return_if_fail (GST_IS_TIMEOVERLAY (videofilter)); - timeoverlay = GST_TIMEOVERLAY (videofilter); - - width = gst_videofilter_get_input_width (videofilter); - height = gst_videofilter_get_input_height (videofilter); - - width = gst_videofilter_get_input_width (videofilter); - height = gst_videofilter_get_input_height (videofilter); - - layout = pango_layout_new (timeoverlay->context); - string = - gst_timeoverlay_print_smpte_time (GST_BUFFER_TIMESTAMP (videofilter-> - in_buf)); - pango_layout_set_text (layout, string, strlen (string)); - g_free (string); - - pango_layout_set_alignment (layout, PANGO_ALIGN_LEFT); - pango_layout_set_width (layout, -1); - - pango_layout_get_extents (layout, NULL, &logical_rect); - b_height = PANGO_PIXELS (logical_rect.height); - b_width = PANGO_PIXELS (logical_rect.width); - - //hheight = 20; - - memcpy (dest, src, videofilter->from_buf_size); - - for (i = 0; i < b_height; i++) { - memset (dest + i * width, 0, b_width); - } - for (i = 0; i < b_height / 2; i++) { - memset (dest + width * height + i * (width / 2), 128, b_width / 2); - memset (dest + width * height + (width / 2) * (height / 2) + - i * (width / 2), 128, b_width / 2); - } - bitmap.rows = b_height; - bitmap.width = b_width; - bitmap.pitch = width; - bitmap.buffer = dest; - bitmap.num_grays = 256; - bitmap.pixel_mode = ft_pixel_mode_grays; - - pango_ft2_render_layout (&bitmap, layout, 0, 0); + textoverlay->valign = GST_TEXT_OVERLAY_VALIGN_TOP; + textoverlay->halign = GST_TEXT_OVERLAY_HALIGN_LEFT; } |