[510/906] GstGLImageSink: update for 1.0

This commit is contained in:
Matthew Waters 2012-06-05 22:59:31 +10:00
parent 528816def4
commit d39eb40a40
2 changed files with 65 additions and 135 deletions

View File

@ -25,7 +25,7 @@
* *
* glimagesink renders video frames to a drawable on a local or remote * glimagesink renders video frames to a drawable on a local or remote
* display using OpenGL. This element can receive a Window ID from the * display using OpenGL. This element can receive a Window ID from the
* application through the XOverlay interface and will then render video * application through the VideoOverlay interface and will then render video
* frames in this drawable. * frames in this drawable.
* If no Window ID was provided by the application, the element will * If no Window ID was provided by the application, the element will
* create its own internal window and render into it. * create its own internal window and render into it.
@ -83,15 +83,13 @@
#include "config.h" #include "config.h"
#endif #endif
#include <gst/interfaces/xoverlay.h> #include <gst/video/videooverlay.h>
#include "gstglimagesink.h" #include "gstglimagesink.h"
GST_DEBUG_CATEGORY (gst_debug_glimage_sink); GST_DEBUG_CATEGORY (gst_debug_glimage_sink);
#define GST_CAT_DEFAULT gst_debug_glimage_sink #define GST_CAT_DEFAULT gst_debug_glimage_sink
static void gst_glimage_sink_init_interfaces (GType type);
static void gst_glimage_sink_finalize (GObject * object); static void gst_glimage_sink_finalize (GObject * object);
static void gst_glimage_sink_set_property (GObject * object, guint prop_id, static void gst_glimage_sink_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * param_spec); const GValue * value, GParamSpec * param_spec);
@ -109,40 +107,18 @@ static gboolean gst_glimage_sink_set_caps (GstBaseSink * bsink, GstCaps * caps);
static GstFlowReturn gst_glimage_sink_render (GstBaseSink * bsink, static GstFlowReturn gst_glimage_sink_render (GstBaseSink * bsink,
GstBuffer * buf); GstBuffer * buf);
static void gst_glimage_sink_xoverlay_init (GstXOverlayClass * iface); static void gst_glimage_sink_video_overlay_init (GstVideoOverlayInterface *
static void gst_glimage_sink_set_window_handle (GstXOverlay * overlay, iface);
static void gst_glimage_sink_set_window_handle (GstVideoOverlay * overlay,
guintptr id); guintptr id);
static void gst_glimage_sink_expose (GstXOverlay * overlay); static void gst_glimage_sink_expose (GstVideoOverlay * overlay);
static gboolean gst_glimage_sink_interface_supported (GstImplementsInterface *
iface, GType type);
static void gst_glimage_sink_implements_init (GstImplementsInterfaceClass *
klass);
#ifndef OPENGL_ES2
static GstStaticPadTemplate gst_glimage_sink_template = static GstStaticPadTemplate gst_glimage_sink_template =
GST_STATIC_PAD_TEMPLATE ("sink", GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK, GST_PAD_SINK,
GST_PAD_ALWAYS, GST_PAD_ALWAYS,
GST_STATIC_CAPS (GST_GL_VIDEO_CAPS ";" GST_STATIC_CAPS (GST_GL_VIDEO_CAPS)
GST_VIDEO_CAPS_RGB ";" GST_VIDEO_CAPS_BGR ";"
GST_VIDEO_CAPS_RGBx ";" GST_VIDEO_CAPS_BGRx ";"
GST_VIDEO_CAPS_xRGB ";" GST_VIDEO_CAPS_xBGR ";"
GST_VIDEO_CAPS_RGBA ";" GST_VIDEO_CAPS_BGRA ";"
GST_VIDEO_CAPS_ARGB ";" GST_VIDEO_CAPS_ABGR ";"
GST_VIDEO_CAPS_YUV ("{ I420, YV12, YUY2, UYVY, AYUV }"))
); );
#else
static GstStaticPadTemplate gst_glimage_sink_template =
GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
GST_STATIC_CAPS (GST_GL_VIDEO_CAPS ";"
GST_VIDEO_CAPS_RGB ";"
GST_VIDEO_CAPS_RGBx ";"
GST_VIDEO_CAPS_RGBA ";"
GST_VIDEO_CAPS_YUV ("{ I420, YV12, YUY2, UYVY, AYUV }"))
);
#endif
enum enum
{ {
@ -155,33 +131,12 @@ enum
PROP_PIXEL_ASPECT_RATIO PROP_PIXEL_ASPECT_RATIO
}; };
#define gst_glimage_sink_parent_class parent_class
G_DEFINE_TYPE_WITH_CODE (GstGLImageSink, gst_glimage_sink, G_DEFINE_TYPE_WITH_CODE (GstGLImageSink, gst_glimage_sink,
GST_TYPE_VIDEO_SINK, gst_glimage_sink_init_interfaces); GST_TYPE_VIDEO_SINK, G_IMPLEMENT_INTERFACE (GST_TYPE_VIDEO_OVERLAY,
gst_glimage_sink_video_overlay_init);
static void GST_DEBUG_CATEGORY_INIT (gst_debug_glimage_sink, "glimagesink", 0,
gst_glimage_sink_init_interfaces (GType type) "OpenGL Video Sink"));
{
static const GInterfaceInfo implements_info = {
(GInterfaceInitFunc) gst_glimage_sink_implements_init,
NULL,
NULL
};
static const GInterfaceInfo xoverlay_info = {
(GInterfaceInitFunc) gst_glimage_sink_xoverlay_init,
NULL,
NULL,
};
g_type_add_interface_static (type, GST_TYPE_IMPLEMENTS_INTERFACE,
&implements_info);
g_type_add_interface_static (type, GST_TYPE_X_OVERLAY, &xoverlay_info);
GST_DEBUG_CATEGORY_INIT (gst_debug_glimage_sink, "glimagesink", 0,
"OpenGL Video Sink");
}
static void static void
gst_glimage_sink_class_init (GstGLImageSinkClass * klass) gst_glimage_sink_class_init (GstGLImageSinkClass * klass)
@ -194,7 +149,7 @@ gst_glimage_sink_class_init (GstGLImageSinkClass * klass)
gobject_class = (GObjectClass *) klass; gobject_class = (GObjectClass *) klass;
gstelement_class = (GstElementClass *) klass; gstelement_class = (GstElementClass *) klass;
gstbasesink_class = (GstBaseSinkClass *) klass; gstbasesink_class = (GstBaseSinkClass *) klass;
element_class = GST_ELEMENT_CLASS (g_class); element_class = GST_ELEMENT_CLASS (klass);
gobject_class->set_property = gst_glimage_sink_set_property; gobject_class->set_property = gst_glimage_sink_set_property;
gobject_class->get_property = gst_glimage_sink_get_property; gobject_class->get_property = gst_glimage_sink_get_property;
@ -380,7 +335,7 @@ gst_glimage_sink_query (GstElement * element, GstQuery * query)
switch (GST_QUERY_TYPE (query)) { switch (GST_QUERY_TYPE (query)) {
case GST_QUERY_CUSTOM: case GST_QUERY_CUSTOM:
{ {
GstStructure *structure = gst_query_get_structure (query); GstStructure *structure = gst_query_writable_structure (query);
gst_structure_set (structure, "gstgldisplay", G_TYPE_POINTER, gst_structure_set (structure, "gstgldisplay", G_TYPE_POINTER,
glimage_sink->display, NULL); glimage_sink->display, NULL);
res = GST_ELEMENT_CLASS (parent_class)->query (element, query); res = GST_ELEMENT_CLASS (parent_class)->query (element, query);
@ -507,37 +462,29 @@ gst_glimage_sink_set_caps (GstBaseSink * bsink, GstCaps * caps)
gint par_n, par_d; gint par_n, par_d;
gint display_par_n, display_par_d; gint display_par_n, display_par_d;
guint display_ratio_num, display_ratio_den; guint display_ratio_num, display_ratio_den;
GstVideoFormat format; GstVideoInfo vinfo;
GstStructure *structure;
gboolean is_gl;
GST_DEBUG ("set caps with %" GST_PTR_FORMAT, caps); GST_DEBUG ("set caps with %" GST_PTR_FORMAT, caps);
glimage_sink = GST_GLIMAGE_SINK (bsink); glimage_sink = GST_GLIMAGE_SINK (bsink);
structure = gst_caps_get_structure (caps, 0); ok = gst_video_info_from_caps (&vinfo, caps);
if (gst_structure_has_name (structure, "video/x-raw-gl")) { if (!ok)
is_gl = TRUE; return FALSE;
format = GST_VIDEO_FORMAT_UNKNOWN;
ok = gst_structure_get_int (structure, "width", &width);
ok &= gst_structure_get_int (structure, "height", &height);
} else {
is_gl = FALSE;
ok = gst_video_format_parse_caps (caps, &format, &width, &height);
if (!ok) width = GST_VIDEO_INFO_WIDTH (&vinfo);
return FALSE; height = GST_VIDEO_INFO_HEIGHT (&vinfo);
/* init colorspace conversion if needed */ /* FIXME: Cannot determine GL stream through caps */
ok = gst_gl_display_init_upload (glimage_sink->display, format, /* init colorspace conversion if needed */
width, height, width, height); /*ok = gst_gl_display_init_upload (glimage_sink->display, format,
width, height, width, height);
if (!ok) { if (!ok) {
GST_ELEMENT_ERROR (glimage_sink, RESOURCE, NOT_FOUND, GST_ELEMENT_ERROR (glimage_sink, RESOURCE, NOT_FOUND,
GST_GL_DISPLAY_ERR_MSG (glimage_sink->display), (NULL)); GST_GL_DISPLAY_ERR_MSG (glimage_sink->display), (NULL));
return FALSE; return FALSE;
} } */
}
gst_gl_display_set_client_reshape_callback (glimage_sink->display, gst_gl_display_set_client_reshape_callback (glimage_sink->display,
glimage_sink->clientReshapeCallback); glimage_sink->clientReshapeCallback);
@ -548,11 +495,10 @@ gst_glimage_sink_set_caps (GstBaseSink * bsink, GstCaps * caps)
gst_gl_display_set_client_data (glimage_sink->display, gst_gl_display_set_client_data (glimage_sink->display,
glimage_sink->client_data); glimage_sink->client_data);
ok &= gst_video_parse_caps_framerate (caps, &fps_n, &fps_d); fps_n = GST_VIDEO_INFO_FPS_N (&vinfo);
ok &= gst_video_parse_caps_pixel_aspect_ratio (caps, &par_n, &par_d); fps_d = GST_VIDEO_INFO_FPS_D (&vinfo);
par_n = GST_VIDEO_INFO_PAR_N (&vinfo);
if (!ok) par_d = GST_VIDEO_INFO_PAR_D (&vinfo);
return FALSE;
/* get display's PAR */ /* get display's PAR */
if (glimage_sink->par) { if (glimage_sink->par) {
@ -593,7 +539,6 @@ gst_glimage_sink_set_caps (GstBaseSink * bsink, GstCaps * caps)
GST_VIDEO_SINK_WIDTH (glimage_sink) = width; GST_VIDEO_SINK_WIDTH (glimage_sink) = width;
GST_VIDEO_SINK_HEIGHT (glimage_sink) = height; GST_VIDEO_SINK_HEIGHT (glimage_sink) = height;
glimage_sink->is_gl = is_gl;
glimage_sink->width = width; glimage_sink->width = width;
glimage_sink->height = height; glimage_sink->height = height;
glimage_sink->fps_n = fps_n; glimage_sink->fps_n = fps_n;
@ -602,7 +547,7 @@ gst_glimage_sink_set_caps (GstBaseSink * bsink, GstCaps * caps)
glimage_sink->par_d = par_d; glimage_sink->par_d = par_d;
if (!glimage_sink->window_id && !glimage_sink->new_window_id) if (!glimage_sink->window_id && !glimage_sink->new_window_id)
gst_x_overlay_prepare_xwindow_id (GST_X_OVERLAY (glimage_sink)); gst_video_overlay_prepare_window_handle (GST_VIDEO_OVERLAY (glimage_sink));
return TRUE; return TRUE;
} }
@ -610,31 +555,29 @@ gst_glimage_sink_set_caps (GstBaseSink * bsink, GstCaps * caps)
static GstFlowReturn static GstFlowReturn
gst_glimage_sink_render (GstBaseSink * bsink, GstBuffer * buf) gst_glimage_sink_render (GstBaseSink * bsink, GstBuffer * buf)
{ {
GstGLImageSink *glimage_sink = NULL; GstGLImageSink *glimage_sink;
GstGLBuffer *gl_buffer = NULL;
glimage_sink = GST_GLIMAGE_SINK (bsink); glimage_sink = GST_GLIMAGE_SINK (bsink);
GST_INFO ("buffer size: %d", GST_BUFFER_SIZE (buf)); /* FIXME: implement using GstGLMeta */
//is gl //is gl
if (glimage_sink->is_gl) { /*if (glimage_sink->is_gl) {
//increment gl buffer ref before storage //increment gl buffer ref before storage
gl_buffer = GST_GL_BUFFER (gst_buffer_ref (buf)); gl_buffer = GST_GL_BUFFER (gst_buffer_ref (buf));
} }
//is not gl //is not gl
else { else {
//blocking call //blocking call
gl_buffer = gst_gl_buffer_new (glimage_sink->display, gl_buffer = gst_gl_buffer_new (glimage_sink->display,
glimage_sink->width, glimage_sink->height); glimage_sink->width, glimage_sink->height);
//blocking call //blocking call
gst_gl_display_do_upload (glimage_sink->display, gl_buffer->texture, gst_gl_display_do_upload (glimage_sink->display, gl_buffer->texture,
glimage_sink->width, glimage_sink->height, GST_BUFFER_DATA (buf)); glimage_sink->width, glimage_sink->height, GST_BUFFER_DATA (buf));
//gl_buffer is created in this block, so the gl buffer is already referenced
}
//gl_buffer is created in this block, so the gl buffer is already referenced
}
*/
if (glimage_sink->window_id != glimage_sink->new_window_id) { if (glimage_sink->window_id != glimage_sink->new_window_id) {
glimage_sink->window_id = glimage_sink->new_window_id; glimage_sink->window_id = glimage_sink->new_window_id;
gst_gl_display_set_window_id (glimage_sink->display, gst_gl_display_set_window_id (glimage_sink->display,
@ -642,12 +585,11 @@ gst_glimage_sink_render (GstBaseSink * bsink, GstBuffer * buf)
} }
//the buffer is cleared when an other comes in //the buffer is cleared when an other comes in
if (glimage_sink->stored_buffer) { if (glimage_sink->stored_buffer) {
gst_buffer_unref (GST_BUFFER_CAST (glimage_sink->stored_buffer)); gst_buffer_unref (glimage_sink->stored_buffer);
glimage_sink->stored_buffer = NULL;
} }
//store current buffer //store current buffer
glimage_sink->stored_buffer = gl_buffer; glimage_sink->stored_buffer = buf;
/*
//redisplay opengl scene //redisplay opengl scene
if (gl_buffer->texture && if (gl_buffer->texture &&
gst_gl_display_redisplay (glimage_sink->display, gst_gl_display_redisplay (glimage_sink->display,
@ -659,12 +601,13 @@ gst_glimage_sink_render (GstBaseSink * bsink, GstBuffer * buf)
GST_ELEMENT_ERROR (glimage_sink, RESOURCE, NOT_FOUND, GST_ELEMENT_ERROR (glimage_sink, RESOURCE, NOT_FOUND,
GST_GL_DISPLAY_ERR_MSG (glimage_sink->display), (NULL)); GST_GL_DISPLAY_ERR_MSG (glimage_sink->display), (NULL));
return GST_FLOW_ERROR; return GST_FLOW_ERROR;
} }*/
return GST_FLOW_OK;
} }
static void static void
gst_glimage_sink_xoverlay_init (GstXOverlayClass * iface) gst_glimage_sink_video_overlay_init (GstVideoOverlayInterface * iface)
{ {
iface->set_window_handle = gst_glimage_sink_set_window_handle; iface->set_window_handle = gst_glimage_sink_set_window_handle;
iface->expose = gst_glimage_sink_expose; iface->expose = gst_glimage_sink_expose;
@ -672,7 +615,7 @@ gst_glimage_sink_xoverlay_init (GstXOverlayClass * iface)
static void static void
gst_glimage_sink_set_window_handle (GstXOverlay * overlay, guintptr id) gst_glimage_sink_set_window_handle (GstVideoOverlay * overlay, guintptr id)
{ {
GstGLImageSink *glimage_sink = GST_GLIMAGE_SINK (overlay); GstGLImageSink *glimage_sink = GST_GLIMAGE_SINK (overlay);
gulong window_id = (gulong) id; gulong window_id = (gulong) id;
@ -686,7 +629,7 @@ gst_glimage_sink_set_window_handle (GstXOverlay * overlay, guintptr id)
static void static void
gst_glimage_sink_expose (GstXOverlay * overlay) gst_glimage_sink_expose (GstVideoOverlay * overlay)
{ {
GstGLImageSink *glimage_sink = GST_GLIMAGE_SINK (overlay); GstGLImageSink *glimage_sink = GST_GLIMAGE_SINK (overlay);
@ -703,20 +646,3 @@ gst_glimage_sink_expose (GstXOverlay * overlay)
glimage_sink->keep_aspect_ratio); glimage_sink->keep_aspect_ratio);
} }
} }
static gboolean
gst_glimage_sink_interface_supported (GstImplementsInterface * iface,
GType type)
{
if (type != GST_TYPE_X_OVERLAY)
return FALSE;
return TRUE;
}
static void
gst_glimage_sink_implements_init (GstImplementsInterfaceClass * klass)
{
klass->supported = gst_glimage_sink_interface_supported;
}

View File

@ -29,6 +29,8 @@
#include "gstglbuffer.h" #include "gstglbuffer.h"
G_BEGIN_DECLS
GST_DEBUG_CATEGORY_EXTERN (gst_debug_glimage_sink); GST_DEBUG_CATEGORY_EXTERN (gst_debug_glimage_sink);
#define GST_TYPE_GLIMAGE_SINK \ #define GST_TYPE_GLIMAGE_SINK \
@ -66,7 +68,7 @@ struct _GstGLImageSink
gint par_n, par_d; gint par_n, par_d;
GstGLDisplay *display; GstGLDisplay *display;
GstGLBuffer *stored_buffer; GstBuffer *stored_buffer;
CRCB clientReshapeCallback; CRCB clientReshapeCallback;
CDCB clientDrawCallback; CDCB clientDrawCallback;
@ -83,5 +85,7 @@ struct _GstGLImageSinkClass
GType gst_glimage_sink_get_type(void); GType gst_glimage_sink_get_type(void);
G_END_DECLS
#endif #endif