diff options
author | Alessandro Decina <alessandro.d@gmail.com> | 2015-12-11 13:20:05 +1100 |
---|---|---|
committer | Alessandro Decina <alessandro.d@gmail.com> | 2015-12-16 17:03:03 +1100 |
commit | 8ae003326157438c12c45589e050c5f446723f61 (patch) | |
tree | 445ce9a431c1a66391336b4b2b55a48ea0e51051 | |
parent | e730b0a8abc4d68e7ebca37a811b601731a30cf7 (diff) | |
download | gstreamer-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--------- | common | 0 | ||||
-rw-r--r-- | sys/applemedia/Makefile.am | 3 | ||||
-rw-r--r-- | sys/applemedia/iosurfacememory.c | 242 | ||||
-rw-r--r-- | sys/applemedia/iosurfacememory.h | 78 | ||||
-rw-r--r-- | sys/applemedia/videotexturecache.h | 6 | ||||
-rw-r--r-- | sys/applemedia/videotexturecache.m | 139 | ||||
-rw-r--r-- | sys/applemedia/vtdec.c | 16 |
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 (); |