summaryrefslogtreecommitdiffstats
path: root/ext/cairo/gsttimeoverlay.c
diff options
context:
space:
mode:
authorJulien Moutte <julien@moutte.net>2005-11-23 15:50:51 +0000
committerJulien Moutte <julien@moutte.net>2005-11-23 15:50:51 +0000
commit2ea4f5b3c92819681f2d9e6f5f8d014b4d179344 (patch)
treedb8696ff4b83e3f0ea882402e3435d8dacdbb488 /ext/cairo/gsttimeoverlay.c
parent48520a455d828b4a6885fb37be48ebb720ae259b (diff)
VideoFilter inherits from
Original commit message from CVS: 2005-11-23 Julien MOUTTE <julien@moutte.net> * ext/cairo/gsttimeoverlay.c: (gst_timeoverlay_update_font_height), (gst_timeoverlay_set_caps), (gst_timeoverlay_get_unit_size), (gst_timeoverlay_transform), (gst_timeoverlay_base_init), (gst_timeoverlay_class_init), (gst_timeoverlay_init), (gst_timeoverlay_get_type): * ext/cairo/gsttimeoverlay.h: * gst/debug/Makefile.am: * gst/debug/gstnavigationtest.c: (gst_navigationtest_handle_src_event), (gst_navigationtest_get_unit_size), (gst_navigationtest_set_caps), (gst_navigationtest_transform), (gst_navigationtest_change_state), (gst_navigationtest_base_init), (gst_navigationtest_class_init), (gst_navigationtest_init), (gst_navigationtest_get_type), (plugin_init): * gst/debug/gstnavigationtest.h: * gst/effectv/Makefile.am: * gst/effectv/gstaging.c: (gst_agingtv_set_caps), (gst_agingtv_get_unit_size), (gst_agingtv_transform), (gst_agingtv_base_init), (gst_agingtv_class_init), (gst_agingtv_init), (gst_agingtv_get_type): * gst/effectv/gstdice.c: (gst_dicetv_set_caps), (gst_dicetv_get_unit_size), (gst_dicetv_transform), (gst_dicetv_base_init), (gst_dicetv_class_init), (gst_dicetv_init), (gst_dicetv_get_type): * gst/effectv/gstedge.c: (gst_edgetv_set_caps), (gst_edgetv_get_unit_size), (gst_edgetv_transform), (gst_edgetv_base_init), (gst_edgetv_class_init), (gst_edgetv_init), (gst_edgetv_get_type): * gst/effectv/gsteffectv.c: * gst/effectv/gsteffectv.h: * gst/effectv/gstquark.c: (gst_quarktv_set_caps), (gst_quarktv_get_unit_size), (fastrand), (gst_quarktv_transform), (gst_quarktv_change_state), (gst_quarktv_base_init), (gst_quarktv_class_init), (gst_quarktv_init), (gst_quarktv_get_type): * gst/effectv/gstrev.c: (gst_revtv_set_caps), (gst_revtv_get_unit_size), (gst_revtv_transform), (gst_revtv_base_init), (gst_revtv_class_init), (gst_revtv_init), (gst_revtv_get_type): * gst/effectv/gstshagadelic.c: (gst_shagadelictv_set_caps), (gst_shagadelictv_get_unit_size), (gst_shagadelictv_transform), (gst_shagadelictv_base_init), (gst_shagadelictv_class_init), (gst_shagadelictv_init), (gst_shagadelictv_get_type): * gst/effectv/gstvertigo.c: (gst_vertigotv_set_caps), (gst_vertigotv_get_unit_size), (gst_vertigotv_transform), (gst_vertigotv_base_init), (gst_vertigotv_class_init), (gst_vertigotv_init), (gst_vertigotv_get_type): * gst/effectv/gstwarp.c: (gst_warptv_set_caps), (gst_warptv_get_unit_size), (gst_warptv_transform), (gst_warptv_base_init), (gst_warptv_class_init), (gst_warptv_init), (gst_warptv_get_type): * gst/videofilter/Makefile.am: * gst/videofilter/gstvideobalance.c: * gst/videofilter/gstvideobalance.h: * gst/videofilter/gstvideofilter.c: (gst_videofilter_get_type), (gst_videofilter_class_init), (gst_videofilter_init): * gst/videofilter/gstvideofilter.h: * gst/videofilter/gstvideoflip.c: (gst_videoflip_set_caps), (gst_videoflip_transform_caps), (gst_videoflip_get_unit_size), (gst_videoflip_flip), (gst_videoflip_transform), (gst_videoflip_handle_src_event), (gst_videoflip_set_property), (gst_videoflip_base_init), (gst_videoflip_class_init), (gst_videoflip_init), (plugin_init), (gst_videoflip_get_type): * gst/videofilter/gstvideoflip.h: VideoFilter inherits from BaseTransform, it's just a place holder for now and every video effect plugin has been ported to use BaseTransform features directly. QuarkTV was fixed too (was broken), navigationtest works and best for the end, videoflip converts navigation events depending on flip method ! Fixes #320953
Diffstat (limited to 'ext/cairo/gsttimeoverlay.c')
-rw-r--r--ext/cairo/gsttimeoverlay.c328
1 files changed, 150 insertions, 178 deletions
diff --git a/ext/cairo/gsttimeoverlay.c b/ext/cairo/gsttimeoverlay.c
index 6016d941..7fc7bd9f 100644
--- a/ext/cairo/gsttimeoverlay.c
+++ b/ext/cairo/gsttimeoverlay.c
@@ -27,179 +27,47 @@
#include "config.h"
#endif
-/*#define DEBUG_ENABLED */
#include <gsttimeoverlay.h>
+
#include <string.h>
#include <math.h>
#include <cairo.h>
+#include <gst/video/video.h>
-/* GstTimeoverlay signals and args */
-enum
-{
- /* 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);
- GstVideofilterClass *videofilter_class = GST_VIDEOFILTER_CLASS (g_class);
- int i;
-
- gst_element_class_set_details (element_class, &timeoverlay_details);
-
- for (i = 0; i < G_N_ELEMENTS (gst_timeoverlay_formats); i++) {
- gst_videofilter_class_add_format (videofilter_class,
- gst_timeoverlay_formats + i);
- }
-
- gst_videofilter_class_add_pad_templates (GST_VIDEOFILTER_CLASS (g_class));
-}
-
-static void
-gst_timeoverlay_class_init (gpointer g_class, gpointer class_data)
-{
- GObjectClass *gobject_class;
- GstVideofilterClass *videofilter_class;
-
- gobject_class = G_OBJECT_CLASS (g_class);
- videofilter_class = GST_VIDEOFILTER_CLASS (g_class);
-
-#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
-
- 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");
+static GstElementDetails timeoverlay_details =
+GST_ELEMENT_DETAILS ("Time Overlay",
+ "Filter/Editor/Video",
+ "Overlays the time on a video stream",
+ "David Schleef <ds@schleef.org>");
- videofilter = GST_VIDEOFILTER (timeoverlay);
-
- /* do stuff */
-}
-
-static void
-gst_timeoverlay_set_property (GObject * object, guint prop_id,
- const GValue * value, GParamSpec * pspec)
-{
- GstTimeoverlay *src;
+static GstStaticPadTemplate gst_timeoverlay_src_template =
+GST_STATIC_PAD_TEMPLATE ("src",
+ GST_PAD_SRC,
+ GST_PAD_ALWAYS,
+ GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("I420"))
+ );
- g_return_if_fail (GST_IS_TIMEOVERLAY (object));
- src = GST_TIMEOVERLAY (object);
+static GstStaticPadTemplate gst_timeoverlay_sink_template =
+GST_STATIC_PAD_TEMPLATE ("sink",
+ GST_PAD_SINK,
+ GST_PAD_ALWAYS,
+ GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("I420"))
+ );
- 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 GstVideofilterClass *parent_class = NULL;
static void
-gst_timeoverlay_get_property (GObject * object, guint prop_id, GValue * value,
- GParamSpec * pspec)
+gst_timeoverlay_update_font_height (GstTimeoverlay * timeoverlay)
{
- 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 void
-gst_timeoverlay_update_font_height (GstVideofilter * videofilter)
-{
- GstTimeoverlay *timeoverlay = GST_TIMEOVERLAY (videofilter);
gint width, height;
cairo_surface_t *font_surface;
cairo_t *font_cairo;
cairo_font_extents_t font_extents;
- width = gst_videofilter_get_input_width (videofilter);
- height = gst_videofilter_get_input_height (videofilter);
+ width = timeoverlay->width;
+ height = timeoverlay->height;
font_surface =
cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
@@ -216,15 +84,58 @@ gst_timeoverlay_update_font_height (GstVideofilter * videofilter)
font_cairo = NULL;
}
-static void
-gst_timeoverlay_setup (GstVideofilter * videofilter)
+static gboolean
+gst_timeoverlay_set_caps (GstBaseTransform * btrans, GstCaps * incaps,
+ GstCaps * outcaps)
{
- GstTimeoverlay *timeoverlay;
+ GstTimeoverlay *filter = GST_TIMEOVERLAY (btrans);
+ GstStructure *structure;
+ gboolean ret = FALSE;
+
+ structure = gst_caps_get_structure (incaps, 0);
+
+ if (gst_structure_get_int (structure, "width", &filter->width) &&
+ gst_structure_get_int (structure, "height", &filter->height)) {
+ gst_timeoverlay_update_font_height (filter);
+ ret = TRUE;
+ }
+
+ return ret;
+}
+
+/* Useful macros */
+#define GST_VIDEO_I420_Y_ROWSTRIDE(width) (GST_ROUND_UP_4(width))
+#define GST_VIDEO_I420_U_ROWSTRIDE(width) (GST_ROUND_UP_8(width)/2)
+#define GST_VIDEO_I420_V_ROWSTRIDE(width) ((GST_ROUND_UP_8(GST_VIDEO_I420_Y_ROWSTRIDE(width)))/2)
+
+#define GST_VIDEO_I420_Y_OFFSET(w,h) (0)
+#define GST_VIDEO_I420_U_OFFSET(w,h) (GST_VIDEO_I420_Y_OFFSET(w,h)+(GST_VIDEO_I420_Y_ROWSTRIDE(w)*GST_ROUND_UP_2(h)))
+#define GST_VIDEO_I420_V_OFFSET(w,h) (GST_VIDEO_I420_U_OFFSET(w,h)+(GST_VIDEO_I420_U_ROWSTRIDE(w)*GST_ROUND_UP_2(h)/2))
+
+#define GST_VIDEO_I420_SIZE(w,h) (GST_VIDEO_I420_V_OFFSET(w,h)+(GST_VIDEO_I420_V_ROWSTRIDE(w)*GST_ROUND_UP_2(h)/2))
+
+static gboolean
+gst_timeoverlay_get_unit_size (GstBaseTransform * btrans, GstCaps * caps,
+ guint * size)
+{
+ GstTimeoverlay *filter;
+ GstStructure *structure;
+ gboolean ret = FALSE;
+ gint width, height;
+
+ filter = GST_TIMEOVERLAY (btrans);
+
+ structure = gst_caps_get_structure (caps, 0);
- g_return_if_fail (GST_IS_TIMEOVERLAY (videofilter));
- timeoverlay = GST_TIMEOVERLAY (videofilter);
+ if (gst_structure_get_int (structure, "width", &width) &&
+ gst_structure_get_int (structure, "height", &height)) {
+ *size = GST_VIDEO_I420_SIZE (width, height);
+ ret = TRUE;
+ GST_DEBUG_OBJECT (filter, "our frame size is %d bytes (%dx%d)", *size,
+ width, height);
+ }
- gst_timeoverlay_update_font_height (videofilter);
+ return ret;
}
static char *
@@ -250,8 +161,9 @@ gst_timeoverlay_print_smpte_time (guint64 time)
}
-static void
-gst_timeoverlay_planar411 (GstVideofilter * videofilter, void *dest, void *src)
+static GstFlowReturn
+gst_timeoverlay_transform (GstBaseTransform * trans, GstBuffer * in,
+ GstBuffer * out)
{
GstTimeoverlay *timeoverlay;
int width;
@@ -261,15 +173,20 @@ gst_timeoverlay_planar411 (GstVideofilter * videofilter, void *dest, void *src)
int i, j;
unsigned char *image;
cairo_text_extents_t extents;
-
+ gpointer dest, src;
cairo_surface_t *font_surface;
cairo_t *text_cairo;
+ GstFlowReturn ret = GST_FLOW_OK;
+
+ timeoverlay = GST_TIMEOVERLAY (trans);
+
+ gst_buffer_stamp (out, in);
- g_return_if_fail (GST_IS_TIMEOVERLAY (videofilter));
- timeoverlay = GST_TIMEOVERLAY (videofilter);
+ src = GST_BUFFER_DATA (in);
+ dest = GST_BUFFER_DATA (out);
- width = gst_videofilter_get_input_width (videofilter);
- height = gst_videofilter_get_input_height (videofilter);
+ width = timeoverlay->width;
+ height = timeoverlay->height;
/* create surface for font rendering */
/* FIXME: preparation of the surface could also be done once when settings
@@ -292,9 +209,7 @@ gst_timeoverlay_planar411 (GstVideofilter * videofilter, void *dest, void *src)
cairo_fill (text_cairo);
cairo_restore (text_cairo);
- string =
- gst_timeoverlay_print_smpte_time (GST_BUFFER_TIMESTAMP (videofilter->
- in_buf));
+ string = gst_timeoverlay_print_smpte_time (GST_BUFFER_TIMESTAMP (in));
cairo_save (text_cairo);
cairo_select_font_face (text_cairo, "monospace", 0, 0);
cairo_set_font_size (text_cairo, 20);
@@ -303,12 +218,6 @@ gst_timeoverlay_planar411 (GstVideofilter * videofilter, void *dest, void *src)
cairo_move_to (text_cairo, 0, timeoverlay->text_height - 2);
cairo_show_text (text_cairo, string);
g_free (string);
-#if 0
- cairo_text_path (timeoverlay->cr, string);
- cairo_set_rgb_color (timeoverlay->cr, 1, 1, 1);
- cairo_set_line_width (timeoverlay->cr, 1.0);
- cairo_stroke (timeoverlay->cr);
-#endif
cairo_restore (text_cairo);
@@ -317,7 +226,7 @@ gst_timeoverlay_planar411 (GstVideofilter * videofilter, void *dest, void *src)
if (b_width > width)
b_width = width;
- memcpy (dest, src, videofilter->from_buf_size);
+ memcpy (dest, src, GST_BUFFER_SIZE (in));
for (i = 0; i < timeoverlay->text_height; i++) {
for (j = 0; j < b_width; j++) {
((unsigned char *) dest)[i * width + j] = image[(i * width + j) * 4 + 0];
@@ -332,4 +241,67 @@ gst_timeoverlay_planar411 (GstVideofilter * videofilter, void *dest, void *src)
cairo_destroy (text_cairo);
text_cairo = NULL;
g_free (image);
+
+ return ret;
+}
+
+static void
+gst_timeoverlay_base_init (gpointer g_class)
+{
+ GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
+
+ gst_element_class_set_details (element_class, &timeoverlay_details);
+
+ gst_element_class_add_pad_template (element_class,
+ gst_static_pad_template_get (&gst_timeoverlay_sink_template));
+ gst_element_class_add_pad_template (element_class,
+ gst_static_pad_template_get (&gst_timeoverlay_src_template));
+}
+
+static void
+gst_timeoverlay_class_init (gpointer klass, gpointer class_data)
+{
+ GObjectClass *gobject_class;
+ GstElementClass *element_class;
+ GstBaseTransformClass *trans_class;
+
+ gobject_class = (GObjectClass *) klass;
+ element_class = (GstElementClass *) klass;
+ trans_class = (GstBaseTransformClass *) klass;
+
+ parent_class = g_type_class_peek_parent (klass);
+
+ trans_class->set_caps = GST_DEBUG_FUNCPTR (gst_timeoverlay_set_caps);
+ trans_class->get_unit_size =
+ GST_DEBUG_FUNCPTR (gst_timeoverlay_get_unit_size);
+ trans_class->transform = GST_DEBUG_FUNCPTR (gst_timeoverlay_transform);
+}
+
+static void
+gst_timeoverlay_init (GTypeInstance * instance, gpointer g_class)
+{
+}
+
+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;
}