cairo: port cairooverlay to 0.11

The other elements are not that interesting now that we're
using pangocairo in the pango plugin, and should probably
just be removed.
This commit is contained in:
Tim-Philipp Müller 2013-01-01 11:52:09 +00:00
parent 1a073355bc
commit 08702be68f
10 changed files with 86 additions and 123 deletions

View file

@ -302,7 +302,7 @@ dnl *** plug-ins to include ***
dnl Non ported plugins (non-dependant, then dependant) dnl Non ported plugins (non-dependant, then dependant)
dnl Make sure you have a space before and after all plugins dnl Make sure you have a space before and after all plugins
GST_PLUGINS_NONPORTED="cairo cairo_gobject osx_audio " GST_PLUGINS_NONPORTED="osx_audio "
AC_SUBST(GST_PLUGINS_NONPORTED) AC_SUBST(GST_PLUGINS_NONPORTED)
dnl these are all the gst plug-ins, compilable without additional libs dnl these are all the gst plug-ins, compilable without additional libs
@ -682,15 +682,8 @@ AG_GST_CHECK_FEATURE(AALIB, [aalib ASCII Art library], aasink, [
dnl *** cairo *** dnl *** cairo ***
translit(dnm, m, l) AM_CONDITIONAL(USE_CAIRO, true) translit(dnm, m, l) AM_CONDITIONAL(USE_CAIRO, true)
AG_GST_CHECK_FEATURE(CAIRO, [Cairo graphics rendering], cairo, [ AG_GST_CHECK_FEATURE(CAIRO, [Cairo graphics rendering and gobject bindings], cairo, [
AG_GST_PKG_CHECK_MODULES(CAIRO, cairo >= 1.0.0) AG_GST_PKG_CHECK_MODULES(CAIRO, cairo >= 1.10.0 cairo-gobject >= 1.10.0)
])
dnl *** cairo-gobject ***
translit(dnm, m, l) AM_CONDITIONAL(USE_CAIRO_GOBJECT, true)
AG_GST_CHECK_FEATURE(CAIRO_GOBJECT,
[Cairo graphics rendering gobject bindings], cairooverlay, [
AG_GST_PKG_CHECK_MODULES(CAIRO_GOBJECT, cairo-gobject >= 1.10.0)
]) ])
dnl *** FLAC *** dnl *** FLAC ***
@ -969,7 +962,6 @@ dnl but we still need to set the conditionals
AM_CONDITIONAL(USE_AALIB, false) AM_CONDITIONAL(USE_AALIB, false)
AM_CONDITIONAL(USE_BZ2, false) AM_CONDITIONAL(USE_BZ2, false)
AM_CONDITIONAL(USE_CAIRO, false) AM_CONDITIONAL(USE_CAIRO, false)
AM_CONDITIONAL(USE_CAIRO_GOBJECT, false)
AM_CONDITIONAL(USE_DIRECTSOUND, false) AM_CONDITIONAL(USE_DIRECTSOUND, false)
AM_CONDITIONAL(USE_DV1394, false) AM_CONDITIONAL(USE_DV1394, false)
AM_CONDITIONAL(USE_FLAC, false) AM_CONDITIONAL(USE_FLAC, false)

View file

@ -1,2 +0,0 @@
gstcairo-marshal.c
gstcairo-marshal.h

View file

@ -1,45 +1,25 @@
plugin_LTLIBRARIES = libgstcairo.la plugin_LTLIBRARIES = libgstcairo.la
if USE_CAIRO_GOBJECT # we probably don't really want to port these
glib_enum_define = GST_CAIRO # gsttimeoverlay.h
glib_gen_prefix = gst_cairo # gsttextoverlay.h
glib_gen_basename = gstcairo # gstcairorender.h
# gsttimeoverlay.c
include $(top_srcdir)/common/gst-glib-gen.mak # gsttextoverlay.c
# gstcairorender.c
built_sources = gstcairo-marshal.c
built_headers = gstcairo-marshal.h
BUILT_SOURCES = $(built_sources) $(built_headers)
gstcairo_gobject_dep_sources = gstcairooverlay.c
gstcairo_gobject_dep_headers = gstcairooverlay.h
CLEANFILES = $(BUILT_SOURCES)
endif
noinst_HEADERS = \ noinst_HEADERS = \
gsttimeoverlay.h \ gstcairooverlay.h
gsttextoverlay.h \
gstcairorender.h \
$(gstcairo_gobject_dep_headers)
libgstcairo_la_SOURCES = \ libgstcairo_la_SOURCES = \
gstcairo.c \ gstcairo.c \
gsttimeoverlay.c \ gstcairooverlay.c
gsttextoverlay.c \
gstcairorender.c \
$(gstcairo_gobject_dep_sources)
nodist_libgstcairo_la_SOURCES = \
$(built_sources)
libgstcairo_la_CFLAGS = \ libgstcairo_la_CFLAGS = \
$(GST_PLUGINS_BASE_CFLAGS) \ $(GST_PLUGINS_BASE_CFLAGS) \
$(GST_BASE_CFLAGS) \ $(GST_BASE_CFLAGS) \
$(GST_CFLAGS) $(CAIRO_CFLAGS) $(CAIRO_GOBJECT_CFLAGS) $(GST_CFLAGS) $(CAIRO_CFLAGS)
libgstcairo_la_LIBADD = \ libgstcairo_la_LIBADD = \
$(GST_PLUGINS_BASE_LIBS) -lgstvideo-$(GST_API_VERSION) \ $(GST_PLUGINS_BASE_LIBS) -lgstvideo-$(GST_API_VERSION) \
$(GST_BASE_LIBS) $(GST_LIBS) $(CAIRO_LIBS) $(CAIRO_GOBJECT_LIBS) $(LIBM) $(GST_BASE_LIBS) $(GST_LIBS) $(CAIRO_LIBS) $(LIBM)
libgstcairo_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) libgstcairo_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
libgstcairo_la_LIBTOOLFLAGS = --tag=disable-static libgstcairo_la_LIBTOOLFLAGS = --tag=disable-static
EXTRA_DIST = gstcairo-marshal.list

View file

@ -1,2 +0,0 @@
VOID:BOXED,UINT64,UINT64
VOID:BOXED

View file

@ -22,14 +22,14 @@
#include "config.h" #include "config.h"
#endif #endif
#if 0
#include <gsttimeoverlay.h> #include <gsttimeoverlay.h>
#include <gsttextoverlay.h> #include <gsttextoverlay.h>
#include <gstcairorender.h> #include <gstcairorender.h>
#ifdef HAVE_CAIRO_GOBJECT
#include <gstcairooverlay.h>
#endif #endif
#include <gstcairooverlay.h>
#include <string.h> #include <string.h>
#include <math.h> #include <math.h>
@ -38,16 +38,18 @@ GST_DEBUG_CATEGORY (cairo_debug);
static gboolean static gboolean
plugin_init (GstPlugin * plugin) plugin_init (GstPlugin * plugin)
{ {
#if 0
/* we probably don't want to port these */
gst_element_register (plugin, "cairotextoverlay", GST_RANK_NONE, gst_element_register (plugin, "cairotextoverlay", GST_RANK_NONE,
GST_TYPE_CAIRO_TEXT_OVERLAY); GST_TYPE_CAIRO_TEXT_OVERLAY);
gst_element_register (plugin, "cairotimeoverlay", GST_RANK_NONE, gst_element_register (plugin, "cairotimeoverlay", GST_RANK_NONE,
GST_TYPE_CAIRO_TIME_OVERLAY); GST_TYPE_CAIRO_TIME_OVERLAY);
#ifdef HAVE_CAIRO_GOBJECT
gst_element_register (plugin, "cairooverlay", GST_RANK_NONE,
GST_TYPE_CAIRO_OVERLAY);
#endif
gst_element_register (plugin, "cairorender", GST_RANK_SECONDARY, gst_element_register (plugin, "cairorender", GST_RANK_SECONDARY,
GST_TYPE_CAIRO_RENDER); GST_TYPE_CAIRO_RENDER);
#endif
gst_element_register (plugin, "cairooverlay", GST_RANK_NONE,
GST_TYPE_CAIRO_OVERLAY);
GST_DEBUG_CATEGORY_INIT (cairo_debug, "cairo", 0, "Cairo elements"); GST_DEBUG_CATEGORY_INIT (cairo_debug, "cairo", 0, "Cairo elements");

View file

@ -91,16 +91,15 @@
#endif #endif
#include "gstcairooverlay.h" #include "gstcairooverlay.h"
#include "gstcairo-marshal.h"
#include <gst/video/video.h> #include <gst/video/video.h>
#include <cairo.h> #include <cairo.h>
#if G_BYTE_ORDER == G_LITTLE_ENDIAN #if G_BYTE_ORDER == G_LITTLE_ENDIAN
#define TEMPLATE_CAPS GST_VIDEO_CAPS_BGRx " ; " GST_VIDEO_CAPS_BGRA " ; " #define TEMPLATE_CAPS GST_VIDEO_CAPS_MAKE("{ BGRx, BGRA }")
#else #else
#define TEMPLATE_CAPS GST_VIDEO_CAPS_xRGB " ; " GST_VIDEO_CAPS_ARGB " ; " #define TEMPLATE_CAPS GST_VIDEO_CAPS_MAKE("{ xRGB, ARGB }")
#endif #endif
@ -118,9 +117,7 @@ GST_STATIC_PAD_TEMPLATE ("sink",
GST_STATIC_CAPS (TEMPLATE_CAPS) GST_STATIC_CAPS (TEMPLATE_CAPS)
); );
G_DEFINE_TYPE (GstCairoOverlay, gst_cairo_overlay, GST_TYPE_VIDEO_FILTER);
GST_BOILERPLATE (GstCairoOverlay, gst_cairo_overlay, GstVideoFilter,
GST_TYPE_VIDEO_FILTER);
enum enum
{ {
@ -132,40 +129,36 @@ enum
static guint gst_cairo_overlay_signals[N_SIGNALS]; static guint gst_cairo_overlay_signals[N_SIGNALS];
static gboolean static gboolean
gst_cairo_overlay_set_caps (GstBaseTransform * btrans, GstCaps * incaps, gst_cairo_overlay_set_info (GstVideoFilter * vfilter, GstCaps * in_caps,
GstCaps * outcaps) GstVideoInfo * in_info, GstCaps * out_caps, GstVideoInfo * out_info)
{ {
GstCairoOverlay *overlay = GST_CAIRO_OVERLAY (btrans); GstCairoOverlay *overlay = GST_CAIRO_OVERLAY (vfilter);
gboolean ret;
ret =
gst_video_format_parse_caps (incaps, &overlay->format, &overlay->width,
&overlay->height);
if (G_UNLIKELY (!ret))
return FALSE;
g_signal_emit (overlay, gst_cairo_overlay_signals[SIGNAL_CAPS_CHANGED], 0, g_signal_emit (overlay, gst_cairo_overlay_signals[SIGNAL_CAPS_CHANGED], 0,
incaps, NULL); in_caps, NULL);
return ret; return TRUE;
} }
static GstFlowReturn static GstFlowReturn
gst_cairo_overlay_transform_ip (GstBaseTransform * btrans, GstBuffer * buf) gst_cairo_overlay_transform_frame_ip (GstVideoFilter * vfilter,
GstVideoFrame * frame)
{ {
GstCairoOverlay *overlay = GST_CAIRO_OVERLAY (vfilter);
GstCairoOverlay *overlay = GST_CAIRO_OVERLAY (btrans);
cairo_surface_t *surface; cairo_surface_t *surface;
cairo_t *cr; cairo_t *cr;
cairo_format_t format; cairo_format_t format;
format = (overlay->format == GST_VIDEO_FORMAT_ARGB if (GST_VIDEO_FRAME_N_COMPONENTS (frame) == 4)
|| overlay->format == GST_VIDEO_FORMAT_BGRA) ? format = CAIRO_FORMAT_ARGB32;
CAIRO_FORMAT_ARGB32 : CAIRO_FORMAT_RGB24; else
format = CAIRO_FORMAT_RGB24;
surface = surface =
cairo_image_surface_create_for_data (GST_BUFFER_DATA (buf), format, cairo_image_surface_create_for_data (GST_VIDEO_FRAME_PLANE_DATA (frame,
overlay->width, overlay->height, overlay->width * 4); 0), format, GST_VIDEO_FRAME_WIDTH (frame),
GST_VIDEO_FRAME_HEIGHT (frame), GST_VIDEO_FRAME_PLANE_STRIDE (frame, 0));
if (G_UNLIKELY (!surface)) if (G_UNLIKELY (!surface))
return GST_FLOW_ERROR; return GST_FLOW_ERROR;
@ -176,7 +169,8 @@ gst_cairo_overlay_transform_ip (GstBaseTransform * btrans, GstBuffer * buf)
} }
g_signal_emit (overlay, gst_cairo_overlay_signals[SIGNAL_DRAW], 0, g_signal_emit (overlay, gst_cairo_overlay_signals[SIGNAL_DRAW], 0,
cr, GST_BUFFER_TIMESTAMP (buf), GST_BUFFER_DURATION (buf), NULL); cr, GST_BUFFER_PTS (frame->buffer), GST_BUFFER_DURATION (frame->buffer),
NULL);
cairo_destroy (cr); cairo_destroy (cr);
cairo_surface_destroy (surface); cairo_surface_destroy (surface);
@ -184,31 +178,17 @@ gst_cairo_overlay_transform_ip (GstBaseTransform * btrans, GstBuffer * buf)
return GST_FLOW_OK; return GST_FLOW_OK;
} }
static void
gst_cairo_overlay_base_init (gpointer g_class)
{
GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
gst_element_class_set_static_metadata (element_class, "Cairo overlay",
"Filter/Editor/Video",
"Render overlay on a video stream using Cairo",
"Jon Nordby <jononor@gmail.com>");
gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&gst_cairo_overlay_sink_template));
gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&gst_cairo_overlay_src_template));
}
static void static void
gst_cairo_overlay_class_init (GstCairoOverlayClass * klass) gst_cairo_overlay_class_init (GstCairoOverlayClass * klass)
{ {
GstBaseTransformClass *trans_class; GstVideoFilterClass *vfilter_class;
GstElementClass *element_class;
trans_class = (GstBaseTransformClass *) klass; vfilter_class = (GstVideoFilterClass *) klass;
element_class = (GstElementClass *) klass;
trans_class->set_caps = gst_cairo_overlay_set_caps; vfilter_class->set_info = gst_cairo_overlay_set_info;
trans_class->transform_ip = gst_cairo_overlay_transform_ip; vfilter_class->transform_frame_ip = gst_cairo_overlay_transform_frame_ip;
/** /**
* GstCairoOverlay::draw: * GstCairoOverlay::draw:
@ -226,7 +206,7 @@ gst_cairo_overlay_class_init (GstCairoOverlayClass * klass)
0, 0,
NULL, NULL,
NULL, NULL,
gst_cairo_marshal_VOID__BOXED_UINT64_UINT64, g_cclosure_marshal_generic,
G_TYPE_NONE, 3, CAIRO_GOBJECT_TYPE_CONTEXT, G_TYPE_UINT64, G_TYPE_UINT64); G_TYPE_NONE, 3, CAIRO_GOBJECT_TYPE_CONTEXT, G_TYPE_UINT64, G_TYPE_UINT64);
/** /**
@ -240,11 +220,21 @@ gst_cairo_overlay_class_init (GstCairoOverlayClass * klass)
g_signal_new ("caps-changed", g_signal_new ("caps-changed",
G_TYPE_FROM_CLASS (klass), G_TYPE_FROM_CLASS (klass),
0, 0,
0, 0, NULL, NULL, g_cclosure_marshal_generic, G_TYPE_NONE, 1, GST_TYPE_CAPS);
NULL, NULL, gst_cairo_marshal_VOID__BOXED, G_TYPE_NONE, 1, GST_TYPE_CAPS);
gst_element_class_set_static_metadata (element_class, "Cairo overlay",
"Filter/Editor/Video",
"Render overlay on a video stream using Cairo",
"Jon Nordby <jononor@gmail.com>");
gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&gst_cairo_overlay_sink_template));
gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&gst_cairo_overlay_src_template));
} }
static void static void
gst_cairo_overlay_init (GstCairoOverlay * overlay, GstCairoOverlayClass * klass) gst_cairo_overlay_init (GstCairoOverlay * overlay)
{ {
/* nothing to do */
} }

