summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlessandro Decina <alessandro.d@gmail.com>2015-12-11 13:20:05 +1100
committerAlessandro Decina <alessandro.d@gmail.com>2015-12-16 17:03:03 +1100
commit8ae003326157438c12c45589e050c5f446723f61 (patch)
tree445ce9a431c1a66391336b4b2b55a48ea0e51051
parente730b0a8abc4d68e7ebca37a811b601731a30cf7 (diff)
downloadgstreamer-plugins-bad-8ae003326157438c12c45589e050c5f446723f61.tar.gz
applemedia: vtdec: switch to IOSurface on Mac
Switch to using IOSurface instead of CVOpenGLTextureCache on OSX. The latter can't be used anymore to do YUV => RGB with opengl3 on El Capitan as GL_YCBCR_422_APPLE has been removed from the opengl3 driver. Also switch to NV12 from UYVY, which was the only YUV format supported by CVOpenGLTextureCache.
m---------common0
-rw-r--r--sys/applemedia/Makefile.am3
-rw-r--r--sys/applemedia/iosurfacememory.c242
-rw-r--r--sys/applemedia/iosurfacememory.h78
-rw-r--r--sys/applemedia/videotexturecache.h6
-rw-r--r--sys/applemedia/videotexturecache.m139
-rw-r--r--sys/applemedia/vtdec.c16
7 files changed, 410 insertions, 74 deletions
diff --git a/common b/common
-Subproject 86e46630ed8af8d94796859db550a9c3d89c9f6
+Subproject b3199090fa16a545d585a54deaa61b687ac369e
diff --git a/sys/applemedia/Makefile.am b/sys/applemedia/Makefile.am
index 2fb60bd70..c9c511ed2 100644
--- a/sys/applemedia/Makefile.am
+++ b/sys/applemedia/Makefile.am
@@ -79,7 +79,8 @@ libgstapplemedia_la_LDFLAGS += \
else
libgstapplemedia_la_SOURCES += \
- qtkitvideosrc.m
+ qtkitvideosrc.m \
+ iosurfacememory.c
libgstapplemedia_la_LDFLAGS += \
-Wl,-framework -Wl,Cocoa \
diff --git a/sys/applemedia/iosurfacememory.c b/sys/applemedia/iosurfacememory.c
new file mode 100644
index 000000000..2736a27c0
--- /dev/null
+++ b/sys/applemedia/iosurfacememory.c
@@ -0,0 +1,242 @@
+/*
+ * GStreamer
+ * Copyright (C) 2015 Alessandro Decina <twi@centricular.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * 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., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "iosurfacememory.h"
+
+GST_DEBUG_CATEGORY_STATIC (GST_CAT_IO_SURFACE_MEMORY);
+#define GST_CAT_DEFAULT GST_CAT_IO_SURFACE_MEMORY
+
+G_DEFINE_TYPE (GstIOSurfaceMemoryAllocator, gst_io_surface_memory_allocator,
+ GST_TYPE_GL_MEMORY_ALLOCATOR);
+
+static void _io_surface_memory_set_surface (GstIOSurfaceMemory * memory,
+ IOSurfaceRef surface);
+
+static GstAllocator *_io_surface_memory_allocator;
+
+static gboolean
+_io_surface_memory_create (GstGLBaseMemory * bmem, GError ** error)
+{
+ GstGLMemory *gl_mem = (GstGLMemory *) bmem;
+ GstGLContext *context = gl_mem->mem.context;
+ const GstGLFuncs *gl = context->gl_vtable;
+ GLuint target;
+
+ target = gst_gl_texture_target_to_gl (gl_mem->tex_target);
+ gl->GenTextures (1, &gl_mem->tex_id);
+ gl->BindTexture (target, gl_mem->tex_id);
+ gl->BindTexture (target, 0);
+
+ GST_LOG ("generated texture id:%d", gl_mem->tex_id);
+
+ return TRUE;
+}
+
+static void
+_io_surface_memory_destroy (GstGLBaseMemory * gl_mem)
+{
+ GST_GL_BASE_MEMORY_ALLOCATOR_CLASS
+ (gst_io_surface_memory_allocator_parent_class)->destroy (gl_mem);
+ _io_surface_memory_set_surface ((GstIOSurfaceMemory *) gl_mem, NULL);
+}
+
+static gpointer
+_io_surface_memory_allocator_map (GstGLBaseMemory * bmem,
+ GstMapInfo * info, gsize size)
+{
+ GstGLMemory *gl_mem = (GstGLMemory *) bmem;
+ GstIOSurfaceMemory *mem = (GstIOSurfaceMemory *) gl_mem;
+
+ GST_LOG ("mapping surface %p flags %d gl? %d",
+ mem->surface, info->flags, ((info->flags & GST_MAP_GL) != 0));
+
+ if (info->flags & GST_MAP_GL) {
+ return &gl_mem->tex_id;
+ } else if (!(info->flags & GST_MAP_WRITE)) {
+ IOSurfaceLock (mem->surface, kIOSurfaceLockReadOnly, NULL);
+ return IOSurfaceGetBaseAddressOfPlane (mem->surface, gl_mem->plane);
+ } else {
+ GST_ERROR ("couldn't map IOSurface %p flags %d", mem->surface, info->flags);
+ return NULL;
+ }
+}
+
+static void
+_io_surface_memory_allocator_unmap (GstGLBaseMemory * bmem, GstMapInfo * info)
+{
+ GstGLMemory *gl_mem = (GstGLMemory *) bmem;
+ GstIOSurfaceMemory *mem = (GstIOSurfaceMemory *) gl_mem;
+
+ GST_LOG ("unmapping surface %p flags %d gl? %d",
+ mem->surface, info->flags, ((info->flags & GST_MAP_GL) != 0));
+
+ if (!(info->flags & GST_MAP_GL)) {
+ IOSurfaceUnlock (mem->surface, kIOSurfaceLockReadOnly, NULL);
+ }
+}
+
+static GstMemory *
+_mem_alloc (GstAllocator * allocator, gsize size, GstAllocationParams * params)
+{
+ g_warning ("use gst_io_surface_memory_wrapped () to allocate from this "
+ "IOSurface allocator");
+
+ return NULL;
+}
+
+static void
+gst_io_surface_memory_allocator_class_init (GstIOSurfaceMemoryAllocatorClass *
+ klass)
+{
+ GstAllocatorClass *allocator_class = (GstAllocatorClass *) klass;
+ GstGLBaseMemoryAllocatorClass *gl_base_allocator_class =
+ (GstGLBaseMemoryAllocatorClass *) klass;
+
+ allocator_class->alloc = _mem_alloc;
+
+ gl_base_allocator_class->create = _io_surface_memory_create;
+ gl_base_allocator_class->destroy = _io_surface_memory_destroy;
+ gl_base_allocator_class->map = _io_surface_memory_allocator_map;
+ gl_base_allocator_class->unmap = _io_surface_memory_allocator_unmap;
+}
+
+static void
+gst_io_surface_memory_allocator_init (GstIOSurfaceMemoryAllocator * allocator)
+{
+ GstAllocator *alloc = GST_ALLOCATOR_CAST (allocator);
+
+ alloc->mem_type = GST_IO_SURFACE_MEMORY_ALLOCATOR_NAME;
+ GST_OBJECT_FLAG_SET (allocator, GST_ALLOCATOR_FLAG_CUSTOM_ALLOC);
+}
+
+void
+gst_ios_surface_memory_init (void)
+{
+ static volatile gsize _init = 0;
+
+ if (g_once_init_enter (&_init)) {
+ GST_DEBUG_CATEGORY_INIT (GST_CAT_IO_SURFACE_MEMORY, "iosurface", 0,
+ "IOSurface Buffer");
+
+ _io_surface_memory_allocator =
+ g_object_new (GST_TYPE_IO_SURFACE_MEMORY_ALLOCATOR, NULL);
+
+ gst_allocator_register (GST_IO_SURFACE_MEMORY_ALLOCATOR_NAME,
+ gst_object_ref (_io_surface_memory_allocator));
+ g_once_init_leave (&_init, 1);
+ }
+}
+
+gboolean
+gst_is_io_surface_memory (GstMemory * mem)
+{
+ return mem != NULL && mem->allocator != NULL &&
+ g_type_is_a (G_OBJECT_TYPE (mem->allocator),
+ GST_TYPE_IO_SURFACE_MEMORY_ALLOCATOR);
+}
+
+static GstIOSurfaceMemory *
+_io_surface_memory_new (GstGLContext * context,
+ IOSurfaceRef surface,
+ GstGLTextureTarget target,
+ GstVideoInfo * info,
+ guint plane,
+ GstVideoAlignment * valign, gpointer user_data, GDestroyNotify notify)
+{
+ GstIOSurfaceMemory *mem;
+
+ g_return_val_if_fail (target == GST_GL_TEXTURE_TARGET_RECTANGLE, NULL);
+
+ mem = g_slice_new0 (GstIOSurfaceMemory);
+ gst_gl_memory_init (&mem->gl_mem, _io_surface_memory_allocator, NULL, context,
+ target, NULL, info, plane, valign, notify, user_data);
+
+ GST_MINI_OBJECT_FLAG_SET (mem, GST_MEMORY_FLAG_READONLY);
+ GST_MINI_OBJECT_FLAG_SET (mem, GST_MEMORY_FLAG_NO_SHARE);
+
+ mem->surface = NULL;
+ _io_surface_memory_set_surface (mem, surface);
+
+ return mem;
+}
+
+GstIOSurfaceMemory *
+gst_io_surface_memory_wrapped (GstGLContext * context,
+ IOSurfaceRef surface,
+ GstGLTextureTarget target,
+ GstVideoInfo * info,
+ guint plane,
+ GstVideoAlignment * valign, gpointer user_data, GDestroyNotify notify)
+{
+ return _io_surface_memory_new (context, surface, target, info,
+ plane, valign, user_data, notify);
+}
+
+static void
+_io_surface_memory_set_surface (GstIOSurfaceMemory * memory,
+ IOSurfaceRef surface)
+{
+ GstGLMemory *gl_mem = (GstGLMemory *) memory;
+ GstGLContext *context = ((GstGLBaseMemory *) gl_mem)->context;
+ GstGLFuncs *gl = context->gl_vtable;
+
+ if (memory->surface)
+ IOSurfaceDecrementUseCount (memory->surface);
+ memory->surface = surface;
+ if (surface) {
+ GLuint tex_id, tex_target, texifmt, texfmt;
+ guint plane;
+ GstVideoGLTextureType textype;
+ CGLError cglError;
+
+ plane = gl_mem->plane;
+ tex_id = gl_mem->tex_id;
+ tex_target = gst_gl_texture_target_to_gl (gl_mem->tex_target);
+ textype = gst_gl_texture_type_from_format (context,
+ GST_VIDEO_INFO_FORMAT (&gl_mem->info), plane);
+ texifmt = gst_gl_format_from_gl_texture_type (textype);
+ texfmt =
+ gst_gl_sized_gl_format_from_gl_format_type (context, texifmt,
+ GL_UNSIGNED_BYTE);
+ gl->BindTexture (tex_target, tex_id);
+ cglError = CGLTexImageIOSurface2D ((CGLContextObj)
+ gst_gl_context_get_gl_context (context), tex_target, texifmt,
+ IOSurfaceGetWidthOfPlane (surface, plane),
+ IOSurfaceGetHeightOfPlane (surface, plane), texifmt, GL_UNSIGNED_BYTE,
+ surface, plane);
+ gl->BindTexture (tex_target, 0);
+ IOSurfaceIncrementUseCount (surface);
+ GST_DEBUG ("bound surface %p to texture %u: %d", surface, tex_id, cglError);
+ }
+}
+
+void
+gst_io_surface_memory_set_surface (GstIOSurfaceMemory * memory,
+ IOSurfaceRef surface)
+{
+ g_return_if_fail (gst_is_io_surface_memory ((GstMemory *) memory));
+ g_return_if_fail (memory->surface == NULL);
+
+ _io_surface_memory_set_surface (memory, surface);
+}
diff --git a/sys/applemedia/iosurfacememory.h b/sys/applemedia/iosurfacememory.h
new file mode 100644
index 000000000..5d0fbe84b
--- /dev/null
+++ b/sys/applemedia/iosurfacememory.h
@@ -0,0 +1,78 @@
+/*
+ * GStreamer
+ * Copyright (C) 2015 Alessandro Decina <twi@centricular.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * 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., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef _GST_IO_SURFACE_MEMORY_H_
+#define _GST_IO_SURFACE_MEMORY_H_
+
+#include <IOSurface/IOSurface.h>
+#include <gst/gst.h>
+#include <gst/gstallocator.h>
+#include <gst/video/video.h>
+#include <gst/gl/gl.h>
+
+G_BEGIN_DECLS
+
+#define GST_TYPE_IO_SURFACE_MEMORY_ALLOCATOR (gst_io_surface_memory_allocator_get_type())
+GType gst_io_surface_memory_allocator_get_type(void);
+
+#define GST_IS_IO_SURFACE_MEMORY_ALLOCATOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_IO_SURFACE_MEMORY_ALLOCATOR))
+#define GST_IS_IO_SURFACE_MEMORY_ALLOCATOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_IO_SURFACE_MEMORY_ALLOCATOR))
+#define GST_IO_SURFACE_MEMORY_ALLOCATOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_IO_SURFACE_MEMORY_ALLOCATOR, GstIOSurfaceMemoryAllocatorClass))
+#define GST_IO_SURFACE_MEMORY_ALLOCATOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_IO_SURFACE_MEMORY_ALLOCATOR, GstIOSurfaceMemoryAllocator))
+#define GST_IO_SURFACE_MEMORY_ALLOCATOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_IO_SURFACE_MEMORY_ALLOCATOR, GstIOSurfaceMemoryAllocatorClass))
+#define GST_IO_SURFACE_MEMORY_ALLOCATOR_CAST(obj) ((GstIOSurfaceMemoryAllocator *)(obj))
+
+typedef struct _GstIOSurfaceMemory
+{
+ GstGLMemory gl_mem;
+ IOSurfaceRef surface;
+} GstIOSurfaceMemory;
+
+#define GST_IO_SURFACE_MEMORY_ALLOCATOR_NAME "IOSurfaceMemory"
+
+void gst_ios_surface_memory_init (void);
+
+GstIOSurfaceMemory *
+gst_io_surface_memory_wrapped (GstGLContext * context,
+ IOSurfaceRef surface,
+ GstGLTextureTarget target,
+ GstVideoInfo * info,
+ guint plane,
+ GstVideoAlignment *valign,
+ gpointer user_data,
+ GDestroyNotify notify);
+
+void gst_io_surface_memory_set_surface (GstIOSurfaceMemory *memory, IOSurfaceRef surface);
+
+gboolean gst_is_io_surface_memory (GstMemory * mem);
+
+typedef struct _GstIOSurfaceMemoryAllocator
+{
+ GstGLMemoryAllocator allocator;
+} GstIOSurfaceMemoryAllocator;
+
+typedef struct _GstIOSurfaceMemoryAllocatorClass
+{
+ GstGLMemoryAllocatorClass parent_class;
+} GstIOSurfaceMemoryAllocatorClass;
+
+G_END_DECLS
+
+#endif /* _GST_IO_SURFACE_MEMORY_H_ */
diff --git a/sys/applemedia/videotexturecache.h b/sys/applemedia/videotexturecache.h
index 3d6e546db..b9103a664 100644
--- a/sys/applemedia/videotexturecache.h
+++ b/sys/applemedia/videotexturecache.h
@@ -29,10 +29,10 @@ G_BEGIN_DECLS
typedef struct _GstVideoTextureCache
{
GstGLContext *ctx;
-#if !HAVE_IOS
- CVOpenGLTextureCacheRef cache;
-#else
+#if HAVE_IOS
CVOpenGLESTextureCacheRef cache;
+#else
+ GstBufferPool *pool;
#endif
GstVideoInfo input_info;
GstVideoInfo output_info;
diff --git a/sys/applemedia/videotexturecache.m b/sys/applemedia/videotexturecache.m
index c263b32f6..68cb6978f 100644
--- a/sys/applemedia/videotexturecache.m
+++ b/sys/applemedia/videotexturecache.m
@@ -24,6 +24,8 @@
#if !HAVE_IOS
#import <AppKit/AppKit.h>
#include <gst/gl/cocoa/gstglcontext_cocoa.h>
+#include <gst/gl/gstglbufferpool.h>
+#include "iosurfacememory.h"
#endif
#include "videotexturecache.h"
#include "coremediabuffer.h"
@@ -43,19 +45,13 @@ gst_video_texture_cache_new (GstGLContext * ctx)
g_return_val_if_fail (ctx != NULL, NULL);
GstVideoTextureCache *cache = g_new0 (GstVideoTextureCache, 1);
+
cache->ctx = gst_object_ref (ctx);
gst_video_info_init (&cache->input_info);
cache->convert = gst_gl_color_convert_new (cache->ctx);
cache->configured = FALSE;
-#if !HAVE_IOS
- CGLPixelFormatObj pixelFormat =
- gst_gl_context_cocoa_get_pixel_format (GST_GL_CONTEXT_COCOA (ctx));
- CGLContextObj platform_ctx =
- (CGLContextObj) gst_gl_context_get_gl_context (ctx);
- CVOpenGLTextureCacheCreate (kCFAllocatorDefault, NULL, platform_ctx,
- pixelFormat, NULL, &cache->cache);
-#else
+#if HAVE_IOS
CFMutableDictionaryRef cache_attrs =
CFDictionaryCreateMutable (NULL, 0, &kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
@@ -63,6 +59,11 @@ gst_video_texture_cache_new (GstGLContext * ctx)
kCVOpenGLESTextureCacheMaximumTextureAgeKey, 0);
CVOpenGLESTextureCacheCreate (kCFAllocatorDefault, (CFDictionaryRef) cache_attrs,
(CVEAGLContext) gst_gl_context_get_gl_context (ctx), NULL, &cache->cache);
+#else
+ gst_ios_surface_memory_init ();
+#if 0
+ cache->pool = GST_BUFFER_POOL (gst_gl_buffer_pool_new (ctx));
+#endif
#endif
return cache;
@@ -73,10 +74,13 @@ gst_video_texture_cache_free (GstVideoTextureCache * cache)
{
g_return_if_fail (cache != NULL);
-#if !HAVE_IOS
- CVOpenGLTextureCacheRelease (cache->cache);
-#else
+#if HAVE_IOS
CFRelease (cache->cache); /* iOS has no "CVOpenGLESTextureCacheRelease" */
+#else
+#if 0
+ gst_buffer_pool_set_active (cache->pool, FALSE);
+ gst_object_unref (cache->pool);
+#endif
#endif
gst_object_unref (cache->convert);
gst_object_unref (cache->ctx);
@@ -99,8 +103,8 @@ gst_video_texture_cache_set_format (GstVideoTextureCache * cache,
out_caps = gst_caps_copy (out_caps);
features = gst_caps_get_features (out_caps, 0);
gst_caps_features_add (features, GST_CAPS_FEATURE_MEMORY_GL_MEMORY);
- gst_video_info_from_caps (&cache->output_info, out_caps);
-
+ gst_video_info_from_caps (&cache->output_info, out_caps);
+
in_caps = gst_caps_copy (out_caps);
gst_caps_set_simple (in_caps, "format",
G_TYPE_STRING, gst_video_format_to_string (in_format), NULL);
@@ -115,6 +119,18 @@ gst_video_texture_cache_set_format (GstVideoTextureCache * cache,
gst_caps_unref (cache->out_caps);
cache->in_caps = in_caps;
cache->out_caps = out_caps;
+
+#if 0
+ GstStructure *config = gst_buffer_pool_get_config (cache->pool);
+ gst_buffer_pool_config_set_params (config, cache->in_caps,
+ GST_VIDEO_INFO_SIZE (&cache->input_info), 0, 0);
+ gst_buffer_pool_config_set_allocator (config,
+ gst_allocator_find (GST_IO_SURFACE_MEMORY_ALLOCATOR_NAME), NULL);
+ gst_buffer_pool_config_add_option (config,
+ GST_BUFFER_POOL_OPTION_GL_TEXTURE_TARGET_RECTANGLE);
+ gst_buffer_pool_set_config (cache->pool, config);
+ gst_buffer_pool_set_active (cache->pool, TRUE);
+#endif
}
static CVPixelBufferRef
@@ -132,44 +148,21 @@ cv_pixel_buffer_from_gst_buffer (GstBuffer * buffer)
return cm_meta ? cm_meta->pixel_buf : cv_meta->pixbuf;
}
+#if HAVE_IOS
static gboolean
gl_mem_from_buffer (GstVideoTextureCache * cache,
GstBuffer * buffer, GstMemory **mem1, GstMemory **mem2)
{
- gboolean ret = TRUE;
-#if !HAVE_IOS
- CVOpenGLTextureRef texture = NULL;
-#else
CVOpenGLESTextureRef texture = NULL;
-#endif
CVPixelBufferRef pixel_buf = cv_pixel_buffer_from_gst_buffer (buffer);
GstGLTextureTarget gl_target;
*mem1 = NULL;
*mem2 = NULL;
-#if !HAVE_IOS
- CVOpenGLTextureCacheFlush (cache->cache, 0);
-#else
CVOpenGLESTextureCacheFlush (cache->cache, 0);
-#endif
switch (GST_VIDEO_INFO_FORMAT (&cache->input_info)) {
-#if !HAVE_IOS
- case GST_VIDEO_FORMAT_UYVY:
- /* both avfvideosrc and vtdec on OSX when doing GLMemory negotiate UYVY
- * under the hood, which means a single output texture. */
- if (CVOpenGLTextureCacheCreateTextureFromImage (kCFAllocatorDefault,
- cache->cache, pixel_buf, NULL, &texture) != kCVReturnSuccess)
- goto error;
-
- gl_target = gst_gl_texture_target_from_gl (CVOpenGLTextureGetTarget (texture));
-
- *mem1 = (GstMemory *) gst_gl_memory_pbo_wrapped_texture (cache->ctx,
- CVOpenGLTextureGetName (texture), gl_target,
- &cache->input_info, 0, NULL, texture, (GDestroyNotify) CFRelease);
- break;
-#else
case GST_VIDEO_FORMAT_BGRA:
/* avfvideosrc does BGRA on iOS when doing GLMemory */
if (CVOpenGLESTextureCacheCreateTextureFromImage (kCFAllocatorDefault,
@@ -223,33 +216,48 @@ gl_mem_from_buffer (GstVideoTextureCache * cache,
&cache->input_info, 0, NULL, texture, (GDestroyNotify) CFRelease);
break;
}
-#endif
- default:
- g_warn_if_reached ();
- ret = FALSE;
- }
-
- if (ret && !cache->configured) {
- const gchar *target_str = gst_gl_texture_target_to_string (gl_target);
- gst_caps_set_simple (cache->in_caps, "texture-target", G_TYPE_STRING, target_str, NULL);
- gst_caps_set_simple (cache->out_caps, "texture-target", G_TYPE_STRING, "2D", NULL);
-
- ret = gst_gl_color_convert_set_caps (cache->convert, cache->in_caps, cache->out_caps);
- cache->configured = ret;
+ default:
+ g_warn_if_reached ();
+ goto error;
}
- return ret;
+ return TRUE;
error:
- ret = FALSE;
-
if (*mem1)
gst_memory_unref (*mem1);
if (*mem2)
gst_memory_unref (*mem2);
- return ret;
+ return FALSE;
}
+#else /* !HAVE_IOS */
+
+static gboolean
+gl_mem_from_buffer (GstVideoTextureCache * cache,
+ GstBuffer * buffer, GstMemory **mem1, GstMemory **mem2)
+{
+ CVPixelBufferRef pixel_buf = cv_pixel_buffer_from_gst_buffer (buffer);
+ IOSurfaceRef surface = CVPixelBufferGetIOSurface(pixel_buf);
+
+ *mem1 = *mem2 = NULL;
+ for (int i = 0; i < GST_VIDEO_INFO_N_PLANES (&cache->input_info); i++) {
+ GstIOSurfaceMemory *mem;
+
+ CFRetain (pixel_buf);
+ mem = gst_io_surface_memory_wrapped (cache->ctx,
+ surface, GST_GL_TEXTURE_TARGET_RECTANGLE, &cache->input_info,
+ i, NULL, pixel_buf, (GDestroyNotify) CFRelease);
+
+ if (i == 0)
+ *mem1 = (GstMemory *) mem;
+ else
+ *mem2 = (GstMemory *) mem;
+ }
+
+ return TRUE;
+}
+#endif
static void
_do_get_gl_buffer (GstGLContext * context, ContextThreadData * data)
@@ -260,10 +268,31 @@ _do_get_gl_buffer (GstGLContext * context, ContextThreadData * data)
if (!gl_mem_from_buffer (cache, buffer, &mem1, &mem2)) {
gst_buffer_unref (buffer);
- data->output_buffer = NULL;
return;
}
+ if (!cache->configured) {
+ cache->in_caps = gst_caps_make_writable (cache->in_caps);
+#if HAVE_IOS
+ gst_caps_set_simple (cache->in_caps, "texture-target", G_TYPE_STRING, GST_GL_TEXTURE_TARGET_2D_STR, NULL);
+#else
+ gst_caps_set_simple (cache->in_caps, "texture-target", G_TYPE_STRING, GST_GL_TEXTURE_TARGET_RECTANGLE_STR, NULL);
+#endif
+ gst_caps_set_simple (cache->out_caps, "texture-target", G_TYPE_STRING, "2D", NULL);
+
+ if (!gst_gl_color_convert_set_caps (cache->convert, cache->in_caps, cache->out_caps)) {
+ if (mem1)
+ gst_memory_unref (mem1);
+ if (mem2)
+ gst_memory_unref (mem2);
+ gst_buffer_unref (buffer);
+
+ return;
+ }
+
+ cache->configured = TRUE;
+ }
+
gst_buffer_append_memory (buffer, mem1);
if (mem2)
gst_buffer_append_memory (buffer, mem2);
diff --git a/sys/applemedia/vtdec.c b/sys/applemedia/vtdec.c
index aa3111b13..54640aeb2 100644
--- a/sys/applemedia/vtdec.c
+++ b/sys/applemedia/vtdec.c
@@ -108,11 +108,7 @@ const CFStringRef
CFSTR ("RequireHardwareAcceleratedVideoDecoder");
#endif
-#ifdef HAVE_IOS
#define GST_VTDEC_VIDEO_FORMAT_STR "NV12"
-#else
-#define GST_VTDEC_VIDEO_FORMAT_STR "UYVY"
-#endif
#define VIDEO_SRC_CAPS \
"video/x-raw(" GST_CAPS_FEATURE_MEMORY_GL_MEMORY "), " \
@@ -231,7 +227,6 @@ query_gl_context (GstVtdec * vtdec)
static void
setup_texture_cache (GstVtdec * vtdec, GstGLContext * context)
{
- GstVideoFormat internal_format;
GstVideoCodecState *output_state;
g_return_if_fail (vtdec->texture_cache == NULL);
@@ -239,14 +234,9 @@ setup_texture_cache (GstVtdec * vtdec, GstGLContext * context)
GST_INFO_OBJECT (vtdec, "Setting up texture cache. GL context %p", context);
output_state = gst_video_decoder_get_output_state (GST_VIDEO_DECODER (vtdec));
-#ifdef HAVE_IOS
- internal_format = GST_VIDEO_FORMAT_NV12;
-#else
- internal_format = GST_VIDEO_FORMAT_UYVY;
-#endif
vtdec->texture_cache = gst_video_texture_cache_new (context);
gst_video_texture_cache_set_format (vtdec->texture_cache,
- internal_format, output_state->caps);
+ GST_VIDEO_FORMAT_NV12, output_state->caps);
gst_video_codec_state_unref (output_state);
}
@@ -486,11 +476,7 @@ gst_vtdec_create_session (GstVtdec * vtdec, GstVideoFormat format)
cv_format = kCVPixelFormatType_422YpCbCr8;
break;
case GST_VIDEO_FORMAT_RGBA:
-#ifdef HAVE_IOS
cv_format = kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange;
-#else
- cv_format = kCVPixelFormatType_422YpCbCr8;
-#endif
break;
default:
g_warn_if_reached ();