eglglessink: Port iOS part to 1.0

This commit is contained in:
Sebastian Dröge 2013-09-23 14:36:40 +02:00
parent f13a574e2b
commit 3d5e214f83
7 changed files with 89 additions and 53 deletions

View file

@ -4,6 +4,7 @@ if HAVE_IOS
DISTRO_SRC = gstegladaptation_eagl.m
else
DISTRO_SRC = gstegladaptation_egl.c video_platform_wrapper.c
GST_EGL_LIBS = $(top_builddir)/gst-libs/gst/egl/libgstegl-$(GST_API_VERSION).la
endif
libgsteglglessink_la_SOURCES = gsteglglessink.c gstegladaptation.c $(DISTRO_SRC)
@ -23,11 +24,10 @@ libgsteglglessink_la_OBJCFLAGS = $(GST_PLUGINS_BAD_OBJCFLAGS) \
libgsteglglessink_la_LIBADD = $(GST_LIBS) $(GST_BASE_LIBS) \
$(GST_PLUGINS_BASE_LIBS) $(EGL_LIBS) $(EGLGLES_LIBS) \
-lgstvideo-$(GST_API_VERSION) \
$(top_builddir)/gst-libs/gst/egl/libgstegl-$(GST_API_VERSION).la
-lgstvideo-$(GST_API_VERSION) $(GST_EGL_LIBS)
if HAVE_IOS
libgsteglglessink_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) -Wl,-framework,OpenGLES -Wl,-framework,QuartzCore -Wl,-framework,IOKit -Wl,-framework,UIKit -Wl,-framework,CoreGraphics -Wl,-framework,CoreFoundation -Wl,-framework,Foundation -W
libgsteglglessink_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) -Wl,-framework,OpenGLES -Wl,-framework,QuartzCore -Wl,-framework,UIKit -Wl,-framework,CoreGraphics -Wl,-framework,CoreFoundation -Wl,-framework,Foundation -W
else
libgsteglglessink_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
endif

View file

