From 0560946c82477633a7dba537037614f0000c5047 Mon Sep 17 00:00:00 2001 From: Matthew Waters Date: Wed, 28 Aug 2019 18:59:35 +1000 Subject: [PATCH] videotexturecache: implement GL specifics as a subclass --- sys/applemedia/avfvideosrc.m | 12 +- sys/applemedia/corevideobuffer.c | 11 +- sys/applemedia/meson.build | 1 + sys/applemedia/videotexturecache-gl.h | 59 ++++++ sys/applemedia/videotexturecache-gl.m | 262 ++++++++++++++++++++++++++ sys/applemedia/videotexturecache.h | 17 +- sys/applemedia/videotexturecache.m | 232 ++--------------------- sys/applemedia/vtdec.c | 14 +- 8 files changed, 374 insertions(+), 234 deletions(-) create mode 100644 sys/applemedia/videotexturecache-gl.h create mode 100644 sys/applemedia/videotexturecache-gl.m diff --git a/sys/applemedia/avfvideosrc.m b/sys/applemedia/avfvideosrc.m index bc7bf19e4d..097bf34935 100644 --- a/sys/applemedia/avfvideosrc.m +++ b/sys/applemedia/avfvideosrc.m @@ -32,7 +32,7 @@ #include #include #include "coremediabuffer.h" -#include "videotexturecache.h" +#include "videotexturecache-gl.h" #define DEFAULT_DEVICE_INDEX -1 #define DEFAULT_POSITION GST_AVF_VIDEO_SOURCE_POSITION_DEFAULT @@ -1088,15 +1088,19 @@ didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer gst_query_parse_allocation (query, &alloc_caps, NULL); features = gst_caps_get_features (alloc_caps, 0); if (gst_caps_features_contains (features, GST_CAPS_FEATURE_MEMORY_GL_MEMORY)) { + GstVideoTextureCacheGL *cache_gl; + + cache_gl = textureCache ? GST_VIDEO_TEXTURE_CACHE_GL (textureCache) : NULL; + gst_gl_context_helper_ensure_context (ctxh); GST_INFO_OBJECT (element, "pushing textures, context %p old context %p", - ctxh->context, textureCache ? textureCache->ctx : NULL); - if (textureCache && textureCache->ctx != ctxh->context) { + ctxh->context, cache_gl ? cache_gl->ctx : NULL); + if (cache_gl && cache_gl->ctx != ctxh->context) { g_object_unref (textureCache); textureCache = NULL; } if (!textureCache) - textureCache = gst_video_texture_cache_new (ctxh->context); + textureCache = gst_video_texture_cache_gl_new (ctxh->context); gst_video_texture_cache_set_format (textureCache, format, alloc_caps); } diff --git a/sys/applemedia/corevideobuffer.c b/sys/applemedia/corevideobuffer.c index eba2592fbf..fdebf20af9 100644 --- a/sys/applemedia/corevideobuffer.c +++ b/sys/applemedia/corevideobuffer.c @@ -25,6 +25,7 @@ #if !HAVE_IOS #include "iosurfacememory.h" #endif +#include "videotexturecache-gl.h" static const GstMetaInfo *gst_core_video_meta_get_info (void); @@ -107,13 +108,15 @@ _create_glmem (GstAppleCoreVideoPixelBuffer * gpixbuf, return gst_video_texture_cache_create_memory (cache, gpixbuf, plane, size); #else GstIOSurfaceMemory *mem; - GstGLFormat tex_format = - gst_gl_format_from_video_info (cache->ctx, info, plane); CVPixelBufferRef pixel_buf = gpixbuf->buf; IOSurfaceRef surface = CVPixelBufferGetIOSurface (pixel_buf); + GstGLFormat tex_format; + GstVideoTextureCacheGL *cache_gl = GST_VIDEO_TEXTURE_CACHE_GL (cache); + + tex_format = gst_gl_format_from_video_info (cache_gl->ctx, info, plane); CFRetain (pixel_buf); - mem = gst_io_surface_memory_wrapped (cache->ctx, + mem = gst_io_surface_memory_wrapped (cache_gl->ctx, surface, GST_GL_TEXTURE_TARGET_RECTANGLE, tex_format, info, plane, NULL, pixel_buf, (GDestroyNotify) CFRelease); return GST_MEMORY_CAST (mem); @@ -132,7 +135,7 @@ gst_core_video_wrap_pixel_buffer (GstBuffer * buf, UInt32 size; GstAppleCoreVideoPixelBuffer *gpixbuf; GstMemory *mem = NULL; - gboolean do_gl = cache != NULL; + gboolean do_gl = GST_IS_VIDEO_TEXTURE_CACHE_GL (cache); gpixbuf = gst_apple_core_video_pixel_buffer_new (pixel_buf); diff --git a/sys/applemedia/meson.build b/sys/applemedia/meson.build index 3649eac275..5a093b2dda 100644 --- a/sys/applemedia/meson.build +++ b/sys/applemedia/meson.build @@ -5,6 +5,7 @@ applemedia_sources = [ 'corevideobuffer.c', 'coremediabuffer.c', 'videotexturecache.m', + 'videotexturecache-gl.m', 'atdec.c', 'glcontexthelper.c' ] diff --git a/sys/applemedia/videotexturecache-gl.h b/sys/applemedia/videotexturecache-gl.h new file mode 100644 index 0000000000..e986bfb324 --- /dev/null +++ b/sys/applemedia/videotexturecache-gl.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2015 Alessandro Decina + * + * 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_CORE_VIDEO_TEXTURE_CACHE_GL_H__ +#define __GST_CORE_VIDEO_TEXTURE_CACHE_GL_H__ + +#include +#include +#include "corevideomemory.h" +#include "videotexturecache.h" + +G_BEGIN_DECLS + +#define GST_TYPE_VIDEO_TEXTURE_CACHE_GL (gst_video_texture_cache_gl_get_type()) +#define GST_VIDEO_TEXTURE_CACHE_GL(o) (G_TYPE_CHECK_INSTANCE_CAST((o), GST_TYPE_VIDEO_TEXTURE_CACHE_GL, GstVideoTextureCacheGL)) +#define GST_VIDEO_TEXTURE_CACHE_GL_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GST_TYPE_VIDEO_TEXTURE_CACHE_GL, GstVideoTextureCacheGLClass)) +#define GST_IS_VIDEO_TEXTURE_CACHE_GL(o) (G_TYPE_CHECK_INSTANCE_TYPE((o), GST_TYPE_VIDEO_TEXTURE_CACHE_GL)) +#define GST_IS_VIDEO_TEXTURE_CACHE_GL_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE((k), GST_TYPE_VIDEO_TEXTURE_CACHE_GL)) +#define GST_VIDEO_TEXTURE_CACHE_GL_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS((o), GST_TYPE_VIDEO_TEXTURE_CACHE_GL, GstVideoTextureCacheGLClass)) +GType gst_video_texture_cache_gl_get_type (void); + +typedef struct _GstVideoTextureCacheGL +{ + GstVideoTextureCache parent; + + GstGLContext *ctx; +#if HAVE_IOS + CVOpenGLESTextureCacheRef cache; +#else + GstBufferPool *pool; +#endif +} GstVideoTextureCacheGL; + +typedef struct _GstVideoTextureCacheGLClass +{ + GstVideoTextureCacheClass parent_class; +} GstVideoTextureCacheGLClass; + +GstVideoTextureCache * gst_video_texture_cache_gl_new (GstGLContext * ctx); + +G_END_DECLS + +#endif /* __GST_CORE_VIDEO_TEXTURE_CACHE_H__ */ diff --git a/sys/applemedia/videotexturecache-gl.m b/sys/applemedia/videotexturecache-gl.m new file mode 100644 index 0000000000..00743faf21 --- /dev/null +++ b/sys/applemedia/videotexturecache-gl.m @@ -0,0 +1,262 @@ +/* + * Copyright (C) 2010 Ole André Vadla Ravnås + * + * 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 + +#if !HAVE_IOS +#import +#include "iosurfacememory.h" +#endif +#include "iosglmemory.h" +#include "videotexturecache-gl.h" +#include "coremediabuffer.h" +#include "corevideobuffer.h" +#include "vtutil.h" + +G_DEFINE_TYPE (GstVideoTextureCacheGL, gst_video_texture_cache_gl, GST_TYPE_VIDEO_TEXTURE_CACHE); + +typedef struct _ContextThreadData +{ + GstVideoTextureCacheGL *cache; + GstAppleCoreVideoPixelBuffer *gpixbuf; + guint plane; + gsize size; + GstMemory *memory; +} ContextThreadData; + +typedef struct _TextureWrapper +{ +#if HAVE_IOS + CVOpenGLESTextureCacheRef cache; + CVOpenGLESTextureRef texture; +#else + CVOpenGLTextureCacheRef cache; + CVOpenGLTextureRef texture; +#endif +} TextureWrapper; + +enum +{ + PROP_0, + PROP_CONTEXT, +}; + +static GstMemory * gst_video_texture_cache_gl_create_memory (GstVideoTextureCache * cache, + GstAppleCoreVideoPixelBuffer *gpixbuf, guint plane, gsize size); + +GstVideoTextureCache * +gst_video_texture_cache_gl_new (GstGLContext * ctx) +{ + g_return_val_if_fail (GST_IS_GL_CONTEXT (ctx), NULL); + + return g_object_new (GST_TYPE_VIDEO_TEXTURE_CACHE_GL, + "context", ctx, NULL); +} + +static void +gst_video_texture_cache_gl_finalize (GObject * object) +{ + GstVideoTextureCacheGL *cache_gl = GST_VIDEO_TEXTURE_CACHE_GL (object); + +#if HAVE_IOS + CFRelease (cache_gl->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_gl->ctx); + + G_OBJECT_CLASS (gst_video_texture_cache_gl_parent_class)->finalize (object); +} + +static void +gst_video_texture_cache_gl_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec) +{ + GstVideoTextureCacheGL *cache_gl = GST_VIDEO_TEXTURE_CACHE_GL (object); + + switch (prop_id) { + case PROP_CONTEXT: + cache_gl->ctx = g_value_dup_object (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gst_video_texture_cache_gl_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec) +{ + GstVideoTextureCacheGL *cache_gl = GST_VIDEO_TEXTURE_CACHE_GL (object); + + switch (prop_id) { + case PROP_CONTEXT: + g_value_set_object (value, cache_gl->ctx); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gst_video_texture_cache_gl_constructed (GObject * object) +{ + GstVideoTextureCacheGL *cache_gl = GST_VIDEO_TEXTURE_CACHE_GL (object); + + g_return_if_fail (GST_IS_GL_CONTEXT (cache_gl->ctx)); + +#if HAVE_IOS + CFMutableDictionaryRef cache_attrs = + CFDictionaryCreateMutable (NULL, 0, &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + CVOpenGLESTextureCacheCreate (kCFAllocatorDefault, (CFDictionaryRef) cache_attrs, + (__bridge CVEAGLContext) (gpointer) gst_gl_context_get_gl_context (cache_gl->ctx), NULL, &cache_gl->cache); +#else + gst_ios_surface_memory_init (); +#if 0 + cache->pool = GST_BUFFER_POOL (gst_gl_buffer_pool_new (ctx)); +#endif +#endif +} + +static void +gst_video_texture_cache_gl_init (GstVideoTextureCacheGL * cache_gl) +{ +} + +static void +gst_video_texture_cache_gl_class_init (GstVideoTextureCacheGLClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + GstVideoTextureCacheClass *cache_class = (GstVideoTextureCacheClass *) klass; + + gobject_class->set_property = gst_video_texture_cache_gl_set_property; + gobject_class->get_property = gst_video_texture_cache_gl_get_property; + gobject_class->constructed = gst_video_texture_cache_gl_constructed; + gobject_class->finalize = gst_video_texture_cache_gl_finalize; + + g_object_class_install_property (gobject_class, PROP_CONTEXT, + g_param_spec_object ("context", "Context", + "Associated OpenGL context", GST_TYPE_GL_CONTEXT, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)); + + cache_class->create_memory = gst_video_texture_cache_gl_create_memory; +} + +#if HAVE_IOS +static void +gst_video_texture_cache_gl_release_texture (TextureWrapper *data) +{ + CFRelease(data->texture); + CFRelease(data->cache); + g_free(data); +} + +static void +_do_create_memory (GstGLContext * context, ContextThreadData * data) +{ + CVOpenGLESTextureRef texture = NULL; + GstVideoTextureCache *cache = GST_VIDEO_TEXTURE_CACHE (data->cache); + GstVideoTextureCacheGL *cache_gl = data->cache; + GstAppleCoreVideoPixelBuffer *gpixbuf = data->gpixbuf; + CVPixelBufferRef pixel_buf = gpixbuf->buf; + guint plane = data->plane; + gssize size = data->size; + GstGLTextureTarget gl_target; + GstAppleCoreVideoMemory *memory; + GstIOSGLMemory *gl_memory; + GstGLFormat texformat; + + switch (GST_VIDEO_INFO_FORMAT (&cache->input_info)) { + case GST_VIDEO_FORMAT_BGRA: + if (CVOpenGLESTextureCacheCreateTextureFromImage (kCFAllocatorDefault, + cache_gl->cache, pixel_buf, NULL, GL_TEXTURE_2D, GL_RGBA, + GST_VIDEO_INFO_WIDTH (&cache->input_info), + GST_VIDEO_INFO_HEIGHT (&cache->input_info), + GL_RGBA, GL_UNSIGNED_BYTE, 0, &texture) != kCVReturnSuccess) + goto error; + + texformat = GST_GL_RGBA; + plane = 0; + goto success; + case GST_VIDEO_FORMAT_NV12: { + GstGLFormat texifmt, texfmt; + + if (plane == 0) + texformat = GST_GL_LUMINANCE; + else + texformat = GST_GL_LUMINANCE_ALPHA; + texfmt = gst_gl_sized_gl_format_from_gl_format_type (cache_gl->ctx, texformat, GL_UNSIGNED_BYTE); + + if (CVOpenGLESTextureCacheCreateTextureFromImage (kCFAllocatorDefault, + cache_gl->cache, pixel_buf, NULL, GL_TEXTURE_2D, texformat, + GST_VIDEO_INFO_COMP_WIDTH (&cache->input_info, plane), + GST_VIDEO_INFO_COMP_HEIGHT (&cache->input_info, plane), + texfmt, GL_UNSIGNED_BYTE, plane, &texture) != kCVReturnSuccess) + goto error; + + goto success; + } + default: + g_warn_if_reached (); + goto error; + } + +success: { + TextureWrapper *texture_data = g_new0 (TextureWrapper, 1); + CFRetain(cache_gl->cache); + texture_data->cache = cache_gl->cache; + texture_data->texture = texture; + gl_target = gst_gl_texture_target_from_gl (CVOpenGLESTextureGetTarget (texture)); + memory = gst_apple_core_video_memory_new_wrapped (gpixbuf, plane, size); + gl_memory = gst_ios_gl_memory_new_wrapped (context, memory, + gl_target, texformat, CVOpenGLESTextureGetName (texture), &cache->input_info, + plane, NULL, texture_data, (GDestroyNotify) gst_video_texture_cache_gl_release_texture); + + data->memory = GST_MEMORY_CAST (gl_memory); + + return; +} + +error: + data->memory = NULL; +} +#endif + +static GstMemory * +gst_video_texture_cache_gl_create_memory (GstVideoTextureCache * cache, + GstAppleCoreVideoPixelBuffer *gpixbuf, guint plane, gsize size) +{ + GstVideoTextureCacheGL *cache_gl = GST_VIDEO_TEXTURE_CACHE_GL (cache); + ContextThreadData data = {cache_gl, gpixbuf, plane, size, NULL}; + +#if HAVE_IOS + gst_gl_context_thread_add (cache_gl->ctx, + (GstGLContextThreadFunc) _do_create_memory, &data); +#endif + + return data.memory; +} diff --git a/sys/applemedia/videotexturecache.h b/sys/applemedia/videotexturecache.h index fcfcf2a439..0cbe3ee9c6 100644 --- a/sys/applemedia/videotexturecache.h +++ b/sys/applemedia/videotexturecache.h @@ -21,7 +21,6 @@ #define __GST_CORE_VIDEO_TEXTURE_CACHE_H__ #include -#include #include "corevideomemory.h" G_BEGIN_DECLS @@ -38,12 +37,6 @@ typedef struct _GstVideoTextureCache { GObject parent; - GstGLContext *ctx; -#if HAVE_IOS - CVOpenGLESTextureCacheRef cache; -#else - GstBufferPool *pool; -#endif GstVideoInfo input_info; GstVideoInfo output_info; @@ -55,9 +48,17 @@ typedef struct _GstVideoTextureCache typedef struct _GstVideoTextureCacheClass { GObjectClass parent_class; + + void (*set_format) (GstVideoTextureCache * cache, + GstVideoFormat in_format, + GstCaps * out_caps); + + GstMemory * (*create_memory) (GstVideoTextureCache * cache, + GstAppleCoreVideoPixelBuffer *gpixbuf, + guint plane, + gsize size); } GstVideoTextureCacheClass; -GstVideoTextureCache * gst_video_texture_cache_new (GstGLContext * ctx); void gst_video_texture_cache_set_format (GstVideoTextureCache * cache, GstVideoFormat in_format, GstCaps * out_caps); diff --git a/sys/applemedia/videotexturecache.m b/sys/applemedia/videotexturecache.m index 21e0bb1bd8..2ecf6ae201 100644 --- a/sys/applemedia/videotexturecache.m +++ b/sys/applemedia/videotexturecache.m @@ -23,127 +23,30 @@ #if !HAVE_IOS #import -#include "iosurfacememory.h" #endif -#include "iosglmemory.h" #include "videotexturecache.h" #include "coremediabuffer.h" #include "corevideobuffer.h" #include "vtutil.h" -G_DEFINE_TYPE (GstVideoTextureCache, gst_video_texture_cache, G_TYPE_OBJECT); +G_DEFINE_ABSTRACT_TYPE (GstVideoTextureCache, gst_video_texture_cache, G_TYPE_OBJECT); -typedef struct _ContextThreadData -{ - GstVideoTextureCache *cache; - GstAppleCoreVideoPixelBuffer *gpixbuf; - guint plane; - gsize size; - GstMemory *memory; -} ContextThreadData; - -typedef struct _TextureWrapper -{ -#if HAVE_IOS - CVOpenGLESTextureCacheRef cache; - CVOpenGLESTextureRef texture; -#else - CVOpenGLTextureCacheRef cache; - CVOpenGLTextureRef texture; -#endif -} TextureWrapper; - -enum -{ - PROP_0, - PROP_CONTEXT, -}; - -GstVideoTextureCache * -gst_video_texture_cache_new (GstGLContext * ctx) -{ - g_return_val_if_fail (GST_IS_GL_CONTEXT (ctx), NULL); - - return g_object_new (GST_TYPE_VIDEO_TEXTURE_CACHE, - "context", ctx, NULL); -} +static void gst_video_texture_cache_default_set_format (GstVideoTextureCache * cache, + GstVideoFormat in_format, GstCaps * out_caps); static void gst_video_texture_cache_finalize (GObject * object) { GstVideoTextureCache *cache = GST_VIDEO_TEXTURE_CACHE (object); -#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->ctx); if (cache->in_caps) gst_caps_unref (cache->in_caps); if (cache->out_caps) gst_caps_unref (cache->out_caps); - g_free (cache); G_OBJECT_CLASS (gst_video_texture_cache_parent_class)->finalize (object); } -static void -gst_video_texture_cache_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec) -{ - GstVideoTextureCache *cache = GST_VIDEO_TEXTURE_CACHE (object); - - switch (prop_id) { - case PROP_CONTEXT: - cache->ctx = g_value_dup_object (value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gst_video_texture_cache_get_property (GObject * object, guint prop_id, - GValue * value, GParamSpec * pspec) -{ - GstVideoTextureCache *cache = GST_VIDEO_TEXTURE_CACHE (object); - - switch (prop_id) { - case PROP_CONTEXT: - g_value_set_object (value, cache->ctx); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gst_video_texture_cache_constructed (GObject * object) -{ - GstVideoTextureCache * cache = GST_VIDEO_TEXTURE_CACHE (object); - - g_return_if_fail (GST_IS_GL_CONTEXT (cache->ctx)); - -#if HAVE_IOS - CFMutableDictionaryRef cache_attrs = - CFDictionaryCreateMutable (NULL, 0, &kCFTypeDictionaryKeyCallBacks, - &kCFTypeDictionaryValueCallBacks); - CVOpenGLESTextureCacheCreate (kCFAllocatorDefault, (CFDictionaryRef) cache_attrs, - (__bridge CVEAGLContext) (gpointer)gst_gl_context_get_gl_context (cache->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 -} - static void gst_video_texture_cache_init (GstVideoTextureCache * cache) { @@ -155,19 +58,13 @@ gst_video_texture_cache_class_init (GstVideoTextureCacheClass *klass) { GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - gobject_class->set_property = gst_video_texture_cache_set_property; - gobject_class->get_property = gst_video_texture_cache_get_property; - gobject_class->constructed = gst_video_texture_cache_constructed; gobject_class->finalize = gst_video_texture_cache_finalize; - g_object_class_install_property (gobject_class, PROP_CONTEXT, - g_param_spec_object ("context", "Context", - "Associated OpenGL context", GST_TYPE_GL_CONTEXT, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)); + klass->set_format = gst_video_texture_cache_default_set_format; } -void -gst_video_texture_cache_set_format (GstVideoTextureCache * cache, +static void +gst_video_texture_cache_default_set_format (GstVideoTextureCache * cache, GstVideoFormat in_format, GstCaps * out_caps) { GstCaps *in_caps; @@ -185,117 +82,26 @@ gst_video_texture_cache_set_format (GstVideoTextureCache * cache, features = gst_caps_get_features (in_caps, 0); gst_video_info_from_caps (&cache->input_info, in_caps); - if (cache->in_caps) - gst_caps_unref (cache->in_caps); - if (cache->out_caps) - 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 + gst_caps_take (&cache->in_caps, in_caps); + gst_caps_take (&cache->out_caps, out_caps); } -#if HAVE_IOS -static void -gst_video_texture_cache_release_texture (TextureWrapper *data) +void +gst_video_texture_cache_set_format (GstVideoTextureCache * cache, + GstVideoFormat in_format, GstCaps * out_caps) { - CFRelease(data->texture); - CFRelease(data->cache); - g_free(data); + GstVideoTextureCacheClass *cache_class = GST_VIDEO_TEXTURE_CACHE_GET_CLASS (cache); + + g_return_if_fail (cache_class->set_format); + cache_class->set_format (cache, in_format, out_caps); } -static void -_do_create_memory (GstGLContext * context, ContextThreadData * data) -{ - CVOpenGLESTextureRef texture = NULL; - GstVideoTextureCache *cache = data->cache; - GstAppleCoreVideoPixelBuffer *gpixbuf = data->gpixbuf; - CVPixelBufferRef pixel_buf = gpixbuf->buf; - guint plane = data->plane; - gssize size = data->size; - GstGLTextureTarget gl_target; - GstAppleCoreVideoMemory *memory; - GstIOSGLMemory *gl_memory; - GstGLFormat texformat; - - switch (GST_VIDEO_INFO_FORMAT (&cache->input_info)) { - case GST_VIDEO_FORMAT_BGRA: - if (CVOpenGLESTextureCacheCreateTextureFromImage (kCFAllocatorDefault, - cache->cache, pixel_buf, NULL, GL_TEXTURE_2D, GL_RGBA, - GST_VIDEO_INFO_WIDTH (&cache->input_info), - GST_VIDEO_INFO_HEIGHT (&cache->input_info), - GL_RGBA, GL_UNSIGNED_BYTE, 0, &texture) != kCVReturnSuccess) - goto error; - - texformat = GST_GL_RGBA; - plane = 0; - goto success; - case GST_VIDEO_FORMAT_NV12: { - GstGLFormat texifmt, texfmt; - - if (plane == 0) - texformat = GST_GL_LUMINANCE; - else - texformat = GST_GL_LUMINANCE_ALPHA; - texfmt = gst_gl_sized_gl_format_from_gl_format_type (cache->ctx, texformat, GL_UNSIGNED_BYTE); - - if (CVOpenGLESTextureCacheCreateTextureFromImage (kCFAllocatorDefault, - cache->cache, pixel_buf, NULL, GL_TEXTURE_2D, texformat, - GST_VIDEO_INFO_COMP_WIDTH (&cache->input_info, plane), - GST_VIDEO_INFO_COMP_HEIGHT (&cache->input_info, plane), - texfmt, GL_UNSIGNED_BYTE, plane, &texture) != kCVReturnSuccess) - goto error; - - goto success; - } - default: - g_warn_if_reached (); - goto error; - } - -success: { - TextureWrapper *texture_data = g_new(TextureWrapper, 1); - CFRetain(cache->cache); - texture_data->cache = cache->cache; - texture_data->texture = texture; - gl_target = gst_gl_texture_target_from_gl (CVOpenGLESTextureGetTarget (texture)); - memory = gst_apple_core_video_memory_new_wrapped (gpixbuf, plane, size); - gl_memory = gst_ios_gl_memory_new_wrapped (context, memory, - gl_target, texformat, CVOpenGLESTextureGetName (texture), &cache->input_info, - plane, NULL, texture_data, (GDestroyNotify) gst_video_texture_cache_release_texture); - - data->memory = GST_MEMORY_CAST (gl_memory); - - return; -} - -error: - data->memory = NULL; -} -#endif - GstMemory * gst_video_texture_cache_create_memory (GstVideoTextureCache * cache, - GstAppleCoreVideoPixelBuffer *gpixbuf, - guint plane, - gsize size) + GstAppleCoreVideoPixelBuffer *gpixbuf, guint plane, gsize size) { - ContextThreadData data = {cache, gpixbuf, plane, size, NULL}; + GstVideoTextureCacheClass *cache_class = GST_VIDEO_TEXTURE_CACHE_GET_CLASS (cache); -#if HAVE_IOS - gst_gl_context_thread_add (cache->ctx, - (GstGLContextThreadFunc) _do_create_memory, &data); -#endif - - return data.memory; + g_return_val_if_fail (cache_class->create_memory, NULL); + return cache_class->create_memory (cache, gpixbuf, plane, size); } diff --git a/sys/applemedia/vtdec.c b/sys/applemedia/vtdec.c index fadfb451ba..40a13ee2cd 100644 --- a/sys/applemedia/vtdec.c +++ b/sys/applemedia/vtdec.c @@ -44,6 +44,7 @@ #include "vtutil.h" #include "corevideobuffer.h" #include "coremediabuffer.h" +#include "videotexturecache-gl.h" GST_DEBUG_CATEGORY_STATIC (gst_vtdec_debug_category); #define GST_CAT_DEFAULT gst_vtdec_debug_category @@ -222,7 +223,7 @@ setup_texture_cache (GstVtdec * vtdec, GstGLContext * context) g_return_if_fail (vtdec->texture_cache == NULL); output_state = gst_video_decoder_get_output_state (GST_VIDEO_DECODER (vtdec)); - vtdec->texture_cache = gst_video_texture_cache_new (context); + vtdec->texture_cache = gst_video_texture_cache_gl_new (context); gst_video_texture_cache_set_format (vtdec->texture_cache, GST_VIDEO_FORMAT_NV12, output_state->caps); gst_video_codec_state_unref (output_state); @@ -328,6 +329,11 @@ gst_vtdec_negotiate (GstVideoDecoder * decoder) } if (err == noErr && output_textures) { + GstVideoTextureCacheGL *cache_gl = NULL; + + if (vtdec->texture_cache) + cache_gl = GST_VIDEO_TEXTURE_CACHE_GL (vtdec->texture_cache); + /* call this regardless of whether caps have changed or not since a new * local context could have become available */ @@ -336,11 +342,9 @@ gst_vtdec_negotiate (GstVideoDecoder * decoder) gst_gl_context_helper_ensure_context (vtdec->ctxh); GST_INFO_OBJECT (vtdec, "pushing textures, context %p old context %p", - vtdec->ctxh->context, - vtdec->texture_cache ? vtdec->texture_cache->ctx : NULL); + vtdec->ctxh->context, cache_gl ? cache_gl->ctx : NULL); - if (vtdec->texture_cache - && vtdec->texture_cache->ctx != vtdec->ctxh->context) { + if (cache_gl && cache_gl->ctx != vtdec->ctxh->context) { g_object_unref (vtdec->texture_cache); vtdec->texture_cache = NULL; }