static void _upload_memory (GstGLMemory * gl_mem, GstMapInfo * info, gsize maxsize) { GstGLContext *context = gl_mem->mem.context; const GstGLFuncs *gl; GLenum gl_format, gl_type, gl_target; gpointer data; gsize plane_start; if ((gl_mem->transfer_state & GST_GL_MEMORY_TRANSFER_NEED_UPLOAD) == 0) return; gl = context->gl_vtable; gl_type = GL_UNSIGNED_BYTE; if (gl_mem->tex_type == GST_VIDEO_GL_TEXTURE_TYPE_RGB16) 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; if (USING_OPENGL (context) || USING_GLES3 (context) || USING_OPENGL3 (context)) { gl->PixelStorei (GL_UNPACK_ROW_LENGTH, gl_mem->unpack_length); } else if (USING_GLES2 (context)) { gl->PixelStorei (GL_UNPACK_ALIGNMENT, gl_mem->unpack_length); } GST_LOG ("upload for texture id:%u, with pbo %u %ux%u", gl_mem->tex_id, gl_mem->mem.id, gl_mem->tex_width, GL_MEM_HEIGHT (gl_mem)); /* find the start of the plane data including padding */ plane_start = _find_plane_frame_start (gl_mem); if (gl_mem->mem.id && CONTEXT_SUPPORTS_PBO_UPLOAD (context)) { gl->BindBuffer (GL_PIXEL_UNPACK_BUFFER, gl_mem->mem.id); data = (void *) plane_start; } else { data = (gpointer) ((gintptr) plane_start + (gintptr) gl_mem->mem.data); } gl->BindTexture (gl_target, gl_mem->tex_id); gl->TexSubImage2D (gl_target, 0, 0, 0, gl_mem->tex_width, GL_MEM_HEIGHT (gl_mem), gl_format, gl_type, data); if (gl_mem->mem.id && CONTEXT_SUPPORTS_PBO_UPLOAD (context)) gl->BindBuffer (GL_PIXEL_UNPACK_BUFFER, 0); /* Reset to default values */ if (USING_OPENGL (context) || USING_GLES3 (context)) { gl->PixelStorei (GL_UNPACK_ROW_LENGTH, 0); } else if (USING_GLES2 (context)) { gl->PixelStorei (GL_UNPACK_ALIGNMENT, 4); } gl->BindTexture (gl_target, 0); gl_mem->transfer_state &= ~GST_GL_MEMORY_TRANSFER_NEED_UPLOAD; }
static void gst_gl_effects_squeeze_callback (gint width, gint height, guint texture, gpointer data) { GstGLShader *shader; GstGLFilter *filter = GST_GL_FILTER (data); GstGLEffects *effects = GST_GL_EFFECTS (data); GstGLContext *context = filter->context; GstGLFuncs *gl = context->gl_vtable; shader = g_hash_table_lookup (effects->shaderstable, "squeeze0"); if (!shader) { shader = gst_gl_shader_new (context); g_hash_table_insert (effects->shaderstable, (gchar *) "squeeze0", shader); if (USING_GLES2 (context) || USING_OPENGL3 (context)) { if (!gst_gl_shader_compile_with_default_v_and_check (shader, squeeze_fragment_source_gles2, &filter->draw_attr_position_loc, &filter->draw_attr_texture_loc)) { /* gst gl context error is already set */ GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND, ("Failed to initialize squeeze shader, %s", gst_gl_context_get_error ()), (NULL)); return; } } #if GST_GL_HAVE_OPENGL if (USING_OPENGL (context)) { if (!gst_gl_shader_compile_and_check (shader, squeeze_fragment_source_opengl, GST_GL_SHADER_FRAGMENT_SOURCE)) { gst_gl_context_set_error (context, "Failed to initialize squeeze shader"); GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND, ("%s", gst_gl_context_get_error ()), (NULL)); return; } } #endif } #if GST_GL_HAVE_OPENGL if (USING_OPENGL (context)) { gl->MatrixMode (GL_PROJECTION); gl->LoadIdentity (); } #endif gst_gl_shader_use (shader); gl->ActiveTexture (GL_TEXTURE0); if (USING_OPENGL (context)) gl->Enable (GL_TEXTURE_2D); gl->BindTexture (GL_TEXTURE_2D, texture); gst_gl_shader_set_uniform_1i (shader, "tex", 0); gst_gl_filter_draw_texture (filter, texture, width, height); }
static void _upload_pbo_memory (GstGLMemoryPBO * gl_mem, GstMapInfo * info, GstGLBuffer * pbo, GstMapInfo * pbo_info) { GstGLContext *context = gl_mem->mem.mem.context; const GstGLFuncs *gl; guint gl_format, gl_type, gl_target; guint pbo_id; gsize plane_start; if (!GST_MEMORY_FLAG_IS_SET (gl_mem, GST_GL_BASE_MEMORY_TRANSFER_NEED_UPLOAD)) return; g_return_if_fail (CONTEXT_SUPPORTS_PBO_UPLOAD (context)); gl = context->gl_vtable; pbo_id = *(guint *) pbo_info->data; gl_type = GL_UNSIGNED_BYTE; if (gl_mem->mem.tex_type == GST_VIDEO_GL_TEXTURE_TYPE_RGB16) gl_type = GL_UNSIGNED_SHORT_5_6_5; gl_format = gst_gl_format_from_gl_texture_type (gl_mem->mem.tex_type); gl_target = gst_gl_texture_target_to_gl (gl_mem->mem.tex_target); if (USING_OPENGL (context) || USING_GLES3 (context) || USING_OPENGL3 (context)) { gl->PixelStorei (GL_UNPACK_ROW_LENGTH, gl_mem->mem.unpack_length); } else if (USING_GLES2 (context)) { gl->PixelStorei (GL_UNPACK_ALIGNMENT, gl_mem->mem.unpack_length); } GST_CAT_LOG (GST_CAT_GL_MEMORY, "upload for texture id:%u, with pbo %u %ux%u", gl_mem->mem.tex_id, pbo_id, gl_mem->mem.tex_width, GL_MEM_HEIGHT (gl_mem)); /* find the start of the plane data including padding */ plane_start = gst_gl_get_plane_start (&gl_mem->mem.info, &gl_mem->mem.valign, gl_mem->mem.plane) + GST_MEMORY_CAST (gl_mem)->offset; gl->BindBuffer (GL_PIXEL_UNPACK_BUFFER, pbo_id); gl->BindTexture (gl_target, gl_mem->mem.tex_id); gl->TexSubImage2D (gl_target, 0, 0, 0, gl_mem->mem.tex_width, GL_MEM_HEIGHT (gl_mem), gl_format, gl_type, (void *) plane_start); gl->BindBuffer (GL_PIXEL_UNPACK_BUFFER, 0); gl->BindTexture (gl_target, 0); /* Reset to default values */ if (USING_OPENGL (context) || USING_GLES3 (context)) { gl->PixelStorei (GL_UNPACK_ROW_LENGTH, 0); } else if (USING_GLES2 (context)) { gl->PixelStorei (GL_UNPACK_ALIGNMENT, 4); } }
static inline void _calculate_unpack_length (GstGLMemory * gl_mem, GstGLContext * context) { guint n_gl_bytes; gl_mem->tex_scaling[0] = 1.0f; gl_mem->tex_scaling[1] = 1.0f; gl_mem->unpack_length = 1; gl_mem->tex_width = GL_MEM_WIDTH (gl_mem); n_gl_bytes = _gl_texture_type_n_bytes (gl_mem->tex_type); if (n_gl_bytes == 0) { GST_ERROR ("Unsupported texture type %d", gl_mem->tex_type); return; } if (USING_OPENGL (context) || USING_GLES3 (context) || USING_OPENGL3 (context)) { gl_mem->unpack_length = GL_MEM_STRIDE (gl_mem) / n_gl_bytes; } else if (USING_GLES2 (context)) { guint j = 8; while (j >= n_gl_bytes) { /* GST_ROUND_UP_j(GL_MEM_WIDTH (gl_mem) * n_gl_bytes) */ guint round_up_j = ((GL_MEM_WIDTH (gl_mem) * n_gl_bytes) + j - 1) & ~(j - 1); if (round_up_j == GL_MEM_STRIDE (gl_mem)) { GST_LOG ("Found alignment of %u based on width " "(with plane width:%u, plane stride:%u and pixel stride:%u. " "RU%u(%u*%u) = %u)", j, GL_MEM_WIDTH (gl_mem), GL_MEM_STRIDE (gl_mem), n_gl_bytes, j, GL_MEM_WIDTH (gl_mem), n_gl_bytes, round_up_j); gl_mem->unpack_length = j; break; } j >>= 1; } if (j < n_gl_bytes) { /* Failed to find a suitable alignment, try based on plane_stride and * scale in the shader. Useful for alignments that are greater than 8. */ j = 8; while (j >= n_gl_bytes) { /* GST_ROUND_UP_j((GL_MEM_STRIDE (gl_mem)) */ guint round_up_j = ((GL_MEM_STRIDE (gl_mem)) + j - 1) & ~(j - 1); if (round_up_j == (GL_MEM_STRIDE (gl_mem))) { GST_LOG ("Found alignment of %u based on " "stride (with plane stride:%u and pixel stride:%u. " "RU%u(%u) = %u)", j, GL_MEM_STRIDE (gl_mem), n_gl_bytes, j, GL_MEM_STRIDE (gl_mem), round_up_j); gl_mem->unpack_length = j; gl_mem->tex_scaling[0] = (gfloat) (GL_MEM_WIDTH (gl_mem) * n_gl_bytes) / (gfloat) GL_MEM_STRIDE (gl_mem); gl_mem->tex_width = GL_MEM_STRIDE (gl_mem) / n_gl_bytes; break; } j >>= 1; } if (j < n_gl_bytes) { GST_ERROR ("Failed to find matching alignment. Image may " "look corrupted. plane width:%u, plane stride:%u and pixel " "stride:%u", GL_MEM_WIDTH (gl_mem), GL_MEM_STRIDE (gl_mem), n_gl_bytes); } } }