Port pango-based textoverlay, timeoverlay and textrender to 0.9 and add background shading and text wrapping modes. M...

Original commit message from CVS:
* configure.ac:
* ext/Makefile.am:
* ext/pango/Makefile.am:
* ext/pango/gstclockoverlay.c: (gst_clock_overlay_base_init),
(gst_clock_overlay_render_time), (gst_clock_overlay_get_text),
(gst_clock_overlay_class_init), (gst_clock_overlay_init):
* ext/pango/gstclockoverlay.h:
* ext/pango/gsttextoverlay.c: (gst_text_overlay_base_init),
(gst_text_overlay_get_text), (gst_text_overlay_class_init),
(gst_text_overlay_finalize), (gst_text_overlay_init),
(gst_text_overlay_update_wrap_mode), (gst_text_overlay_setcaps),
(gst_text_overlay_text_pad_linked),
(gst_text_overlay_text_pad_unlinked),
(gst_text_overlay_set_property), (gst_text_overlay_getcaps),
(gst_text_overlay_shade_y), (gst_text_overlay_blit_yuv420),
(gst_text_overlay_resize_bitmap), (gst_text_overlay_render_text),
(gst_text_overlay_push_frame), (gst_text_overlay_pop_video),
(gst_text_overlay_pop_text), (gst_text_overlay_collected),
(gst_text_overlay_change_state), (plugin_init):
* ext/pango/gsttextoverlay.h:
* ext/pango/gsttimeoverlay.c: (gst_time_overlay_base_init),
(gst_time_overlay_render_time), (gst_time_overlay_get_text),
(gst_time_overlay_class_init), (gst_time_overlay_init):
* ext/pango/gsttimeoverlay.h:
Port pango-based textoverlay, timeoverlay and textrender to 0.9
and add background shading and text wrapping modes. Make
timoverlay derive from textoverlay. Also add new clockoverlay
element.
This commit is contained in:
Tim-Philipp Müller 2005-11-30 13:20:57 +00:00
parent 9211681208
commit b1d87b1ffb
10 changed files with 1150 additions and 891 deletions

View file

@ -1,3 +1,34 @@
2005-11-30 Tim-Philipp Müller <tim at centricular dot net>
* configure.ac:
* ext/Makefile.am:
* ext/pango/Makefile.am:
* ext/pango/gstclockoverlay.c: (gst_clock_overlay_base_init),
(gst_clock_overlay_render_time), (gst_clock_overlay_get_text),
(gst_clock_overlay_class_init), (gst_clock_overlay_init):
* ext/pango/gstclockoverlay.h:
* ext/pango/gsttextoverlay.c: (gst_text_overlay_base_init),
(gst_text_overlay_get_text), (gst_text_overlay_class_init),
(gst_text_overlay_finalize), (gst_text_overlay_init),
(gst_text_overlay_update_wrap_mode), (gst_text_overlay_setcaps),
(gst_text_overlay_text_pad_linked),
(gst_text_overlay_text_pad_unlinked),
(gst_text_overlay_set_property), (gst_text_overlay_getcaps),
(gst_text_overlay_shade_y), (gst_text_overlay_blit_yuv420),
(gst_text_overlay_resize_bitmap), (gst_text_overlay_render_text),
(gst_text_overlay_push_frame), (gst_text_overlay_pop_video),
(gst_text_overlay_pop_text), (gst_text_overlay_collected),
(gst_text_overlay_change_state), (plugin_init):
* ext/pango/gsttextoverlay.h:
* ext/pango/gsttimeoverlay.c: (gst_time_overlay_base_init),
(gst_time_overlay_render_time), (gst_time_overlay_get_text),
(gst_time_overlay_class_init), (gst_time_overlay_init):
* ext/pango/gsttimeoverlay.h:
Port pango-based textoverlay, timeoverlay and textrender to 0.9
and add background shading and text wrapping modes. Make
timoverlay derive from textoverlay. Also add new clockoverlay
element.
2005-11-30 Julien MOUTTE <julien@moutte.net> 2005-11-30 Julien MOUTTE <julien@moutte.net>
* gst/udp/Makefile.am: Moved to netbuffer. * gst/udp/Makefile.am: Moved to netbuffer.

View file