View file

@ -44,19 +44,14 @@ typedef struct _GstCairoOverlay GstCairoOverlay;
typedef struct _GstCairoOverlayClass GstCairoOverlayClass; typedef struct _GstCairoOverlayClass GstCairoOverlayClass;
struct _GstCairoOverlay { struct _GstCairoOverlay {
GstVideoFilter parent_instance; GstVideoFilter video_filter;
/* < private > */
GstVideoFormat format;
gint width;
gint height;
}; };
struct _GstCairoOverlayClass { struct _GstCairoOverlayClass {
GstVideoFilterClass parent_class; GstVideoFilterClass video_filter_class;
}; };
GType gst_cairo_overlay_get_type(void); GType gst_cairo_overlay_get_type (void);
G_END_DECLS G_END_DECLS

View file

@ -4,7 +4,7 @@ else
JACK_DIR= JACK_DIR=
endif endif
if USE_CAIRO_GOBJECT if USE_CAIRO
CAIRO_DIR=cairo CAIRO_DIR=cairo
else else
CAIRO_DIR= CAIRO_DIR=

View file

@ -1,6 +1,4 @@
if USE_CAIRO_GOBJECT
noinst_PROGRAMS = cairo_overlay noinst_PROGRAMS = cairo_overlay
endif
cairo_overlay_SOURCES = cairo_overlay.c cairo_overlay_SOURCES = cairo_overlay.c
cairo_overlay_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS) $(CAIRO_CFLAGS) cairo_overlay_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS) $(CAIRO_CFLAGS)