@ -273,12 +273,14 @@ gst_egl_adaptation_fill_supported_fbuffer_configs (GstEglAdaptationContext *
copy1 = gst_caps_copy (caps);
copy2 = gst_caps_copy (caps);
#ifndef HAVE_IOS
n = gst_caps_get_size (caps);
for (i = 0; i < n; i++) {
GstCapsFeatures *features =
gst_caps_features_new (GST_CAPS_FEATURE_MEMORY_EGL_IMAGE, NULL);
gst_caps_set_features (caps, i, features);
}
#endif
n = gst_caps_get_size (copy1);
for (i = 0; i < n; i++) {
@ -444,7 +446,7 @@ HANDLE_ERROR:
}
gboolean
gst_egl_adaptation_init_egl_surface (GstEglAdaptationContext * ctx,
gst_egl_adaptation_init_surface (GstEglAdaptationContext * ctx,
GstVideoFormat format)
{
GLboolean ret;
@ -465,7 +467,7 @@ gst_egl_adaptation_init_egl_surface (GstEglAdaptationContext * ctx,
gst_egl_adaptation_query_buffer_preserved (ctx);
gst_egl_adaptation_init_egl_exts (ctx);
gst_egl_adaptation_init_exts (ctx);
/* Save surface dims */
gst_egl_adaptation_update_surface_dimensions (ctx);

View file

@ -67,11 +67,10 @@
#define EGL_EGLEXT_PROTOTYPES
#define GL_GLEXT_PROTOTYPES
#include <gst/egl/egl.h>
#ifdef HAVE_IOS
#include <OpenGLES/ES2/gl.h>
#else
#include <gst/egl/egl.h>
#include <EGL/egl.h>
#include <EGL/eglext.h>
#include <GLES2/gl2.h>
@ -83,18 +82,6 @@
#pragma GCC diagnostic pop
#endif
#define GST_EGLGLESSINK_EGL_MIN_VERSION 1
static const EGLint eglglessink_RGBA8888_attribs[] = {
EGL_RED_SIZE, 8,
EGL_GREEN_SIZE, 8,
EGL_BLUE_SIZE, 8,
EGL_ALPHA_SIZE, 8,
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
EGL_NONE
};
G_BEGIN_DECLS
typedef struct _GstEglAdaptationContext GstEglAdaptationContext;
@ -134,12 +121,12 @@ struct _GstEglAdaptationContext
#ifdef HAVE_IOS
GstEaglContext *eaglctx;
void * window, *used_window;
#else
GstEglGlesRenderContext *eglglesctx;
#endif
GstEGLDisplay *display, *set_display;
EGLNativeWindowType window, used_window;
#endif
GLuint fragshader[2]; /* frame, border */
GLuint vertshader[2]; /* frame, border */
@ -155,10 +142,10 @@ struct _GstEglAdaptationContext
unsigned int position_buffer, index_buffer;
gint n_textures;
EGLint surface_width;
EGLint surface_height;
EGLint pixel_aspect_ratio_n;
EGLint pixel_aspect_ratio_d;
gint surface_width;
gint surface_height;
gint pixel_aspect_ratio_n;
gint pixel_aspect_ratio_d;
gboolean have_vbo;
gboolean have_texture;
@ -194,10 +181,10 @@ gboolean gst_egl_adaptation_create_native_window (GstEglAdaptationContext
void gst_egl_adaptation_destroy_native_window (GstEglAdaptationContext * ctx, gpointer * own_window_data);
GstCaps *gst_egl_adaptation_fill_supported_fbuffer_configs (GstEglAdaptationContext * ctx);
gboolean gst_egl_adaptation_init_egl_display (GstEglAdaptationContext * ctx);
gboolean gst_egl_adaptation_init_display (GstEglAdaptationContext * ctx);
gboolean gst_egl_adaptation_choose_config (GstEglAdaptationContext * ctx);
gboolean gst_egl_adaptation_init_egl_surface (GstEglAdaptationContext * ctx, GstVideoFormat format);
void gst_egl_adaptation_init_egl_exts (GstEglAdaptationContext * ctx);
gboolean gst_egl_adaptation_init_surface (GstEglAdaptationContext * ctx, GstVideoFormat format);
void gst_egl_adaptation_init_exts (GstEglAdaptationContext * ctx);
gboolean gst_egl_adaptation_update_surface_dimensions (GstEglAdaptationContext * ctx);
gboolean _gst_egl_choose_config (GstEglAdaptationContext * ctx, gboolean try_only, gint * num_configs);
@ -209,8 +196,9 @@ void gst_egl_adaptation_set_window (GstEglAdaptationContext * ctx, guintptr wind
gboolean gst_egl_adaptation_context_make_current (GstEglAdaptationContext * ctx, gboolean bind);
void gst_egl_adaptation_cleanup (GstEglAdaptationContext * ctx);
gboolean
gst_egl_adaptation_context_swap_buffers (GstEglAdaptationContext * ctx);
void gst_egl_adaptation_bind_API (GstEglAdaptationContext * ctx);
gboolean gst_egl_adaptation_context_swap_buffers (GstEglAdaptationContext * ctx);
#ifndef HAVE_IOS
/* TODO: The goal is to move this function to gstegl lib (or

View file

@ -129,11 +129,11 @@ gst_egl_adaptation_create_egl_context (GstEglAdaptationContext * ctx)
return FALSE;
/* EAGL needs the context to be set here to allow surface creation */
return gst_egl_adaptation_make_current (ctx, TRUE);
return gst_egl_adaptation_context_make_current (ctx, TRUE);
}
gboolean
gst_egl_adaptation_make_current (GstEglAdaptationContext * ctx,
gst_egl_adaptation_context_make_current (GstEglAdaptationContext * ctx,
gboolean bind)
{
__block EAGLContext *ctx_to_set = nil;
@ -230,7 +230,7 @@ gst_egl_adaptation_create_surface (GstEglAdaptationContext * ctx)
}
gboolean
gst_egl_choose_config (GstEglAdaptationContext * ctx, gboolean try_only, gint * num_configs)
_gst_egl_choose_config (GstEglAdaptationContext * ctx, gboolean try_only, gint * num_configs)
{
CAEAGLLayer *eaglLayer = (CAEAGLLayer *)[ctx->eaglctx->window layer];
NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:
@ -291,7 +291,7 @@ gst_egl_adaptation_update_surface_dimensions (GstEglAdaptationContext *
}
void
gst_egl_adaptation_init_egl_exts (GstEglAdaptationContext * ctx)
gst_egl_adaptation_init_exts (GstEglAdaptationContext * ctx)
{
const gchar *extensions = (const gchar *) glGetString(GL_EXTENSIONS);
NSString *extensionsString = NULL;
@ -342,7 +342,7 @@ gst_egl_adaptation_destroy_context (GstEglAdaptationContext * ctx)
}
gboolean
gst_egl_adaptation_swap_buffers (GstEglAdaptationContext * ctx)
gst_egl_adaptation_context_swap_buffers (GstEglAdaptationContext * ctx)
{
[ctx->eaglctx->eagl_context presentRenderbuffer:GL_RENDERBUFFER];
return TRUE;

View file

@ -67,6 +67,18 @@
#define EGL_SANE_DAR_MIN ((EGL_DISPLAY_SCALING)/10)
#define EGL_SANE_DAR_MAX ((EGL_DISPLAY_SCALING)*10)
#define GST_EGLGLESSINK_EGL_MIN_VERSION 1
static const EGLint eglglessink_RGBA8888_attribs[] = {
EGL_RED_SIZE, 8,
EGL_GREEN_SIZE, 8,
EGL_BLUE_SIZE, 8,
EGL_ALPHA_SIZE, 8,
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
EGL_NONE
};
/*
* GstEglGlesRenderContext:
* @config: Current EGL config
@ -104,7 +116,7 @@ got_egl_error (const char *wtf)
* EGL/GLES extensions.
*/
void
gst_egl_adaptation_init_egl_exts (GstEglAdaptationContext * ctx)
gst_egl_adaptation_init_exts (GstEglAdaptationContext * ctx)
{
#ifndef GST_DISABLE_GST_DEBUG
const char *eglexts;
@ -122,7 +134,7 @@ gst_egl_adaptation_init_egl_exts (GstEglAdaptationContext * ctx)
}
gboolean
gst_egl_adaptation_init_egl_display (GstEglAdaptationContext * ctx)
gst_egl_adaptation_init_display (GstEglAdaptationContext * ctx)
{
GstMessage *msg;
EGLDisplay display;
@ -249,6 +261,12 @@ gst_egl_adaptation_update_surface_dimensions (GstEglAdaptationContext * ctx)
return FALSE;
}
void
gst_egl_adaptation_bind_API (GstEglAdaptationContext * ctx)
{
eglBindAPI (EGL_OPENGL_ES_API);
}
gboolean
gst_egl_adaptation_context_swap_buffers (GstEglAdaptationContext * ctx)
{

View file

@ -142,16 +142,19 @@ static GstStaticPadTemplate gst_eglglessink_sink_template_factory =
GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE_WITH_FEATURES
(GST_CAPS_FEATURE_MEMORY_EGL_IMAGE,
GST_STATIC_CAPS (
#ifndef HAVE_IOS
GST_VIDEO_CAPS_MAKE_WITH_FEATURES (GST_CAPS_FEATURE_MEMORY_EGL_IMAGE,
"{ " "RGBA, BGRA, ARGB, ABGR, " "RGBx, BGRx, xRGB, xBGR, "
"AYUV, Y444, I420, YV12, " "NV12, NV21, Y42B, Y41B, "
"RGB, BGR, RGB16 }") ";"
#endif
GST_VIDEO_CAPS_MAKE_WITH_FEATURES
(GST_CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META,
"{ " "RGBA, BGRA, ARGB, ABGR, " "RGBx, BGRx, xRGB, xBGR, "
"AYUV, Y444, I420, YV12, " "NV12, NV21, Y42B, Y41B, "
"RGB, BGR, RGB16 }") ";" GST_VIDEO_CAPS_MAKE ("{ "
"RGB, BGR, RGB16 }") ";"
GST_VIDEO_CAPS_MAKE ("{ "
"RGBA, BGRA, ARGB, ABGR, " "RGBx, BGRx, xRGB, xBGR, "
"AYUV, Y444, I420, YV12, " "NV12, NV21, Y42B, Y41B, "
"RGB, BGR, RGB16 }")));
@ -213,6 +216,7 @@ static GstFlowReturn gst_eglglessink_queue_object (GstEglGlesSink * sink,
GstMiniObject * obj);
static inline gboolean egl_init (GstEglGlesSink * eglglessink);
#ifndef HAVE_IOS
typedef GstBuffer *(*GstEGLImageBufferPoolSendBlockingAllocate) (GstBufferPool *
pool, gpointer data);
@ -498,6 +502,7 @@ static void
gst_egl_image_buffer_pool_init (GstEGLImageBufferPool * pool)
{
}
#endif
#define parent_class gst_eglglessink_parent_class
G_DEFINE_TYPE_WITH_CODE (GstEglGlesSink, gst_eglglessink, GST_TYPE_VIDEO_SINK,
@ -509,7 +514,7 @@ egl_init (GstEglGlesSink * eglglessink)
{
GstCaps *caps;
if (!gst_egl_adaptation_init_egl_display (eglglessink->egl_context)) {
if (!gst_egl_adaptation_init_display (eglglessink->egl_context)) {
GST_ERROR_OBJECT (eglglessink, "Couldn't init EGL display");
goto HANDLE_ERROR;
}
@ -553,7 +558,7 @@ render_thread_func (GstEglGlesSink * eglglessink)
gst_element_post_message (GST_ELEMENT_CAST (eglglessink), message);
g_value_unset (&val);
eglBindAPI (EGL_OPENGL_ES_API);
gst_egl_adaptation_bind_API (eglglessink->egl_context);
while (gst_data_queue_pop (eglglessink->queue, &item)) {
GstMiniObject *object = item->object;
@ -568,6 +573,7 @@ render_thread_func (GstEglGlesSink * eglglessink)
last_flow = GST_FLOW_NOT_NEGOTIATED;
}
}
#ifndef HAVE_IOS
} else if (GST_IS_QUERY (object)) {
GstQuery *query = GST_QUERY_CAST (object);
GstStructure *s = (GstStructure *) gst_query_get_structure (query);
@ -598,6 +604,7 @@ render_thread_func (GstEglGlesSink * eglglessink)
g_assert_not_reached ();
}
last_flow = GST_FLOW_OK;
#endif
} else if (GST_IS_BUFFER (object)) {
GstBuffer *buf = GST_BUFFER_CAST (item->object);
@ -728,9 +735,11 @@ gst_eglglessink_stop (GstEglGlesSink * eglglessink)
}
eglglessink->last_flow = GST_FLOW_FLUSHING;
#ifndef HAVE_IOS
if (eglglessink->pool)
gst_egl_image_buffer_pool_replace_last_buffer (GST_EGL_IMAGE_BUFFER_POOL
(eglglessink->pool), NULL);
#endif
if (eglglessink->using_own_window) {
gst_egl_adaptation_destroy_native_window (eglglessink->egl_context,
@ -1002,7 +1011,7 @@ gst_eglglessink_set_window_handle (GstVideoOverlay * overlay, guintptr id)
/* OK, we have a new window */
GST_OBJECT_LOCK (eglglessink);
eglglessink->egl_context->window = (EGLNativeWindowType) id;
gst_egl_adaptation_set_window (eglglessink->egl_context, id);
eglglessink->have_window = ((gpointer) id != NULL);
GST_OBJECT_UNLOCK (eglglessink);
@ -1542,7 +1551,9 @@ gst_eglglessink_upload (GstEglGlesSink * eglglessink, GstBuffer * buf)
if (!buf) {
GST_DEBUG_OBJECT (eglglessink, "Rendering previous buffer again");
} else if (buf) {
#ifndef HAVE_IOS
GstMemory *mem;
#endif
GstVideoGLTextureUploadMeta *upload_meta;
crop = gst_buffer_get_video_crop_meta (buf);
@ -1589,6 +1600,7 @@ gst_eglglessink_upload (GstEglGlesSink * eglglessink, GstBuffer * buf)
eglglessink->stride[0] = 1;
eglglessink->stride[1] = 1;
eglglessink->stride[2] = 1;
#ifndef HAVE_IOS
} else if (gst_buffer_n_memory (buf) >= 1 &&
(mem = gst_buffer_peek_memory (buf, 0))
&& gst_is_egl_image_memory (mem)) {
@ -1628,6 +1640,7 @@ gst_eglglessink_upload (GstEglGlesSink * eglglessink, GstBuffer * buf)
eglglessink->stride[0] = 1;
eglglessink->stride[1] = 1;
eglglessink->stride[2] = 1;
#endif
} else {
eglglessink->orientation =
GST_VIDEO_GL_TEXTURE_ORIENTATION_X_NORMAL_Y_NORMAL;
@ -1893,6 +1906,7 @@ gst_eglglessink_query (GstBaseSink * bsink, GstQuery * query)
eglglessink = GST_EGLGLESSINK (bsink);
switch (GST_QUERY_TYPE (query)) {
#ifndef HAVE_IOS
case GST_QUERY_CONTEXT:{
const gchar *context_type;
@ -1914,6 +1928,7 @@ gst_eglglessink_query (GstBaseSink * bsink, GstQuery * query)
}
break;
}
#endif
default:
return GST_BASE_SINK_CLASS (gst_eglglessink_parent_class)->query (bsink,
query);
@ -1924,6 +1939,7 @@ gst_eglglessink_query (GstBaseSink * bsink, GstQuery * query)
static void
gst_eglglessink_set_context (GstElement * element, GstContext * context)
{
#ifndef HAVE_IOS
GstEglGlesSink *eglglessink;
GstEGLDisplay *display = NULL;
@ -1936,11 +1952,13 @@ gst_eglglessink_set_context (GstElement * element, GstContext * context)
eglglessink->egl_context->set_display = display;
GST_OBJECT_UNLOCK (eglglessink);
}
#endif
}
static gboolean
gst_eglglessink_propose_allocation (GstBaseSink * bsink, GstQuery * query)
{
#ifndef HAVE_IOS
GstEglGlesSink *eglglessink;
GstBufferPool *pool;
GstStructure *config;
@ -2036,10 +2054,12 @@ gst_eglglessink_propose_allocation (GstBaseSink * bsink, GstQuery * query)
gst_query_add_allocation_param (query, allocator, &params);
gst_object_unref (allocator);
gst_query_add_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL);
gst_query_add_allocation_meta (query, GST_VIDEO_CROP_META_API_TYPE, NULL);
gst_query_add_allocation_meta (query,
GST_VIDEO_GL_TEXTURE_UPLOAD_META_API_TYPE, NULL);
#endif
gst_query_add_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL);
gst_query_add_allocation_meta (query, GST_VIDEO_CROP_META_API_TYPE, NULL);
return TRUE;
}
@ -2107,14 +2127,14 @@ gst_eglglessink_configure_caps (GstEglGlesSink * eglglessink, GstCaps * caps)
(guintptr) eglglessink->egl_context->used_window);
if (!eglglessink->egl_context->have_surface) {
if (!gst_egl_adaptation_init_egl_surface (eglglessink->egl_context,
if (!gst_egl_adaptation_init_surface (eglglessink->egl_context,
eglglessink->configured_info.finfo->format)) {
GST_ERROR_OBJECT (eglglessink, "Couldn't init EGL surface from window");
goto HANDLE_ERROR;
}
}
gst_egl_adaptation_init_egl_exts (eglglessink->egl_context);
gst_egl_adaptation_init_exts (eglglessink->egl_context);
SUCCEED:
GST_INFO_OBJECT (eglglessink, "Configured caps successfully");
@ -2130,9 +2150,11 @@ gst_eglglessink_setcaps (GstBaseSink * bsink, GstCaps * caps)
{
GstEglGlesSink *eglglessink;
GstVideoInfo info;
#ifndef HAVE_IOS
GstBufferPool *newpool, *oldpool;
GstStructure *config;
GstAllocationParams params = { 0, };
#endif
eglglessink = GST_EGLGLESSINK (bsink);
@ -2150,7 +2172,7 @@ gst_eglglessink_setcaps (GstBaseSink * bsink, GstCaps * caps)
GST_ERROR_OBJECT (eglglessink, "Invalid caps %" GST_PTR_FORMAT, caps);
return FALSE;
}
#ifndef HAVE_IOS
newpool =
gst_egl_image_buffer_pool_new
(gst_eglglessink_egl_image_buffer_pool_send_blocking,
@ -2173,6 +2195,7 @@ gst_eglglessink_setcaps (GstBaseSink * bsink, GstCaps * caps)
if (oldpool)
gst_object_unref (oldpool);
#endif
gst_caps_replace (&eglglessink->current_caps, caps);
@ -2192,20 +2215,22 @@ gst_eglglessink_open (GstEglGlesSink * eglglessink)
static gboolean
gst_eglglessink_close (GstEglGlesSink * eglglessink)
{
#ifndef HAVE_IOS
if (eglglessink->egl_context->display) {
gst_egl_display_unref (eglglessink->egl_context->display);
eglglessink->egl_context->display = NULL;
}
gst_caps_unref (eglglessink->sinkcaps);
eglglessink->sinkcaps = NULL;
eglglessink->egl_started = FALSE;
GST_OBJECT_LOCK (eglglessink);
if (eglglessink->pool)
gst_object_unref (eglglessink->pool);
eglglessink->pool = NULL;
GST_OBJECT_UNLOCK (eglglessink);
#endif
gst_caps_unref (eglglessink->sinkcaps);
eglglessink->sinkcaps = NULL;
eglglessink->egl_started = FALSE;
return TRUE;
}
@ -2424,6 +2449,7 @@ gst_eglglessink_init (GstEglGlesSink * eglglessink)
eglglessink->render_region_user = FALSE;
}
#ifndef HAVE_IOS
static GstBufferPool *
gst_egl_image_buffer_pool_new (GstEGLImageBufferPoolSendBlockingAllocate
blocking_allocate_func, gpointer blocking_allocate_data,
@ -2439,6 +2465,7 @@ gst_egl_image_buffer_pool_new (GstEGLImageBufferPoolSendBlockingAllocate
return (GstBufferPool *) pool;
}
#endif
/* entry point to initialize the plug-in
* initialize the plug-in itself

View file

@ -50,7 +50,6 @@
#include <gst/video/video.h>
#include <gst/video/gstvideosink.h>
#include <gst/base/gstdataqueue.h>
#include <gst/egl/egl.h>
#include "gstegladaptation.h"
@ -107,7 +106,9 @@ struct _GstEglGlesSink
GstVideoInfo configured_info;
gfloat stride[3];
GstVideoGLTextureOrientation orientation;
#ifndef HAVE_IOS
GstBufferPool *pool;
#endif
GstEglAdaptationContext *egl_context;