From bfd44accb6bc057f07d335b8b652bf2b099c68b1 Mon Sep 17 00:00:00 2001 From: David Schleef Date: Wed, 2 Jul 2003 08:07:24 +0000 Subject: [PATCH] overlays text of the current timestamp Original commit message from CVS: overlays text of the current timestamp --- ext/pango/Makefile.am | 14 ++ ext/pango/gsttimeoverlay.c | 370 +++++++++++++++++++++++++++++++++++++ ext/pango/gsttimeoverlay.h | 65 +++++++ 3 files changed, 449 insertions(+) create mode 100644 ext/pango/Makefile.am create mode 100644 ext/pango/gsttimeoverlay.c create mode 100644 ext/pango/gsttimeoverlay.h diff --git a/ext/pango/Makefile.am b/ext/pango/Makefile.am new file mode 100644 index 0000000000..ff6c2abada --- /dev/null +++ b/ext/pango/Makefile.am @@ -0,0 +1,14 @@ +plugindir = $(libdir)/gstreamer-@GST_MAJORMINOR@ + +#PANGO_CFLAGS = -I/usr/include/pango-1.0 -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -I/usr/include/freetype2 +#PANGO_LDFLAGS = -Wl,--export-dynamic -lpangoft2-1.0 -lpango-1.0 -lgobject-2.0 -lgmodule-2.0 -ldl -lglib-2.0 + +plugin_LTLIBRARIES = libgsttimeoverlay.la + +noinst_HEADERS = gsttimeoverlay.h + +libgsttimeoverlay_la_SOURCES = gsttimeoverlay.c +libgsttimeoverlay_la_CFLAGS = $(GST_CFLAGS) $(PANGO_CFLAGS) -I$(top_srcdir)/gst/videofilter +libgsttimeoverlay_la_LIBADD = +libgsttimeoverlay_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) $(PANGO_LIBS) -lm + diff --git a/ext/pango/gsttimeoverlay.c b/ext/pango/gsttimeoverlay.c new file mode 100644 index 0000000000..5682b821b0 --- /dev/null +++ b/ext/pango/gsttimeoverlay.c @@ -0,0 +1,370 @@ +/* GStreamer + * Copyright (C) <1999> Erik Walthinsen + * Copyright (C) <2003> David Schleef + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * 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 + */ + + +/*#define DEBUG_ENABLED */ +#include + +#include +#include + +#include + + + +/* elementfactory information */ +static GstElementDetails timeoverlay_details = { + "Video Filter Template", + "Filter/Video", + "LGPL", + "Template for a video filter", + VERSION, + "David Schleef ", + "(C) 2003", +}; + +/* GstTimeoverlay signals and args */ +enum { + /* FILL ME */ + LAST_SIGNAL +}; + +enum { + ARG_0, + /* FILL ME */ +}; + +static void gst_timeoverlay_class_init (GstTimeoverlayClass *klass); +static void gst_timeoverlay_init (GstTimeoverlay *timeoverlay); + +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 void gst_timeoverlay_planar411(GstVideofilter *videofilter, void *dest, void *src); +static void gst_timeoverlay_setup(GstVideofilter *videofilter); + +static GstTimeoverlayClass *this_class = NULL; +static GstVideofilterClass *parent_class = NULL; +static GstElementClass *element_class = NULL; + +GType +gst_timeoverlay_get_type (void) +{ + static GType timeoverlay_type = 0; + + if (!timeoverlay_type) { + static const GTypeInfo timeoverlay_info = { + sizeof(GstTimeoverlayClass), NULL, + NULL, + (GClassInitFunc)gst_timeoverlay_class_init, + NULL, + NULL, + sizeof(GstTimeoverlay), + 0, + (GInstanceInitFunc)gst_timeoverlay_init, + }; + timeoverlay_type = g_type_register_static(GST_TYPE_VIDEOFILTER, "GstTimeoverlay", &timeoverlay_info, 0); + } + return timeoverlay_type; +} + +static GstVideofilterFormat gst_timeoverlay_formats[] = { + { "I420", 12, gst_timeoverlay_planar411, }, +}; + +static void +gst_timeoverlay_class_init (GstTimeoverlayClass *klass) +{ + GObjectClass *gobject_class; + GstElementClass *gstelement_class; + GstVideofilterClass *gstvideofilter_class; + int i; + + gobject_class = (GObjectClass*)klass; + gstelement_class = (GstElementClass*)klass; + gstvideofilter_class = (GstVideofilterClass *)klass; + +#if 0 + g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_METHOD, + g_param_spec_enum("method","method","method", + GST_TYPE_TIMEOVERLAY_METHOD, GST_TIMEOVERLAY_METHOD_90R, + G_PARAM_READWRITE)); +#endif + + this_class = klass; + parent_class = g_type_class_ref(GST_TYPE_VIDEOFILTER); + element_class = g_type_class_ref(GST_TYPE_ELEMENT); + + gobject_class->set_property = gst_timeoverlay_set_property; + gobject_class->get_property = gst_timeoverlay_get_property; + + gstvideofilter_class->setup = gst_timeoverlay_setup; + + for(i=0;isinkpad = gst_pad_new_from_template ( + GST_PAD_TEMPLATE_GET (gst_timeoverlay_sink_template_factory), + "sink"); + + videofilter->srcpad = gst_pad_new_from_template ( + GST_PAD_TEMPLATE_GET (gst_timeoverlay_src_template_factory), + "src"); + + gst_videofilter_postinit(GST_VIDEOFILTER(timeoverlay)); +} + +static void +gst_timeoverlay_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +{ + GstTimeoverlay *src; + + /* it's not null if we got it, but it might not be ours */ + g_return_if_fail(GST_IS_TIMEOVERLAY(object)); + src = GST_TIMEOVERLAY(object); + + 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; + } +} + +static void +gst_timeoverlay_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + GstTimeoverlay *src; + + /* it's not null if we got it, but it might not be ours */ + 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 (GModule *module, GstPlugin *plugin) +{ + GstElementFactory *factory; + + if(!gst_library_load("gstvideofilter")) + return FALSE; + + /* create an elementfactory for the timeoverlay element */ + factory = gst_element_factory_new("timeoverlay",GST_TYPE_TIMEOVERLAY, + &timeoverlay_details); + g_return_val_if_fail(factory != NULL, FALSE); + + gst_element_factory_add_pad_template (factory, GST_PAD_TEMPLATE_GET (gst_timeoverlay_sink_template_factory)); + gst_element_factory_add_pad_template (factory, GST_PAD_TEMPLATE_GET (gst_timeoverlay_src_template_factory)); + + gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (factory)); + + return TRUE; +} + +GstPluginDesc plugin_desc = { + GST_VERSION_MAJOR, + GST_VERSION_MINOR, + "timeoverlay", + plugin_init +}; + +static void gst_timeoverlay_setup(GstVideofilter *videofilter) +{ + GstTimeoverlay *timeoverlay; + PangoFontDescription *font_description; + PangoContext *context; + + g_return_if_fail(GST_IS_TIMEOVERLAY(videofilter)); + timeoverlay = GST_TIMEOVERLAY(videofilter); + + /* if any setup needs to be done, do it here */ + + /* what does this affect? */ + context = pango_ft2_get_context (100, 100); + + 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 (font_description, g_strdup ("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, 12 * PANGO_SCALE); + + pango_context_set_font_description (context, 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 height; + int width; + 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); + + 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 Erik Walthinsen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + + +#ifndef __GST_TIMEOVERLAY_H__ +#define __GST_TIMEOVERLAY_H__ + + +#include +#include +#include + +#include "gstvideofilter.h" + + +G_BEGIN_DECLS + +#define GST_TYPE_TIMEOVERLAY \ + (gst_timeoverlay_get_type()) +#define GST_TIMEOVERLAY(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_TIMEOVERLAY,GstTimeoverlay)) +#define GST_TIMEOVERLAY_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_TIMEOVERLAY,GstTimeoverlayClass)) +#define GST_IS_TIMEOVERLAY(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_TIMEOVERLAY)) +#define GST_IS_TIMEOVERLAY_CLASS(obj) \ + (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_TIMEOVERLAY)) + +typedef struct _GstTimeoverlay GstTimeoverlay; +typedef struct _GstTimeoverlayClass GstTimeoverlayClass; + +struct _GstTimeoverlay { + GstVideofilter videofilter; + + PangoFontDescription *font_description; + PangoContext *context; + +}; + +struct _GstTimeoverlayClass { + GstVideofilterClass parent_class; +}; + +GType gst_timeoverlay_get_type(void); + +G_END_DECLS + +#endif /* __GST_TIMEOVERLAY_H__ */ +