mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-06-07 16:08:51 +00:00
glcolorconvert: add support for converting texture targets
Solved with a simple shader templating mechanism and string replacements of the necessary sampler types/texture accesses and texture coordinate mangling for rectangular and external-oes textures.
This commit is contained in:
parent
e61d504556
commit
ccce217502
6 changed files with 614 additions and 381 deletions
|
@ -238,18 +238,8 @@ static GstCaps *
|
||||||
gst_gl_color_convert_element_fixate_caps (GstBaseTransform *
|
gst_gl_color_convert_element_fixate_caps (GstBaseTransform *
|
||||||
bt, GstPadDirection direction, GstCaps * caps, GstCaps * othercaps)
|
bt, GstPadDirection direction, GstCaps * caps, GstCaps * othercaps)
|
||||||
{
|
{
|
||||||
|
GstGLContext *context = GST_GL_BASE_FILTER (bt)->context;
|
||||||
GstCaps *ret;
|
GstCaps *ret;
|
||||||
|
|
||||||
ret =
|
return gst_gl_color_convert_fixate_caps (context, direction, caps, othercaps);
|
||||||
GST_BASE_TRANSFORM_CLASS
|
|
||||||
(gst_gl_color_convert_element_parent_class)->fixate_caps (bt, direction,
|
|
||||||
caps, othercaps);
|
|
||||||
|
|
||||||
if (direction == GST_PAD_SINK) {
|
|
||||||
if (gst_caps_is_subset (caps, ret)) {
|
|
||||||
gst_caps_replace (&ret, caps);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -100,7 +100,7 @@ struct _GstGLColorConvertClass
|
||||||
"width = " GST_VIDEO_SIZE_RANGE ", " \
|
"width = " GST_VIDEO_SIZE_RANGE ", " \
|
||||||
"height = " GST_VIDEO_SIZE_RANGE ", " \
|
"height = " GST_VIDEO_SIZE_RANGE ", " \
|
||||||
"framerate = " GST_VIDEO_FPS_RANGE ", " \
|
"framerate = " GST_VIDEO_FPS_RANGE ", " \
|
||||||
"texture-target = (string) 2D " \
|
"texture-target = (string) { 2D, rectangle, oes } " \
|
||||||
" ; " \
|
" ; " \
|
||||||
"video/x-raw(" GST_CAPS_FEATURE_MEMORY_GL_MEMORY "," \
|
"video/x-raw(" GST_CAPS_FEATURE_MEMORY_GL_MEMORY "," \
|
||||||
GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION "), " \
|
GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION "), " \
|
||||||
|
@ -108,7 +108,7 @@ struct _GstGLColorConvertClass
|
||||||
"width = " GST_VIDEO_SIZE_RANGE ", " \
|
"width = " GST_VIDEO_SIZE_RANGE ", " \
|
||||||
"height = " GST_VIDEO_SIZE_RANGE ", " \
|
"height = " GST_VIDEO_SIZE_RANGE ", " \
|
||||||
"framerate = " GST_VIDEO_FPS_RANGE ", " \
|
"framerate = " GST_VIDEO_FPS_RANGE ", " \
|
||||||
"texture-target = (string) 2D"
|
"texture-target = (string) { 2D, rectangle, oes }"
|
||||||
|
|
||||||
GstGLColorConvert * gst_gl_color_convert_new (GstGLContext * context);
|
GstGLColorConvert * gst_gl_color_convert_new (GstGLContext * context);
|
||||||
|
|
||||||
|
@ -116,6 +116,10 @@ GstCaps * gst_gl_color_convert_transform_caps (GstGLContext * convert,
|
||||||
GstPadDirection direction,
|
GstPadDirection direction,
|
||||||
GstCaps * caps,
|
GstCaps * caps,
|
||||||
GstCaps * filter);
|
GstCaps * filter);
|
||||||
|
GstCaps * gst_gl_color_convert_fixate_caps (GstGLContext * convert,
|
||||||
|
GstPadDirection direction,
|
||||||
|
GstCaps * caps,
|
||||||
|
GstCaps * other);
|
||||||
gboolean gst_gl_color_convert_set_caps (GstGLColorConvert * convert,
|
gboolean gst_gl_color_convert_set_caps (GstGLColorConvert * convert,
|
||||||
GstCaps * in_caps,
|
GstCaps * in_caps,
|
||||||
GstCaps * out_caps);
|
GstCaps * out_caps);
|
||||||
|
|
|
@ -36,6 +36,10 @@ typedef struct _GstCoreVideoTextureCache
|
||||||
#endif
|
#endif
|
||||||
GstVideoInfo input_info;
|
GstVideoInfo input_info;
|
||||||
GstVideoInfo output_info;
|
GstVideoInfo output_info;
|
||||||
|
|
||||||
|
gboolean configured;
|
||||||
|
GstCaps *in_caps;
|
||||||
|
GstCaps *out_caps;
|
||||||
GstGLColorConvert *convert;
|
GstGLColorConvert *convert;
|
||||||
} GstCoreVideoTextureCache;
|
} GstCoreVideoTextureCache;
|
||||||
|
|
||||||
|
|
|
@ -46,6 +46,7 @@ gst_core_video_texture_cache_new (GstGLContext * ctx)
|
||||||
cache->ctx = gst_object_ref (ctx);
|
cache->ctx = gst_object_ref (ctx);
|
||||||
gst_video_info_init (&cache->input_info);
|
gst_video_info_init (&cache->input_info);
|
||||||
cache->convert = gst_gl_color_convert_new (cache->ctx);
|
cache->convert = gst_gl_color_convert_new (cache->ctx);
|
||||||
|
cache->configured = FALSE;
|
||||||
|
|
||||||
#if !HAVE_IOS
|
#if !HAVE_IOS
|
||||||
CGLPixelFormatObj pixelFormat =
|
CGLPixelFormatObj pixelFormat =
|
||||||
|
@ -79,6 +80,10 @@ gst_core_video_texture_cache_free (GstCoreVideoTextureCache * cache)
|
||||||
#endif
|
#endif
|
||||||
gst_object_unref (cache->convert);
|
gst_object_unref (cache->convert);
|
||||||
gst_object_unref (cache->ctx);
|
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_free (cache);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,10 +108,13 @@ gst_core_video_texture_cache_set_format (GstCoreVideoTextureCache * cache,
|
||||||
gst_caps_features_add (features, GST_CAPS_FEATURE_MEMORY_GL_MEMORY);
|
gst_caps_features_add (features, GST_CAPS_FEATURE_MEMORY_GL_MEMORY);
|
||||||
gst_video_info_from_caps (&cache->input_info, in_caps);
|
gst_video_info_from_caps (&cache->input_info, in_caps);
|
||||||
|
|
||||||
gst_gl_color_convert_set_caps (cache->convert, in_caps, out_caps);
|
cache->configured = FALSE;
|
||||||
|
if (cache->in_caps)
|
||||||
gst_caps_unref (out_caps);
|
gst_caps_unref (cache->in_caps);
|
||||||
gst_caps_unref (in_caps);
|
if (cache->out_caps)
|
||||||
|
gst_caps_unref (cache->out_caps);
|
||||||
|
cache->in_caps = in_caps;
|
||||||
|
cache->out_caps = out_caps;
|
||||||
}
|
}
|
||||||
|
|
||||||
static CVPixelBufferRef
|
static CVPixelBufferRef
|
||||||
|
@ -124,17 +132,6 @@ cv_pixel_buffer_from_gst_buffer (GstBuffer * buffer)
|
||||||
return cm_meta ? cm_meta->pixel_buf : cv_meta->pixbuf;
|
return cm_meta ? cm_meta->pixel_buf : cv_meta->pixbuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstGLTextureTarget
|
|
||||||
_gl_target_to_gst (guint target)
|
|
||||||
{
|
|
||||||
switch (target) {
|
|
||||||
case GL_TEXTURE_2D: return GST_GL_TEXTURE_TARGET_2D;
|
|
||||||
case GL_TEXTURE_RECTANGLE: return GST_GL_TEXTURE_TARGET_RECTANGLE;
|
|
||||||
case GL_TEXTURE_EXTERNAL_OES: return GST_GL_TEXTURE_TARGET_OES;
|
|
||||||
default: return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gl_mem_from_buffer (GstCoreVideoTextureCache * cache,
|
gl_mem_from_buffer (GstCoreVideoTextureCache * cache,
|
||||||
GstBuffer * buffer, GstMemory **mem1, GstMemory **mem2)
|
GstBuffer * buffer, GstMemory **mem1, GstMemory **mem2)
|
||||||
|
@ -146,6 +143,7 @@ gl_mem_from_buffer (GstCoreVideoTextureCache * cache,
|
||||||
CVOpenGLESTextureRef texture = NULL;
|
CVOpenGLESTextureRef texture = NULL;
|
||||||
#endif
|
#endif
|
||||||
CVPixelBufferRef pixel_buf = cv_pixel_buffer_from_gst_buffer (buffer);
|
CVPixelBufferRef pixel_buf = cv_pixel_buffer_from_gst_buffer (buffer);
|
||||||
|
GstGLTextureTarget gl_target;
|
||||||
|
|
||||||
*mem1 = NULL;
|
*mem1 = NULL;
|
||||||
*mem2 = NULL;
|
*mem2 = NULL;
|
||||||
|
@ -165,9 +163,10 @@ gl_mem_from_buffer (GstCoreVideoTextureCache * cache,
|
||||||
cache->cache, pixel_buf, NULL, &texture) != kCVReturnSuccess)
|
cache->cache, pixel_buf, NULL, &texture) != kCVReturnSuccess)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
|
gl_target = gst_gl_texture_target_from_gl (CVOpenGLTextureGetTarget (texture));
|
||||||
|
|
||||||
*mem1 = (GstMemory *) gst_gl_memory_wrapped_texture (cache->ctx,
|
*mem1 = (GstMemory *) gst_gl_memory_wrapped_texture (cache->ctx,
|
||||||
CVOpenGLTextureGetName (texture),
|
CVOpenGLTextureGetName (texture), gl_target,
|
||||||
_gl_target_to_gst (CVOpenGLTextureGetTarget (texture)),
|
|
||||||
&cache->input_info, 0, NULL, texture, (GDestroyNotify) CFRelease);
|
&cache->input_info, 0, NULL, texture, (GDestroyNotify) CFRelease);
|
||||||
break;
|
break;
|
||||||
#else
|
#else
|
||||||
|
@ -180,9 +179,10 @@ gl_mem_from_buffer (GstCoreVideoTextureCache * cache,
|
||||||
GL_RGBA, GL_UNSIGNED_BYTE, 0, &texture) != kCVReturnSuccess)
|
GL_RGBA, GL_UNSIGNED_BYTE, 0, &texture) != kCVReturnSuccess)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
|
gl_target = _gl_target_to_gst (CVOpenGLESTextureGetTarget (texture));
|
||||||
|
|
||||||
*mem1 = (GstMemory *) gst_gl_memory_wrapped_texture (cache->ctx,
|
*mem1 = (GstMemory *) gst_gl_memory_wrapped_texture (cache->ctx,
|
||||||
CVOpenGLESTextureGetName (texture),
|
CVOpenGLESTextureGetName (texture), gl_target,
|
||||||
_gl_target_to_gst (CVOpenGLESTextureGetTarget (texture)),
|
|
||||||
&cache->input_info, 0, NULL, texture, (GDestroyNotify) CFRelease);
|
&cache->input_info, 0, NULL, texture, (GDestroyNotify) CFRelease);
|
||||||
break;
|
break;
|
||||||
case GST_VIDEO_FORMAT_NV12: {
|
case GST_VIDEO_FORMAT_NV12: {
|
||||||
|
@ -191,6 +191,7 @@ gl_mem_from_buffer (GstCoreVideoTextureCache * cache,
|
||||||
|
|
||||||
textype = gst_gl_texture_type_from_format (cache->ctx, GST_VIDEO_FORMAT_NV12, 0);
|
textype = gst_gl_texture_type_from_format (cache->ctx, GST_VIDEO_FORMAT_NV12, 0);
|
||||||
texfmt = gst_gl_format_from_gl_texture_type (textype);
|
texfmt = gst_gl_format_from_gl_texture_type (textype);
|
||||||
|
gl_target = gst_gl_texture_target_from_gl (CVOpenGLESTextureGetTarget (texture));
|
||||||
|
|
||||||
/* vtdec does NV12 on iOS when doing GLMemory */
|
/* vtdec does NV12 on iOS when doing GLMemory */
|
||||||
if (CVOpenGLESTextureCacheCreateTextureFromImage (kCFAllocatorDefault,
|
if (CVOpenGLESTextureCacheCreateTextureFromImage (kCFAllocatorDefault,
|
||||||
|
@ -201,8 +202,7 @@ gl_mem_from_buffer (GstCoreVideoTextureCache * cache,
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
*mem1 = (GstMemory *) gst_gl_memory_wrapped_texture (cache->ctx,
|
*mem1 = (GstMemory *) gst_gl_memory_wrapped_texture (cache->ctx,
|
||||||
CVOpenGLESTextureGetName (texture),
|
CVOpenGLESTextureGetName (texture), gl_target,
|
||||||
_gl_target_to_gst (CVOpenGLESTextureGetTarget (texture)),
|
|
||||||
&cache->input_info, 0, NULL, texture, (GDestroyNotify) CFRelease);
|
&cache->input_info, 0, NULL, texture, (GDestroyNotify) CFRelease);
|
||||||
|
|
||||||
textype = gst_gl_texture_type_from_format (cache->ctx, GST_VIDEO_FORMAT_NV12, 1);
|
textype = gst_gl_texture_type_from_format (cache->ctx, GST_VIDEO_FORMAT_NV12, 1);
|
||||||
|
@ -216,8 +216,7 @@ gl_mem_from_buffer (GstCoreVideoTextureCache * cache,
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
*mem2 = (GstMemory *) gst_gl_memory_wrapped_texture (cache->ctx,
|
*mem2 = (GstMemory *) gst_gl_memory_wrapped_texture (cache->ctx,
|
||||||
CVOpenGLESTextureGetName (texture),
|
CVOpenGLESTextureGetName (texture), gl_target,
|
||||||
_gl_target_to_gst (CVOpenGLESTextureGetTarget (texture)),
|
|
||||||
&cache->input_info, 0, NULL, texture, (GDestroyNotify) CFRelease);
|
&cache->input_info, 0, NULL, texture, (GDestroyNotify) CFRelease);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -227,6 +226,14 @@ gl_mem_from_buffer (GstCoreVideoTextureCache * cache,
|
||||||
ret = FALSE;
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
|
|
|
@ -110,9 +110,13 @@ CFSTR ("RequireHardwareAcceleratedVideoDecoder");
|
||||||
|
|
||||||
#ifdef HAVE_IOS
|
#ifdef HAVE_IOS
|
||||||
#define VIDEO_SRC_CAPS \
|
#define VIDEO_SRC_CAPS \
|
||||||
GST_VIDEO_CAPS_MAKE_WITH_FEATURES \
|
"video/x-raw(" GST_CAPS_FEATURE_MEMORY_GL_MEMORY "), " \
|
||||||
(GST_CAPS_FEATURE_MEMORY_GL_MEMORY, \
|
"format = (string) RGBA, " \
|
||||||
"RGBA") ";" \
|
"width = " GST_VIDEO_SIZE_RANGE ", " \
|
||||||
|
"height = " GST_VIDEO_SIZE_RANGE ", " \
|
||||||
|
"framerate = " GST_VIDEO_FPS_RANGE ", " \
|
||||||
|
"texture-target = (string) 2D " \
|
||||||
|
" ; " \
|
||||||
GST_VIDEO_CAPS_MAKE(GST_VTDEC_VIDEO_FORMAT_STR) ";"
|
GST_VIDEO_CAPS_MAKE(GST_VTDEC_VIDEO_FORMAT_STR) ";"
|
||||||
#else
|
#else
|
||||||
#define VIDEO_SRC_CAPS \
|
#define VIDEO_SRC_CAPS \
|
||||||
|
|
Loading…
Reference in a new issue