summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Schmidt <thaytan@mad.scientist.com>2005-07-01 16:52:35 +0000
committerRonald S. Bultje <rbultje@ronald.bitfreak.net>2005-07-01 16:52:35 +0000
commite997c35f5429cccdc7816879ef29685e0a738b55 (patch)
treebfabf699e21f76a5de8b2515875a94a8b2869297
parent9b7ca34ee317fc30d3166a71219aa1f56588f3e2 (diff)
downloadgstreamer-plugins-base-e997c35f5429cccdc7816879ef29685e0a738b55.tar.gz
configure.ac: Add imagemixer/dvdsubdec.
Original commit message from CVS: * configure.ac: Add imagemixer/dvdsubdec. * ext/dvdnav/dvdnavsrc.c: (dvdnav_build_titlelang_event): For menu subpicture streams, set a name too, so dvddemux picks it up and can still validly emit no-more-pads. * ext/dvdnav/gst-dvd-2: Example. * ext/pango/Makefile.am: * ext/pango/gsttextoverlay.c: (plugin_init): * ext/pango/gsttextrender.c: (gst_text_render_get_type), (gst_text_render_base_init), (gst_text_render_class_init), (resize_bitmap), (render_text), (gst_text_render_link), (gst_text_render_fixate), (gst_text_overlay_blit_yuv420), (gst_text_render_chain), (gst_text_render_finalize), (gst_text_render_init), (gst_text_render_set_property), (gst_text_render_get_property): * ext/pango/gsttextrender.h: Chain-based text-rendering element (#306555). * gst/dvdsubdec/Makefile.am: * gst/dvdsubdec/dvdsubdec.c: (gst_dvdsubdec_get_type), (gst_dvdsubdec_base_init), (gst_dvdsubdec_class_init), (gst_dvdsubdec_init), (gst_dvdsubdec_finalize), (gst_dvdsubdec_getcaps_video), (gst_dvdsubdec_link_video), (gst_dvdsubdec_src_event), (dvdsubdec_get_event_delay), (gst_dvdsubdec_parse_subpic), (gst_get_nibble), (gst_setup_palette), (gst_get_rle_code), (gst_draw_rle_line), (gst_dvdsubdec_merge_title), (gst_send_empty_fill), (gst_send_subtitle_frame), (dvdsubdec_advance_time), (gst_dvdsubdec_handle_subtitle), (gst_dvdsubdec_handle_dvd_event), (plugin_init): Chain-based DVD subtitle decoder element (#301312), based on patch by Jan Schmidt <thaytan@mad.scientist.com>. * gst/ffmpegcolorspace/gstffmpegcodecmap.c: (gst_ffmpeg_pixfmt_to_caps), (gst_ffmpeg_caps_to_pixfmt): * gst/ffmpegcolorspace/imgconvert.c: * gst/ffmpegcolorspace/imgconvert_template.h: Conserve alpha channel for BGRA32->AYUV, fix BGRA/BGRX masks (#308638). * gst/imagemixer/Makefile.am: * gst/imagemixer/README: * gst/imagemixer/blend.c: * gst/imagemixer/blend.h: * gst/imagemixer/mixer.c: (gst_image_mixer_base_init), (gst_image_mixer_class_init), (gst_image_mixer_init), (gst_image_mixer_request_pad), (gst_image_mixer_release_pad), (gst_image_mixer_fixate), (gst_image_mixer_get_caps), (gst_image_mixer_set_caps), (gst_image_mixer_read_a), (gst_image_mixer_read_y), (gst_image_mixer_read_u_v), (gst_image_mixer_do_mix_i420), (gst_image_mixer_do_mix_yuy2), (gst_image_mixer_do_mix_x444), (gst_image_mixer_do_mix_y444), (gst_image_mixer_do_mix_ayuv), (gst_image_mixer_do_mix), (is_past_end), (gst_image_mixer_blend_subpicture), (gst_image_mixer_src_event), (gst_image_mixer_handle_sink_event), (cb_compare), (gst_image_mixer_loop), (gst_image_mixer_change_state): * gst/imagemixer/mixer.h: * gst/imagemixer/mixerpad.c: (gst_image_mixer_pad_v_align_get_type), (gst_image_mixer_pad_h_align_get_type), (gst_image_mixer_pad_set_property), (gst_image_mixer_pad_get_property), (gst_image_mixer_pad_class_init), (gst_image_mixer_pad_init): * gst/imagemixer/mixerpad.h: * gst/imagemixer/plugin.c: (plugin_init): Image-mixing element, in the style of the pango textrendering element, but image- instead of text-based, including all cool stuff like seeking, overlays, picture-in-picture, DVD subtitle support, text subtitle support and everything. Can do negative z-orders for inverted overlay (force to AYUV in that case) so it can be used for chroma-keying software, too (#166783). * gst/imagemixer/test-dvd-subtitle.sh: Example. * gst/mpegstream/gstdvddemux.c: (gst_dvd_demux_init), (gst_dvd_demux_handle_dvd_event), (gst_dvd_demux_handle_discont), (gst_dvd_demux_send_subbuffer), (gst_dvd_demux_reset), (gst_dvd_demux_change_state): * gst/mpegstream/gstdvddemux.h: * gst/mpegstream/gstmpegdemux.c: (gst_mpeg_demux_reset): Implement no-more-pads if the source knows the amount of pads, which dvd sources known from the IFO files. * gst/playback/gstplaybasebin.c: (gst_play_base_bin_class_init), (group_is_muted), (gen_preroll_element), (probe_triggered), (has_subtitle_ancestor), (new_decoded_pad), (gst_play_base_bin_set_property), (gst_play_base_bin_get_property): * gst/playback/gstplaybasebin.h: Implement subpicture pad support. * gst/playback/gstplaybin.c: (gen_video_element), (gen_subtitle_element), (gen_audio_element), (remove_sinks), (add_sink), (setup_sinks): Changes so we support subtitles in a more generic way and thus support DVD subtitles and menus in addition to text subtitles. * gst/playback/gststreaminfo.c: (gst_stream_type_get_type): * gst/playback/gststreaminfo.h: Subpicture type. * gst/playback/gststreamselector.c: (gst_stream_selector_chain): Event handling. * gst/videomixer/videomixer.c: (gst_videomixer_fill_queues), (gst_videomixer_update_queues): Do EOS correctly for endless streams on mainpad, while other pads are infinite (e.g. single picture; #309179).
m---------common0
-rw-r--r--ext/pango/Makefile.am4
-rw-r--r--ext/pango/gsttextoverlay.c7
-rw-r--r--ext/pango/gsttextrender.c421
-rw-r--r--ext/pango/gsttextrender.h47
5 files changed, 475 insertions, 4 deletions
diff --git a/common b/common
-Subproject 131c2632127e6f061b5270d8f80651782a4fdd1
+Subproject 4ca96aedcf2be0b3dcf31fce732aed1da21b885
diff --git a/ext/pango/Makefile.am b/ext/pango/Makefile.am
index 2ec7e4ea0..83e620e77 100644
--- a/ext/pango/Makefile.am
+++ b/ext/pango/Makefile.am
@@ -4,14 +4,14 @@
plugin_LTLIBRARIES = libgsttimeoverlay.la libgsttextoverlay.la
-noinst_HEADERS = gsttimeoverlay.h gsttextoverlay.h
+noinst_HEADERS = gsttimeoverlay.h gsttextoverlay.h gsttextrender.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
-libgsttextoverlay_la_SOURCES = gsttextoverlay.c
+libgsttextoverlay_la_SOURCES = gsttextoverlay.c gsttextrender.c
libgsttextoverlay_la_CFLAGS = $(GST_CFLAGS) $(PANGO_CFLAGS)
libgsttextoverlay_la_LIBADD =
libgsttextoverlay_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) $(PANGO_LIBS)
diff --git a/ext/pango/gsttextoverlay.c b/ext/pango/gsttextoverlay.c
index 57c0ce4a2..572d0534e 100644
--- a/ext/pango/gsttextoverlay.c
+++ b/ext/pango/gsttextoverlay.c
@@ -22,9 +22,10 @@
#include <config.h>
#endif
#include <gst/gst.h>
+#include "gsttextrender.h"
#include "gsttextoverlay.h"
-GST_DEBUG_CATEGORY_STATIC (pango_debug);
+GST_DEBUG_CATEGORY (pango_debug);
#define GST_CAT_DEFAULT pango_debug
static GstElementDetails textoverlay_details = {
@@ -810,7 +811,9 @@ static gboolean
plugin_init (GstPlugin * plugin)
{
if (!gst_element_register (plugin, "textoverlay", GST_RANK_NONE,
- GST_TYPE_TEXTOVERLAY))
+ GST_TYPE_TEXTOVERLAY) ||
+ !gst_element_register (plugin, "textrender", GST_RANK_NONE,
+ GST_TYPE_TEXT_RENDER))
return FALSE;
/*texttestsrc_plugin_init(module, plugin); */
diff --git a/ext/pango/gsttextrender.c b/ext/pango/gsttextrender.c
new file mode 100644
index 000000000..9891accea
--- /dev/null
+++ b/ext/pango/gsttextrender.c
@@ -0,0 +1,421 @@
+/* GStreamer
+ * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
+ * Copyright (C) <2003> David Schleef <ds@schleef.org>
+ *
+ * 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 <gst/gst.h>
+#include "gsttextrender.h"
+
+GST_DEBUG_CATEGORY_EXTERN (pango_debug);
+#define GST_CAT_DEFAULT pango_debug
+
+static GstElementDetails text_render_details = {
+ "Text Render",
+ "Filter/Editor/Video",
+ "Renders a text string to a image bitmap",
+ "David Schleef <ds@schleef.org>, "
+ "Ronald S. Bultje <rbultje@ronald.bitfreak.net>"
+};
+
+enum
+{
+ ARG_0,
+ ARG_FONT_DESC
+};
+
+
+static GstStaticPadTemplate src_template_factory =
+GST_STATIC_PAD_TEMPLATE ("src",
+ GST_PAD_SRC,
+ GST_PAD_ALWAYS,
+ GST_STATIC_CAPS ("video/x-raw-yuv, "
+ "format = (fourcc) AYUV, "
+ "width = (int) [ 1, MAX ], "
+ "height = (int) [ 1, MAX ], framerate = (double) 1")
+ );
+
+static GstStaticPadTemplate sink_template_factory =
+ GST_STATIC_PAD_TEMPLATE ("sink",
+ GST_PAD_SINK,
+ GST_PAD_ALWAYS,
+ GST_STATIC_CAPS ("text/x-pango-markup; text/plain")
+ );
+
+static void gst_text_render_base_init (gpointer g_class);
+static void gst_text_render_class_init (GstTextRenderClass * klass);
+static void gst_text_render_init (GstTextRender * overlay);
+static void gst_text_render_set_property (GObject * object,
+ guint prop_id, const GValue * value, GParamSpec * pspec);
+static void gst_text_render_get_property (GObject * object,
+ guint prop_id, GValue * value, GParamSpec * pspec);
+static void gst_text_render_finalize (GObject * object);
+
+static GstElementClass *parent_class = NULL;
+
+/*static guint gst_text_render_signals[LAST_SIGNAL] = { 0 }; */
+
+GType
+gst_text_render_get_type (void)
+{
+ static GType text_render_type = 0;
+
+ if (!text_render_type) {
+ static const GTypeInfo text_render_info = {
+ sizeof (GstTextRenderClass),
+ gst_text_render_base_init,
+ NULL,
+ (GClassInitFunc) gst_text_render_class_init,
+ NULL,
+ NULL,
+ sizeof (GstTextRender),
+ 0,
+ (GInstanceInitFunc) gst_text_render_init,
+ };
+
+ text_render_type =
+ g_type_register_static (GST_TYPE_ELEMENT, "GstTextRender",
+ &text_render_info, 0);
+ }
+ return text_render_type;
+}
+
+static void
+gst_text_render_base_init (gpointer g_class)
+{
+ GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
+
+ gst_element_class_add_pad_template (element_class,
+ gst_static_pad_template_get (&src_template_factory));
+ gst_element_class_add_pad_template (element_class,
+ gst_static_pad_template_get (&sink_template_factory));
+
+ gst_element_class_set_details (element_class, &text_render_details);
+}
+
+static void
+gst_text_render_class_init (GstTextRenderClass * klass)
+{
+ GObjectClass *gobject_class;
+ GstElementClass *gstelement_class;
+
+ gobject_class = (GObjectClass *) klass;
+ gstelement_class = (GstElementClass *) klass;
+
+ parent_class = g_type_class_peek_parent (klass);
+
+ gobject_class->finalize = gst_text_render_finalize;
+ gobject_class->set_property = gst_text_render_set_property;
+ gobject_class->get_property = gst_text_render_get_property;
+
+ klass->pango_context = pango_ft2_get_context (72, 72);
+ g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_FONT_DESC,
+ g_param_spec_string ("font-desc", "font description",
+ "Pango font description of font "
+ "to be used for rendering. "
+ "See documentation of "
+ "pango_font_description_from_string"
+ " for syntax.", "", G_PARAM_WRITABLE));
+}
+
+
+static void
+resize_bitmap (GstTextRender * overlay, int width, int height)
+{
+ FT_Bitmap *bitmap = &overlay->bitmap;
+ int pitch = (width | 3) + 1;
+ int size = pitch * height;
+
+ /* no need to keep reallocating; just keep the maximum size so far */
+ if (size <= overlay->bitmap_buffer_size) {
+ bitmap->rows = height;
+ bitmap->width = width;
+ bitmap->pitch = pitch;
+ memset (bitmap->buffer, 0, overlay->bitmap_buffer_size);
+ return;
+ }
+ if (!bitmap->buffer) {
+ /* initialize */
+ bitmap->pixel_mode = ft_pixel_mode_grays;
+ bitmap->num_grays = 256;
+ }
+ if (bitmap->buffer)
+ bitmap->buffer = g_realloc (bitmap->buffer, size);
+ else
+ bitmap->buffer = g_malloc (size);
+ bitmap->rows = height;
+ bitmap->width = width;
+ bitmap->pitch = pitch;
+ memset (bitmap->buffer, 0, size);
+ overlay->bitmap_buffer_size = size;
+}
+
+static void
+render_text (GstTextRender * overlay)
+{
+ PangoRectangle ink_rect, logical_rect;
+
+ pango_layout_get_pixel_extents (overlay->layout, &ink_rect, &logical_rect);
+ resize_bitmap (overlay, ink_rect.width, ink_rect.height + ink_rect.y);
+ pango_ft2_render_layout (&overlay->bitmap, overlay->layout, -ink_rect.x, 0);
+ overlay->baseline_y = ink_rect.y;
+}
+
+static GstPadLinkReturn
+gst_text_render_link (GstPad * pad, const GstCaps * caps)
+{
+ GstTextRender *overlay = GST_TEXT_RENDER (gst_pad_get_parent (pad));
+ GstStructure *structure;
+
+ structure = gst_caps_get_structure (caps, 0);
+ overlay->width = overlay->height = 0;
+ gst_structure_get_int (structure, "width", &overlay->width);
+ gst_structure_get_int (structure, "height", &overlay->height);
+
+ return GST_PAD_LINK_OK;
+}
+
+static GstCaps *
+gst_text_render_fixate (GstPad * pad, const GstCaps * caps)
+{
+ GstTextRender *overlay = GST_TEXT_RENDER (gst_pad_get_parent (pad));
+ GstCaps *copy = gst_caps_copy (caps);
+ GstStructure *s = gst_caps_get_structure (copy, 0);
+
+ if (gst_caps_structure_fixate_field_nearest_int (s, "width",
+ overlay->bitmap.width) ||
+ gst_caps_structure_fixate_field_nearest_int (s, "height",
+ overlay->bitmap.rows))
+ return copy;
+
+ gst_caps_free (copy);
+
+ return NULL;
+}
+
+static void
+gst_text_overlay_blit_yuv420 (GstTextRender * overlay, FT_Bitmap * bitmap,
+ guchar * pixbuf, int x0, int y0)
+{
+ int y; /* text bitmap coordinates */
+ int x1, y1; /* video buffer coordinates */
+ int rowinc, bit_rowinc;
+ guchar *p, *bitp;
+ int video_width = overlay->width, video_height = overlay->height;
+ int bitmap_x0 = 0; //x0 < 1 ? -(x0 - 1) : 1; /* 1 pixel border */
+ int bitmap_y0 = y0 < 1 ? -(y0 - 1) : 1; /* 1 pixel border */
+ int bitmap_width = bitmap->width - bitmap_x0;
+ int bitmap_height = bitmap->rows - bitmap_y0;
+ int skip_y, skip_x;
+ guchar v;
+
+ if (x0 + bitmap_x0 + bitmap_width > video_width - 1) /* 1 pixel border */
+ bitmap_width -= x0 + bitmap_x0 + bitmap_width - video_width + 1;
+ if (y0 + bitmap_y0 + bitmap_height > video_height - 1) /* 1 pixel border */
+ bitmap_height -= y0 + bitmap_y0 + bitmap_height - video_height + 1;
+
+ rowinc = video_width - bitmap_width;
+ bit_rowinc = bitmap->pitch - bitmap_width;
+
+ y1 = y0 + bitmap_y0;
+ x1 = x0 + bitmap_x0;
+ p = pixbuf + 1 + (video_width * y1 + x1) * 4;
+ bitp = bitmap->buffer + bitmap->pitch * bitmap_y0 + bitmap_x0;
+ for (y = bitmap_y0; y < bitmap_y0 + bitmap_height; y++) {
+ int n;
+
+ for (n = bitmap_width; n > 0; --n) {
+ v = *bitp;
+ if (v) {
+ p[-4] = CLAMP (p[-4] - v, 0, 255);
+ p[4] = CLAMP (p[4] - v, 0, 255);
+ p[-4 * video_width] = CLAMP (p[-4 * video_width] - v, 0, 255);
+ p[4 * video_width] = CLAMP (p[4 * video_width] - v, 0, 255);
+ }
+ p += 4;
+ bitp++;
+ }
+ p += rowinc * 4;
+ bitp += bit_rowinc;
+ }
+
+ y1 = y0 + bitmap_y0;
+ x1 = x0 + bitmap_x0;
+ bitp = bitmap->buffer + bitmap->pitch * bitmap_y0 + bitmap_x0;
+ p = pixbuf + (video_width * y1 + x1) * 4;
+ skip_y = 0;
+ skip_x = 0;
+
+ for (y = bitmap_y0; y < bitmap_y0 + bitmap_height; y++) {
+ int n;
+
+ x1 = x0 + bitmap_x0;
+ skip_x = 0;
+ for (n = bitmap_width; n > 0; --n) {
+ v = *bitp;
+ if (v) {
+ p[0] = v;
+ p[1] = 255;
+ p[2] = p[3] = 0x80;
+ }
+ p += 4;
+ bitp++;
+ }
+ /*if (!skip_x && !skip_y) u_p--; */
+ p += rowinc * 4;
+ bitp += bit_rowinc;
+ }
+}
+
+
+static void
+gst_text_render_chain (GstPad * pad, GstData * _data)
+{
+ GstBuffer *buf = GST_BUFFER (_data), *out;
+ GstTextRender *overlay = GST_TEXT_RENDER (gst_pad_get_parent (pad));
+ guint size = GST_BUFFER_SIZE (buf);
+ guint8 *data = GST_BUFFER_DATA (buf);
+
+ /* somehow pango barfs over "\0" buffers... */
+ while (size > 0 &&
+ (data[size - 1] == '\r' ||
+ data[size - 1] == '\n' || data[size - 1] == '\0')) {
+ size--;
+ }
+
+ /* render text */
+ GST_DEBUG ("rendering '%*s'", size, data);
+ pango_layout_set_markup (overlay->layout, (gchar *) data, size);
+ render_text (overlay);
+
+ if (GST_PAD_LINK_FAILED (gst_pad_renegotiate (overlay->srcpad))) {
+ GST_ELEMENT_ERROR (overlay, CORE, NEGOTIATION, (NULL), (NULL));
+ return;
+ }
+
+ /* put in a buffer */
+ out = gst_buffer_new_and_alloc (overlay->width * overlay->height * 4);
+ gst_buffer_stamp (out, GST_BUFFER (buf));
+// gst_buffer_stamp (out, buf);
+ data = GST_BUFFER_DATA (out);
+ gint n;
+
+ for (n = 0; n < overlay->width * overlay->height; n++) {
+ data[n * 4] = 0;
+ data[n * 4 + 1] = 0;
+ data[n * 4 + 2] = data[n * 4 + 3] = 128;
+ }
+ if (overlay->bitmap.buffer) {
+ gst_text_overlay_blit_yuv420 (overlay, &overlay->bitmap, data, 0, 0);
+ }
+ gst_data_unref (_data);
+
+ gst_pad_push (overlay->srcpad, GST_DATA (out));
+}
+
+static void
+gst_text_render_finalize (GObject * object)
+{
+ GstTextRender *overlay = GST_TEXT_RENDER (object);
+
+ if (overlay->layout) {
+ g_object_unref (overlay->layout);
+ overlay->layout = NULL;
+ }
+ if (overlay->bitmap.buffer) {
+ g_free (overlay->bitmap.buffer);
+ overlay->bitmap.buffer = NULL;
+ }
+
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+gst_text_render_init (GstTextRender * overlay)
+{
+ /* sink */
+ overlay->sinkpad =
+ gst_pad_new_from_template (gst_static_pad_template_get
+ (&sink_template_factory), "sink");
+ gst_pad_set_chain_function (overlay->sinkpad, gst_text_render_chain);
+ gst_element_add_pad (GST_ELEMENT (overlay), overlay->sinkpad);
+
+ /* source */
+ overlay->srcpad =
+ gst_pad_new_from_template (gst_static_pad_template_get
+ (&src_template_factory), "src");
+ gst_pad_set_link_function (overlay->srcpad, gst_text_render_link);
+ gst_pad_set_fixate_function (overlay->srcpad, gst_text_render_fixate);
+ gst_element_add_pad (GST_ELEMENT (overlay), overlay->srcpad);
+
+ overlay->layout =
+ pango_layout_new (GST_TEXT_RENDER_GET_CLASS (overlay)->pango_context);
+ memset (&overlay->bitmap, 0, sizeof (overlay->bitmap));
+}
+
+
+static void
+gst_text_render_set_property (GObject * object, guint prop_id,
+ const GValue * value, GParamSpec * pspec)
+{
+ GstTextRender *overlay;
+
+ /* it's not null if we got it, but it might not be ours */
+ g_return_if_fail (GST_IS_TEXT_RENDER (object));
+ overlay = GST_TEXT_RENDER (object);
+
+ switch (prop_id) {
+ case ARG_FONT_DESC:
+ {
+ PangoFontDescription *desc;
+
+ desc = pango_font_description_from_string (g_value_get_string (value));
+ if (desc) {
+ GST_LOG ("font description set: %s", g_value_get_string (value));
+ pango_layout_set_font_description (overlay->layout, desc);
+ pango_font_description_free (desc);
+ render_text (overlay);
+ } else
+ GST_WARNING ("font description parse failed: %s",
+ g_value_get_string (value));
+ break;
+ }
+
+ default:
+ break;
+ }
+}
+
+static void
+gst_text_render_get_property (GObject * object, guint prop_id, GValue * value,
+ GParamSpec * pspec)
+{
+ GstTextRender *overlay;
+
+ /* it's not null if we got it, but it might not be ours */
+ g_return_if_fail (GST_IS_TEXT_RENDER (object));
+ overlay = GST_TEXT_RENDER (object);
+
+ switch (prop_id) {
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
diff --git a/ext/pango/gsttextrender.h b/ext/pango/gsttextrender.h
new file mode 100644
index 000000000..f90bb1e4d
--- /dev/null
+++ b/ext/pango/gsttextrender.h
@@ -0,0 +1,47 @@
+/* -*- Mode: C; c-file-style: "stroustrup" -*- */
+#ifndef __GST_TEXT_RENDER_H__
+#define __GST_TEXT_RENDER_H__
+
+#include <gst/gst.h>
+#include <pango/pangoft2.h>
+
+G_BEGIN_DECLS
+
+#define GST_TYPE_TEXT_RENDER (gst_text_render_get_type())
+#define GST_TEXT_RENDER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),\
+ GST_TYPE_TEXT_RENDER, GstTextRender))
+#define GST_TEXT_RENDER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),\
+ GST_TYPE_ULAW, GstTextRender))
+#define GST_TEXT_RENDER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj),\
+ GST_TYPE_TEXT_RENDER, GstTextRenderClass))
+#define GST_IS_TEXT_RENDER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),\
+ GST_TYPE_TEXT_RENDER))
+#define GST_IS_TEXT_RENDER_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE((klass),\
+ GST_TYPE_TEXT_RENDER))
+
+typedef struct _GstTextRender GstTextRender;
+typedef struct _GstTextRenderClass GstTextRenderClass;
+
+struct _GstTextRender {
+ GstElement element;
+
+ GstPad *sinkpad, *srcpad;
+ gint width;
+ gint height;
+ PangoLayout *layout;
+ FT_Bitmap bitmap;
+ gint bitmap_buffer_size;
+ gint baseline_y;
+};
+
+struct _GstTextRenderClass {
+ GstElementClass parent_class;
+
+ PangoContext *pango_context;
+};
+
+GType gst_text_render_get_type(void) G_GNUC_CONST;
+
+G_END_DECLS
+
+#endif /* __GST_TEXT_RENDER_H */