static void check_wrapped (gpointer data) { GstGLContext *wrapped_context = data; GError *error = NULL; gint i = 0; gboolean ret; /* check that scheduling on an unactivated wrapped context asserts */ ASSERT_CRITICAL (gst_gl_context_thread_add (wrapped_context, (GstGLContextThreadFunc) accum_true, &i)); fail_if (i != 0); /* check that scheduling on an activated context succeeds */ gst_gl_context_activate (wrapped_context, TRUE); gst_gl_context_thread_add (wrapped_context, (GstGLContextThreadFunc) accum_true, &i); fail_if (i != 1); /* check filling out the wrapped context's info */ fail_if (wrapped_context->gl_vtable->TexImage2D != NULL); ret = gst_gl_context_fill_info (wrapped_context, &error); fail_if (!ret, "error received %s\n", error ? error->message : "Unknown error"); fail_if (wrapped_context->gl_vtable->TexImage2D == NULL); gst_gl_context_activate (wrapped_context, FALSE); }
static void gst_gl_composition_overlay_add_transformation (GstGLCompositionOverlay * overlay, GstBuffer * video_buffer) { gint comp_x, comp_y; guint comp_width, comp_height; GstVideoMeta *meta; guint width, height; float rel_x, rel_y, rel_w, rel_h; meta = gst_buffer_get_video_meta (video_buffer); gst_video_overlay_rectangle_get_render_rectangle (overlay->rectangle, &comp_x, &comp_y, &comp_width, &comp_height); width = meta->width; height = meta->height; /* calculate relative position */ rel_x = (float) comp_x / (float) width; rel_y = (float) comp_y / (float) height; rel_w = (float) comp_width / (float) width; rel_h = (float) comp_height / (float) height; /* transform from [0,1] to [-1,1], invert y axis */ rel_x = rel_x * 2.0 - 1.0; rel_y = (1.0 - rel_y) * 2.0 - 1.0; rel_w = rel_w * 2.0; rel_h = rel_h * 2.0; /* initialize position array */ overlay->positions[0] = rel_x + rel_w; overlay->positions[1] = rel_y; overlay->positions[2] = 0.0; overlay->positions[3] = 1.0; overlay->positions[4] = rel_x; overlay->positions[5] = rel_y; overlay->positions[6] = 0.0; overlay->positions[7] = 1.0; overlay->positions[8] = rel_x; overlay->positions[9] = rel_y - rel_h; overlay->positions[10] = 0.0; overlay->positions[11] = 1.0; overlay->positions[12] = rel_x + rel_w; overlay->positions[13] = rel_y - rel_h; overlay->positions[14] = 0.0; overlay->positions[15] = 1.0; gst_gl_context_thread_add (overlay->context, gst_gl_composition_overlay_free_vertex_buffer, overlay); gst_gl_context_thread_add (overlay->context, gst_gl_composition_overlay_init_vertex_buffer, overlay); GST_DEBUG ("overlay position: (%d,%d) size: %dx%d video size: %dx%d", comp_x, comp_y, comp_width, comp_height, meta->width, meta->height); }
void gst_gl_sync_meta_set_sync_point (GstGLSyncMeta * sync_meta, GstGLContext * context) { gst_gl_context_thread_add (context, (GstGLContextThreadFunc) _set_sync_point, sync_meta); }
static gboolean gst_gl_overlay_filter_texture (GstGLFilter * filter, guint in_tex, guint out_tex) { GstGLOverlay *overlay = GST_GL_OVERLAY (filter); if (overlay->pbuf_has_changed && (overlay->location != NULL)) { if ((overlay->type_file = gst_gl_overlay_load_png (filter)) == 0) if ((overlay->type_file = gst_gl_overlay_load_jpeg (filter)) == 0) overlay->pixbuf = NULL; /* if loader failed then context is turned off */ gst_gl_context_thread_add (filter->context, init_pixbuf_texture, overlay); if (overlay->pixbuf) { free (overlay->pixbuf); overlay->pixbuf = NULL; } overlay->pbuf_has_changed = FALSE; } gst_gl_filter_render_to_target (filter, TRUE, in_tex, out_tex, gst_gl_overlay_callback, overlay); return TRUE; }
static void _mem_free (GstAllocator * allocator, GstMemory * memory) { GstGLBaseMemory *mem = (GstGLBaseMemory *) memory; GST_CAT_TRACE (GST_CAT_GL_BASE_MEMORY, "freeing buffer memory:%p", mem); gst_gl_context_thread_add (mem->context, (GstGLContextThreadFunc) _destroy_gl_objects, mem); g_mutex_clear (&mem->lock); if (mem->alloc_data) { g_free (mem->alloc_data); mem->alloc_data = NULL; } mem->data = NULL; if (mem->notify) mem->notify (mem->user_data); gst_object_unref (mem->context); g_free (memory); }
/** * gst_gl_memory_pbo_download_transfer: * @gl_mem: a #GstGLMemoryPBO * * Transfer the texture data from the texture into the PBO if necessary. * * Since: 1.8 */ void gst_gl_memory_pbo_download_transfer (GstGLMemoryPBO * gl_mem) { g_return_if_fail (gst_is_gl_memory ((GstMemory *) gl_mem)); gst_gl_context_thread_add (gl_mem->mem.mem.context, (GstGLContextThreadFunc) _download_transfer, gl_mem); }
void gst_gl_sync_meta_wait (GstGLSyncMeta * sync_meta, GstGLContext * context) { if (sync_meta->glsync) { gst_gl_context_thread_add (context, (GstGLContextThreadFunc) _wait, sync_meta); } }
static void _gst_gl_sync_meta_free (GstGLSyncMeta * sync_meta, GstBuffer * buffer) { if (sync_meta->glsync) { gst_gl_context_thread_add (sync_meta->context, (GstGLContextThreadFunc) _free_gl_sync_meta, sync_meta); } gst_object_unref (sync_meta->context); }
/** * gst_gl_sync_meta_wait_cpu: * @sync_meta: a #GstGLSyncMeta * @context: a #GstGLContext * * Perform a wait so that the sync point has passed from the CPU's perspective * What that means, is that all GL operations changing CPU-visible data before * the sync point are now visible. * * Since: 1.8 */ void gst_gl_sync_meta_wait_cpu (GstGLSyncMeta * sync_meta, GstGLContext * context) { if (sync_meta->wait_cpu) sync_meta->wait_cpu (sync_meta, context); else gst_gl_context_thread_add (context, (GstGLContextThreadFunc) _wait_cpu, sync_meta); }
/** * gst_gl_memory_pbo_download_transfer: * @gl_mem: a #GstGLMemoryPBO * * Transfer the texture data from the PBO into the texture if necessary. * * Since: 1.8 */ void gst_gl_memory_pbo_upload_transfer (GstGLMemoryPBO * gl_mem) { g_return_if_fail (gst_is_gl_memory ((GstMemory *) gl_mem)); if (gl_mem->pbo && CONTEXT_SUPPORTS_PBO_UPLOAD (gl_mem->mem.mem.context)) gst_gl_context_thread_add (gl_mem->mem.mem.context, (GstGLContextThreadFunc) _upload_transfer, gl_mem); }
/** * gst_gl_sync_meta_set_sync_point: * @sync_meta: a #GstGLSyncMeta * @context: a #GstGLContext * * Set a sync point to possibly wait on at a later time. * * Since: 1.6 */ void gst_gl_sync_meta_set_sync_point (GstGLSyncMeta * sync_meta, GstGLContext * context) { if (sync_meta->set_sync) sync_meta->set_sync (sync_meta, context); else gst_gl_context_thread_add (context, (GstGLContextThreadFunc) _set_sync_point, sync_meta); }
void gst_gl_context_gen_texture (GstGLContext * context, GLuint * pTexture, GstVideoFormat v_format, GLint width, GLint height) { GenTexture data = { width, height, v_format, 0 }; gst_gl_context_thread_add (context, (GstGLContextThreadFunc) _gen_texture, &data); *pTexture = data.result; }
static void _mem_unmap_full (GstGLBaseBuffer * mem, GstMapInfo * info) { struct unmap_data transfer; transfer.mem = mem; transfer.info = info; gst_gl_context_thread_add (mem->context, (GstGLContextThreadFunc) _unmap_data_gl, &transfer); }
static void _gst_egl_image_free (GstMiniObject * object) { GstEGLImage *image = GST_EGL_IMAGE (object); if (image->context) { gst_gl_context_thread_add (GST_GL_CONTEXT (image->context), (GstGLContextThreadFunc) _gst_egl_image_free_thread, image); gst_object_unref (image->context); } }
static void teardown (void) { gst_object_unref (convert); gst_object_unref (window); gst_gl_context_thread_add (context, (GstGLContextThreadFunc) _check_gl_error, NULL); gst_object_unref (context); gst_object_unref (display); }
/* Called by gltestsrc and glfilter */ void gst_gl_context_del_fbo (GstGLContext * context, GLuint fbo, GLuint depth_buffer) { GstGLFramebuffer *frame = gst_gl_framebuffer_new (context); DelFBO data = { frame, fbo, depth_buffer }; gst_gl_context_thread_add (context, (GstGLContextThreadFunc) _del_fbo, &data); gst_object_unref (frame); }
static gboolean gst_gl_mosaic_process_textures (GstGLMixer * mix, GstGLMemory * out_tex) { GstGLMosaic *mosaic = GST_GL_MOSAIC (mix); GstGLContext *context = GST_GL_BASE_MIXER (mix)->context; mosaic->out_tex = out_tex; gst_gl_context_thread_add (context, (GstGLContextThreadFunc) _mosaic_render, mosaic); return TRUE; }
static gboolean gst_gl_differencematte_filter_texture (GstGLFilter * filter, guint in_tex, guint out_tex) { GstGLDifferenceMatte *differencematte = GST_GL_DIFFERENCEMATTE (filter); differencematte->intexture = in_tex; if (differencematte->bg_has_changed && (differencematte->location != NULL)) { if (!gst_gl_differencematte_loader (filter)) differencematte->pixbuf = NULL; /* if loader failed then context is turned off */ gst_gl_context_thread_add (GST_GL_BASE_FILTER (filter)->context, init_pixbuf_texture, differencematte); /* save current frame, needed to calculate difference between * this frame and next ones */ gst_gl_filter_render_to_target (filter, TRUE, in_tex, differencematte->savedbgtexture, gst_gl_differencematte_identity, differencematte); if (differencematte->pixbuf) { free (differencematte->pixbuf); differencematte->pixbuf = NULL; } differencematte->bg_has_changed = FALSE; } if (differencematte->savedbgtexture != 0) { gst_gl_filter_render_to_target (filter, TRUE, in_tex, differencematte->midtexture[0], gst_gl_differencematte_diff, differencematte); gst_gl_filter_render_to_target (filter, FALSE, differencematte->midtexture[0], differencematte->midtexture[1], gst_gl_differencematte_hblur, differencematte); gst_gl_filter_render_to_target (filter, FALSE, differencematte->midtexture[1], differencematte->midtexture[2], gst_gl_differencematte_vblur, differencematte); gst_gl_filter_render_to_target (filter, TRUE, in_tex, out_tex, gst_gl_differencematte_interp, differencematte); } else { gst_gl_filter_render_to_target (filter, TRUE, in_tex, out_tex, gst_gl_differencematte_identity, differencematte); } return TRUE; }
gboolean gst_gl_context_gen_fbo (GstGLContext * context, gint width, gint height, GLuint * fbo, GLuint * depthbuffer) { GstGLFramebuffer *frame = gst_gl_framebuffer_new (context); GenFBO data = { frame, width, height, fbo, depthbuffer }; gst_gl_context_thread_add (context, (GstGLContextThreadFunc) _gen_fbo, &data); gst_object_unref (frame); return TRUE; }
GstGLOverlayCompositor * gst_gl_overlay_compositor_new (GstGLContext * context) { GstGLOverlayCompositor *compositor = g_object_new (GST_TYPE_GL_OVERLAY_COMPOSITOR, NULL); compositor->context = gst_object_ref (context); gst_gl_context_thread_add (compositor->context, gst_gl_overlay_compositor_init_gl, compositor); GST_DEBUG_OBJECT (compositor, "Created new GstGLOverlayCompositor"); return compositor; }
static GstMemory * _mem_copy (GstGLBaseBuffer * src, gssize offset, gssize size) { struct copy_params transfer; transfer.dest = NULL; transfer.src = src; transfer.offset = offset; transfer.size = size; if (size == -1 || size > 0) gst_gl_context_thread_add (src->context, (GstGLContextThreadFunc) _mem_copy_gl, &transfer); return (GstMemory *) transfer.dest; }
static gpointer _mem_map_full (GstGLBaseBuffer * mem, GstMapInfo * info, gsize size) { struct map_data transfer; transfer.mem = mem; transfer.info = info; transfer.size = size; transfer.data = NULL; gst_gl_context_thread_add (mem->context, (GstGLContextThreadFunc) _map_data_gl, &transfer); return transfer.data; }
static void gst_gl_filter_reset (GstGLFilter * filter) { GstGLFilterClass *filter_class = GST_GL_FILTER_GET_CLASS (filter); if (filter->upload) { gst_object_unref (filter->upload); filter->upload = NULL; } if (filter->download) { gst_object_unref (filter->download); filter->download = NULL; } if (filter->context) { if (filter_class->onReset) filter_class->onReset (filter); if (filter_class->display_reset_cb != NULL) { gst_gl_context_thread_add (filter->context, gst_gl_filter_stop_gl, filter); } //blocking call, delete the FBO if (filter->fbo != 0) { gst_gl_context_del_fbo (filter->context, filter->fbo, filter->depthbuffer); } gst_object_unref (filter->context); filter->context = NULL; } if (filter->display) { gst_object_unref (filter->display); filter->display = NULL; } filter->fbo = 0; filter->depthbuffer = 0; filter->default_shader = NULL; if (filter->other_context) gst_object_unref (filter->other_context); filter->other_context = NULL; if (filter->context) gst_object_unref (filter->context); filter->context = NULL; }
static gboolean _surface_texture_detach_from_gl_context_perform (GstAmc2DTextureRenderer * renderer, GError ** error) { renderer->gl_context_result = FALSE; renderer->gl_context_error = NULL; gst_gl_context_thread_add (renderer->context, (GstGLContextThreadFunc) _surface_texture_detach_from_gl_context, renderer); *error = renderer->gl_context_error; renderer->gl_context_error = NULL; return renderer->gl_context_result; }
static gboolean gst_gl_effects_filter_texture (GstGLFilter * filter, guint in_tex, guint out_tex) { GstGLEffects *effects = GST_GL_EFFECTS (filter); effects->intexture = in_tex; effects->outtexture = out_tex; if (effects->horizontal_swap == TRUE) gst_gl_context_thread_add (filter->context, set_horizontal_swap, effects); effects->effect (effects); return TRUE; }
/* Called by glfilter */ gboolean gst_gl_context_gen_shader (GstGLContext * context, const gchar * vert_src, const gchar * frag_src, GstGLShader ** shader) { struct _compile_shader data; g_return_val_if_fail (frag_src != NULL || vert_src != NULL, FALSE); g_return_val_if_fail (shader != NULL, FALSE); data.shader = shader; data.vertex_src = vert_src; data.fragment_src = frag_src; gst_gl_context_thread_add (context, (GstGLContextThreadFunc) _compile_shader, &data); return *shader != NULL; }
static void gst_gl_composition_overlay_finalize (GObject * object) { GstGLCompositionOverlay *overlay; overlay = GST_GL_COMPOSITION_OVERLAY (object); if (overlay->gl_memory) gst_memory_unref ((GstMemory *) overlay->gl_memory); if (overlay->context) { gst_gl_context_thread_add (overlay->context, gst_gl_composition_overlay_free_vertex_buffer, overlay); gst_object_unref (overlay->context); } G_OBJECT_CLASS (gst_gl_composition_overlay_parent_class)->finalize (object); }
gboolean gst_gl_context_use_fbo_v2 (GstGLContext * context, gint texture_fbo_width, gint texture_fbo_height, GLuint fbo, GLuint depth_buffer, GLuint texture_fbo, GLCB_V2 cb, gpointer stuff) { GstGLFramebuffer *frame = gst_gl_framebuffer_new (context); UseFBO2 data = { frame, texture_fbo_width, texture_fbo_height, fbo, depth_buffer, texture_fbo, cb, stuff }; gst_gl_context_thread_add (context, (GstGLContextThreadFunc) _use_fbo_v2, &data); gst_object_unref (frame); return TRUE; }
/* Called by glfilter */ gboolean gst_gl_context_gen_shader (GstGLContext * context, const gchar * vert_src, const gchar * frag_src, GstGLShader ** shader) { g_return_val_if_fail (frag_src != NULL || vert_src != NULL, FALSE); g_return_val_if_fail (shader != NULL, FALSE); *shader = gst_gl_shader_new (context); if (frag_src) gst_gl_shader_set_fragment_source (*shader, frag_src); if (vert_src) gst_gl_shader_set_vertex_source (*shader, vert_src); gst_gl_context_thread_add (context, (GstGLContextThreadFunc) _compile_shader, shader); return *shader != NULL; }
static gboolean gst_gl_colorscale_gen_gl_resources (GstGLFilter * filter) { GstGLColorscale *colorscale = GST_GL_COLORSCALE (filter); if (gst_gl_context_get_gl_api (filter->context) & GST_GL_API_GLES2) { gst_gl_context_thread_add (filter->context, (GstGLContextThreadFunc) _compile_identity_shader, colorscale); if (!colorscale->shader) { gst_gl_context_set_error (filter->context, "Failed to initialize identity shader"); GST_ELEMENT_ERROR (colorscale, RESOURCE, NOT_FOUND, ("%s", gst_gl_context_get_error ()), (NULL)); return FALSE; } } return TRUE; }