GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
- GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE_WITH_FEATURES
- (GST_CAPS_FEATURE_MEMORY_GL_MEMORY,
- "RGBA"))
+ GST_STATIC_CAPS ("video/x-raw(" GST_CAPS_FEATURE_MEMORY_GL_MEMORY "), "
+ "format = (string) RGBA, "
+ "width = " GST_VIDEO_SIZE_RANGE ", "
+ "height = " GST_VIDEO_SIZE_RANGE ", "
+ "framerate = " GST_VIDEO_FPS_RANGE ","
+ "texture-target = (string) 2D")
);
enum
GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC,
GST_PAD_ALWAYS,
- GST_STATIC_CAPS (GST_GL_COLOR_CONVERT_VIDEO_CAPS ";"
- GST_GL_COLOR_CONVERT_VIDEO_OVERLAY_COMPOSITION_CAPS));
+ GST_STATIC_CAPS (GST_GL_COLOR_CONVERT_VIDEO_CAPS));
static GstStaticPadTemplate gst_gl_color_convert_element_sink_pad_template =
GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
- GST_STATIC_CAPS (GST_GL_COLOR_CONVERT_VIDEO_CAPS ";"
- GST_GL_COLOR_CONVERT_VIDEO_OVERLAY_COMPOSITION_CAPS));
+ GST_STATIC_CAPS (GST_GL_COLOR_CONVERT_VIDEO_CAPS));
static gboolean
gst_gl_color_convert_element_stop (GstBaseTransform * bt)
static gboolean update_output_format (GstGLImageSink * glimage_sink);
#define GST_GL_SINK_CAPS \
- GST_VIDEO_CAPS_MAKE_WITH_FEATURES (GST_CAPS_FEATURE_MEMORY_GL_MEMORY, "RGBA")
-
-#define GST_GL_SINK_OVERLAY_CAPS \
- GST_VIDEO_CAPS_MAKE_WITH_FEATURES (GST_CAPS_FEATURE_MEMORY_GL_MEMORY "," \
- GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION, "RGBA")
+ "video/x-raw(" GST_CAPS_FEATURE_MEMORY_GL_MEMORY "), " \
+ "format = (string) RGBA, " \
+ "width = " GST_VIDEO_SIZE_RANGE ", " \
+ "height = " GST_VIDEO_SIZE_RANGE ", " \
+ "framerate = " GST_VIDEO_FPS_RANGE ", " \
+ "texture-target = (string) 2D " \
+ " ; " \
+ "video/x-raw(" GST_CAPS_FEATURE_MEMORY_GL_MEMORY "," \
+ GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION "), " \
+ "format = (string) RGBA, " \
+ "width = " GST_VIDEO_SIZE_RANGE ", " \
+ "height = " GST_VIDEO_SIZE_RANGE ", " \
+ "framerate = " GST_VIDEO_FPS_RANGE ", " \
+ "texture-target = (string) 2D "
static GstStaticPadTemplate gst_glimage_sink_template =
- GST_STATIC_PAD_TEMPLATE ("sink",
+GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
- GST_STATIC_CAPS (GST_GL_SINK_CAPS ";" GST_GL_SINK_OVERLAY_CAPS));
+ GST_STATIC_CAPS (GST_GL_SINK_CAPS));
enum
{
overlay->image_memory = (GstGLMemory *)
gst_gl_memory_alloc (GST_GL_BASE_FILTER (overlay)->context,
- NULL, &v_info, 0, &v_align);
+ GST_GL_TEXTURE_TARGET_2D, NULL, &v_info, 0, &v_align);
if (!gst_memory_map ((GstMemory *) overlay->image_memory, &map_info,
GST_MAP_WRITE)) {
gst_video_info_set_format (&v_info, GST_VIDEO_FORMAT_RGBA, width, height);
overlay->image_memory = (GstGLMemory *)
gst_gl_memory_alloc (GST_GL_BASE_FILTER (overlay)->context,
- NULL, &v_info, 0, NULL);
+ GST_GL_TEXTURE_TARGET_2D, NULL, &v_info, 0, NULL);
if (!gst_memory_map ((GstMemory *) overlay->image_memory, &map_info,
GST_MAP_WRITE)) {
static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC,
GST_PAD_ALWAYS,
- GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE_WITH_FEATURES
- (GST_CAPS_FEATURE_MEMORY_GL_MEMORY,
- "RGBA") "; "
+ GST_STATIC_CAPS ("video/x-raw(" GST_CAPS_FEATURE_MEMORY_GL_MEMORY "), "
+ "format = (string) RGBA, "
+ "width = " GST_VIDEO_SIZE_RANGE ", "
+ "height = " GST_VIDEO_SIZE_RANGE ", "
+ "framerate = " GST_VIDEO_FPS_RANGE ","
+ "texture-target = (string) 2D"
+ "; "
GST_VIDEO_CAPS_MAKE_WITH_FEATURES
(GST_CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META,
"RGBA")
static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink_%u",
GST_PAD_SINK,
GST_PAD_REQUEST,
- GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE_WITH_FEATURES
- (GST_CAPS_FEATURE_MEMORY_GL_MEMORY,
- "RGBA") "; "
+ GST_STATIC_CAPS ("video/x-raw(" GST_CAPS_FEATURE_MEMORY_GL_MEMORY "), "
+ "format = (string) RGBA, "
+ "width = " GST_VIDEO_SIZE_RANGE ", "
+ "height = " GST_VIDEO_SIZE_RANGE ", "
+ "framerate = " GST_VIDEO_FPS_RANGE ","
+ "texture-target = (string) 2D"
+ "; "
GST_VIDEO_CAPS_MAKE_WITH_FEATURES
(GST_CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META,
"RGBA")
/* FILL ME */
};
+/* *INDENT-OFF* */
static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC,
GST_PAD_ALWAYS,
- GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE_WITH_FEATURES
- (GST_CAPS_FEATURE_MEMORY_GL_MEMORY,
- "RGBA"))
+ GST_STATIC_CAPS ("video/x-raw(" GST_CAPS_FEATURE_MEMORY_GL_MEMORY "), "
+ "format = (string) RGBA, "
+ "width = " GST_VIDEO_SIZE_RANGE ", "
+ "height = " GST_VIDEO_SIZE_RANGE ", "
+ "framerate = " GST_VIDEO_FPS_RANGE ","
+ "texture-target = (string) 2D")
);
+/* *INDENT-ON* */
#define gst_gl_test_src_parent_class parent_class
G_DEFINE_TYPE (GstGLTestSrc, gst_gl_test_src, GST_TYPE_PUSH_SRC);
}
#endif
- if (!gst_gl_memory_setup_buffer (glpool->context, &priv->params, info,
- valign, buf))
+ if (!gst_gl_memory_setup_buffer (glpool->context, priv->tex_target,
+ &priv->params, info, valign, buf))
goto mem_create_failed;
if (priv->add_uploadmeta)
if (!convert->priv->out_tex[j])
convert->priv->out_tex[j] =
- (GstGLMemory *) gst_gl_memory_alloc (context, NULL, &temp_info, 0,
- NULL);
+ (GstGLMemory *) gst_gl_memory_alloc (context,
+ convert->priv->to_texture_target, NULL, &temp_info, 0, NULL);
} else {
convert->priv->out_tex[j] = out_tex;
}
continue;
}
gst_gl_memory_copy_into_texture (convert->priv->out_tex[j],
- out_tex->tex_id, out_tex->tex_type, mem_width, mem_height,
- GST_VIDEO_INFO_PLANE_STRIDE (&out_tex->info, out_tex->plane), FALSE);
+ out_tex->tex_id, convert->priv->to_texture_target, out_tex->tex_type,
+ mem_width, mem_height, GST_VIDEO_INFO_PLANE_STRIDE (&out_tex->info,
+ out_tex->plane), FALSE);
gst_memory_unmap ((GstMemory *) convert->priv->out_tex[j], &from_info);
gst_memory_unmap ((GstMemory *) out_tex, &to_info);
} else {
}
convert->outbuf = gst_buffer_new ();
- if (!gst_gl_memory_setup_buffer (convert->context, NULL, &convert->out_info,
- NULL, convert->outbuf)) {
+ if (!gst_gl_memory_setup_buffer (convert->context,
+ convert->priv->to_texture_target, NULL, &convert->out_info, NULL,
+ convert->outbuf)) {
convert->priv->result = FALSE;
return;
}
* The currently supported #GstCaps that can be converted
*/
#define GST_GL_COLOR_CONVERT_VIDEO_CAPS \
- GST_VIDEO_CAPS_MAKE_WITH_FEATURES (GST_CAPS_FEATURE_MEMORY_GL_MEMORY, \
- GST_GL_COLOR_CONVERT_FORMATS)
-
-#define GST_GL_COLOR_CONVERT_VIDEO_OVERLAY_COMPOSITION_CAPS \
- GST_VIDEO_CAPS_MAKE_WITH_FEATURES (GST_CAPS_FEATURE_MEMORY_GL_MEMORY \
- "," GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION, \
- GST_GL_COLOR_CONVERT_FORMATS)
+ "video/x-raw(" GST_CAPS_FEATURE_MEMORY_GL_MEMORY "), " \
+ "format = (string) " GST_GL_COLOR_CONVERT_FORMATS ", " \
+ "width = " GST_VIDEO_SIZE_RANGE ", " \
+ "height = " GST_VIDEO_SIZE_RANGE ", " \
+ "framerate = " GST_VIDEO_FPS_RANGE ", " \
+ "texture-target = (string) 2D " \
+ " ; " \
+ "video/x-raw(" GST_CAPS_FEATURE_MEMORY_GL_MEMORY "," \
+ GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION "), " \
+ "format = (string) " GST_GL_COLOR_CONVERT_FORMATS ", " \
+ "width = " GST_VIDEO_SIZE_RANGE ", " \
+ "height = " GST_VIDEO_SIZE_RANGE ", " \
+ "framerate = " GST_VIDEO_FPS_RANGE ", " \
+ "texture-target = (string) 2D"
GstGLColorConvert * gst_gl_color_convert_new (GstGLContext * context);
#define GST_CAT_DEFAULT gst_gl_filter_debug
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
-
+/* *INDENT-OFF* */
static GstStaticPadTemplate gst_gl_filter_src_pad_template =
GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC,
GST_PAD_ALWAYS,
- GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE_WITH_FEATURES
- (GST_CAPS_FEATURE_MEMORY_GL_MEMORY,
- "RGBA"))
- );
+ GST_STATIC_CAPS ("video/x-raw(" GST_CAPS_FEATURE_MEMORY_GL_MEMORY "), "
+ "format = (string) RGBA, "
+ "width = " GST_VIDEO_SIZE_RANGE ", "
+ "height = " GST_VIDEO_SIZE_RANGE ", "
+ "framerate = " GST_VIDEO_FPS_RANGE ","
+ "texture-target = (string) 2D"
+ ));
static GstStaticPadTemplate gst_gl_filter_sink_pad_template =
GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
- GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE_WITH_FEATURES
- (GST_CAPS_FEATURE_MEMORY_GL_MEMORY,
- "RGBA"))
- );
+ GST_STATIC_CAPS ("video/x-raw(" GST_CAPS_FEATURE_MEMORY_GL_MEMORY "), "
+ "format = (string) RGBA, "
+ "width = " GST_VIDEO_SIZE_RANGE ", "
+ "height = " GST_VIDEO_SIZE_RANGE ", "
+ "framerate = " GST_VIDEO_FPS_RANGE ","
+ "texture-target = (string) 2D"
+ ));
+/* *INDENT-ON* */
/* Properties */
enum
#define GL_UNPACK_ROW_LENGTH 0x0CF2
#endif
+#ifndef GL_TEXTURE_RECTANGLE
+#define GL_TEXTURE_RECTANGLE 0x84F5
+#endif
+#ifndef GL_TEXTURE_EXTERNAL_OES
+#define GL_TEXTURE_EXTERNAL_OES 0x8D65
+#endif
+
G_DEFINE_TYPE (GstGLAllocator, gst_gl_allocator,
GST_TYPE_GL_BASE_BUFFER_ALLOCATOR);
guint out_width, out_height;
guint out_stride;
gboolean respecify;
- guint tex_target;
+ GstGLTextureTarget tex_target;
/* inout */
guint tex_id;
/* out */
return 0;
}
+const gchar *
+gst_gl_texture_target_to_string (GstGLTextureTarget target)
+{
+ switch (target) {
+ case GST_GL_TEXTURE_TARGET_2D:
+ return GST_GL_TEXTURE_TARGET_2D_STR;
+ case GST_GL_TEXTURE_TARGET_RECTANGLE:
+ return GST_GL_TEXTURE_TARGET_RECTANGLE_STR;
+ case GST_GL_TEXTURE_TARGET_EXTERNAL_OES:
+ return GST_GL_TEXTURE_TARGET_EXTERNAL_OES_STR;
+ default:
+ return NULL;
+ }
+}
+
+GstGLTextureTarget
+gst_gl_texture_target_from_string (const gchar * str)
+{
+ if (!str)
+ return GST_GL_TEXTURE_TARGET_NONE;
+
+ if (g_strcmp0 (str, GST_GL_TEXTURE_TARGET_2D_STR) == 0)
+ return GST_GL_TEXTURE_TARGET_2D;
+ if (g_strcmp0 (str, GST_GL_TEXTURE_TARGET_RECTANGLE_STR) == 0)
+ return GST_GL_TEXTURE_TARGET_RECTANGLE;
+ if (g_strcmp0 (str, GST_GL_TEXTURE_TARGET_EXTERNAL_OES_STR) == 0)
+ return GST_GL_TEXTURE_TARGET_EXTERNAL_OES;
+
+ return GST_GL_TEXTURE_TARGET_NONE;
+}
+
+guint
+gst_gl_texture_target_to_gl (GstGLTextureTarget target)
+{
+ switch (target) {
+ case GST_GL_TEXTURE_TARGET_2D:
+ return GL_TEXTURE_2D;
+ case GST_GL_TEXTURE_TARGET_RECTANGLE:
+ return GL_TEXTURE_RECTANGLE;
+ case GST_GL_TEXTURE_TARGET_EXTERNAL_OES:
+ return GL_TEXTURE_EXTERNAL_OES;
+ default:
+ return 0;
+ }
+}
+
+GstGLTextureTarget
+gst_gl_texture_target_from_gl (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_EXTERNAL_OES;
+ default:
+ return GST_GL_TEXTURE_TARGET_NONE;
+ }
+}
+
static inline guint
_get_plane_width (GstVideoInfo * info, guint plane)
{
gl_type = GL_UNSIGNED_SHORT_5_6_5;
gl_format = gst_gl_format_from_gl_texture_type (gl_mem->tex_type);
- gl_target = gl_mem->tex_target;
+ gl_target = gst_gl_texture_target_to_gl (gl_mem->tex_target);
if (USING_OPENGL (context) || USING_GLES3 (context)
|| USING_OPENGL3 (context)) {
gl->GenTextures (1, &tex_id);
gl->BindTexture (target, tex_id);
- gl->TexImage2D (target, 0, internal_format, width, height, 0, format, type,
- NULL);
+ if (target == GL_TEXTURE_2D || target == GL_TEXTURE_RECTANGLE)
+ gl->TexImage2D (target, 0, internal_format, width, height, 0, format, type,
+ NULL);
gl->TexParameteri (target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
gl->TexParameteri (target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
gl->TexParameteri (target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
gl->TexParameteri (target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ gl->BindTexture (target, 0);
+
return tex_id;
}
if (!gl_mem->texture_wrapped) {
gl_mem->tex_id =
- _new_texture (context, gl_mem->tex_target, internal_format, tex_format,
- tex_type, gl_mem->tex_width, GL_MEM_HEIGHT (gl_mem));
+ _new_texture (context, gst_gl_texture_target_to_gl (gl_mem->tex_target),
+ internal_format, tex_format, tex_type, gl_mem->tex_width,
+ GL_MEM_HEIGHT (gl_mem));
}
GST_LOG ("generated texture id:%d", gl_mem->tex_id);
static void
_gl_mem_init (GstGLMemory * mem, GstAllocator * allocator, GstMemory * parent,
- GstGLContext * context, GstAllocationParams * params, GstVideoInfo * info,
+ GstGLContext * context, GstGLTextureTarget target,
+ GstAllocationParams * params, GstVideoInfo * info,
GstVideoAlignment * valign, guint plane, gpointer user_data,
GDestroyNotify notify)
{
+ const gchar *target_str;
gsize size;
g_return_if_fail (plane < GST_VIDEO_INFO_N_PLANES (info));
size = gst_gl_get_plane_data_size (info, valign, plane);
/* we always operate on 2D textures unless we're dealing with wrapped textures */
- mem->tex_target = GL_TEXTURE_2D;
+ mem->tex_target = target;
mem->tex_type =
gst_gl_texture_type_from_format (context, GST_VIDEO_INFO_FORMAT (info),
plane);
gst_gl_base_buffer_init ((GstGLBaseBuffer *) mem, allocator, parent, context,
params, size);
- GST_DEBUG ("new GL texture context:%" GST_PTR_FORMAT " memory:%p format:%u "
- "dimensions:%ux%u stride:%u size:%" G_GSIZE_FORMAT, context, mem,
- mem->tex_type, mem->tex_width, GL_MEM_HEIGHT (mem), GL_MEM_STRIDE (mem),
- mem->mem.mem.size);
+ target_str = gst_gl_texture_target_to_string (target);
+ GST_DEBUG ("new GL texture context:%" GST_PTR_FORMAT " memory:%p target:%s "
+ "format:%u dimensions:%ux%u stride:%u size:%" G_GSIZE_FORMAT, context,
+ mem, target_str, mem->tex_type, mem->tex_width, GL_MEM_HEIGHT (mem),
+ GL_MEM_STRIDE (mem), mem->mem.mem.size);
}
static GstGLMemory *
_gl_mem_new (GstAllocator * allocator, GstMemory * parent,
- GstGLContext * context, GstAllocationParams * params, GstVideoInfo * info,
+ GstGLContext * context, GstGLTextureTarget target,
+ GstAllocationParams * params, GstVideoInfo * info,
GstVideoAlignment * valign, guint plane, gpointer user_data,
GDestroyNotify notify)
{
mem = g_slice_new0 (GstGLMemory);
mem->texture_wrapped = FALSE;
- _gl_mem_init (mem, allocator, parent, context, params, info, valign, plane,
- user_data, notify);
+ _gl_mem_init (mem, allocator, parent, context, target, params, info, valign,
+ plane, user_data, notify);
return mem;
}
gl->BindFramebuffer (GL_FRAMEBUFFER, fbo);
gl->FramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
- gl_mem->tex_target, gl_mem->tex_id, 0);
+ gst_gl_texture_target_to_gl (gl_mem->tex_target), gl_mem->tex_id, 0);
if (!gst_gl_context_check_framebuffer_status (context)) {
GST_CAT_WARNING (GST_CAT_GL_MEMORY,
if (info->flags & GST_MAP_READ
&& gl_mem->transfer_state & GST_GL_MEMORY_TRANSFER_NEED_DOWNLOAD) {
guint format, type;
+ guint target;
GST_CAT_TRACE (GST_CAT_GL_MEMORY, "attempting download of texture %u "
"using glGetTexImage", gl_mem->tex_id);
if (gl_mem->tex_type == GST_VIDEO_GL_TEXTURE_TYPE_RGB16)
type = GL_UNSIGNED_SHORT_5_6_5;
- gl->BindTexture (gl_mem->tex_target, gl_mem->tex_id);
- gl->GetTexImage (gl_mem->tex_target, 0, format, type, gl_mem->mem.data);
- gl->BindTexture (gl_mem->tex_target, 0);
+ target = gst_gl_texture_target_to_gl (gl_mem->tex_target);
+ gl->BindTexture (target, gl_mem->tex_id);
+ gl->GetTexImage (target, 0, format, type, gl_mem->mem.data);
+ gl->BindTexture (target, 0);
}
return gl_mem->mem.data;
GST_GL_BASE_BUFFER_ALLOCATOR_CLASS (gst_gl_allocator_parent_class);
if ((info->flags & GST_MAP_GL) == GST_MAP_GL) {
+ if (gl_mem->tex_target == GST_GL_TEXTURE_TARGET_EXTERNAL_OES)
+ return &gl_mem->tex_id;
+
if ((info->flags & GST_MAP_READ) == GST_MAP_READ) {
GST_TRACE ("mapping GL texture:%u for reading", gl_mem->tex_id);
data = &gl_mem->tex_id;
} else { /* not GL */
+ if (gl_mem->tex_target == GST_GL_TEXTURE_TARGET_EXTERNAL_OES) {
+ GST_CAT_ERROR (GST_CAT_GL_MEMORY, "Cannot map External OES textures");
+ return NULL;
+ }
+
data = _gl_mem_map_cpu_access (gl_mem, info, maxsize);
if (info->flags & GST_MAP_WRITE)
gl_mem->transfer_state |= GST_GL_MEMORY_TRANSFER_NEED_UPLOAD;
GstGLMemoryCopyParams *copy_params;
GstGLMemory *src;
guint tex_id;
- GLuint out_tex_target;
+ guint out_tex_target;
GLuint fboId;
gsize out_width, out_height, out_stride;
GLuint out_gl_format, out_gl_type;
copy_params = (GstGLMemoryCopyParams *) data;
src = copy_params->src;
tex_id = copy_params->tex_id;
- out_tex_target = copy_params->tex_target;
+ out_tex_target = gst_gl_texture_target_to_gl (copy_params->tex_target);
out_width = copy_params->out_width;
out_height = copy_params->out_height;
out_stride = copy_params->out_stride;
out_gl_type);
tex_id =
- _new_texture (context, out_tex_target, internal_format, out_gl_format,
- out_gl_type, copy_params->out_width, copy_params->out_height);
+ _new_texture (context, out_tex_target,
+ internal_format, out_gl_format, out_gl_type, copy_params->out_width,
+ copy_params->out_height);
}
if (!tex_id) {
gl->BindFramebuffer (GL_FRAMEBUFFER, fboId);
gl->FramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
- src->tex_target, src->tex_id, 0);
+ gst_gl_texture_target_to_gl (src->tex_target), src->tex_id, 0);
// if (!gst_gl_context_check_framebuffer_status (src->context))
// goto fbo_error;
GstGLAllocator *allocator = (GstGLAllocator *) src->mem.mem.allocator;
GstMemory *ret = NULL;
+ if (src->tex_target == GST_GL_TEXTURE_TARGET_EXTERNAL_OES) {
+ GST_CAT_ERROR (GST_CAT_GL_MEMORY, "Cannot copy External OES textures");
+ return NULL;
+ }
+
/* If not doing a full copy, then copy to sysmem, the 2D represention of the
* texture would become wrong */
if (offset > 0 || size < src->mem.mem.size) {
GstAllocationParams params = { 0, src->mem.mem.align, 0, 0 };
GstGLMemory *dest;
- dest = _gl_mem_new (src->mem.mem.allocator, NULL, src->mem.context, ¶ms,
- &src->info, &src->valign, src->plane, NULL, NULL);
+ dest = _gl_mem_new (src->mem.mem.allocator, NULL, src->mem.context,
+ src->tex_target, ¶ms, &src->info, &src->valign, src->plane, NULL,
+ NULL);
dest = (GstGLMemory *) gst_gl_base_buffer_alloc_data ((GstGLBaseBuffer *)
dest);
dest = g_slice_new0 (GstGLMemory);
/* don't create our own texture */
dest->texture_wrapped = TRUE;
- _gl_mem_init (dest, src->mem.mem.allocator, NULL, src->mem.context, ¶ms,
- &src->info, &src->valign, src->plane, NULL, NULL);
+ _gl_mem_init (dest, src->mem.mem.allocator, NULL, src->mem.context,
+ src->tex_target, ¶ms, &src->info, &src->valign, src->plane, NULL,
+ NULL);
dest->texture_wrapped = FALSE;
dest->tex_id = copy_params.tex_id;
*/
gboolean
gst_gl_memory_copy_into_texture (GstGLMemory * gl_mem, guint tex_id,
- GstVideoGLTextureType tex_type, gint width, gint height, gint stride,
- gboolean respecify)
+ GstGLTextureTarget target, GstVideoGLTextureType tex_type, gint width,
+ gint height, gint stride, gboolean respecify)
{
GstGLMemoryCopyParams copy_params;
copy_params.src = gl_mem;
- copy_params.tex_target = gl_mem->tex_target;
+ copy_params.tex_target = target;
copy_params.tex_id = tex_id;
copy_params.out_format = tex_type;
copy_params.out_width = width;
*/
GstGLMemory *
gst_gl_memory_wrapped_texture (GstGLContext * context,
- guint texture_id, guint texture_target,
+ guint texture_id, GstGLTextureTarget target,
GstVideoInfo * info, guint plane, GstVideoAlignment * valign,
gpointer user_data, GDestroyNotify notify)
{
mem->tex_id = texture_id;
mem->texture_wrapped = TRUE;
- _gl_mem_init (mem, _gl_allocator, NULL, context, NULL, info, valign, plane,
- user_data, notify);
-
- mem->tex_target = texture_target;
+ _gl_mem_init (mem, _gl_allocator, NULL, context, target, NULL, info, valign,
+ plane, user_data, notify);
mem = (GstGLMemory *) gst_gl_base_buffer_alloc_data ((GstGLBaseBuffer *) mem);
GST_MINI_OBJECT_FLAG_SET (mem, GST_GL_BASE_BUFFER_FLAG_NEED_DOWNLOAD);
* from @context
*/
GstMemory *
-gst_gl_memory_alloc (GstGLContext * context, GstAllocationParams * params,
- GstVideoInfo * info, guint plane, GstVideoAlignment * valign)
+gst_gl_memory_alloc (GstGLContext * context, GstGLTextureTarget target,
+ GstAllocationParams * params, GstVideoInfo * info, guint plane,
+ GstVideoAlignment * valign)
{
GstGLMemory *mem;
- mem = _gl_mem_new (_gl_allocator, NULL, context, params, info, valign, plane,
- NULL, NULL);
+ mem =
+ _gl_mem_new (_gl_allocator, NULL, context, target, params, info, valign,
+ plane, NULL, NULL);
mem = (GstGLMemory *) gst_gl_base_buffer_alloc_data ((GstGLBaseBuffer *) mem);
return (GstMemory *) mem;
* from @context and contents specified by @data
*/
GstGLMemory *
-gst_gl_memory_wrapped (GstGLContext * context, GstVideoInfo * info,
- guint plane, GstVideoAlignment * valign, gpointer data, gpointer user_data,
- GDestroyNotify notify)
+gst_gl_memory_wrapped (GstGLContext * context, GstGLTextureTarget target,
+ GstVideoInfo * info, guint plane, GstVideoAlignment * valign, gpointer data,
+ gpointer user_data, GDestroyNotify notify)
{
GstGLMemory *mem;
- mem = _gl_mem_new (_gl_allocator, NULL, context, NULL, info, valign, plane,
- user_data, notify);
+ mem = _gl_mem_new (_gl_allocator, NULL, context, target, NULL, info, valign,
+ plane, user_data, notify);
if (!mem)
return NULL;
* Returns: whether the memory's were sucessfully added.
*/
gboolean
-gst_gl_memory_setup_buffer (GstGLContext * context,
+gst_gl_memory_setup_buffer (GstGLContext * context, GstGLTextureTarget target,
GstAllocationParams * params, GstVideoInfo * info,
GstVideoAlignment * valign, GstBuffer * buffer)
{
for (v = 0; v < views; v++) {
for (i = 0; i < n_mem; i++) {
gl_mem[i] =
- (GstGLMemory *) gst_gl_memory_alloc (context, params, info, i,
+ (GstGLMemory *) gst_gl_memory_alloc (context, target, params, info, i,
valign);
if (gl_mem[i] == NULL)
return FALSE;
* Returns: whether the memory's were sucessfully created.
*/
gboolean
-gst_gl_memory_setup_wrapped (GstGLContext * context, GstVideoInfo * info,
- GstVideoAlignment * valign, gpointer data[GST_VIDEO_MAX_PLANES],
+gst_gl_memory_setup_wrapped (GstGLContext * context, GstGLTextureTarget target,
+ GstVideoInfo * info, GstVideoAlignment * valign,
+ gpointer data[GST_VIDEO_MAX_PLANES],
GstGLMemory * textures[GST_VIDEO_MAX_PLANES], gpointer user_data,
GDestroyNotify notify)
{
gint i;
for (i = 0; i < GST_VIDEO_INFO_N_PLANES (info); i++) {
- textures[i] = (GstGLMemory *) gst_gl_memory_wrapped (context, info, i,
- valign, data[i], user_data, notify);
+ textures[i] =
+ (GstGLMemory *) gst_gl_memory_wrapped (context, target, info, i, valign,
+ data[i], user_data, notify);
}
return TRUE;
#define GST_GL_MEMORY_ADD_TRANSFER(mem,state) ((GstGLMemory *)mem)->transfer_state |= state
+typedef enum
+{
+ GST_GL_TEXTURE_TARGET_NONE,
+ GST_GL_TEXTURE_TARGET_2D,
+ GST_GL_TEXTURE_TARGET_RECTANGLE,
+ GST_GL_TEXTURE_TARGET_EXTERNAL_OES,
+} GstGLTextureTarget;
+
+#define GST_GL_TEXTURE_TARGET_2D_STR "2D"
+#define GST_GL_TEXTURE_TARGET_RECTANGLE_STR "rectangle"
+#define GST_GL_TEXTURE_TARGET_EXTERNAL_OES_STR "external-oes"
+
+
/**
* GstGLMemory:
* @mem: the parent object
GstGLBaseBuffer mem;
guint tex_id;
- guint tex_target;
+ GstGLTextureTarget tex_target;
GstVideoGLTextureType tex_type;
GstVideoInfo info;
GstVideoAlignment valign;
gboolean gst_is_gl_memory (GstMemory * mem);
GstMemory * gst_gl_memory_alloc (GstGLContext * context,
+ GstGLTextureTarget target,
GstAllocationParams *params,
GstVideoInfo * info,
guint plane,
GstVideoAlignment *valign);
GstGLMemory * gst_gl_memory_wrapped (GstGLContext * context,
+ GstGLTextureTarget target,
GstVideoInfo * info,
guint plane,
GstVideoAlignment *valign,
GDestroyNotify notify);
GstGLMemory * gst_gl_memory_wrapped_texture (GstGLContext * context,
guint texture_id,
- guint texture_target,
+ GstGLTextureTarget target,
GstVideoInfo * info,
guint plane,
GstVideoAlignment *valign,
gboolean gst_gl_memory_copy_into_texture (GstGLMemory *gl_mem,
guint tex_id,
+ GstGLTextureTarget target,
GstVideoGLTextureType tex_type,
gint width,
gint height,
gboolean respecify);
gboolean gst_gl_memory_setup_buffer (GstGLContext * context,
+ GstGLTextureTarget target,
GstAllocationParams * params,
GstVideoInfo * info,
GstVideoAlignment *valign,
GstBuffer * buffer);
gboolean gst_gl_memory_setup_wrapped (GstGLContext * context,
+ GstGLTextureTarget target,
GstVideoInfo * info,
GstVideoAlignment *valign,
gpointer data[GST_VIDEO_MAX_PLANES],
guint format,
guint type);
+const gchar * gst_gl_texture_target_to_string (GstGLTextureTarget target);
+GstGLTextureTarget gst_gl_texture_target_from_string (const gchar * str);
+GstGLTextureTarget gst_gl_texture_target_from_gl (guint target);
+guint gst_gl_texture_target_to_gl (GstGLTextureTarget target);
+
+
/**
* GstGLAllocator
*
gst_gl_composition_overlay_add_transformation (overlay, buf);
comp_gl_memory =
- gst_gl_memory_wrapped (overlay->context, &comp_frame->info, 0, NULL,
- comp_frame->data[0], comp_frame, _video_frame_unmap_and_free);
+ gst_gl_memory_wrapped (overlay->context, GST_GL_TEXTURE_TARGET_2D,
+ &comp_frame->info, 0, NULL, comp_frame->data[0], comp_frame,
+ _video_frame_unmap_and_free);
overlay_buffer = gst_buffer_new ();
gst_buffer_append_memory (overlay_buffer, (GstMemory *) comp_gl_memory);
if (direction == GST_PAD_SINK) {
ret = _set_caps_features (caps, GST_CAPS_FEATURE_MEMORY_GL_MEMORY);
} else {
+ gint i, n;
+
ret = _set_caps_features (caps, GST_CAPS_FEATURE_MEMORY_EGL_IMAGE);
gst_caps_set_simple (ret, "format", G_TYPE_STRING, "RGBA", NULL);
+
+ n = gst_caps_get_size (ret);
+ for (i = 0; i < n; i++) {
+ GstStructure *s = gst_caps_get_structure (ret, i);
+
+ gst_structure_remove_fields (s, "texture-target", NULL);
+ }
}
return ret;
/* FIXME: buffer pool */
*image->outbuf = gst_buffer_new ();
- gst_gl_memory_setup_buffer (image->upload->context,
+ gst_gl_memory_setup_buffer (image->upload->context, GST_GL_TEXTURE_TARGET_2D,
NULL, &image->upload->priv->out_info, NULL, *image->outbuf);
n = gst_buffer_n_memory (image->buffer);
if (direction == GST_PAD_SINK) {
ret = _set_caps_features (caps, GST_CAPS_FEATURE_MEMORY_GL_MEMORY);
} else {
+ gint i, n;
+
ret =
_set_caps_features (caps,
GST_CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META);
gst_caps_set_simple (ret, "format", G_TYPE_STRING, "RGBA", NULL);
+
+ n = gst_caps_get_size (ret);
+ for (i = 0; i < n; i++) {
+ GstStructure *s = gst_caps_get_structure (ret, i);
+
+ gst_structure_remove_fields (s, "texture-target", NULL);
+ }
}
return ret;
/* FIXME: buffer pool */
*outbuf = gst_buffer_new ();
- gst_gl_memory_setup_buffer (upload->upload->context,
+ gst_gl_memory_setup_buffer (upload->upload->context, GST_GL_TEXTURE_TARGET_2D,
NULL, &upload->upload->priv->in_info, NULL, *outbuf);
for (i = 0; i < GST_GL_UPLOAD_MAX_PLANES; i++) {
if (direction == GST_PAD_SINK) {
ret = _set_caps_features (caps, GST_CAPS_FEATURE_MEMORY_GL_MEMORY);
} else {
+ gint i, n;
+
ret = _set_caps_features (caps, GST_CAPS_FEATURE_MEMORY_SYSTEM_MEMORY);
+
+ n = gst_caps_get_size (ret);
+ for (i = 0; i < n; i++) {
+ GstStructure *s = gst_caps_get_structure (ret, i);
+
+ gst_structure_remove_fields (s, "texture-target", NULL);
+ }
}
return ret;
GST_VIDEO_MULTIVIEW_MODE_SEPARATED)
max_planes *= GST_VIDEO_INFO_VIEWS (in_info);
- gst_gl_memory_setup_wrapped (raw->upload->context,
+ gst_gl_memory_setup_wrapped (raw->upload->context, GST_GL_TEXTURE_TARGET_2D,
&raw->upload->priv->in_info, NULL, raw->in_frame->frame.data, in_tex,
raw->in_frame, (GDestroyNotify) _raw_upload_frame_unref);
if (!upload->priv->out_tex[i]) {
/* the GL upload meta creates GL_TEXTURE_2D textures */
upload->priv->out_tex[i] = gst_gl_memory_wrapped_texture (upload->context,
- texture_id[i], GL_TEXTURE_2D, &upload->info, i, NULL, NULL, NULL);
+ texture_id[i], GST_GL_TEXTURE_TARGET_2D, &upload->info, i, NULL, NULL, NULL);
}
out_mem = upload->priv->out_tex[i];
mem_height = gst_gl_memory_get_texture_height (out_mem);
if (!(res = gst_gl_memory_copy_into_texture (in_mem, out_mem->tex_id,
- out_mem->tex_type, mem_width, mem_height,
+ GST_GL_TEXTURE_TARGET_2D, out_mem->tex_type, mem_width, mem_height,
GST_VIDEO_INFO_PLANE_STRIDE (&out_mem->info, out_mem->plane),
FALSE)))
break;
for (i = 0; i < GST_VIDEO_INFO_N_PLANES (&upload->info); i++) {
if (!upload->priv->in_tex[i])
upload->priv->in_tex[i] = gst_gl_memory_wrapped (upload->context,
- &upload->info, i, NULL, data[i], NULL, NULL);
+ GST_GL_TEXTURE_TARGET_2D, &upload->info, i, NULL, data[i], NULL, NULL);
}
return _perform_with_gl_memory (upload, meta, texture_id);
#define USING_GLES3(context) (gst_gl_context_check_gl_version (context, GST_GL_API_GLES2, 3, 0))
static GstStaticCaps caps_template =
-GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE_WITH_FEATURES
- (GST_CAPS_FEATURE_MEMORY_GL_MEMORY, "RGBA"));
+GST_STATIC_CAPS ("video/x-raw(" GST_CAPS_FEATURE_MEMORY_GL_MEMORY "), "
+ "format = (string) RGBA, "
+ "width = " GST_VIDEO_SIZE_RANGE ", "
+ "height = " GST_VIDEO_SIZE_RANGE ", "
+ "framerate = " GST_VIDEO_FPS_RANGE ", " "texture-target = (string) 2D ");
#define GST_CAT_DEFAULT gst_gl_view_convert_debug
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
_gen_buffer (GstGLViewConvert * viewconvert, GstBuffer ** target)
{
*target = gst_buffer_new ();
- if (!gst_gl_memory_setup_buffer (viewconvert->context, NULL,
- &viewconvert->out_info, NULL, *target)) {
+ if (!gst_gl_memory_setup_buffer (viewconvert->context,
+ GST_GL_TEXTURE_TARGET_2D, NULL, &viewconvert->out_info, NULL,
+ *target)) {
return FALSE;
}
gst_buffer_add_video_meta_full (*target, 0,
* the attachments i.e. the smallest attachment size */
if (!priv->out_tex[j])
priv->out_tex[j] =
- (GstGLMemory *) gst_gl_memory_alloc (context, NULL, &temp_info, 0,
- NULL);
+ (GstGLMemory *) gst_gl_memory_alloc (context,
+ GST_GL_TEXTURE_TARGET_2D, NULL, &temp_info, 0, NULL);
} else {
priv->out_tex[j] = out_tex;
}
continue;
}
gst_gl_memory_copy_into_texture (priv->out_tex[j],
- out_tex->tex_id, out_tex->tex_type, width, height,
- GST_VIDEO_INFO_PLANE_STRIDE (&out_tex->info, out_tex->plane), FALSE);
+ out_tex->tex_id, GST_GL_TEXTURE_TARGET_2D, out_tex->tex_type, width,
+ height, GST_VIDEO_INFO_PLANE_STRIDE (&out_tex->info, out_tex->plane),
+ FALSE);
gst_memory_unmap ((GstMemory *) out_tex, &to_info);
}
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
gl_mem_from_buffer (GstCoreVideoTextureCache * cache,
GstBuffer * buffer, GstMemory **mem1, GstMemory **mem2)
goto error;
*mem1 = (GstMemory *) gst_gl_memory_wrapped_texture (cache->ctx,
- CVOpenGLTextureGetName (texture), CVOpenGLTextureGetTarget (texture),
+ CVOpenGLTextureGetName (texture),
+ _gl_target_to_gst (CVOpenGLTextureGetTarget (texture)),
&cache->input_info, 0, NULL, texture, (GDestroyNotify) CFRelease);
break;
#else
goto error;
*mem1 = (GstMemory *) gst_gl_memory_wrapped_texture (cache->ctx,
- CVOpenGLESTextureGetName (texture), CVOpenGLESTextureGetTarget (texture),
+ CVOpenGLESTextureGetName (texture),
+ _gl_target_to_gst (CVOpenGLESTextureGetTarget (texture)),
&cache->input_info, 0, NULL, texture, (GDestroyNotify) CFRelease);
break;
case GST_VIDEO_FORMAT_NV12: {
goto error;
*mem1 = (GstMemory *) gst_gl_memory_wrapped_texture (cache->ctx,
- CVOpenGLESTextureGetName (texture), CVOpenGLESTextureGetTarget (texture),
+ CVOpenGLESTextureGetName (texture),
+ _gl_target_to_gst (CVOpenGLESTextureGetTarget (texture)),
&cache->input_info, 0, NULL, texture, (GDestroyNotify) CFRelease);
textype = gst_gl_texture_type_from_format (cache->ctx, GST_VIDEO_FORMAT_NV12, 1);
goto error;
*mem2 = (GstMemory *) gst_gl_memory_wrapped_texture (cache->ctx,
- CVOpenGLESTextureGetName (texture), CVOpenGLESTextureGetTarget (texture),
+ CVOpenGLESTextureGetName (texture),
+ _gl_target_to_gst (CVOpenGLESTextureGetTarget (texture)),
&cache->input_info, 0, NULL, texture, (GDestroyNotify) CFRelease);
break;
}
/* wrapped texture creation */
mem3 = (GstMemory *) gst_gl_memory_wrapped_texture (context,
- ((GstGLMemory *) mem)->tex_id, GL_TEXTURE_2D, &v_info, 0, NULL, NULL,
- NULL);
+ ((GstGLMemory *) mem)->tex_id, GST_GL_TEXTURE_TARGET_2D, &v_info, 0, NULL,
+ NULL, NULL);
fail_unless (!GST_MEMORY_FLAG_IS_SET (mem3,
GST_GL_BASE_BUFFER_FLAG_NEED_UPLOAD));
fail_unless (GST_MEMORY_FLAG_IS_SET (mem3,