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 GstFlowReturn gst_glimage_sink_show_frame (GstVideoSink * vsink, GstBuffer * buf) { GstGLImageSink *glimage_sink; GstBuffer *stored_buffer; GST_TRACE ("rendering buffer:%p", buf); glimage_sink = GST_GLIMAGE_SINK (vsink); GST_TRACE ("redisplay texture:%u of size:%ux%u, window size:%ux%u", glimage_sink->next_tex, GST_VIDEO_INFO_WIDTH (&glimage_sink->info), GST_VIDEO_INFO_HEIGHT (&glimage_sink->info), GST_VIDEO_SINK_WIDTH (glimage_sink), GST_VIDEO_SINK_HEIGHT (glimage_sink)); /* Avoid to release the texture while drawing */ GST_GLIMAGE_SINK_LOCK (glimage_sink); glimage_sink->redisplay_texture = glimage_sink->next_tex; stored_buffer = glimage_sink->stored_buffer; glimage_sink->stored_buffer = gst_buffer_ref (buf); GST_GLIMAGE_SINK_UNLOCK (glimage_sink); if (stored_buffer) gst_buffer_unref (stored_buffer); /* Ask the underlying window to redraw its content */ if (!gst_glimage_sink_redisplay (glimage_sink)) goto redisplay_failed; GST_TRACE ("post redisplay"); if (g_atomic_int_get (&glimage_sink->to_quit) != 0) { GST_ELEMENT_ERROR (glimage_sink, RESOURCE, NOT_FOUND, ("%s", gst_gl_context_get_error ()), (NULL)); gst_gl_upload_release_buffer (glimage_sink->upload); return GST_FLOW_ERROR; } return GST_FLOW_OK; /* ERRORS */ redisplay_failed: { gst_gl_upload_release_buffer (glimage_sink->upload); GST_ELEMENT_ERROR (glimage_sink, RESOURCE, NOT_FOUND, ("%s", gst_gl_context_get_error ()), (NULL)); return GST_FLOW_ERROR; } }
void gst_gl_effects_xray_step_five (gint width, gint height, guint texture, gpointer data) { GstGLShader *shader; GstGLEffects *effects = GST_GL_EFFECTS (data); GstGLFilter *filter = GST_GL_FILTER (effects); GstGLContext *context = filter->context; GstGLFuncs *gl = context->gl_vtable; shader = g_hash_table_lookup (effects->shaderstable, "xray4"); if (!shader) { shader = gst_gl_shader_new (context); g_hash_table_insert (effects->shaderstable, "xray4", shader); } if (!gst_gl_shader_compile_and_check (shader, multiply_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)) { gst_gl_context_set_error (context, "Failed to initialize multiply shader"); GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND, ("%s", gst_gl_context_get_error ()), (NULL)); return; } gl->MatrixMode (GL_PROJECTION); gl->LoadIdentity (); gst_gl_shader_use (shader); gl->ActiveTexture (GL_TEXTURE2); gl->Enable (GL_TEXTURE_2D); gl->BindTexture (GL_TEXTURE_2D, effects->midtexture[2]); gl->Disable (GL_TEXTURE_2D); gst_gl_shader_set_uniform_1i (shader, "base", 2); gl->ActiveTexture (GL_TEXTURE1); gl->Enable (GL_TEXTURE_2D); gl->BindTexture (GL_TEXTURE_2D, texture); gl->Disable (GL_TEXTURE_2D); gst_gl_shader_set_uniform_1f (shader, "alpha", (gfloat) 0.5f); gst_gl_shader_set_uniform_1i (shader, "blend", 1); gst_gl_filter_draw_texture (filter, texture, width, height); }
static void gst_gl_effects_xray_step_two (gint width, gint height, guint texture, gpointer data) { GstGLShader *shader; GstGLEffects *effects = GST_GL_EFFECTS (data); GstGLFilter *filter = GST_GL_FILTER (effects); GstGLContext *context = filter->context; GstGLFuncs *gl = context->gl_vtable; shader = g_hash_table_lookup (effects->shaderstable, "xray1"); if (!shader) { shader = gst_gl_shader_new (context); g_hash_table_insert (effects->shaderstable, "xray1", shader); } if (!kernel_ready) { fill_gaussian_kernel (gauss_kernel, 7, 1.5); kernel_ready = TRUE; } if (!gst_gl_shader_compile_and_check (shader, hconv7_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)) { gst_gl_context_set_error (context, "Failed to initialize hconv7 shader"); GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND, ("%s", gst_gl_context_get_error ()), (NULL)); return; } gl->MatrixMode (GL_PROJECTION); gl->LoadIdentity (); gst_gl_shader_use (shader); gl->ActiveTexture (GL_TEXTURE1); gl->Enable (GL_TEXTURE_2D); gl->BindTexture (GL_TEXTURE_2D, texture); gl->Disable (GL_TEXTURE_2D); gst_gl_shader_set_uniform_1i (shader, "tex", 1); gst_gl_shader_set_uniform_1fv (shader, "kernel", 9, gauss_kernel); gst_gl_shader_set_uniform_1f (shader, "width", width); gst_gl_filter_draw_texture (filter, texture, width, height); }
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; }
static void gst_gl_effects_square_callback (gint width, gint height, guint texture, gpointer data) { GstGLShader *shader; GstGLEffects *effects = GST_GL_EFFECTS (data); GstGLFilter *filter = GST_GL_FILTER (effects); GstGLContext *context = filter->context; GstGLFuncs *gl = context->gl_vtable; shader = g_hash_table_lookup (effects->shaderstable, "square0"); if (!shader) { shader = gst_gl_shader_new (context); g_hash_table_insert (effects->shaderstable, "square0", shader); } if (!gst_gl_shader_compile_and_check (shader, square_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)) { gst_gl_context_set_error (context, "Failed to initialize square shader"); GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND, ("%s", gst_gl_context_get_error ()), (NULL)); return; } gl->MatrixMode (GL_PROJECTION); gl->LoadIdentity (); gst_gl_shader_use (shader); gl->ActiveTexture (GL_TEXTURE0); gl->Enable (GL_TEXTURE_2D); gl->BindTexture (GL_TEXTURE_2D, texture); gst_gl_shader_set_uniform_1i (shader, "tex", 0); gst_gl_shader_set_uniform_1f (shader, "width", (gfloat) width / 2.0f); gst_gl_shader_set_uniform_1f (shader, "height", (gfloat) height / 2.0f); gst_gl_filter_draw_texture (filter, texture, width, height); }
static void gst_gl_effects_xray_sobel_length (gint width, gint height, guint texture, gpointer data) { GstGLShader *shader; GstGLEffects *effects = GST_GL_EFFECTS (data); GstGLFilter *filter = GST_GL_FILTER (effects); GstGLContext *context = filter->context; GstGLFuncs *gl = context->gl_vtable; shader = g_hash_table_lookup (effects->shaderstable, "xray_sob_len"); if (!shader) { shader = gst_gl_shader_new (context); g_hash_table_insert (effects->shaderstable, (gchar *) "xray_sob_len", shader); } if (!gst_gl_shader_compile_and_check (shader, sep_sobel_length_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)) { gst_gl_context_set_error (context, "Failed to initialize seobel length shader"); GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND, ("%s", gst_gl_context_get_error ()), (NULL)); return; } gl->MatrixMode (GL_PROJECTION); gl->LoadIdentity (); gst_gl_shader_use (shader); gl->ActiveTexture (GL_TEXTURE1); gl->Enable (GL_TEXTURE_2D); gl->BindTexture (GL_TEXTURE_2D, texture); gl->Disable (GL_TEXTURE_2D); gst_gl_shader_set_uniform_1i (shader, "tex", 1); gst_gl_shader_set_uniform_1i (shader, "invert", TRUE); gst_gl_filter_draw_texture (filter, texture, width, height); }
static GstFlowReturn gst_glimage_sink_render (GstBaseSink * bsink, GstBuffer * buf) { GstGLImageSink *glimage_sink; guint tex_id; GST_TRACE ("rendering buffer:%p", buf); glimage_sink = GST_GLIMAGE_SINK (bsink); if (GST_VIDEO_SINK_WIDTH (glimage_sink) < 1 || GST_VIDEO_SINK_HEIGHT (glimage_sink) < 1) { return GST_FLOW_NOT_NEGOTIATED; } if (!_ensure_gl_setup (glimage_sink)) return GST_FLOW_NOT_NEGOTIATED; if (!gst_gl_upload_perform_with_buffer (glimage_sink->upload, buf, &tex_id)) goto upload_failed; if (glimage_sink->window_id != glimage_sink->new_window_id) { GstGLWindow *window = gst_gl_context_get_window (glimage_sink->context); glimage_sink->window_id = glimage_sink->new_window_id; gst_gl_window_set_window_handle (window, glimage_sink->window_id); gst_object_unref (window); } GST_TRACE ("redisplay texture:%u of size:%ux%u, window size:%ux%u", tex_id, GST_VIDEO_INFO_WIDTH (&glimage_sink->info), GST_VIDEO_INFO_HEIGHT (&glimage_sink->info), GST_VIDEO_SINK_WIDTH (glimage_sink), GST_VIDEO_SINK_HEIGHT (glimage_sink)); /* Avoid to release the texture while drawing */ GST_GLIMAGE_SINK_LOCK (glimage_sink); glimage_sink->redisplay_texture = tex_id; GST_GLIMAGE_SINK_UNLOCK (glimage_sink); /* Ask the underlying window to redraw its content */ if (!gst_glimage_sink_redisplay (glimage_sink)) goto redisplay_failed; GST_TRACE ("post redisplay"); if (g_atomic_int_get (&glimage_sink->to_quit) != 0) { GST_ELEMENT_ERROR (glimage_sink, RESOURCE, NOT_FOUND, ("%s", gst_gl_context_get_error ()), (NULL)); gst_gl_upload_release_buffer (glimage_sink->upload); return GST_FLOW_ERROR; } gst_gl_upload_release_buffer (glimage_sink->upload); return GST_FLOW_OK; /* ERRORS */ redisplay_failed: { gst_gl_upload_release_buffer (glimage_sink->upload); GST_ELEMENT_ERROR (glimage_sink, RESOURCE, NOT_FOUND, ("%s", gst_gl_context_get_error ()), (NULL)); return GST_FLOW_ERROR; } upload_failed: { GST_ELEMENT_ERROR (glimage_sink, RESOURCE, NOT_FOUND, ("%s", "Failed to upload format"), (NULL)); return FALSE; } }
void gst_gl_effects_luma_to_curve (GstGLEffects * effects, GstGLEffectsCurve curve, gint curve_index, gint width, gint height, GLuint texture) { GstGLShader *shader; GstGLFilter *filter = GST_GL_FILTER (effects); GstGLContext *context = filter->context; GstGLFuncs *gl = context->gl_vtable; shader = g_hash_table_lookup (effects->shaderstable, "lumamap0"); if (!shader) { shader = gst_gl_shader_new (context); g_hash_table_insert (effects->shaderstable, "lumamap0", shader); } if (!gst_gl_shader_compile_and_check (shader, luma_to_curve_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)) { gst_gl_context_set_error (context, "Failed to initialize luma to curve shader"); GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND, ("%s", gst_gl_context_get_error ()), (NULL)); return; } gl->MatrixMode (GL_PROJECTION); gl->LoadIdentity (); gst_gl_shader_use (shader); if (effects->curve[curve_index] == 0) { /* this parameters are needed to have a right, predictable, mapping */ gl->GenTextures (1, &effects->curve[curve_index]); gl->Enable (GL_TEXTURE_1D); gl->BindTexture (GL_TEXTURE_1D, effects->curve[curve_index]); gl->TexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); gl->TexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); gl->TexParameteri (GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP); gl->TexParameteri (GL_TEXTURE_1D, GL_TEXTURE_WRAP_T, GL_CLAMP); gl->TexImage1D (GL_TEXTURE_1D, 0, curve.bytes_per_pixel, curve.width, 0, GL_RGB, GL_UNSIGNED_BYTE, curve.pixel_data); gl->Disable (GL_TEXTURE_1D); } gl->ActiveTexture (GL_TEXTURE2); gl->Enable (GL_TEXTURE_2D); gl->BindTexture (GL_TEXTURE_2D, texture); gst_gl_shader_set_uniform_1i (shader, "tex", 2); gl->Disable (GL_TEXTURE_2D); gl->ActiveTexture (GL_TEXTURE1); gl->Enable (GL_TEXTURE_1D); gl->BindTexture (GL_TEXTURE_1D, effects->curve[curve_index]); gst_gl_shader_set_uniform_1i (shader, "curve", 1); gl->Disable (GL_TEXTURE_1D); gst_gl_filter_draw_texture (filter, texture, width, height); }
/* init resources that need a gl context */ static void gst_gl_differencematte_init_gl_resources (GstGLFilter * filter) { GstGLDifferenceMatte *differencematte = GST_GL_DIFFERENCEMATTE (filter); GstGLContext *context = GST_GL_BASE_FILTER (filter)->context; const GstGLFuncs *gl = context->gl_vtable; GError *error = NULL; gint i; for (i = 0; i < 4; i++) { gl->GenTextures (1, &differencematte->midtexture[i]); gl->BindTexture (GL_TEXTURE_2D, differencematte->midtexture[i]); gl->TexImage2D (GL_TEXTURE_2D, 0, GL_RGBA8, 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); differencematte->shader[i] = gst_gl_shader_new (GST_GL_BASE_FILTER (filter)->context); } if (!(differencematte->shader[0] = gst_gl_shader_new_link_with_stages (context, &error, gst_glsl_stage_new_default_vertex (context), gst_glsl_stage_new_with_string (context, GL_FRAGMENT_SHADER, GST_GLSL_VERSION_NONE, GST_GLSL_PROFILE_ES, difference_fragment_source), NULL))) { GST_ELEMENT_ERROR (differencematte, RESOURCE, NOT_FOUND, ("%s", gst_gl_context_get_error ()), (NULL)); return; } if (!(differencematte->shader[1] = gst_gl_shader_new_link_with_stages (context, &error, gst_glsl_stage_new_default_vertex (context), gst_glsl_stage_new_with_string (context, GL_FRAGMENT_SHADER, GST_GLSL_VERSION_NONE, GST_GLSL_PROFILE_ES, hconv7_fragment_source_gles2), NULL))) { GST_ELEMENT_ERROR (differencematte, RESOURCE, NOT_FOUND, ("%s", gst_gl_context_get_error ()), (NULL)); return; } if (!(differencematte->shader[2] = gst_gl_shader_new_link_with_stages (context, &error, gst_glsl_stage_new_default_vertex (context), gst_glsl_stage_new_with_string (context, GL_FRAGMENT_SHADER, GST_GLSL_VERSION_NONE, GST_GLSL_PROFILE_ES, vconv7_fragment_source_gles2), NULL))) { GST_ELEMENT_ERROR (differencematte, RESOURCE, NOT_FOUND, ("%s", gst_gl_context_get_error ()), (NULL)); return; } if (!(differencematte->shader[3] = gst_gl_shader_new_link_with_stages (context, &error, gst_glsl_stage_new_default_vertex (context), gst_glsl_stage_new_with_string (context, GL_FRAGMENT_SHADER, GST_GLSL_VERSION_NONE, GST_GLSL_PROFILE_ES, texture_interp_fragment_source), NULL))) { GST_ELEMENT_ERROR (differencematte, RESOURCE, NOT_FOUND, ("%s", gst_gl_context_get_error ()), (NULL)); return; } /* FIXME: this should really be per shader */ filter->draw_attr_position_loc = gst_gl_shader_get_attribute_location (differencematte->shader[3], "a_position"); filter->draw_attr_texture_loc = gst_gl_shader_get_attribute_location (differencematte->shader[3], "a_texcoord"); }