*
* 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.
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
*/
/**
#endif
#include "gstcairooverlay.h"
-#include "gstcairo-marshal.h"
#include <gst/video/video.h>
#include <cairo.h>
+/* RGB16 is native-endianness in GStreamer */
#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, RGB16 }")
#else
-#define TEMPLATE_CAPS GST_VIDEO_CAPS_xRGB " ; " GST_VIDEO_CAPS_ARGB " ; "
-
+#define TEMPLATE_CAPS GST_VIDEO_CAPS_MAKE("{ xRGB, ARGB, RGB16 }")
#endif
static GstStaticPadTemplate gst_cairo_overlay_src_template =
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
{
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;
+ switch (GST_VIDEO_FRAME_FORMAT (frame)) {
+ case GST_VIDEO_FORMAT_ARGB:
+ case GST_VIDEO_FORMAT_BGRA:
+ format = CAIRO_FORMAT_ARGB32;
+ break;
+ case GST_VIDEO_FORMAT_xRGB:
+ case GST_VIDEO_FORMAT_BGRx:
+ format = CAIRO_FORMAT_RGB24;
+ break;
+ case GST_VIDEO_FORMAT_RGB16:
+ format = CAIRO_FORMAT_RGB16_565;
+ break;
+ default:
+ {
+ GST_WARNING ("No matching cairo format for %s",
+ gst_video_format_to_string (GST_VIDEO_FRAME_FORMAT (frame)));
+ return GST_FLOW_ERROR;
+ }
+ }
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;
}
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);
}
static void
-gst_cairo_overlay_base_init (gpointer g_class)
-{
- GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
-
- gst_element_class_set_details_simple (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:
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);
/**
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_static_pad_template (element_class,
+ &gst_cairo_overlay_sink_template);
+ gst_element_class_add_static_pad_template (element_class,
+ &gst_cairo_overlay_src_template);
}
static void
-gst_cairo_overlay_init (GstCairoOverlay * overlay, GstCairoOverlayClass * klass)
+gst_cairo_overlay_init (GstCairoOverlay * overlay)
{
+ /* nothing to do */
}