Commit 08702be6 authored by Tim-Philipp Müller's avatar Tim-Philipp Müller

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.
parent 1a073355
......@@ -302,7 +302,7 @@ dnl *** plug-ins to include ***
dnl Non ported plugins (non-dependant, then dependant)
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)
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 ***
translit(dnm, m, l) AM_CONDITIONAL(USE_CAIRO, true)
AG_GST_CHECK_FEATURE(CAIRO, [Cairo graphics rendering], cairo, [
AG_GST_PKG_CHECK_MODULES(CAIRO, cairo >= 1.0.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)
AG_GST_CHECK_FEATURE(CAIRO, [Cairo graphics rendering and gobject bindings], cairo, [
AG_GST_PKG_CHECK_MODULES(CAIRO, cairo >= 1.10.0 cairo-gobject >= 1.10.0)
])
dnl *** FLAC ***
......@@ -969,7 +962,6 @@ dnl but we still need to set the conditionals
AM_CONDITIONAL(USE_AALIB, false)
AM_CONDITIONAL(USE_BZ2, false)
AM_CONDITIONAL(USE_CAIRO, false)
AM_CONDITIONAL(USE_CAIRO_GOBJECT, false)
AM_CONDITIONAL(USE_DIRECTSOUND, false)
AM_CONDITIONAL(USE_DV1394, false)
AM_CONDITIONAL(USE_FLAC, false)
......
gstcairo-marshal.c
gstcairo-marshal.h
plugin_LTLIBRARIES = libgstcairo.la
if USE_CAIRO_GOBJECT
glib_enum_define = GST_CAIRO
glib_gen_prefix = gst_cairo
glib_gen_basename = gstcairo
include $(top_srcdir)/common/gst-glib-gen.mak
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
# we probably don't really want to port these
# gsttimeoverlay.h
# gsttextoverlay.h
# gstcairorender.h
# gsttimeoverlay.c
# gsttextoverlay.c
# gstcairorender.c
noinst_HEADERS = \
gsttimeoverlay.h \
gsttextoverlay.h \
gstcairorender.h \
$(gstcairo_gobject_dep_headers)
gstcairooverlay.h
libgstcairo_la_SOURCES = \
gstcairo.c \
gsttimeoverlay.c \
gsttextoverlay.c \
gstcairorender.c \
$(gstcairo_gobject_dep_sources)
nodist_libgstcairo_la_SOURCES = \
$(built_sources)
gstcairooverlay.c
libgstcairo_la_CFLAGS = \
$(GST_PLUGINS_BASE_CFLAGS) \
$(GST_BASE_CFLAGS) \
$(GST_CFLAGS) $(CAIRO_CFLAGS) $(CAIRO_GOBJECT_CFLAGS)
$(GST_CFLAGS) $(CAIRO_CFLAGS)
libgstcairo_la_LIBADD = \
$(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_LIBTOOLFLAGS = --tag=disable-static
EXTRA_DIST = gstcairo-marshal.list
VOID:BOXED,UINT64,UINT64
VOID:BOXED
......@@ -22,13 +22,13 @@
#include "config.h"
#endif
#if 0
#include <gsttimeoverlay.h>
#include <gsttextoverlay.h>
#include <gstcairorender.h>
#endif
#ifdef HAVE_CAIRO_GOBJECT
#include <gstcairooverlay.h>
#endif
#include <string.h>
#include <math.h>
......@@ -38,16 +38,18 @@ GST_DEBUG_CATEGORY (cairo_debug);
static gboolean
plugin_init (GstPlugin * plugin)
{
#if 0
/* we probably don't want to port these */
gst_element_register (plugin, "cairotextoverlay", GST_RANK_NONE,
GST_TYPE_CAIRO_TEXT_OVERLAY);
gst_element_register (plugin, "cairotimeoverlay", GST_RANK_NONE,
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_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");
......
......@@ -91,16 +91,15 @@
#endif
#include "gstcairooverlay.h"
#include "gstcairo-marshal.h"
#include <gst/video/video.h>
#include <cairo.h>
#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
#define TEMPLATE_CAPS GST_VIDEO_CAPS_xRGB " ; " GST_VIDEO_CAPS_ARGB " ; "
#define TEMPLATE_CAPS GST_VIDEO_CAPS_MAKE("{ xRGB, ARGB }")
#endif
......@@ -118,9 +117,7 @@ GST_STATIC_PAD_TEMPLATE ("sink",
GST_STATIC_CAPS (TEMPLATE_CAPS)
);
GST_BOILERPLATE (GstCairoOverlay, gst_cairo_overlay, GstVideoFilter,
GST_TYPE_VIDEO_FILTER);
G_DEFINE_TYPE (GstCairoOverlay, gst_cairo_overlay, GST_TYPE_VIDEO_FILTER);
enum
{
......@@ -132,40 +129,36 @@ enum
static guint gst_cairo_overlay_signals[N_SIGNALS];
static gboolean
gst_cairo_overlay_set_caps (GstBaseTransform * btrans, GstCaps * incaps,
GstCaps * outcaps)
gst_cairo_overlay_set_info (GstVideoFilter * vfilter, GstCaps * in_caps,
GstVideoInfo * in_info, GstCaps * out_caps, GstVideoInfo * out_info)
{
GstCairoOverlay *overlay = GST_CAIRO_OVERLAY (btrans);
gboolean ret;
ret =
gst_video_format_parse_caps (incaps, &overlay->format, &overlay->width,
&overlay->height);
if (G_UNLIKELY (!ret))
return FALSE;
GstCairoOverlay *overlay = GST_CAIRO_OVERLAY (vfilter);
g_signal_emit (overlay, gst_cairo_overlay_signals[SIGNAL_CAPS_CHANGED], 0,
incaps, NULL);
in_caps, NULL);
return ret;
return TRUE;
}
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 (btrans);
GstCairoOverlay *overlay = GST_CAIRO_OVERLAY (vfilter);
cairo_surface_t *surface;
cairo_t *cr;
cairo_format_t format;
format = (overlay->format == GST_VIDEO_FORMAT_ARGB
|| overlay->format == GST_VIDEO_FORMAT_BGRA) ?
CAIRO_FORMAT_ARGB32 : CAIRO_FORMAT_RGB24;
if (GST_VIDEO_FRAME_N_COMPONENTS (frame) == 4)
format = CAIRO_FORMAT_ARGB32;
else
format = CAIRO_FORMAT_RGB24;
surface =
cairo_image_surface_create_for_data (GST_BUFFER_DATA (buf), format,
overlay->width, overlay->height, overlay->width * 4);
cairo_image_surface_create_for_data (GST_VIDEO_FRAME_PLANE_DATA (frame,
0), format, GST_VIDEO_FRAME_WIDTH (frame),
GST_VIDEO_FRAME_HEIGHT (frame), GST_VIDEO_FRAME_PLANE_STRIDE (frame, 0));
if (G_UNLIKELY (!surface))
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,
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_surface_destroy (surface);
......@@ -184,31 +178,17 @@ gst_cairo_overlay_transform_ip (GstBaseTransform * btrans, GstBuffer * buf)
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
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;
trans_class->transform_ip = gst_cairo_overlay_transform_ip;
vfilter_class->set_info = gst_cairo_overlay_set_info;
vfilter_class->transform_frame_ip = gst_cairo_overlay_transform_frame_ip;
/**
* GstCairoOverlay::draw:
......@@ -226,7 +206,7 @@ gst_cairo_overlay_class_init (GstCairoOverlayClass * klass)
0,
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);
/**
......@@ -240,11 +220,21 @@ gst_cairo_overlay_class_init (GstCairoOverlayClass * klass)
g_signal_new ("caps-changed",
G_TYPE_FROM_CLASS (klass),
0,
0,
NULL, NULL, gst_cairo_marshal_VOID__BOXED, G_TYPE_NONE, 1, GST_TYPE_CAPS);
0, NULL, NULL, g_cclosure_marshal_generic, 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
gst_cairo_overlay_init (GstCairoOverlay * overlay, GstCairoOverlayClass * klass)
gst_cairo_overlay_init (GstCairoOverlay * overlay)
{
/* nothing to do */
}
......@@ -44,19 +44,14 @@ typedef struct _GstCairoOverlay GstCairoOverlay;
typedef struct _GstCairoOverlayClass GstCairoOverlayClass;
struct _GstCairoOverlay {
GstVideoFilter parent_instance;
/* < private > */
GstVideoFormat format;
gint width;
gint height;
GstVideoFilter video_filter;
};
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
......
......@@ -4,7 +4,7 @@ else
JACK_DIR=
endif
if USE_CAIRO_GOBJECT
if USE_CAIRO
CAIRO_DIR=cairo
else
CAIRO_DIR=
......
if USE_CAIRO_GOBJECT
noinst_PROGRAMS = cairo_overlay
endif
cairo_overlay_SOURCES = cairo_overlay.c
cairo_overlay_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS) $(CAIRO_CFLAGS)
......
......@@ -69,8 +69,7 @@ on_message (GstBus * bus, GstMessage * message, gpointer user_data)
typedef struct
{
gboolean valid;
int width;
int height;
GstVideoInfo vinfo;
} CairoOverlayState;
/* 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;
gst_video_format_parse_caps (caps, NULL, &state->width, &state->height);
state->valid = TRUE;
state->valid = gst_video_info_from_caps (&state->vinfo, caps);
}
/* Draw the overlay.
......@@ -91,12 +89,18 @@ draw_overlay (GstElement * overlay, cairo_t * cr, guint64 timestamp,
{
CairoOverlayState *s = (CairoOverlayState *) user_data;
double scale;
int width, height;
if (!s->valid)
return;
width = GST_VIDEO_INFO_WIDTH (&s->vinfo);
height = GST_VIDEO_INFO_HEIGHT (&s->vinfo);
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_move_to (cr, 0, 0);
......@@ -122,7 +126,9 @@ setup_gst_pipeline (CairoOverlayState * overlay_state)
adaptor1 = gst_element_factory_make ("videoconvert", "adaptor1");
cairo_overlay = gst_element_factory_make ("cairooverlay", "overlay");
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 */
g_assert (cairo_overlay);
......@@ -150,12 +156,15 @@ main (int argc, char **argv)
GMainLoop *loop;
GstElement *pipeline;
GstBus *bus;
CairoOverlayState overlay_state = { FALSE, 0, 0 };
CairoOverlayState *overlay_state;
gst_init (&argc, &argv);
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));
gst_bus_add_signal_watch (bus);
......@@ -168,5 +177,6 @@ main (int argc, char **argv)
gst_element_set_state (pipeline, GST_STATE_NULL);
gst_object_unref (pipeline);
g_free (overlay_state);
return 0;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment