static void init_pixbuf_texture (GstGLContext * context, gpointer data) { GstGLDifferenceMatte *differencematte = GST_GL_DIFFERENCEMATTE (data); GstGLFilter *filter = GST_GL_FILTER (data); const GstGLFuncs *gl = context->gl_vtable; guint internal_format = gst_gl_sized_gl_format_from_gl_format_type (context, GL_RGBA, GL_UNSIGNED_BYTE); gl->DeleteTextures (1, &differencematte->newbgtexture); gl->GenTextures (1, &differencematte->newbgtexture); gl->BindTexture (GL_TEXTURE_2D, differencematte->newbgtexture); gl->TexImage2D (GL_TEXTURE_2D, 0, internal_format, (gint) differencematte->pbuf_width, (gint) differencematte->pbuf_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, differencematte->pixbuf); gl->TexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); gl->TexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); gl->TexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); gl->TexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); if (differencematte->savedbgtexture == 0) { gl->GenTextures (1, &differencematte->savedbgtexture); gl->BindTexture (GL_TEXTURE_2D, differencematte->savedbgtexture); gl->TexImage2D (GL_TEXTURE_2D, 0, internal_format, GST_VIDEO_INFO_WIDTH (&filter->out_info), GST_VIDEO_INFO_HEIGHT (&filter->out_info), 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); gl->TexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); gl->TexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); gl->TexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); gl->TexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); } }
static void _gen_texture_full (GstGLContext * context, GenTextureFull * data) { const GstGLFuncs *gl = context->gl_vtable; GstVideoGLTextureType tex_type; GstVideoFormat v_format; GLint glinternalformat = 0; GLenum glformat = 0; GLenum gltype = 0; gl->GenTextures (1, &data->result); gl->BindTexture (GL_TEXTURE_2D, data->result); v_format = GST_VIDEO_INFO_FORMAT (data->info); tex_type = gst_gl_texture_type_from_format (context, v_format, data->comp); glformat = gst_gl_format_from_gl_texture_type (tex_type); gltype = GL_UNSIGNED_BYTE; if (v_format == GST_VIDEO_FORMAT_RGB16) gltype = GL_UNSIGNED_SHORT_5_6_5; glinternalformat = gst_gl_sized_gl_format_from_gl_format_type (context, glformat, gltype); gl->TexImage2D (GL_TEXTURE_2D, 0, glinternalformat, GST_VIDEO_INFO_COMP_WIDTH (data->info, data->comp), GST_VIDEO_INFO_COMP_HEIGHT (data->info, data->comp), 0, glformat, gltype, NULL); gl->TexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); gl->TexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); gl->TexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); gl->TexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); }
static void _gen_texture (GstGLContext * context, GenTexture * data) { const GstGLFuncs *gl = context->gl_vtable; GLenum internal_format; GST_TRACE ("Generating texture format:%u dimensions:%ux%u", data->format, data->width, data->height); gl->GenTextures (1, &data->result); gl->BindTexture (GL_TEXTURE_2D, data->result); internal_format = gst_gl_sized_gl_format_from_gl_format_type (context, GL_RGBA, GL_UNSIGNED_BYTE); if (data->width > 0 && data->height > 0) gl->TexImage2D (GL_TEXTURE_2D, 0, internal_format, data->width, data->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); gl->TexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); gl->TexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); gl->TexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); gl->TexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); GST_LOG ("generated texture id:%d", data->result); }
static void _gl_mem_copy_thread (GstGLContext * context, gpointer data) { const GstGLFuncs *gl; GstGLMemoryPBOCopyParams *copy_params; GstGLMemoryPBO *src; guint tex_id; guint out_tex_target; GLuint fboId; gsize out_width, out_height, out_stride; GLuint out_gl_format, out_gl_type; GLuint in_gl_format, in_gl_type; gsize in_size, out_size; copy_params = (GstGLMemoryPBOCopyParams *) data; src = copy_params->src; tex_id = copy_params->tex_id; 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; gl = context->gl_vtable; out_gl_format = gst_gl_format_from_gl_texture_type (copy_params->out_format); out_gl_type = GL_UNSIGNED_BYTE; if (copy_params->out_format == GST_VIDEO_GL_TEXTURE_TYPE_RGB16) out_gl_type = GL_UNSIGNED_SHORT_5_6_5; in_gl_format = gst_gl_format_from_gl_texture_type (src->mem.tex_type); in_gl_type = GL_UNSIGNED_BYTE; if (src->mem.tex_type == GST_VIDEO_GL_TEXTURE_TYPE_RGB16) in_gl_type = GL_UNSIGNED_SHORT_5_6_5; if (!gl->GenFramebuffers) { gst_gl_context_set_error (context, "Context, EXT_framebuffer_object not supported"); goto error; } in_size = GL_MEM_HEIGHT (src) * GL_MEM_STRIDE (src); out_size = out_height * out_stride; if (copy_params->respecify) { if (in_size != out_size) { GST_ERROR ("Cannot copy between textures with backing data of different" "sizes. input %" G_GSIZE_FORMAT " output %" G_GSIZE_FORMAT, in_size, out_size); goto error; } } if (!tex_id) { guint internal_format; guint out_gl_type; out_gl_type = GL_UNSIGNED_BYTE; if (copy_params->out_format == GST_VIDEO_GL_TEXTURE_TYPE_RGB16) out_gl_type = GL_UNSIGNED_SHORT_5_6_5; internal_format = gst_gl_sized_gl_format_from_gl_format_type (context, out_gl_format, 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); } if (!tex_id) { GST_WARNING ("Could not create GL texture with context:%p", context); } GST_LOG ("copying memory %p, tex %u into texture %i", src, src->mem.tex_id, tex_id); /* FIXME: try and avoid creating and destroying fbo's every copy... */ /* create a framebuffer object */ gl->GenFramebuffers (1, &fboId); gl->BindFramebuffer (GL_FRAMEBUFFER, fboId); gl->FramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, gst_gl_texture_target_to_gl (src->mem.tex_target), src->mem.tex_id, 0); // if (!gst_gl_context_check_framebuffer_status (src->mem.mem.context)) // goto fbo_error; gl->BindTexture (out_tex_target, tex_id); if (copy_params->respecify) { GstMapInfo pbo_info; if (!gl->GenBuffers || !src->pbo) { gst_gl_context_set_error (context, "Cannot reinterpret texture contents " "without pixel buffer objects"); gl->BindTexture (out_tex_target, 0); goto fbo_error; } if (gst_gl_context_get_gl_api (context) & GST_GL_API_GLES2 && (in_gl_format != GL_RGBA || in_gl_type != GL_UNSIGNED_BYTE)) { gst_gl_context_set_error (context, "Cannot copy non RGBA/UNSIGNED_BYTE " "textures on GLES2"); gl->BindTexture (out_tex_target, 0); goto fbo_error; } GST_TRACE ("copying texture data with size of %u*%u*%u", gst_gl_format_type_n_bytes (in_gl_format, in_gl_type), src->mem.tex_width, GL_MEM_HEIGHT (src)); /* copy tex */ _read_pixels_to_pbo (src); src->pbo->target = GL_PIXEL_UNPACK_BUFFER; if (!gst_memory_map (GST_MEMORY_CAST (src->pbo), &pbo_info, GST_MAP_READ | GST_MAP_GL)) { GST_CAT_ERROR (GST_CAT_GL_MEMORY, "Failed to map pbo for reading"); goto fbo_error; } gl->TexSubImage2D (out_tex_target, 0, 0, 0, out_width, out_height, out_gl_format, out_gl_type, 0); gst_memory_unmap (GST_MEMORY_CAST (src->pbo), &pbo_info); } else { /* different sizes */ gst_gl_memory_copy_teximage (GST_GL_MEMORY_CAST (src), tex_id, copy_params->tex_target, copy_params->out_format, out_width, out_height); } gl->BindTexture (out_tex_target, 0); gl->BindFramebuffer (GL_FRAMEBUFFER, 0); gl->DeleteFramebuffers (1, &fboId); copy_params->tex_id = tex_id; copy_params->result = TRUE; return; /* ERRORS */ fbo_error: { gl->DeleteFramebuffers (1, &fboId); copy_params->tex_id = 0; copy_params->result = FALSE; return; } error: { copy_params->result = FALSE; return; } }