diff options
author | Julien Moutte <julien@moutte.net> | 2005-11-23 15:50:51 +0000 |
---|---|---|
committer | Julien Moutte <julien@moutte.net> | 2005-11-23 15:50:51 +0000 |
commit | 2ea4f5b3c92819681f2d9e6f5f8d014b4d179344 (patch) | |
tree | db8696ff4b83e3f0ea882402e3435d8dacdbb488 /ext/cairo/gsttimeoverlay.c | |
parent | 48520a455d828b4a6885fb37be48ebb720ae259b (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.c | 328 |
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; } |