View file

@ -69,8 +69,7 @@ on_message (GstBus * bus, GstMessage * message, gpointer user_data)
typedef struct typedef struct
{ {
gboolean valid; gboolean valid;
int width; GstVideoInfo vinfo;
int height;
} CairoOverlayState; } CairoOverlayState;
/* Store the information from the caps that we are interested in. */ /* Store the information from the caps that we are interested in. */
@ -79,8 +78,7 @@ prepare_overlay (GstElement * overlay, GstCaps * caps, gpointer user_data)
{ {
CairoOverlayState *state = (CairoOverlayState *) user_data; CairoOverlayState *state = (CairoOverlayState *) user_data;
gst_video_format_parse_caps (caps, NULL, &state->width, &state->height); state->valid = gst_video_info_from_caps (&state->vinfo, caps);
state->valid = TRUE;
} }
/* Draw the overlay. /* Draw the overlay.
@ -91,12 +89,18 @@ draw_overlay (GstElement * overlay, cairo_t * cr, guint64 timestamp,
{ {
CairoOverlayState *s = (CairoOverlayState *) user_data; CairoOverlayState *s = (CairoOverlayState *) user_data;
double scale; double scale;
int width, height;
if (!s->valid) if (!s->valid)
return; return;
width = GST_VIDEO_INFO_WIDTH (&s->vinfo);
height = GST_VIDEO_INFO_HEIGHT (&s->vinfo);
scale = 2 * (((timestamp / (int) 1e7) % 70) + 30) / 100.0; scale = 2 * (((timestamp / (int) 1e7) % 70) + 30) / 100.0;
cairo_translate (cr, s->width / 2, (s->height / 2) - 30); cairo_translate (cr, width / 2, (height / 2) - 30);
/* FIXME: this assumes a pixel-aspect-ratio of 1/1 */
cairo_scale (cr, scale, scale); cairo_scale (cr, scale, scale);
cairo_move_to (cr, 0, 0); cairo_move_to (cr, 0, 0);
@ -122,7 +126,9 @@ setup_gst_pipeline (CairoOverlayState * overlay_state)
adaptor1 = gst_element_factory_make ("videoconvert", "adaptor1"); adaptor1 = gst_element_factory_make ("videoconvert", "adaptor1");
cairo_overlay = gst_element_factory_make ("cairooverlay", "overlay"); cairo_overlay = gst_element_factory_make ("cairooverlay", "overlay");
adaptor2 = gst_element_factory_make ("videoconvert", "adaptor2"); adaptor2 = gst_element_factory_make ("videoconvert", "adaptor2");
sink = gst_element_factory_make ("autovideosink", "sink"); sink = gst_element_factory_make ("ximagesink", "sink");
if (sink == NULL)
sink = gst_element_factory_make ("autovideosink", "sink");
/* If failing, the element could not be created */ /* If failing, the element could not be created */
g_assert (cairo_overlay); g_assert (cairo_overlay);
@ -150,12 +156,15 @@ main (int argc, char **argv)
GMainLoop *loop; GMainLoop *loop;
GstElement *pipeline; GstElement *pipeline;
GstBus *bus; GstBus *bus;
CairoOverlayState overlay_state = { FALSE, 0, 0 }; CairoOverlayState *overlay_state;
gst_init (&argc, &argv); gst_init (&argc, &argv);
loop = g_main_loop_new (NULL, FALSE); loop = g_main_loop_new (NULL, FALSE);
pipeline = setup_gst_pipeline (&overlay_state); /* allocate on heap for pedagogical reasons, makes code easier to transfer */
overlay_state = g_new0 (CairoOverlayState, 1);
pipeline = setup_gst_pipeline (overlay_state);
bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline)); bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
gst_bus_add_signal_watch (bus); gst_bus_add_signal_watch (bus);
@ -168,5 +177,6 @@ main (int argc, char **argv)
gst_element_set_state (pipeline, GST_STATE_NULL); gst_element_set_state (pipeline, GST_STATE_NULL);
gst_object_unref (pipeline); gst_object_unref (pipeline);
g_free (overlay_state);
return 0; return 0;
} }