#define DEBUG_INIT \
GST_DEBUG_CATEGORY_INIT (gst_gl_differencematte_debug, "gldifferencematte", 0, "gldifferencematte element");
+#define gst_gl_differencematte_parent_class parent_class
G_DEFINE_TYPE_WITH_CODE (GstGLDifferenceMatte, gst_gl_differencematte,
GST_TYPE_GL_FILTER, DEBUG_INIT);
/* init resources that need a gl context */
-static void
-gst_gl_differencematte_init_gl_resources (GstGLFilter * filter)
+static gboolean
+gst_gl_differencematte_gl_start (GstGLBaseFilter * base_filter)
{
- GstGLDifferenceMatte *differencematte = GST_GL_DIFFERENCEMATTE (filter);
- GstGLContext *context = GST_GL_BASE_FILTER (filter)->context;
+ GstGLDifferenceMatte *differencematte = GST_GL_DIFFERENCEMATTE (base_filter);
+ GstGLFilter *filter = GST_GL_FILTER (base_filter);
+ GstGLContext *context = base_filter->context;
GstGLBaseMemoryAllocator *tex_alloc;
GstGLAllocationParams *params;
GError *error = NULL;
gint i;
+ if (!GST_GL_BASE_FILTER_CLASS (parent_class)->gl_start (base_filter))
+ return FALSE;
+
tex_alloc = (GstGLBaseMemoryAllocator *)
gst_gl_memory_allocator_get_default (context);
params =
gst_gl_shader_new_default (context, &error))) {
GST_ELEMENT_ERROR (differencematte, RESOURCE, NOT_FOUND, ("%s",
"Failed to compile identity shader"), ("%s", error->message));
- return;
+ return FALSE;
}
if (!(differencematte->shader[0] =
difference_fragment_source), NULL))) {
GST_ELEMENT_ERROR (differencematte, RESOURCE, NOT_FOUND, ("%s",
"Failed to compile difference shader"), ("%s", error->message));
- return;
+ return FALSE;
}
if (!(differencematte->shader[1] =
hconv7_fragment_source_gles2), NULL))) {
GST_ELEMENT_ERROR (differencematte, RESOURCE, NOT_FOUND, ("%s",
"Failed to compile convolution shader"), ("%s", error->message));
- return;
+ return FALSE;
}
if (!(differencematte->shader[2] =
vconv7_fragment_source_gles2), NULL))) {
GST_ELEMENT_ERROR (differencematte, RESOURCE, NOT_FOUND, ("%s",
"Failed to compile convolution shader"), ("%s", error->message));
- return;
+ return FALSE;
}
if (!(differencematte->shader[3] =
texture_interp_fragment_source), NULL))) {
GST_ELEMENT_ERROR (differencematte, RESOURCE, NOT_FOUND, ("%s",
"Failed to compile interpolation shader"), ("%s", error->message));
- return;
+ return FALSE;
}
/* FIXME: this should really be per shader */
filter->draw_attr_texture_loc =
gst_gl_shader_get_attribute_location (differencematte->shader[2],
"a_texcoord");
+
+ return TRUE;
}
/* free resources that need a gl context */
static void
-gst_gl_differencematte_reset_gl_resources (GstGLFilter * filter)
+gst_gl_differencematte_gl_stop (GstGLBaseFilter * base_filter)
{
- GstGLDifferenceMatte *differencematte = GST_GL_DIFFERENCEMATTE (filter);
+ GstGLDifferenceMatte *differencematte = GST_GL_DIFFERENCEMATTE (base_filter);
gint i;
if (differencematte->savedbgtexture) {
differencematte->location = NULL;
differencematte->pixbuf = NULL;
differencematte->bg_has_changed = FALSE;
+
+ GST_GL_BASE_FILTER_CLASS (parent_class)->gl_stop (base_filter);
}
static void
gobject_class->set_property = gst_gl_differencematte_set_property;
gobject_class->get_property = gst_gl_differencematte_get_property;
+ GST_GL_BASE_FILTER_CLASS (klass)->gl_start = gst_gl_differencematte_gl_start;
+ GST_GL_BASE_FILTER_CLASS (klass)->gl_stop = gst_gl_differencematte_gl_stop;
+
GST_GL_FILTER_CLASS (klass)->filter_texture =
gst_gl_differencematte_filter_texture;
- GST_GL_FILTER_CLASS (klass)->display_init_cb =
- gst_gl_differencematte_init_gl_resources;
- GST_GL_FILTER_CLASS (klass)->display_reset_cb =
- gst_gl_differencematte_reset_gl_resources;
g_object_class_install_property (gobject_class,
PROP_LOCATION,
}
/* init resources that need a gl context */
-static void
-gst_gl_effects_init_gl_resources (GstGLFilter * filter)
+static gboolean
+gst_gl_effects_gl_start (GstGLBaseFilter * base_filter)
{
- GstGLEffects *effects = GST_GL_EFFECTS (filter);
- GstGLContext *context = GST_GL_BASE_FILTER (filter)->context;
+ GstGLEffects *effects = GST_GL_EFFECTS (base_filter);
+ GstGLFilter *filter = GST_GL_FILTER (base_filter);
+ GstGLContext *context = base_filter->context;
GstGLBaseMemoryAllocator *base_alloc;
GstGLAllocationParams *params;
gint i;
+ if (!GST_GL_BASE_FILTER_CLASS (parent_class)->gl_start (base_filter))
+ return FALSE;
+
base_alloc = (GstGLBaseMemoryAllocator *)
gst_gl_memory_allocator_get_default (context);
params =
gst_object_unref (base_alloc);
gst_gl_allocation_params_free (params);
+
+ return TRUE;
}
/* free resources that need a gl context */
static void
-gst_gl_effects_reset_gl_resources (GstGLFilter * filter)
+gst_gl_effects_gl_stop (GstGLBaseFilter * base_filter)
{
- GstGLEffects *effects = GST_GL_EFFECTS (filter);
- GstGLFuncs *gl = GST_GL_BASE_FILTER (filter)->context->gl_vtable;
+ GstGLEffects *effects = GST_GL_EFFECTS (base_filter);
+ const GstGLFuncs *gl = base_filter->context->gl_vtable;
gint i = 0;
for (i = 0; i < NEEDED_TEXTURES; i++) {
gst_memory_unref (GST_MEMORY_CAST (effects->midtexture[i]));
}
+
for (i = 0; i < GST_GL_EFFECTS_N_CURVES; i++) {
gl->DeleteTextures (1, &effects->curve[i]);
effects->curve[i] = 0;
}
+
+ GST_GL_BASE_FILTER_CLASS (parent_class)->gl_stop (base_filter);
}
static void
GST_BASE_TRANSFORM_CLASS (klass)->start = gst_gl_effects_init_resources;
GST_BASE_TRANSFORM_CLASS (klass)->stop = gst_gl_effects_reset_resources;
+ GST_GL_BASE_FILTER_CLASS (klass)->gl_start = gst_gl_effects_gl_start;
+ GST_GL_BASE_FILTER_CLASS (klass)->gl_stop = gst_gl_effects_gl_stop;
+
GST_GL_FILTER_CLASS (klass)->filter_texture = gst_gl_effects_filter_texture;
- GST_GL_FILTER_CLASS (klass)->display_init_cb =
- gst_gl_effects_init_gl_resources;
- GST_GL_FILTER_CLASS (klass)->display_reset_cb =
- gst_gl_effects_reset_gl_resources;
GST_GL_FILTER_CLASS (klass)->init_fbo = gst_gl_effects_on_init_gl_context;
klass->filter_descriptor = NULL;
static void gst_gl_filter_cube_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec);
-static gboolean gst_gl_filter_cube_stop (GstBaseTransform * trans);
-
static gboolean gst_gl_filter_cube_set_caps (GstGLFilter * filter,
GstCaps * incaps, GstCaps * outcaps);
-static void gst_gl_filter_cube_reset_gl (GstGLFilter * filter);
-static gboolean gst_gl_filter_cube_init_shader (GstGLFilter * filter);
+static gboolean gst_gl_filter_cube_gl_start (GstGLBaseFilter * filter);
+static void gst_gl_filter_cube_gl_stop (GstGLBaseFilter * filter);
static gboolean _callback (gpointer stuff);
static gboolean gst_gl_filter_cube_filter_texture (GstGLFilter * filter,
GstGLMemory * in_tex, GstGLMemory * out_tex);
gobject_class->set_property = gst_gl_filter_cube_set_property;
gobject_class->get_property = gst_gl_filter_cube_get_property;
- GST_BASE_TRANSFORM_CLASS (klass)->stop = gst_gl_filter_cube_stop;
+ GST_GL_BASE_FILTER_CLASS (klass)->gl_start = gst_gl_filter_cube_gl_start;
+ GST_GL_BASE_FILTER_CLASS (klass)->gl_stop = gst_gl_filter_cube_gl_stop;
- GST_GL_FILTER_CLASS (klass)->init_fbo = gst_gl_filter_cube_init_shader;
- GST_GL_FILTER_CLASS (klass)->display_reset_cb = gst_gl_filter_cube_reset_gl;
GST_GL_FILTER_CLASS (klass)->set_caps = gst_gl_filter_cube_set_caps;
GST_GL_FILTER_CLASS (klass)->filter_texture =
gst_gl_filter_cube_filter_texture;
}
static void
-gst_gl_filter_cube_reset_gl (GstGLFilter * filter)
+gst_gl_filter_cube_gl_stop (GstGLBaseFilter * base_filter)
{
- GstGLFilterCube *cube_filter = GST_GL_FILTER_CUBE (filter);
- const GstGLFuncs *gl = GST_GL_BASE_FILTER (filter)->context->gl_vtable;
+ GstGLFilterCube *cube_filter = GST_GL_FILTER_CUBE (base_filter);
+ const GstGLFuncs *gl = base_filter->context->gl_vtable;
if (cube_filter->vao) {
gl->DeleteVertexArrays (1, &cube_filter->vao);
}
if (cube_filter->shader) {
- gst_gl_context_del_shader (GST_GL_BASE_FILTER (filter)->context,
- cube_filter->shader);
+ gst_object_unref (cube_filter->shader);
cube_filter->shader = NULL;
}
-}
-
-static gboolean
-gst_gl_filter_cube_stop (GstBaseTransform * trans)
-{
- GstGLFilterCube *cube_filter = GST_GL_FILTER_CUBE (trans);
- /* blocking call, wait the opengl thread has destroyed the shader */
- if (cube_filter->shader)
- gst_gl_context_del_shader (GST_GL_BASE_FILTER (trans)->context,
- cube_filter->shader);
- cube_filter->shader = NULL;
-
- return GST_BASE_TRANSFORM_CLASS (parent_class)->stop (trans);
+ GST_GL_BASE_FILTER_CLASS (parent_class)->gl_stop (base_filter);
}
static gboolean
-gst_gl_filter_cube_init_shader (GstGLFilter * filter)
+gst_gl_filter_cube_gl_start (GstGLBaseFilter * filter)
{
GstGLFilterCube *cube_filter = GST_GL_FILTER_CUBE (filter);
- if (cube_filter->shader) {
- gst_object_unref (cube_filter->shader);
- cube_filter->shader = NULL;
- }
-
/* blocking call, wait the opengl thread has compiled the shader */
return gst_gl_context_gen_shader (GST_GL_BASE_FILTER (filter)->context,
cube_v_src, cube_f_src, &cube_filter->shader);
#define DEBUG_INIT \
GST_DEBUG_CATEGORY_INIT (gst_gl_overlay_debug, "gloverlay", 0, "gloverlay element");
+#define gst_gl_overlay_parent_class parent_class
G_DEFINE_TYPE_WITH_CODE (GstGLOverlay, gst_gl_overlay, GST_TYPE_GL_FILTER,
DEBUG_INIT);
/* init resources that need a gl context */
static gboolean
-gst_gl_overlay_init_gl_resources (GstGLFilter * filter)
+gst_gl_overlay_gl_start (GstGLBaseFilter * base_filter)
{
- GstGLOverlay *overlay = GST_GL_OVERLAY (filter);
+ GstGLOverlay *overlay = GST_GL_OVERLAY (base_filter);
- if (overlay->shader)
- gst_gl_context_del_shader (GST_GL_BASE_FILTER (filter)->context,
- overlay->shader);
+ if (!GST_GL_BASE_FILTER_CLASS (parent_class)->gl_start (base_filter))
+ return FALSE;
- return gst_gl_context_gen_shader (GST_GL_BASE_FILTER (filter)->context,
- overlay_v_src, overlay_f_src, &overlay->shader);
+ return gst_gl_context_gen_shader (base_filter->context, overlay_v_src,
+ overlay_f_src, &overlay->shader);
}
/* free resources that need a gl context */
static void
-gst_gl_overlay_reset_gl_resources (GstGLFilter * filter)
+gst_gl_overlay_gl_stop (GstGLBaseFilter * base_filter)
{
- GstGLOverlay *overlay = GST_GL_OVERLAY (filter);
- const GstGLFuncs *gl = GST_GL_BASE_FILTER (filter)->context->gl_vtable;
+ GstGLOverlay *overlay = GST_GL_OVERLAY (base_filter);
+ const GstGLFuncs *gl = base_filter->context->gl_vtable;
if (overlay->shader) {
- gst_gl_context_del_shader (GST_GL_BASE_FILTER (filter)->context,
- overlay->shader);
+ gst_object_unref (overlay->shader);
overlay->shader = NULL;
}
gl->DeleteBuffers (1, &overlay->overlay_vbo);
overlay->overlay_vbo = 0;
}
+
+ GST_GL_BASE_FILTER_CLASS (parent_class)->gl_stop (base_filter);
}
static void
gobject_class->set_property = gst_gl_overlay_set_property;
gobject_class->get_property = gst_gl_overlay_get_property;
+ GST_GL_BASE_FILTER_CLASS (klass)->gl_start = gst_gl_overlay_gl_start;
+ GST_GL_BASE_FILTER_CLASS (klass)->gl_stop = gst_gl_overlay_gl_stop;
+
GST_GL_FILTER_CLASS (klass)->set_caps = gst_gl_overlay_set_caps;
GST_GL_FILTER_CLASS (klass)->filter_texture = gst_gl_overlay_filter_texture;
- GST_GL_FILTER_CLASS (klass)->display_reset_cb =
- gst_gl_overlay_reset_gl_resources;
- GST_GL_FILTER_CLASS (klass)->init_fbo = gst_gl_overlay_init_gl_resources;
GST_BASE_TRANSFORM_CLASS (klass)->before_transform =
GST_DEBUG_FUNCPTR (gst_gl_overlay_before_transform);
static gboolean gst_gl_transformation_decide_allocation (GstBaseTransform *
trans, GstQuery * query);
-static void gst_gl_transformation_reset_gl (GstGLFilter * filter);
-static gboolean gst_gl_transformation_stop (GstBaseTransform * trans);
-static gboolean gst_gl_transformation_init_shader (GstGLFilter * filter);
+static void gst_gl_transformation_gl_stop (GstGLBaseFilter * filter);
+static gboolean gst_gl_transformation_gl_start (GstGLBaseFilter * base_filter);
static gboolean gst_gl_transformation_callback (gpointer stuff);
static void gst_gl_transformation_build_mvp (GstGLTransformation *
transformation);
gst_gl_transformation_decide_allocation;
base_transform_class->filter_meta = gst_gl_transformation_filter_meta;
- GST_GL_FILTER_CLASS (klass)->init_fbo = gst_gl_transformation_init_shader;
- GST_GL_FILTER_CLASS (klass)->display_reset_cb =
- gst_gl_transformation_reset_gl;
+ GST_GL_BASE_FILTER_CLASS (klass)->gl_start = gst_gl_transformation_gl_start;
+ GST_GL_BASE_FILTER_CLASS (klass)->gl_stop = gst_gl_transformation_gl_stop;
+
GST_GL_FILTER_CLASS (klass)->set_caps = gst_gl_transformation_set_caps;
GST_GL_FILTER_CLASS (klass)->filter = gst_gl_transformation_filter;
GST_GL_FILTER_CLASS (klass)->filter_texture =
gst_gl_transformation_filter_texture;
- GST_BASE_TRANSFORM_CLASS (klass)->stop = gst_gl_transformation_stop;
GST_BASE_TRANSFORM_CLASS (klass)->prepare_output_buffer =
gst_gl_transformation_prepare_output_buffer;
}
static void
-gst_gl_transformation_reset_gl (GstGLFilter * filter)
+gst_gl_transformation_gl_stop (GstGLBaseFilter * base_filter)
{
- GstGLTransformation *transformation = GST_GL_TRANSFORMATION (filter);
- const GstGLFuncs *gl = GST_GL_BASE_FILTER (filter)->context->gl_vtable;
+ GstGLTransformation *transformation = GST_GL_TRANSFORMATION (base_filter);
+ const GstGLFuncs *gl = base_filter->context->gl_vtable;
if (transformation->vao) {
gl->DeleteVertexArrays (1, &transformation->vao);
gst_object_unref (transformation->shader);
transformation->shader = NULL;
}
-}
-
-static gboolean
-gst_gl_transformation_stop (GstBaseTransform * trans)
-{
- GstGLBaseFilter *basefilter = GST_GL_BASE_FILTER (trans);
- GstGLTransformation *transformation = GST_GL_TRANSFORMATION (trans);
-
- /* blocking call, wait until the opengl thread has destroyed the shader */
- if (basefilter->context && transformation->shader) {
- gst_gl_context_del_shader (basefilter->context, transformation->shader);
- transformation->shader = NULL;
- }
- return GST_BASE_TRANSFORM_CLASS (parent_class)->stop (trans);
+ GST_GL_BASE_FILTER_CLASS (parent_class)->gl_stop (base_filter);
}
static gboolean
-gst_gl_transformation_init_shader (GstGLFilter * filter)
+gst_gl_transformation_gl_start (GstGLBaseFilter * base_filter)
{
- GstGLTransformation *transformation = GST_GL_TRANSFORMATION (filter);
+ GstGLTransformation *transformation = GST_GL_TRANSFORMATION (base_filter);
- if (transformation->shader) {
- gst_object_unref (transformation->shader);
- transformation->shader = NULL;
- }
+ if (!GST_GL_BASE_FILTER_CLASS (parent_class)->gl_start (base_filter))
+ return FALSE;
- if (gst_gl_context_get_gl_api (GST_GL_BASE_FILTER (filter)->context)) {
+ if (gst_gl_context_get_gl_api (base_filter->context)) {
/* blocking call, wait until the opengl thread has compiled the shader */
- return gst_gl_context_gen_shader (GST_GL_BASE_FILTER (filter)->context,
+ return gst_gl_context_gen_shader (base_filter->context,
gst_gl_shader_string_vertex_mat4_vertex_transform,
gst_gl_shader_string_fragment_default, &transformation->shader);
}
static void gst_gl_base_filter_gl_start (GstGLContext * context, gpointer data);
static void gst_gl_base_filter_gl_stop (GstGLContext * context, gpointer data);
+static gboolean gst_gl_base_filter_default_gl_start (GstGLBaseFilter * filter);
+static void gst_gl_base_filter_default_gl_stop (GstGLBaseFilter * filter);
+
static void
gst_gl_base_filter_class_init (GstGLBaseFilterClass * klass)
{
GST_TYPE_GL_CONTEXT, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
klass->supported_gl_api = GST_GL_API_ANY;
+ klass->gl_start = gst_gl_base_filter_default_gl_start;
+ klass->gl_stop = gst_gl_base_filter_default_gl_stop;
}
static void
return TRUE;
}
+static gboolean
+gst_gl_base_filter_default_gl_start (GstGLBaseFilter * filter)
+{
+ return TRUE;
+}
+
static void
gst_gl_base_filter_gl_start (GstGLContext * context, gpointer data)
{
gst_gl_insert_debug_marker (filter->context,
"starting element %s", GST_OBJECT_NAME (filter));
- if (filter_class->gl_start) {
- filter->priv->gl_result = filter_class->gl_start (filter);
- } else {
- filter->priv->gl_result = TRUE;
- }
+ filter->priv->gl_result = filter_class->gl_start (filter);
+}
- filter->priv->gl_started |= filter->priv->gl_result;
+static void
+gst_gl_base_filter_default_gl_stop (GstGLBaseFilter * filter)
+{
}
static void
gst_gl_insert_debug_marker (filter->context,
"stopping element %s", GST_OBJECT_NAME (filter));
- if (filter->priv->gl_started) {
- if (filter_class->gl_stop)
- filter_class->gl_stop (filter);
- }
+ if (filter->priv->gl_started)
+ filter_class->gl_stop (filter);
filter->priv->gl_started = FALSE;
}
GstQuery * query);
static gboolean gst_gl_filter_set_caps (GstBaseTransform * bt, GstCaps * incaps,
GstCaps * outcaps);
-static gboolean gst_gl_filter_gl_start (GstGLBaseFilter * filter);
static void gst_gl_filter_gl_stop (GstGLBaseFilter * filter);
static gboolean gst_gl_filter_gl_set_caps (GstGLBaseFilter * bt,
GstCaps * incaps, GstCaps * outcaps);
gst_gl_filter_decide_allocation;
GST_BASE_TRANSFORM_CLASS (klass)->get_unit_size = gst_gl_filter_get_unit_size;
- GST_GL_BASE_FILTER_CLASS (klass)->gl_start = gst_gl_filter_gl_start;
GST_GL_BASE_FILTER_CLASS (klass)->gl_stop = gst_gl_filter_gl_stop;
GST_GL_BASE_FILTER_CLASS (klass)->gl_set_caps = gst_gl_filter_gl_set_caps;
return GST_BASE_TRANSFORM_CLASS (parent_class)->stop (bt);
}
-static gboolean
-gst_gl_filter_gl_start (GstGLBaseFilter * base_filter)
-{
- GstGLFilter *filter = GST_GL_FILTER (base_filter);
- GstGLFilterClass *filter_class = GST_GL_FILTER_GET_CLASS (filter);
-
- if (filter_class->display_init_cb)
- filter_class->display_init_cb (filter);
-
- return TRUE;
-}
-
static void
gst_gl_filter_gl_stop (GstGLBaseFilter * base_filter)
{
GstGLFilter *filter = GST_GL_FILTER (base_filter);
- GstGLFilterClass *filter_class = GST_GL_FILTER_GET_CLASS (filter);
- GstGLContext *context = GST_GL_BASE_FILTER (filter)->context;
+ GstGLContext *context = base_filter->context;
const GstGLFuncs *gl = context->gl_vtable;
- if (filter_class->display_reset_cb)
- filter_class->display_reset_cb (filter);
-
if (filter->vao) {
gl->DeleteVertexArrays (1, &filter->vao);
filter->vao = 0;
filter->default_shader = NULL;
filter->draw_attr_position_loc = -1;
filter->draw_attr_texture_loc = -1;
+
+ GST_GL_BASE_FILTER_CLASS (parent_class)->gl_stop (base_filter);
}
static GstCaps *
* @filter_texture: given @in_tex, transform it into @out_tex. Not used
* if @filter exists
* @init_fbo: perform initialization when the Framebuffer object is created
- * @display_init_cb: execute arbitrary gl code on start
- * @display_reset_cb: execute arbitrary gl code at stop
* @transform_internal_caps: Perform sub-class specific modifications of the
* caps to be processed between upload on input and before download for output.
*/
GstCaps *(*transform_internal_caps) (GstGLFilter *filter,
GstPadDirection direction, GstCaps * caps, GstCaps * filter_caps);
- /* useful to init and cleanup custom gl resources */
- void (*display_init_cb) (GstGLFilter *filter);
- void (*display_reset_cb) (GstGLFilter *filter);
-
/* <private> */
gpointer _padding[GST_PADDING];
};