@ -413,6 +413,15 @@ GST_CHECK_FEATURE(DV1394, [raw1394 and avc1394 library], dv1394src, [
fi fi
]) ])
dnl *** pango ***
translit(dnm, m, l) AM_CONDITIONAL(USE_PANGO, true)
GST_CHECK_FEATURE(PANGO, [pango], pango, [
PKG_CHECK_MODULES(PANGO, pango pangoft2,
HAVE_PANGO="yes", HAVE_PANGO="no")
AC_SUBST(PANGO_CFLAGS)
AC_SUBST(PANGO_LIBS)
])
dnl *** shout2 *** dnl *** shout2 ***
translit(dnm, m, l) AM_CONDITIONAL(USE_SHOUT2, true) translit(dnm, m, l) AM_CONDITIONAL(USE_SHOUT2, true)
GST_CHECK_FEATURE(SHOUT2, [shout2 plug-in], shout2send, [ GST_CHECK_FEATURE(SHOUT2, [shout2 plug-in], shout2send, [
@ -557,6 +566,7 @@ ext/gconf/Makefile
ext/ladspa/Makefile ext/ladspa/Makefile
ext/libcaca/Makefile ext/libcaca/Makefile
ext/libpng/Makefile ext/libpng/Makefile
ext/pango/Makefile
ext/raw1394/Makefile ext/raw1394/Makefile
ext/shout2/Makefile ext/shout2/Makefile
ext/speex/Makefile ext/speex/Makefile

View file

@ -76,11 +76,11 @@ endif
MIKMOD_DIR = MIKMOD_DIR =
# endif # endif
# if USE_PANGO if USE_PANGO
# PANGO_DIR = pango PANGO_DIR = pango
# else else
PANGO_DIR = PANGO_DIR =
# endif endif
if USE_DV1394 if USE_DV1394
DV1394_DIR = raw1394 DV1394_DIR = raw1394
@ -130,6 +130,7 @@ DIST_SUBDIRS = \
ladspa \ ladspa \
libcaca \ libcaca \
libpng \ libpng \
pango \
raw1394 \ raw1394 \
shout2 \ shout2 \
speex speex

View file

@ -1,16 +1,28 @@
#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 libgsttextoverlay.la plugin_LTLIBRARIES = libgstpango.la
noinst_HEADERS = gsttimeoverlay.h gsttextoverlay.h noinst_HEADERS = \
gstclockoverlay.h \
gsttextoverlay.h \
gsttextrender.h \
gsttimeoverlay.h
libgsttimeoverlay_la_SOURCES = gsttimeoverlay.c libgstpango_la_SOURCES = \
libgsttimeoverlay_la_CFLAGS = $(GST_CFLAGS) $(PANGO_CFLAGS) -I$(top_srcdir)/gst/videofilter gstclockoverlay.c \
libgsttimeoverlay_la_LIBADD = $(GST_LIBS) $(PANGO_LIBS) -lm gsttextoverlay.c \
libgsttimeoverlay_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) gsttextrender.c \
gsttimeoverlay.c
libgsttextoverlay_la_SOURCES = gsttextoverlay.c libgstpango_la_CFLAGS = \
libgsttextoverlay_la_CFLAGS = $(GST_CFLAGS) $(PANGO_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS) \
libgsttextoverlay_la_LIBADD = $(GST_LIBS) $(PANGO_LIBS) $(GST_BASE_CFLAGS) \
libgsttextoverlay_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) $(GST_CFLAGS) \
$(PANGO_CFLAGS)
libgstpango_la_LIBADD = \
$(GST_BASE_LIBS) \
$(GST_LIBS) \
$(PANGO_LIBS)
libgstpango_la_LDFLAGS = \
$(GST_PLUGIN_LDFLAGS)

119
ext/pango/gstclockoverlay.c Normal file
View file

@ -0,0 +1,119 @@
/* GStreamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
* 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
* 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.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <gstclockoverlay.h>
#include <gst/video/video.h>
#include <time.h>
static GstElementDetails clock_overlay_details =
GST_ELEMENT_DETAILS ("Time Overlay",
"Filter/Editor/Video",
"Overlays the time on a video stream",
"Tim-Philipp Müller <tim@centricular.net>");
GST_BOILERPLATE (GstClockOverlay, gst_clock_overlay, GstTextOverlay,
GST_TYPE_TEXT_OVERLAY)
static void gst_clock_overlay_base_init (gpointer g_class)
{
GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
gst_element_class_set_details (element_class, &clock_overlay_details);
}
static gchar *
gst_clock_overlay_render_time (GstClockOverlay * overlay)
{
struct tm t;
time_t now;
now = time (NULL);
if (localtime_r (&now, &t) == NULL)
return g_strdup ("--:--:--");
return g_strdup_printf ("%02u:%02u:%02u", t.tm_hour, t.tm_min, t.tm_sec);
}
static gchar *
gst_clock_overlay_get_text (GstTextOverlay * overlay, GstBuffer * video_frame)
{
gchar *time_str, *txt, *ret;
overlay->need_render = TRUE;
GST_OBJECT_LOCK (overlay);
txt = g_strdup (overlay->default_text);
GST_OBJECT_UNLOCK (overlay);
time_str = gst_clock_overlay_render_time (GST_CLOCK_OVERLAY (overlay));
if (txt != NULL && *txt != '\0') {
ret = g_strdup_printf ("%s %s", txt, time_str);
} else {
ret = time_str;
time_str = NULL;
}
g_free (txt);
g_free (time_str);
return ret;
}
static void
gst_clock_overlay_class_init (GstClockOverlayClass * klass)
{
GstTextOverlayClass *gsttextoverlay_class;
gsttextoverlay_class = (GstTextOverlayClass *) klass;
gsttextoverlay_class->get_text = gst_clock_overlay_get_text;
}
static void
gst_clock_overlay_init (GstClockOverlay * overlay, GstClockOverlayClass * klass)
{
PangoFontDescription *font_description;
GstTextOverlay *textoverlay;
PangoContext *context;
textoverlay = GST_TEXT_OVERLAY (overlay);
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);
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, 18 * PANGO_SCALE);
pango_context_set_font_description (context, font_description);
pango_font_description_free (font_description);
textoverlay->valign = GST_TEXT_OVERLAY_VALIGN_TOP;
textoverlay->halign = GST_TEXT_OVERLAY_HALIGN_LEFT;
}

View file

@ -0,0 +1,56 @@
/* GStreamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
* 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
* 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_CLOCK_OVERLAY_H__
#define __GST_CLOCK_OVERLAY_H__
#include "gsttextoverlay.h"
G_BEGIN_DECLS
#define GST_TYPE_CLOCK_OVERLAY \
(gst_clock_overlay_get_type())
#define GST_CLOCK_OVERLAY(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_CLOCK_OVERLAY,GstClockOverlay))
#define GST_CLOCK_OVERLAY_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_CLOCK_OVERLAY,GstClockOverlayClass))
#define GST_IS_CLOCK_OVERLAY(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_CLOCK_OVERLAY))
#define GST_IS_CLOCK_OVERLAY_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_CLOCK_OVERLAY))
typedef struct _GstClockOverlay GstClockOverlay;
typedef struct _GstClockOverlayClass GstClockOverlayClass;
struct _GstClockOverlay {
GstTextOverlay textoverlay;
};
struct _GstClockOverlayClass {
GstTextOverlayClass parent_class;
};
GType gst_clock_overlay_get_type (void);
G_END_DECLS
#endif /* __GST_CLOCK_OVERLAY_H__ */

File diff suppressed because it is too large Load diff

View file

@ -1,29 +1,30 @@
/* -*- Mode: C; c-file-style: "stroustrup" -*- */ #ifndef __GST_TEXT_OVERLAY_H__
#ifndef __GST_TEXTOVERLAY_H__ #define __GST_TEXT_OVERLAY_H__
#define __GST_TEXTOVERLAY_H__
#include <gst/gst.h> #include <gst/gst.h>
#include <gst/base/gstcollectpads.h>
#include <pango/pangoft2.h> #include <pango/pangoft2.h>
G_BEGIN_DECLS G_BEGIN_DECLS
#define GST_TYPE_TEXTOVERLAY (gst_textoverlay_get_type()) #define GST_TYPE_TEXT_OVERLAY (gst_text_overlay_get_type())
#define GST_TEXTOVERLAY(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),\ #define GST_TEXT_OVERLAY(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),\
GST_TYPE_TEXTOVERLAY, GstTextOverlay)) GST_TYPE_TEXT_OVERLAY, GstTextOverlay))
#define GST_TEXTOVERLAY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),\ #define GST_TEXT_OVERLAY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),\
GST_TYPE_ULAW, GstTextOverlay)) GST_TYPE_TEXT_OVERLAY,GstTextOverlayClass))
#define GST_TEXTOVERLAY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj),\ #define GST_TEXT_OVERLAY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj),\
GST_TYPE_TEXTOVERLAY, GstTextOverlayClass)) GST_TYPE_TEXT_OVERLAY, GstTextOverlayClass))
#define GST_IS_TEXTOVERLAY(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),\ #define GST_IS_TEXT_OVERLAY(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),\
GST_TYPE_TEXTOVERLAY)) GST_TYPE_TEXT_OVERLAY))
#define GST_IS_TEXTOVERLAY_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE((klass),\ #define GST_IS_TEXT_OVERLAY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),\
GST_TYPE_TEXTOVERLAY)) GST_TYPE_TEXT_OVERLAY))
typedef struct _GstTextOverlay GstTextOverlay; typedef struct _GstTextOverlay GstTextOverlay;
typedef struct _GstTextOverlayClass GstTextOverlayClass; typedef struct _GstTextOverlayClass GstTextOverlayClass;
typedef enum _GstTextOverlayVAlign GstTextOverlayVAlign; typedef enum _GstTextOverlayVAlign GstTextOverlayVAlign;
typedef enum _GstTextOverlayHAlign GstTextOverlayHAlign; typedef enum _GstTextOverlayHAlign GstTextOverlayHAlign;
typedef enum _GstTextOverlayWrapMode GstTextOverlayWrapMode;
enum _GstTextOverlayVAlign { enum _GstTextOverlayVAlign {
GST_TEXT_OVERLAY_VALIGN_BASELINE, GST_TEXT_OVERLAY_VALIGN_BASELINE,
@ -37,37 +38,62 @@ enum _GstTextOverlayHAlign {
GST_TEXT_OVERLAY_HALIGN_RIGHT GST_TEXT_OVERLAY_HALIGN_RIGHT
}; };
enum _GstTextOverlayWrapMode {
GST_TEXT_OVERLAY_WRAP_MODE_NONE = -1,
GST_TEXT_OVERLAY_WRAP_MODE_WORD = PANGO_WRAP_WORD,
GST_TEXT_OVERLAY_WRAP_MODE_CHAR = PANGO_WRAP_CHAR,
GST_TEXT_OVERLAY_WRAP_MODE_WORD_CHAR = PANGO_WRAP_WORD_CHAR
};
struct _GstTextOverlay { struct _GstTextOverlay {
GstElement element; GstElement element;
GstPad *video_sinkpad; GstPad *video_sinkpad;
GstPad *text_sinkpad; GstPad *text_sinkpad;
GstPad *srcpad; GstPad *srcpad;
gint width;
gint height; GstCollectPads *collect;
PangoLayout *layout; GstCollectData *video_collect_data;
FT_Bitmap bitmap; GstCollectData *text_collect_data;
gint bitmap_buffer_size;
gint baseline_y; gint width;
GstTextOverlayVAlign valign; gint height;
GstTextOverlayHAlign halign; gint fps_n;
gint x0; gint fps_d;
gint y0;
GstData *current_data; GstTextOverlayVAlign valign;
GstData *next_data; GstTextOverlayHAlign halign;
gchar *default_text; GstTextOverlayWrapMode wrap_mode;
gboolean need_render;
gint xpad;
gint ypad;
gint deltax;
gint deltay;
gchar *default_text;
gboolean want_shading;
PangoLayout *layout;
FT_Bitmap bitmap;
gint bitmap_buffer_size;
gint baseline_y;
gboolean need_render;
gint shading_value; /* for timeoverlay subclass */
}; };
struct _GstTextOverlayClass { struct _GstTextOverlayClass {
GstElementClass parent_class; GstElementClass parent_class;
PangoContext *pango_context; PangoContext *pango_context;
gchar * (*get_text) (GstTextOverlay *overlay, GstBuffer *video_frame);
}; };
GType gst_textoverlay_get_type(void) G_GNUC_CONST; GType gst_text_overlay_get_type(void) G_GNUC_CONST;
G_END_DECLS G_END_DECLS
#endif /* __GST_TEXTOVERLAY_H */ #endif /* __GST_TEXT_OVERLAY_H */

View file

@ -1,6 +1,6 @@
/* GStreamer /* GStreamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu> * 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 * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public * modify it under the terms of the GNU Library General Public
@ -18,215 +18,99 @@
* Boston, MA 02111-1307, USA. * 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 #ifdef HAVE_CONFIG_H
#include "config.h" #include "config.h"
#endif #endif
/*#define DEBUG_ENABLED */ #include <gst/video/video.h>
#include <gsttimeoverlay.h> #include <gsttimeoverlay.h>
#include <string.h>
#include <math.h>
#include <pango/pango.h>
#include <pango/pangoft2.h>
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>");
/* GstTimeoverlay signals and args */ GST_BOILERPLATE (GstTimeOverlay, gst_time_overlay, GstTextOverlay,
enum GST_TYPE_TEXT_OVERLAY)
static void gst_time_overlay_base_init (gpointer g_class)
{ {
/* FILL ME */
LAST_SIGNAL
};
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);
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);
GType
gst_timeoverlay_get_type (void)
{
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,
};
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_base_init (gpointer g_class)
{
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); GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
GstVideofilterClass *videofilter_class = GST_VIDEOFILTER_CLASS (g_class);
int i;
gst_element_class_set_details (element_class, &timeoverlay_details); gst_element_class_set_details (element_class, &time_overlay_details);
}
for (i = 0; i < G_N_ELEMENTS (gst_timeoverlay_formats); i++) { static gchar *
gst_videofilter_class_add_format (videofilter_class, gst_time_overlay_render_time (GstTimeOverlay * overlay, GstClockTime time)
gst_timeoverlay_formats + i); {
guint hours, mins, secs, msecs;
if (!GST_CLOCK_TIME_IS_VALID (time))
return g_strdup ("");
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));
return g_strdup_printf ("%u:%02u:%02u.%03u", hours, mins, secs, msecs);
}
static gchar *
gst_time_overlay_get_text (GstTextOverlay * overlay, GstBuffer * video_frame)
{
GstClockTime time = GST_BUFFER_TIMESTAMP (video_frame);
gchar *time_str, *txt, *ret;
overlay->need_render = TRUE;
if (!GST_CLOCK_TIME_IS_VALID (time)) {
GST_DEBUG ("buffer without valid timestamp");
return g_strdup ("");
} }
gst_videofilter_class_add_pad_templates (GST_VIDEOFILTER_CLASS (g_class)); GST_DEBUG ("buffer with timestamp %" GST_TIME_FORMAT, GST_TIME_ARGS (time));
}
static void GST_OBJECT_LOCK (overlay);
gst_timeoverlay_class_init (gpointer g_class, gpointer class_data) txt = g_strdup (overlay->default_text);
{ GST_OBJECT_UNLOCK (overlay);
GObjectClass *gobject_class;
GstVideofilterClass *videofilter_class;
gobject_class = G_OBJECT_CLASS (g_class); time_str = gst_time_overlay_render_time (GST_TIME_OVERLAY (overlay), time);
videofilter_class = GST_VIDEOFILTER_CLASS (g_class); if (txt != NULL && *txt != '\0') {
ret = g_strdup_printf ("%s %s", txt, time_str);
#if 0 } else {
g_object_class_install_property (gobject_class, ARG_METHOD, ret = time_str;
g_param_spec_enum ("method", "method", "method", time_str = NULL;
GST_TYPE_TIMEOVERLAY_METHOD, GST_TIMEOVERLAY_METHOD_1,
G_PARAM_READWRITE));
#endif
gobject_class->set_property = gst_timeoverlay_set_property;
gobject_class->get_property = gst_timeoverlay_get_property;
videofilter_class->setup = gst_timeoverlay_setup;
}
static void
gst_timeoverlay_init (GTypeInstance * instance, gpointer g_class)
{
GstTimeoverlay *timeoverlay = GST_TIMEOVERLAY (instance);
GstVideofilter *videofilter;
GST_DEBUG ("gst_timeoverlay_init");
videofilter = GST_VIDEOFILTER (timeoverlay);
/* do stuff */
}
static void
gst_timeoverlay_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec)
{
GstTimeoverlay *src;
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;
} }
g_free (txt);
g_free (time_str);
return ret;
} }
static void static void
gst_timeoverlay_get_property (GObject * object, guint prop_id, GValue * value, gst_time_overlay_class_init (GstTimeOverlayClass * klass)
GParamSpec * pspec)
{ {
GstTimeoverlay *src; GstTextOverlayClass *gsttextoverlay_class;
g_return_if_fail (GST_IS_TIMEOVERLAY (object)); gsttextoverlay_class = (GstTextOverlayClass *) klass;
src = GST_TIMEOVERLAY (object);
switch (prop_id) { gsttextoverlay_class->get_text = gst_time_overlay_get_text;
#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 static void
plugin_init (GstPlugin * plugin) gst_time_overlay_init (GstTimeOverlay * overlay, GstTimeOverlayClass * klass)
{ {
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; PangoFontDescription *font_description;
GstTextOverlay *textoverlay;
PangoContext *context; PangoContext *context;
g_return_if_fail (GST_IS_TIMEOVERLAY (videofilter)); textoverlay = GST_TEXT_OVERLAY (overlay);
timeoverlay = GST_TIMEOVERLAY (videofilter);
/* if any setup needs to be done, do it here */ context = GST_TEXT_OVERLAY_CLASS (klass)->pango_context;
/* 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_language (context, pango_language_from_string ("en_US"));
pango_context_set_base_dir (context, PANGO_DIRECTION_LTR); 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_variant (font_description, PANGO_VARIANT_NORMAL);
pango_font_description_set_weight (font_description, PANGO_WEIGHT_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_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_context_set_font_description (context, font_description);
pango_font_description_free (font_description);
timeoverlay->context = context; textoverlay->valign = GST_TEXT_OVERLAY_VALIGN_TOP;
timeoverlay->font_description = font_description; textoverlay->halign = GST_TEXT_OVERLAY_HALIGN_LEFT;
}
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);
} }

View file

@ -1,5 +1,6 @@
/* GStreamer /* GStreamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu> * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
* Copyright (C) <2005> Tim-Philipp Müller <tim@centricular.net>
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public * modify it under the terms of the GNU Library General Public
@ -18,47 +19,38 @@
*/ */
#ifndef __GST_TIMEOVERLAY_H__ #ifndef __GST_TIME_OVERLAY_H__
#define __GST_TIMEOVERLAY_H__ #define __GST_TIME_OVERLAY_H__
#include <gst/gst.h>
#include <pango/pango.h>
#include "gstvideofilter.h"
#include "gsttextoverlay.h"
G_BEGIN_DECLS G_BEGIN_DECLS
#define GST_TYPE_TIMEOVERLAY \ #define GST_TYPE_TIME_OVERLAY \
(gst_timeoverlay_get_type()) (gst_time_overlay_get_type())
#define GST_TIMEOVERLAY(obj) \ #define GST_TIME_OVERLAY(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_TIMEOVERLAY,GstTimeoverlay)) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_TIME_OVERLAY,GstTimeOverlay))
#define GST_TIMEOVERLAY_CLASS(klass) \ #define GST_TIME_OVERLAY_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_TIMEOVERLAY,GstTimeoverlayClass)) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_TIME_OVERLAY,GstTimeOverlayClass))
#define GST_IS_TIMEOVERLAY(obj) \ #define GST_IS_TIME_OVERLAY(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_TIMEOVERLAY)) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_TIME_OVERLAY))
#define GST_IS_TIMEOVERLAY_CLASS(obj) \ #define GST_IS_TIME_OVERLAY_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_TIMEOVERLAY)) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_TIME_OVERLAY))
typedef struct _GstTimeoverlay GstTimeoverlay; typedef struct _GstTimeOverlay GstTimeOverlay;
typedef struct _GstTimeoverlayClass GstTimeoverlayClass; typedef struct _GstTimeOverlayClass GstTimeOverlayClass;
struct _GstTimeoverlay {
GstVideofilter videofilter;
PangoFontDescription *font_description;
PangoContext *context;
struct _GstTimeOverlay {
GstTextOverlay textoverlay;
}; };
struct _GstTimeoverlayClass { struct _GstTimeOverlayClass {
GstVideofilterClass parent_class; GstTextOverlayClass parent_class;
}; };
GType gst_timeoverlay_get_type(void); GType gst_time_overlay_get_type (void);
G_END_DECLS G_END_DECLS
#endif /* __GST_TIMEOVERLAY_H__ */ #endif /* __GST_TIME_OVERLAY_H__ */