diff options
Diffstat (limited to 'import-layers/yocto-poky/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad')
9 files changed, 1536 insertions, 38 deletions
diff --git a/import-layers/yocto-poky/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0001-Makefile.am-don-t-hardcode-libtool-name-when-running.patch b/import-layers/yocto-poky/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0001-Makefile.am-don-t-hardcode-libtool-name-when-running.patch index 154d340e4..33efc503e 100644 --- a/import-layers/yocto-poky/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0001-Makefile.am-don-t-hardcode-libtool-name-when-running.patch +++ b/import-layers/yocto-poky/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0001-Makefile.am-don-t-hardcode-libtool-name-when-running.patch @@ -17,7 +17,7 @@ diff --git a/gst-libs/gst/gl/Makefile.am b/gst-libs/gst/gl/Makefile.am index f968357..7cc2c7a 100644 --- a/gst-libs/gst/gl/Makefile.am +++ b/gst-libs/gst/gl/Makefile.am -@@ -149,7 +149,7 @@ GstGL-@GST_API_VERSION@.gir: $(INTROSPECTION_SCANNER) libgstgl-@GST_API_VERSION@ +@@ -167,7 +167,7 @@ GstGL-@GST_API_VERSION@.gir: $(INTROSPECTION_SCANNER) libgstgl-@GST_API_VERSION@ --library=libgstgl-@GST_API_VERSION@.la \ --include=Gst-@GST_API_VERSION@ \ --include=GstBase-@GST_API_VERSION@ \ @@ -30,7 +30,7 @@ diff --git a/gst-libs/gst/insertbin/Makefile.am b/gst-libs/gst/insertbin/Makefil index 09eb97c..b746885 100644 --- a/gst-libs/gst/insertbin/Makefile.am +++ b/gst-libs/gst/insertbin/Makefile.am -@@ -43,7 +43,7 @@ GstInsertBin-@GST_API_VERSION@.gir: $(INTROSPECTION_SCANNER) libgstinsertbin-@GS +@@ -44,7 +44,7 @@ GstInsertBin-@GST_API_VERSION@.gir: $(INTROSPECTION_SCANNER) libgstinsertbin-@GS --library=libgstinsertbin-@GST_API_VERSION@.la \ --include=Gst-@GST_API_VERSION@ \ --include=GstBase-@GST_API_VERSION@ \ diff --git a/import-layers/yocto-poky/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0002-glplugin-enable-gldeinterlace-on-OpenGL-ES.patch b/import-layers/yocto-poky/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0002-glplugin-enable-gldeinterlace-on-OpenGL-ES.patch new file mode 100755 index 000000000..51f4eb4b3 --- /dev/null +++ b/import-layers/yocto-poky/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0002-glplugin-enable-gldeinterlace-on-OpenGL-ES.patch @@ -0,0 +1,634 @@ +From 8a0e97f7e672301cc76e394855e8c7a3448b0249 Mon Sep 17 00:00:00 2001 +From: Haihua Hu <jared.hu@nxp.com> +Date: Fri, 8 Apr 2016 16:47:15 +0800 +Subject: [PATCH 4/6] [glplugin] enable gldeinterlace on OpenGL ES +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +1.Porting the exist deinterlace shader and OpenGL callback + to be compatible with OpenGL ES. +2.Add a our blur vertical shader to gldeinterlace. +3.Add a property named “method” to let user choose which + deinterlace function to use. Default to choose blur vertical + method for better performance. + +Upstream-Status: Backport [1.9.1] + +https://bugzilla.gnome.org/show_bug.cgi?id=764873 + +Signed-off-by: Haihua Hu <jared.hu@nxp.com> +--- + ext/gl/Makefile.am | 4 +- + ext/gl/gstgldeinterlace.c | 344 +++++++++++++++++++++++++++++++++++----------- + ext/gl/gstgldeinterlace.h | 6 +- + ext/gl/gstopengl.c | 13 +- + 4 files changed, 275 insertions(+), 92 deletions(-) + +diff --git a/ext/gl/Makefile.am b/ext/gl/Makefile.am +index 5d55f54..46419a7 100644 +--- a/ext/gl/Makefile.am ++++ b/ext/gl/Makefile.am +@@ -40,6 +40,7 @@ libgstopengl_la_SOURCES = \ + gstglfilterapp.c \ + gstglviewconvert.c \ + gstglstereosplit.c \ ++ gstgldeinterlace.c \ + gstglstereomix.c + + noinst_HEADERS = \ +@@ -63,20 +64,19 @@ noinst_HEADERS = \ + gstglfilterapp.h \ + gstglstereosplit.h \ + gstglstereomix.h \ ++ gstgldeinterlace.h \ + gstglviewconvert.h + + # full opengl required + if USE_OPENGL + libgstopengl_la_SOURCES += \ + gstglfilterglass.c \ +- gstgldeinterlace.c \ + gltestsrc.c \ + gstgltestsrc.c \ + gstglmosaic.c + + noinst_HEADERS += \ + gstglfilterglass.h \ +- gstgldeinterlace.h \ + gltestsrc.h \ + gstgltestsrc.h \ + gstglmosaic.h \ +diff --git a/ext/gl/gstgldeinterlace.c b/ext/gl/gstgldeinterlace.c +index bd0eff0..c1250dc 100644 +--- a/ext/gl/gstgldeinterlace.c ++++ b/ext/gl/gstgldeinterlace.c +@@ -43,7 +43,8 @@ GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT); + + enum + { +- PROP_0 ++ PROP_0, ++ PROP_METHOD + }; + + #define DEBUG_INIT \ +@@ -57,17 +58,23 @@ static void gst_gl_deinterlace_set_property (GObject * object, + static void gst_gl_deinterlace_get_property (GObject * object, + guint prop_id, GValue * value, GParamSpec * pspec); + ++static gboolean gst_gl_deinterlace_start (GstBaseTransform * trans); + static gboolean gst_gl_deinterlace_reset (GstBaseTransform * trans); +-static gboolean gst_gl_deinterlace_init_shader (GstGLFilter * filter); ++static gboolean gst_gl_deinterlace_init_fbo (GstGLFilter * filter); + static gboolean gst_gl_deinterlace_filter (GstGLFilter * filter, + GstBuffer * inbuf, GstBuffer * outbuf); + static gboolean gst_gl_deinterlace_filter_texture (GstGLFilter * filter, + guint in_tex, guint out_tex); +-static void gst_gl_deinterlace_callback (gint width, gint height, ++static void gst_gl_deinterlace_vfir_callback (gint width, gint height, ++ guint texture, gpointer stuff); ++static void gst_gl_deinterlace_greedyh_callback (gint width, gint height, + guint texture, gpointer stuff); + + /* *INDENT-OFF* */ + static const gchar *greedyh_fragment_source = ++ "#ifdef GL_ES\n" ++ "precision mediump float;\n" ++ "#endif\n" + "uniform sampler2D tex;\n" + "uniform sampler2D tex_prev;\n" + "uniform float max_comb;\n" +@@ -75,35 +82,35 @@ static const gchar *greedyh_fragment_source = + "uniform float motion_sense;\n" + "uniform float width;\n" + "uniform float height;\n" ++ "varying vec2 v_texcoord;\n" + + "void main () {\n" +- " vec2 texcoord = gl_TexCoord[0].xy;\n" +- " if (int(mod(texcoord.y * height, 2.0)) == 0) {\n" +- " gl_FragColor = vec4(texture2D(tex_prev, texcoord).rgb, 1.0);\n" ++ " if (int(mod(v_texcoord.y * height, 2.0)) == 0) {\n" ++ " gl_FragColor = vec4(texture2D(tex_prev, v_texcoord).rgb, 1.0);\n" + " } else {\n" + " vec2 texcoord_L1_a1, texcoord_L3_a1, texcoord_L1, texcoord_L3, texcoord_L1_1, texcoord_L3_1;\n" + " vec3 L1_a1, L3_a1, L1, L3, L1_1, L3_1;\n" + +- " texcoord_L1 = vec2(texcoord.x, texcoord.y - 1.0 / height);\n" +- " texcoord_L3 = vec2(texcoord.x, texcoord.y + 1.0 / height);\n" ++ " texcoord_L1 = vec2(v_texcoord.x, v_texcoord.y - 1.0 / height);\n" ++ " texcoord_L3 = vec2(v_texcoord.x, v_texcoord.y + 1.0 / height);\n" + " L1 = texture2D(tex_prev, texcoord_L1).rgb;\n" + " L3 = texture2D(tex_prev, texcoord_L3).rgb;\n" +- " if (texcoord.x == 1.0 && texcoord.y == 1.0) {\n" ++ " if (v_texcoord.x == 1.0 && v_texcoord.y == 1.0) {\n" + " L1_1 = L1;\n" + " L3_1 = L3;\n" + " } else {\n" +- " texcoord_L1_1 = vec2(texcoord.x + 1.0 / width, texcoord.y - 1.0 / height);\n" +- " texcoord_L3_1 = vec2(texcoord.x + 1.0 / width, texcoord.y + 1.0 / height);\n" ++ " texcoord_L1_1 = vec2(v_texcoord.x + 1.0 / width, v_texcoord.y - 1.0 / height);\n" ++ " texcoord_L3_1 = vec2(v_texcoord.x + 1.0 / width, v_texcoord.y + 1.0 / height);\n" + " L1_1 = texture2D(tex_prev, texcoord_L1_1).rgb;\n" + " L3_1 = texture2D(tex_prev, texcoord_L3_1).rgb;\n" + " }\n" + +- " if (int(ceil(texcoord.x + texcoord.y)) == 0) {\n" ++ " if (int(ceil(v_texcoord.x + v_texcoord.y)) == 0) {\n" + " L1_a1 = L1;\n" + " L3_a1 = L3;\n" + " } else {\n" +- " texcoord_L1_a1 = vec2(texcoord.x - 1.0 / width, texcoord.y - 1.0 / height);\n" +- " texcoord_L3_a1 = vec2(texcoord.x - 1.0 / width, texcoord.y + 1.0 / height);\n" ++ " texcoord_L1_a1 = vec2(v_texcoord.x - 1.0 / width, v_texcoord.y - 1.0 / height);\n" ++ " texcoord_L3_a1 = vec2(v_texcoord.x - 1.0 / width, v_texcoord.y + 1.0 / height);\n" + " L1_a1 = texture2D(tex_prev, texcoord_L1_a1).rgb;\n" + " L3_a1 = texture2D(tex_prev, texcoord_L3_a1).rgb;\n" + " }\n" +@@ -113,8 +120,8 @@ static const gchar *greedyh_fragment_source = + " vec3 avg_1 = (L1_1 + L3_1) / 2.0;\n" + " vec3 avg_s = (avg_a1 + avg_1) / 2.0;\n" + " vec3 avg_sc = (avg_s + avg) / 2.0;\n" +- " vec3 L2 = texture2D(tex, texcoord).rgb;\n" +- " vec3 LP2 = texture2D(tex_prev, texcoord).rgb;\n" ++ " vec3 L2 = texture2D(tex, v_texcoord).rgb;\n" ++ " vec3 LP2 = texture2D(tex_prev, v_texcoord).rgb;\n" + " vec3 best;\n" + " if (abs(L2.r - avg_sc.r) < abs(LP2.r - avg_sc.r)) {\n" + " best.r = L2.r;\n" " } else {\n" +@@ -144,8 +151,87 @@ static const gchar *greedyh_fragment_source = + " gl_FragColor = vec4(last, 1.0);\n" + " }\n" + "}\n"; ++ ++const gchar *vfir_fragment_source = ++ "#ifdef GL_ES\n" ++ "precision mediump float;\n" ++ "#endif\n" ++ "uniform sampler2D tex;\n" ++ "uniform float width;\n" ++ "uniform float height;\n" ++ "varying vec2 v_texcoord;\n" ++ "void main()\n" ++ "{\n" ++ " vec2 topcoord, botcoord;\n" ++ " vec4 cur_color, top_color, bot_color;\n" ++ " topcoord.x = v_texcoord.x;\n" ++ " botcoord.x = v_texcoord.x;\n" ++ " if (v_texcoord.y == 0.0 || v_texcoord.y == 1.0) {\n" ++ " topcoord.y = v_texcoord.y ;\n" ++ " botcoord.y = v_texcoord.y ;\n" ++ " }\n" ++ " else {\n" ++ " topcoord.y = v_texcoord.y - 1.0/height;\n" ++ " botcoord.y = v_texcoord.y + 1.0/height;\n" ++ " }\n" ++ " cur_color = texture2D(tex, v_texcoord);\n" ++ " top_color = texture2D(tex, topcoord);\n" ++ " bot_color = texture2D(tex, botcoord);\n" ++ " gl_FragColor = 0.5*cur_color + 0.25*top_color + 0.25*bot_color;\n" ++ "}"; + /* *INDENT-ON* */ + ++/* dont' forget to edit the following when a new method is added */ ++typedef enum ++{ ++ GST_GL_DEINTERLACE_VFIR, ++ GST_GL_DEINTERLACE_GREEDYH ++} GstGLDeinterlaceMethod; ++ ++static const GEnumValue * ++gst_gl_deinterlace_get_methods (void) ++{ ++ static const GEnumValue method_types[] = { ++ {GST_GL_DEINTERLACE_VFIR, "Blur Vertical", "vfir"}, ++ {GST_GL_DEINTERLACE_GREEDYH, "Motion Adaptive: Advanced Detection", ++ "greedhy"}, ++ {0, NULL, NULL} ++ }; ++ return method_types; ++} ++ ++#define GST_TYPE_GL_DEINTERLACE_METHODS (gst_gl_deinterlace_method_get_type ()) ++static GType ++gst_gl_deinterlace_method_get_type (void) ++{ ++ static GType gl_deinterlace_method_type = 0; ++ if (!gl_deinterlace_method_type) { ++ gl_deinterlace_method_type = ++ g_enum_register_static ("GstGLDeinterlaceMethod", ++ gst_gl_deinterlace_get_methods ()); ++ } ++ return gl_deinterlace_method_type; ++} ++ ++static void ++gst_gl_deinterlace_set_method (GstGLDeinterlace * deinterlace, ++ guint method_types) ++{ ++ switch (method_types) { ++ case GST_GL_DEINTERLACE_VFIR: ++ deinterlace->deinterlacefunc = gst_gl_deinterlace_vfir_callback; ++ deinterlace->current_method = method_types; ++ break; ++ case GST_GL_DEINTERLACE_GREEDYH: ++ deinterlace->deinterlacefunc = gst_gl_deinterlace_greedyh_callback; ++ deinterlace->current_method = method_types; ++ break; ++ default: ++ g_assert_not_reached (); ++ break; ++ } ++} ++ + static void + gst_gl_deinterlace_class_init (GstGLDeinterlaceClass * klass) + { +@@ -163,25 +249,60 @@ gst_gl_deinterlace_class_init (GstGLDeinterlaceClass * klass) + "Deinterlacing based on fragment shaders", + "Julien Isorce <julien.isorce@mail.com>"); + ++ g_object_class_install_property (gobject_class, ++ PROP_METHOD, ++ g_param_spec_enum ("method", ++ "Deinterlace Method", ++ "Select which deinterlace method apply to GL video texture", ++ GST_TYPE_GL_DEINTERLACE_METHODS, ++ GST_GL_DEINTERLACE_VFIR, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); ++ ++ GST_BASE_TRANSFORM_CLASS (klass)->start = gst_gl_deinterlace_start; + GST_BASE_TRANSFORM_CLASS (klass)->stop = gst_gl_deinterlace_reset; + + GST_GL_FILTER_CLASS (klass)->filter = gst_gl_deinterlace_filter; + GST_GL_FILTER_CLASS (klass)->filter_texture = + gst_gl_deinterlace_filter_texture; +- GST_GL_FILTER_CLASS (klass)->init_fbo = gst_gl_deinterlace_init_shader; ++ GST_GL_FILTER_CLASS (klass)->init_fbo = gst_gl_deinterlace_init_fbo; + +- GST_GL_BASE_FILTER_CLASS (klass)->supported_gl_api = GST_GL_API_OPENGL; ++ GST_GL_BASE_FILTER_CLASS (klass)->supported_gl_api = ++ GST_GL_API_OPENGL | GST_GL_API_GLES2 | GST_GL_API_OPENGL3; + } + + static void + gst_gl_deinterlace_init (GstGLDeinterlace * filter) + { +- filter->shader = NULL; ++ filter->shaderstable = NULL; ++ filter->deinterlacefunc = gst_gl_deinterlace_vfir_callback; ++ filter->current_method = GST_GL_DEINTERLACE_VFIR; + filter->prev_buffer = NULL; + filter->prev_tex = 0; + } + + static gboolean ++gst_gl_deinterlace_start (GstBaseTransform * trans) ++{ ++ GstGLDeinterlace *deinterlace_filter = GST_GL_DEINTERLACE (trans); ++ ++ deinterlace_filter->shaderstable = g_hash_table_new (g_str_hash, g_str_equal); ++ ++ return GST_BASE_TRANSFORM_CLASS (parent_class)->start (trans); ++} ++ ++static void ++gst_gl_deinterlace_ghash_func_clean (gpointer key, gpointer value, ++ gpointer data) ++{ ++ GstGLShader *shader = (GstGLShader *) value; ++ GstGLFilter *filter = (GstGLFilter *) data; ++ ++ //blocking call, wait the opengl thread has destroyed the shader ++ gst_gl_context_del_shader (GST_GL_BASE_FILTER (filter)->context, shader); ++ ++ value = NULL; ++} ++ ++static gboolean + gst_gl_deinterlace_reset (GstBaseTransform * trans) + { + GstGLDeinterlace *deinterlace_filter = GST_GL_DEINTERLACE (trans); +@@ -189,10 +310,17 @@ gst_gl_deinterlace_reset (GstBaseTransform * trans) + gst_buffer_replace (&deinterlace_filter->prev_buffer, NULL); + + //blocking call, wait the opengl thread has destroyed the shader +- if (deinterlace_filter->shader) +- gst_gl_context_del_shader (GST_GL_BASE_FILTER (trans)->context, +- deinterlace_filter->shader); +- deinterlace_filter->shader = NULL; ++ if (deinterlace_filter->shaderstable) { ++ /* release shaders in the gl thread */ ++ g_hash_table_foreach (deinterlace_filter->shaderstable, ++ gst_gl_deinterlace_ghash_func_clean, deinterlace_filter); ++ ++ /* clean the htable without calling values destructors ++ * because shaders have been released in the glthread ++ * through the foreach func */ ++ g_hash_table_unref (deinterlace_filter->shaderstable); ++ deinterlace_filter->shaderstable = NULL; ++ } + + return GST_BASE_TRANSFORM_CLASS (parent_class)->stop (trans); + } +@@ -201,9 +329,12 @@ static void + gst_gl_deinterlace_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec) + { +- //GstGLDeinterlace *filter = GST_GL_DEINTERLACE (object); ++ GstGLDeinterlace *filter = GST_GL_DEINTERLACE (object); + + switch (prop_id) { ++ case PROP_METHOD: ++ gst_gl_deinterlace_set_method (filter, g_value_get_enum (value)); ++ break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; +@@ -214,9 +345,12 @@ static void + gst_gl_deinterlace_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec) + { +- //GstGLDeinterlace *filter = GST_GL_DEINTERLACE (object); ++ GstGLDeinterlace *filter = GST_GL_DEINTERLACE (object); + + switch (prop_id) { ++ case PROP_METHOD: ++ g_value_set_enum (value, filter->current_method); ++ break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; +@@ -224,13 +358,9 @@ gst_gl_deinterlace_get_property (GObject * object, guint prop_id, + } + + static gboolean +-gst_gl_deinterlace_init_shader (GstGLFilter * filter) ++gst_gl_deinterlace_init_fbo (GstGLFilter * filter) + { +- GstGLDeinterlace *deinterlace_filter = GST_GL_DEINTERLACE (filter); +- +- //blocking call, wait the opengl thread has compiled the shader +- return gst_gl_context_gen_shader (GST_GL_BASE_FILTER (filter)->context, 0, +- greedyh_fragment_source, &deinterlace_filter->shader); ++ return TRUE; + } + + static gboolean +@@ -241,7 +371,7 @@ gst_gl_deinterlace_filter_texture (GstGLFilter * filter, guint in_tex, + + //blocking call, use a FBO + gst_gl_filter_render_to_target (filter, TRUE, in_tex, out_tex, +- gst_gl_deinterlace_callback, deinterlace_filter); ++ deinterlace_filter->deinterlacefunc, deinterlace_filter); + + return TRUE; + } +@@ -259,36 +389,104 @@ gst_gl_deinterlace_filter (GstGLFilter * filter, GstBuffer * inbuf, + return TRUE; + } + +-//opengl scene, params: input texture (not the output filter->texture) ++static GstGLShader * ++gst_gl_deinterlace_get_fragment_shader (GstGLFilter * filter, ++ const gchar * shader_name, const gchar * shader_source) ++{ ++ GstGLShader *shader = NULL; ++ GstGLDeinterlace *deinterlace_filter = GST_GL_DEINTERLACE (filter); ++ GstGLContext *context = GST_GL_BASE_FILTER (filter)->context; ++ ++ shader = g_hash_table_lookup (deinterlace_filter->shaderstable, shader_name); ++ ++ if (!shader) { ++ GError *error = NULL; ++ ++ if (!(shader = 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 | GST_GLSL_PROFILE_COMPATIBILITY, ++ shader_source), NULL))) { ++ GST_ELEMENT_ERROR (deinterlace_filter, RESOURCE, NOT_FOUND, ++ ("Failed to initialize %s shader", shader_name), (NULL)); ++ } ++ ++ filter->draw_attr_position_loc = ++ gst_gl_shader_get_attribute_location (shader, "a_position"); ++ filter->draw_attr_texture_loc = ++ gst_gl_shader_get_attribute_location (shader, "a_texcoord"); ++ } ++ ++ g_hash_table_insert (deinterlace_filter->shaderstable, (gchar *) shader_name, ++ shader); ++ ++ return shader; ++} ++ + static void +-gst_gl_deinterlace_callback (gint width, gint height, guint texture, ++gst_gl_deinterlace_vfir_callback (gint width, gint height, guint texture, + gpointer stuff) + { +- GstGLDeinterlace *deinterlace_filter = GST_GL_DEINTERLACE (stuff); ++ GstGLShader *shader; + GstGLFilter *filter = GST_GL_FILTER (stuff); +- GstGLFuncs *gl = GST_GL_BASE_FILTER (filter)->context->gl_vtable; ++ GstGLDeinterlace *deinterlace_filter = GST_GL_DEINTERLACE (filter); ++ GstGLContext *context = GST_GL_BASE_FILTER (filter)->context; ++ GstGLFuncs *gl = context->gl_vtable; ++ ++ shader = gst_gl_deinterlace_get_fragment_shader (deinterlace_filter, "vfir", ++ vfir_fragment_source); ++ ++ if (!shader) ++ return; ++ ++#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); ++ gl->BindTexture (GL_TEXTURE_2D, texture); ++ ++ gst_gl_shader_set_uniform_1i (shader, "tex", 0); ++ gst_gl_shader_set_uniform_1f (shader, "width", ++ GST_VIDEO_INFO_WIDTH (&filter->out_info)); ++ gst_gl_shader_set_uniform_1f (shader, "height", ++ GST_VIDEO_INFO_HEIGHT (&filter->out_info)); ++ ++ gst_gl_filter_draw_texture (filter, texture, width, height); ++} ++ ++static void ++gst_gl_deinterlace_greedyh_callback (gint width, gint height, guint texture, ++ gpointer stuff) ++{ ++ GstGLShader *shader; ++ GstGLFilter *filter = GST_GL_FILTER (stuff); ++ GstGLDeinterlace *deinterlace_filter = GST_GL_DEINTERLACE (filter); ++ GstGLContext *context = GST_GL_BASE_FILTER (filter)->context; ++ GstGLFuncs *gl = context->gl_vtable; + guint temp; + +- GLfloat verts[] = { -1.0, -1.0, +- 1.0, -1.0, +- 1.0, 1.0, +- -1.0, 1.0 +- }; +- GLfloat texcoords0[] = { 0.0f, 0.0f, +- 1.0f, 0.0f, +- 1.0f, 1.0f, +- 0.0f, 1.0f +- }; +- GLfloat texcoords1[] = { 0.0f, 0.0f, +- 1.0f, 0.0f, +- 1.0f, 1.0f, +- 0.0f, 1.0f +- }; ++ shader = ++ gst_gl_deinterlace_get_fragment_shader (deinterlace_filter, "greedhy", ++ greedyh_fragment_source); + +- gl->MatrixMode (GL_PROJECTION); +- gl->LoadIdentity (); ++ if (!shader) ++ return; + +- gst_gl_shader_use (deinterlace_filter->shader); ++#if GST_GL_HAVE_OPENGL ++ if (USING_OPENGL (context)) { ++ gl->MatrixMode (GL_PROJECTION); ++ gl->LoadIdentity (); ++ } ++#endif ++ ++ gst_gl_shader_use (shader); + + if (G_UNLIKELY (deinterlace_filter->prev_tex == 0)) { + gst_gl_context_gen_texture (GST_GL_BASE_FILTER (filter)->context, +@@ -298,44 +496,24 @@ gst_gl_deinterlace_callback (gint width, gint height, guint texture, + GST_VIDEO_INFO_HEIGHT (&filter->out_info)); + } else { + gl->ActiveTexture (GL_TEXTURE1); +- gst_gl_shader_set_uniform_1i (deinterlace_filter->shader, "tex_prev", 1); ++ gst_gl_shader_set_uniform_1i (shader, "tex_prev", 1); + gl->BindTexture (GL_TEXTURE_2D, deinterlace_filter->prev_tex); + } + + gl->ActiveTexture (GL_TEXTURE0); +- gst_gl_shader_set_uniform_1i (deinterlace_filter->shader, "tex", 0); ++ gl->BindTexture (GL_TEXTURE_2D, texture); + +- gst_gl_shader_set_uniform_1f (deinterlace_filter->shader, "max_comb", +- 5.0f / 255.0f); +- gst_gl_shader_set_uniform_1f (deinterlace_filter->shader, "motion_threshold", +- 25.0f / 255.0f); +- gst_gl_shader_set_uniform_1f (deinterlace_filter->shader, "motion_sense", +- 30.0f / 255.0f); ++ gst_gl_shader_set_uniform_1i (shader, "tex", 0); ++ gst_gl_shader_set_uniform_1f (shader, "max_comb", 5.0f / 255.0f); ++ gst_gl_shader_set_uniform_1f (shader, "motion_threshold", 25.0f / 255.0f); ++ gst_gl_shader_set_uniform_1f (shader, "motion_sense", 30.0f / 255.0f); + +- gst_gl_shader_set_uniform_1f (deinterlace_filter->shader, "width", ++ gst_gl_shader_set_uniform_1f (shader, "width", + GST_VIDEO_INFO_WIDTH (&filter->out_info)); +- gst_gl_shader_set_uniform_1f (deinterlace_filter->shader, "height", ++ gst_gl_shader_set_uniform_1f (shader, "height", + GST_VIDEO_INFO_HEIGHT (&filter->out_info)); + +- gl->ClientActiveTexture (GL_TEXTURE0); +- +- gl->EnableClientState (GL_TEXTURE_COORD_ARRAY); +- gl->EnableClientState (GL_VERTEX_ARRAY); +- +- gl->VertexPointer (2, GL_FLOAT, 0, &verts); +- gl->TexCoordPointer (2, GL_FLOAT, 0, &texcoords0); +- +- gl->ClientActiveTexture (GL_TEXTURE1); +- gl->EnableClientState (GL_TEXTURE_COORD_ARRAY); +- gl->TexCoordPointer (2, GL_FLOAT, 0, &texcoords1); +- +- gl->DrawArrays (GL_TRIANGLE_FAN, 0, 4); +- +- gl->DisableClientState (GL_VERTEX_ARRAY); +- gl->DisableClientState (GL_TEXTURE_COORD_ARRAY); +- +- gl->ClientActiveTexture (GL_TEXTURE0); +- gl->DisableClientState (GL_TEXTURE_COORD_ARRAY); ++ gst_gl_filter_draw_texture (filter, texture, width, height); + + if (texture == filter->in_tex_id) { + temp = filter->in_tex_id; +diff --git a/ext/gl/gstgldeinterlace.h b/ext/gl/gstgldeinterlace.h +index a81a2e7..58a9c0c 100644 +--- a/ext/gl/gstgldeinterlace.h ++++ b/ext/gl/gstgldeinterlace.h +@@ -38,9 +38,13 @@ typedef struct _GstGLDeinterlaceClass GstGLDeinterlaceClass; + struct _GstGLDeinterlace + { + GstGLFilter filter; +- GstGLShader *shader; ++ ++ GLCB deinterlacefunc; ++ GHashTable *shaderstable; + GstBuffer *prev_buffer; + guint prev_tex; ++ ++ gint current_method; + }; + + struct _GstGLDeinterlaceClass +diff --git a/ext/gl/gstopengl.c b/ext/gl/gstopengl.c +index 50676c4..135862a 100644 +--- a/ext/gl/gstopengl.c ++++ b/ext/gl/gstopengl.c +@@ -62,6 +62,7 @@ + #include "gstglstereosplit.h" + #include "gstglstereomix.h" + #include "gstglviewconvert.h" ++#include "gstgldeinterlace.h" + + #if HAVE_GRAPHENE + #include "gstgltransformation.h" +@@ -77,7 +78,6 @@ + #include "gstgltestsrc.h" + #include "gstglfilterglass.h" + /* #include "gstglfilterreflectedscreen.h" */ +-#include "gstgldeinterlace.h" + #include "gstglmosaic.h" + #if HAVE_PNG + #include "gstgldifferencematte.h" +@@ -226,6 +226,12 @@ plugin_init (GstPlugin * plugin) + GST_RANK_NONE, GST_TYPE_GL_STEREO_MIX)) { + return FALSE; + } ++ ++ if (!gst_element_register (plugin, "gldeinterlace", ++ GST_RANK_NONE, GST_TYPE_GL_DEINTERLACE)) { ++ return FALSE; ++ } ++ + #if HAVE_JPEG + #if HAVE_PNG + if (!gst_element_register (plugin, "gloverlay", +@@ -250,11 +256,6 @@ plugin_init (GstPlugin * plugin) + return FALSE; + } + #endif +- if (!gst_element_register (plugin, "gldeinterlace", +- GST_RANK_NONE, GST_TYPE_GL_DEINTERLACE)) { +- return FALSE; +- } +- + if (!gst_element_register (plugin, "glmosaic", + GST_RANK_NONE, GST_TYPE_GL_MOSAIC)) { + return FALSE; +-- +1.9.1 + diff --git a/import-layers/yocto-poky/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0002-glplugin-glwindow-fix-memory-leak-of-navigation-thre.patch b/import-layers/yocto-poky/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0002-glplugin-glwindow-fix-memory-leak-of-navigation-thre.patch deleted file mode 100755 index 3491a15e6..000000000 --- a/import-layers/yocto-poky/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0002-glplugin-glwindow-fix-memory-leak-of-navigation-thre.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 95cda7fbcf1a81289d9315c801c8e2b3d896f4cb Mon Sep 17 00:00:00 2001 -From: Haihua Hu <b55597@freescale.com> -Date: Mon, 30 Nov 2015 09:36:09 +0800 -Subject: [PATCH 2/5] [glplugin] glwindow: fix memory leak of navigation - thread - -When exit navigation thread, call g_thread_join() to release -the resource hold by it. - -Upstream-Status: Backport [1.7.1] - -bugzilla URL: https://bugzilla.gnome.org/show_bug.cgi?id=758820 - -Signed-off-by: Haihua Hu <b55597@freescale.com> ---- - gst-libs/gst/gl/gstglwindow.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/gst-libs/gst/gl/gstglwindow.c b/gst-libs/gst/gl/gstglwindow.c -index 44b74ca..42ef296 100644 ---- a/gst-libs/gst/gl/gstglwindow.c -+++ b/gst-libs/gst/gl/gstglwindow.c -@@ -343,6 +343,9 @@ gst_gl_window_finalize (GObject * object) - while (window->nav_alive) { - g_cond_wait (&window->nav_destroy_cond, &window->nav_lock); - } -+ /* release resource hold by navigation thread */ -+ g_thread_join(window->priv->navigation_thread); -+ window->priv->navigation_thread = NULL; - g_mutex_unlock (&window->nav_lock); - } - --- -1.7.9.5 - diff --git a/import-layers/yocto-poky/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0003-glcolorconvert-implement-multiple-render-targets-for.patch b/import-layers/yocto-poky/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0003-glcolorconvert-implement-multiple-render-targets-for.patch new file mode 100755 index 000000000..31d8e052f --- /dev/null +++ b/import-layers/yocto-poky/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0003-glcolorconvert-implement-multiple-render-targets-for.patch @@ -0,0 +1,244 @@ +From 127e517568490fc147211d8b2fb4da01cecbbeb5 Mon Sep 17 00:00:00 2001 +From: Matthew Waters <matthew@centricular.com> +Date: Thu, 31 Mar 2016 19:50:28 +1100 +Subject: [PATCH 5/6] glcolorconvert: implement multiple render targets for + GLES3 + +There are numerous slight differences required between Desktop GL and GLES3 for +multiple render targets. + +1. gl_FragData doesn't exist at all and one is required to use + 'layout (location = ?) out ...' instead. +2. gl_FragColor doesn't exist, same as 1 +3. texture2D() has been deprecated + +Fortunately most of these have been taken care of with GL3 and the shader +mangling already exists so just expand the conditions they are used in. The +gl_FragData issue requires a new mangle pass though. We also use this new +pass on desktop GL for consistency. + +Upstream-Status: Backport [1.9.1] + +--- + gst-libs/gst/gl/gstglcolorconvert.c | 125 ++++++++++++++++++++++++++++-------- + 1 file changed, 99 insertions(+), 26 deletions(-) + +diff --git a/gst-libs/gst/gl/gstglcolorconvert.c b/gst-libs/gst/gl/gstglcolorconvert.c +index 490ec54..f478faa 100644 +--- a/gst-libs/gst/gl/gstglcolorconvert.c ++++ b/gst-libs/gst/gl/gstglcolorconvert.c +@@ -1802,10 +1802,11 @@ _mangle_sampler_type (const gchar * str, GstGLTextureTarget from, + + static gchar * + _mangle_varying_attribute (const gchar * str, guint shader_type, +- GstGLAPI gl_api) ++ GstGLAPI gl_api, guint gl_major, guint gl_minor) + { +- if (gl_api & GST_GL_API_OPENGL3) { +- if (shader_type == GL_VERTEX_SHADER) { ++ if (shader_type == GL_VERTEX_SHADER) { ++ if ((gl_api & GST_GL_API_OPENGL3) || (gl_api & GST_GL_API_GLES2 ++ && gl_major >= 3)) { + gchar *tmp, *tmp2; + GRegex *regex; + +@@ -1821,7 +1822,10 @@ _mangle_varying_attribute (const gchar * str, guint shader_type, + + g_free (tmp); + return tmp2; +- } else if (shader_type == GL_FRAGMENT_SHADER) { ++ } ++ } else if (shader_type == GL_FRAGMENT_SHADER) { ++ if ((gl_api & GST_GL_API_OPENGL3) || (gl_api & GST_GL_API_GLES2 ++ && gl_major > 3)) { + gchar *tmp; + GRegex *regex; + +@@ -1837,28 +1841,48 @@ _mangle_varying_attribute (const gchar * str, guint shader_type, + } + + static gchar * +-_mangle_frag_color (const gchar * str) ++_mangle_frag_color_data (const gchar * str) + { + GRegex *regex; +- gchar *ret; ++ gchar *ret, *tmp; + + regex = g_regex_new ("gl_FragColor", 0, 0, NULL); + ret = g_regex_replace_literal (regex, str, -1, 0, "fragColor", 0, NULL); + g_regex_unref (regex); + ++ tmp = ret; ++ /* search and replace 'gl_FragData[NUM]' into fragColor_NUM */ ++ regex = g_regex_new ("gl_FragData\\[(\\d+)\\]", 0, 0, NULL); ++ ret = g_regex_replace (regex, tmp, -1, 0, "fragColor_\\1", 0, NULL); ++ g_regex_unref (regex); ++ g_free (tmp); ++ + return ret; + } + + static void +-_mangle_version_profile_from_gl_api (GstGLAPI gl_api, GstGLSLVersion * version, +- GstGLSLProfile * profile) ++_mangle_version_profile_from_gl_api (GstGLAPI gl_api, gint gl_major, ++ gint gl_minor, GstGLSLVersion * version, GstGLSLProfile * profile) + { ++ *version = GST_GLSL_VERSION_NONE; ++ *profile = GST_GLSL_PROFILE_NONE; ++ + if (gl_api & GST_GL_API_OPENGL3) { +- *version = GST_GLSL_VERSION_150; +- *profile = GST_GLSL_PROFILE_NONE; ++ if (gl_major > 3 || gl_minor >= 3) { ++ *version = GST_GLSL_VERSION_330; ++ *profile = GST_GLSL_PROFILE_CORE; ++ } else { ++ *version = GST_GLSL_VERSION_150; ++ *profile = GST_GLSL_PROFILE_NONE; ++ } + } else if (gl_api & GST_GL_API_GLES2) { +- *version = GST_GLSL_VERSION_100; +- *profile = GST_GLSL_PROFILE_ES; ++ if (gl_major >= 3) { ++ *version = GST_GLSL_VERSION_300; ++ *profile = GST_GLSL_PROFILE_ES; ++ } else if (gl_major >= 2) { ++ *version = GST_GLSL_VERSION_100; ++ *profile = GST_GLSL_PROFILE_ES; ++ } + } else if (gl_api & GST_GL_API_OPENGL) { + *version = GST_GLSL_VERSION_110; + *profile = GST_GLSL_PROFILE_COMPATIBILITY; +@@ -1867,22 +1891,28 @@ _mangle_version_profile_from_gl_api (GstGLAPI gl_api, GstGLSLVersion * version, + + static gchar * + _mangle_shader (const gchar * str, guint shader_type, GstGLTextureTarget from, +- GstGLTextureTarget to, GstGLAPI gl_api, GstGLSLVersion * version, +- GstGLSLProfile * profile) ++ GstGLTextureTarget to, GstGLAPI gl_api, gint gl_major, gint gl_minor, ++ GstGLSLVersion * version, GstGLSLProfile * profile) + { + gchar *tmp, *tmp2; + ++ _mangle_version_profile_from_gl_api (gl_api, gl_major, gl_minor, version, ++ profile); + tmp = _mangle_texture_access (str, from, to, gl_api); + tmp2 = _mangle_sampler_type (tmp, from, to); + g_free (tmp); +- tmp = _mangle_varying_attribute (tmp2, shader_type, gl_api); ++ tmp = ++ _mangle_varying_attribute (tmp2, shader_type, gl_api, gl_major, gl_minor); + g_free (tmp2); +- if (shader_type == GL_FRAGMENT_SHADER && gl_api & GST_GL_API_OPENGL3) { +- tmp2 = _mangle_frag_color (tmp); +- g_free (tmp); +- tmp = tmp2; ++ if (shader_type == GL_FRAGMENT_SHADER) { ++ if ((*profile == GST_GLSL_PROFILE_ES && *version >= GST_GLSL_VERSION_300) ++ || (*profile == GST_GLSL_PROFILE_CORE ++ && *version >= GST_GLSL_VERSION_150)) { ++ tmp2 = _mangle_frag_color_data (tmp); ++ g_free (tmp); ++ tmp = tmp2; ++ } + } +- _mangle_version_profile_from_gl_api (gl_api, version, profile); + return tmp; + } + +@@ -1899,15 +1929,18 @@ _create_shader (GstGLColorConvert * convert) + const gchar *strings[2]; + GError *error = NULL; + GstGLAPI gl_api; ++ gint gl_major, gl_minor; + int i; + + gl_api = gst_gl_context_get_gl_api (convert->context); ++ gst_gl_context_get_gl_version (convert->context, &gl_major, &gl_minor); + + ret = gst_gl_shader_new (convert->context); + + tmp = + _mangle_shader (text_vertex_shader, GL_VERTEX_SHADER, info->templ->target, +- convert->priv->from_texture_target, gl_api, &version, &profile); ++ convert->priv->from_texture_target, gl_api, gl_major, gl_minor, &version, ++ &profile); + + tmp1 = gst_glsl_version_profile_to_string (version, profile); + version_str = g_strdup_printf ("#version %s\n", tmp1); +@@ -1945,9 +1978,37 @@ _create_shader (GstGLColorConvert * convert) + if (info->templ->uniforms) + g_string_append (str, info->templ->uniforms); + +- if (gl_api & GST_GL_API_OPENGL3) { +- g_string_append_c (str, '\n'); +- g_string_append (str, "out vec4 fragColor;\n"); ++ g_string_append_c (str, '\n'); ++ ++ /* GL 3.3+ and GL ES 3.x */ ++ if ((profile == GST_GLSL_PROFILE_CORE && version >= GST_GLSL_VERSION_330) ++ || (profile == GST_GLSL_PROFILE_ES && version >= GST_GLSL_VERSION_300)) { ++ if (info->out_n_textures > 1) { ++ gint i; ++ ++ for (i = 0; i < info->out_n_textures; i++) { ++ g_string_append_printf (str, ++ "layout(location = %d) out vec4 fragColor_%d;\n", i, i); ++ } ++ } else { ++ g_string_append (str, "layout (location = 0) out vec4 fragColor;\n"); ++ } ++ } else if (profile == GST_GLSL_PROFILE_CORE ++ && version >= GST_GLSL_VERSION_150) { ++ /* no layout specifiers, use glBindFragDataLocation instead */ ++ if (info->out_n_textures > 1) { ++ gint i; ++ ++ for (i = 0; i < info->out_n_textures; i++) { ++ gchar *var_name = g_strdup_printf ("fragColor_%d", i); ++ g_string_append_printf (str, "out vec4 %s;\n", var_name); ++ gst_gl_shader_bind_frag_data_location (ret, i, var_name); ++ g_free (var_name); ++ } ++ } else { ++ g_string_append (str, "out vec4 fragColor;\n"); ++ gst_gl_shader_bind_frag_data_location (ret, 0, "fragColor"); ++ } + } + + for (i = 0; i < MAX_FUNCTIONS; i++) { +@@ -1959,7 +2020,19 @@ _create_shader (GstGLColorConvert * convert) + g_string_append_c (str, '\n'); + } + +- g_string_append (str, "\nvarying vec2 v_texcoord;\nvoid main (void) {\n"); ++ { ++ const gchar *varying = NULL; ++ ++ if ((profile == GST_GLSL_PROFILE_ES && version >= GST_GLSL_VERSION_300) ++ || (profile == GST_GLSL_PROFILE_CORE ++ && version >= GST_GLSL_VERSION_150)) { ++ varying = "in"; ++ } else { ++ varying = "varying"; ++ } ++ g_string_append_printf (str, "\n%s vec2 v_texcoord;\nvoid main (void) {\n", ++ varying); ++ } + if (info->frag_body) { + g_string_append (str, "vec2 texcoord;\n"); + if (convert->priv->from_texture_target == GST_GL_TEXTURE_TARGET_RECTANGLE +@@ -1975,7 +2048,7 @@ _create_shader (GstGLColorConvert * convert) + tmp = g_string_free (str, FALSE); + info->frag_prog = _mangle_shader (tmp, GL_FRAGMENT_SHADER, + info->templ->target, convert->priv->from_texture_target, gl_api, +- &version, &profile); ++ gl_major, gl_minor, &version, &profile); + g_free (tmp); + + strings[1] = info->frag_prog; +-- +1.9.1 + diff --git a/import-layers/yocto-poky/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0004-glcolorconvert-don-t-use-the-predefined-variable-nam.patch b/import-layers/yocto-poky/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0004-glcolorconvert-don-t-use-the-predefined-variable-nam.patch new file mode 100755 index 000000000..b75f402d8 --- /dev/null +++ b/import-layers/yocto-poky/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0004-glcolorconvert-don-t-use-the-predefined-variable-nam.patch @@ -0,0 +1,32 @@ +From b069672ace2b762f400ca6d318571cbedf5141f2 Mon Sep 17 00:00:00 2001 +From: Matthew Waters <matthew@centricular.com> +Date: Thu, 31 Mar 2016 20:00:37 +1100 +Subject: [PATCH 1/3] glcolorconvert: don't use the predefined variable name + sample + +Using 'sample' as a variable name is an error in GLES3 + +Upstream-Status: Backport [1.9.1] +--- + gst-libs/gst/gl/gstglcolorconvert.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/gst-libs/gst/gl/gstglcolorconvert.c b/gst-libs/gst/gl/gstglcolorconvert.c +index f478faa..c23624f 100644 +--- a/gst-libs/gst/gl/gstglcolorconvert.c ++++ b/gst-libs/gst/gl/gstglcolorconvert.c +@@ -261,9 +261,9 @@ static const struct shader_templ templ_RGB_to_PLANAR_YUV = + " for (int j = 0; j < int(chroma_sampling.y); j++) {\n" + " int n = (i+1)*(j+1);\n" + " delta.y = float(j);\n" +- " vec4 sample = texture2D(tex, (chroma_pos + delta) / unnormalization).%c%c%c%c;\n" ++ " vec4 s = texture2D(tex, (chroma_pos + delta) / unnormalization).%c%c%c%c;\n" + /* rolling average */ +- " uv_texel = (float(n-1) * uv_texel + sample) / float(n);\n" ++ " uv_texel = (float(n-1) * uv_texel + s) / float(n);\n" + " }\n" + " }\n" + "}\n" +-- +1.9.1 + diff --git a/import-layers/yocto-poky/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0005-glshader-add-glBindFragDataLocation.patch b/import-layers/yocto-poky/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0005-glshader-add-glBindFragDataLocation.patch new file mode 100755 index 000000000..57e9d1a46 --- /dev/null +++ b/import-layers/yocto-poky/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0005-glshader-add-glBindFragDataLocation.patch @@ -0,0 +1,77 @@ +From 38221080181229d520522a20bcb1663ca19f7aff Mon Sep 17 00:00:00 2001 +From: Matthew Waters <matthew@centricular.com> +Date: Thu, 31 Mar 2016 19:25:32 +1100 +Subject: [PATCH 2/3] glshader: add glBindFragDataLocation + +There are some cases where it's needed for binding in/out variables in shaders. +e.g. glsl 150 (gl 3.2) doesn't support the 'layout (location = ?)' specifiers in +the shader source so we have to bind them ourselves. + +Upstream-Status: Backport [1.9.1] +--- + gst-libs/gst/gl/glprototypes/shaders.h | 10 ++++++++++ + gst-libs/gst/gl/gstglshader.c | 20 ++++++++++++++++++++ + gst-libs/gst/gl/gstglshader.h | 1 + + 3 files changed, 31 insertions(+) + +diff --git a/gst-libs/gst/gl/glprototypes/shaders.h b/gst-libs/gst/gl/glprototypes/shaders.h +index 817e479..6d828db 100644 +--- a/gst-libs/gst/gl/glprototypes/shaders.h ++++ b/gst-libs/gst/gl/glprototypes/shaders.h +@@ -362,3 +362,13 @@ GST_GL_EXT_FUNCTION (void, UniformMatrix3x4fv, + GST_GL_EXT_FUNCTION (void, UniformMatrix4x3fv, + (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)) + GST_GL_EXT_END () ++ ++GST_GL_EXT_BEGIN (bind_frag_data, ++ GST_GL_API_OPENGL | GST_GL_API_OPENGL3, ++ 3, 0, ++ 255, 255, ++ "\0", ++ "\0") ++GST_GL_EXT_FUNCTION (void, BindFragDataLocation, ++ (GLuint program, GLuint index, const GLchar * name)) ++GST_GL_EXT_END () +diff --git a/gst-libs/gst/gl/gstglshader.c b/gst-libs/gst/gl/gstglshader.c +index 9d96784..9f09236 100644 +--- a/gst-libs/gst/gl/gstglshader.c ++++ b/gst-libs/gst/gl/gstglshader.c +@@ -1306,3 +1306,23 @@ gst_gl_shader_bind_attribute_location (GstGLShader * shader, GLuint index, + + gl->BindAttribLocation (priv->program_handle, index, name); + } ++ ++void ++gst_gl_shader_bind_frag_data_location (GstGLShader * shader, ++ guint index, const gchar * name) ++{ ++ GstGLShaderPrivate *priv; ++ GstGLFuncs *gl; ++ ++ g_return_if_fail (shader != NULL); ++ if (!_ensure_program (shader)) ++ g_return_if_fail (shader->priv->program_handle); ++ priv = shader->priv; ++ gl = shader->context->gl_vtable; ++ g_return_if_fail (gl->BindFragDataLocation); ++ ++ GST_TRACE_OBJECT (shader, "binding program %i frag data \'%s\' location %i", ++ (int) priv->program_handle, name, index); ++ ++ gl->BindFragDataLocation (priv->program_handle, index, name); ++} +diff --git a/gst-libs/gst/gl/gstglshader.h b/gst-libs/gst/gl/gstglshader.h +index 21410e2..2200b89 100644 +--- a/gst-libs/gst/gl/gstglshader.h ++++ b/gst-libs/gst/gl/gstglshader.h +@@ -104,6 +104,7 @@ void gst_gl_shader_set_uniform_matrix_4x3fv (GstGLShader *shader, const gchar *n + + gint gst_gl_shader_get_attribute_location (GstGLShader *shader, const gchar *name); + void gst_gl_shader_bind_attribute_location (GstGLShader * shader, guint index, const gchar * name); ++void gst_gl_shader_bind_frag_data_location (GstGLShader * shader, guint index, const gchar * name); + + G_END_DECLS + +-- +1.9.1 + diff --git a/import-layers/yocto-poky/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0006-glcolorconvert-GLES3-deprecates-texture2D-and-it-doe.patch b/import-layers/yocto-poky/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0006-glcolorconvert-GLES3-deprecates-texture2D-and-it-doe.patch new file mode 100755 index 000000000..79ef4c81a --- /dev/null +++ b/import-layers/yocto-poky/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0006-glcolorconvert-GLES3-deprecates-texture2D-and-it-doe.patch @@ -0,0 +1,51 @@ +From 764fd69f8482eca9f925cefe72ebae090ae59d43 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= <sebastian@centricular.com> +Date: Tue, 19 Apr 2016 19:27:33 +0300 +Subject: [PATCH 3/3] glcolorconvert: GLES3 deprecates texture2D() and it does + not work at all in newer versions than 3.3 + +Use the newer texture() function instead. This fixes glimagesink and other +things on various Android devices. + +Upstream-Status: Backport [1.9.1] + +https://bugzilla.gnome.org/show_bug.cgi?id=765266 +--- + gst-libs/gst/gl/gstglcolorconvert.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/gst-libs/gst/gl/gstglcolorconvert.c b/gst-libs/gst/gl/gstglcolorconvert.c +index c23624f..f472d5d 100644 +--- a/gst-libs/gst/gl/gstglcolorconvert.c ++++ b/gst-libs/gst/gl/gstglcolorconvert.c +@@ -1716,7 +1716,7 @@ _unbind_buffer (GstGLColorConvert * convert) + + static gchar * + _mangle_texture_access (const gchar * str, GstGLTextureTarget from, +- GstGLTextureTarget to, GstGLAPI gl_api) ++ GstGLTextureTarget to, GstGLAPI gl_api, guint gl_major, guint gl_minor) + { + const gchar *from_str = NULL, *to_str = NULL; + gchar *ret, *tmp; +@@ -1730,7 +1730,8 @@ _mangle_texture_access (const gchar * str, GstGLTextureTarget from, + if (from == GST_GL_TEXTURE_TARGET_EXTERNAL_OES) + from_str = "texture2D"; + +- if (gl_api & GST_GL_API_OPENGL3) { ++ if ((gl_api & GST_GL_API_OPENGL3) || (gl_api & GST_GL_API_GLES2 ++ && gl_major >= 3)) { + to_str = "texture"; + } else { + if (to == GST_GL_TEXTURE_TARGET_2D) +@@ -1898,7 +1899,7 @@ _mangle_shader (const gchar * str, guint shader_type, GstGLTextureTarget from, + + _mangle_version_profile_from_gl_api (gl_api, gl_major, gl_minor, version, + profile); +- tmp = _mangle_texture_access (str, from, to, gl_api); ++ tmp = _mangle_texture_access (str, from, to, gl_api, gl_major, gl_minor); + tmp2 = _mangle_sampler_type (tmp, from, to); + g_free (tmp); + tmp = +-- +1.9.1 + diff --git a/import-layers/yocto-poky/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0008-gl-implement-GstGLMemoryEGL.patch b/import-layers/yocto-poky/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0008-gl-implement-GstGLMemoryEGL.patch new file mode 100644 index 000000000..a67381cfe --- /dev/null +++ b/import-layers/yocto-poky/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0008-gl-implement-GstGLMemoryEGL.patch @@ -0,0 +1,495 @@ +From 806bbe75b0b6947f589bce3960c28fee51b5c6c2 Mon Sep 17 00:00:00 2001 +From: Gwang Yoon Hwang <yoon@igalia.com> +Date: Thu, 21 Jan 2016 22:18:17 +0900 +Subject: [PATCH] gl: implement GstGLMemoryEGL + +Because current GstEGLImageMemory does not inherit GstGLMemory, GLUpload +allocates additional GLMemory and upload the decoded contents from the decoder +which uses EGLImage (e.g. gst-omx in RPi). + +This work adds GstGLMemoryEGL to avoid this overhead. Decoders allocate +GstGLMemoryEGL and decode its contents to the EGLImage of GstGLMemoryEGL. And +GLUpload uses this memory without allocation of additional textures and blit +operations. + +https://bugzilla.gnome.org/show_bug.cgi?id=760916 +--- +Upstream-Status: Backport +Signed-off-by: Khem Raj <raj.khem@gmail.com> + + gst-libs/gst/gl/egl/Makefile.am | 2 + + gst-libs/gst/gl/egl/gstgldisplay_egl.c | 2 + + gst-libs/gst/gl/egl/gstglmemoryegl.c | 241 +++++++++++++++++++++++++++++++++ + gst-libs/gst/gl/egl/gstglmemoryegl.h | 108 +++++++++++++++ + gst-libs/gst/gl/gstgl_fwd.h | 4 + + gst-libs/gst/gl/gstgldisplay.c | 2 + + gst-libs/gst/gl/gstglupload.c | 8 ++ + 7 files changed, 367 insertions(+) + create mode 100644 gst-libs/gst/gl/egl/gstglmemoryegl.c + create mode 100644 gst-libs/gst/gl/egl/gstglmemoryegl.h + +diff --git a/gst-libs/gst/gl/egl/Makefile.am b/gst-libs/gst/gl/egl/Makefile.am +index b808178..878f16c 100644 +--- a/gst-libs/gst/gl/egl/Makefile.am ++++ b/gst-libs/gst/gl/egl/Makefile.am +@@ -5,6 +5,7 @@ noinst_LTLIBRARIES = libgstgl-egl.la + libgstgl_egl_la_SOURCES = \ + gstgldisplay_egl.c \ + gstglcontext_egl.c \ ++ gstglmemoryegl.c \ + gsteglimagememory.c + + noinst_HEADERS = +@@ -13,6 +14,7 @@ libgstgl_eglincludedir = $(includedir)/gstreamer-@GST_API_VERSION@/gst/gl/egl + libgstgl_eglinclude_HEADERS = \ + gstgldisplay_egl.h \ + gstglcontext_egl.h \ ++ gstglmemoryegl.h \ + gsteglimagememory.h \ + gstegl.h + +diff --git a/gst-libs/gst/gl/egl/gstgldisplay_egl.c b/gst-libs/gst/gl/egl/gstgldisplay_egl.c +index 9acf4f0..20816c2 100644 +--- a/gst-libs/gst/gl/egl/gstgldisplay_egl.c ++++ b/gst-libs/gst/gl/egl/gstgldisplay_egl.c +@@ -24,6 +24,7 @@ + + #include <gst/gl/egl/gstgldisplay_egl.h> + #include <gst/gl/egl/gsteglimagememory.h> ++#include <gst/gl/egl/gstglmemoryegl.h> + + GST_DEBUG_CATEGORY_STATIC (gst_gl_display_debug); + #define GST_CAT_DEFAULT gst_gl_display_debug +@@ -51,6 +52,7 @@ gst_gl_display_egl_init (GstGLDisplayEGL * display_egl) + display_egl->foreign_display = FALSE; + + gst_egl_image_memory_init (); ++ gst_gl_memory_egl_init_once (); + } + + static void +diff --git a/gst-libs/gst/gl/egl/gstglmemoryegl.c b/gst-libs/gst/gl/egl/gstglmemoryegl.c +new file mode 100644 +index 0000000..03cf432 +--- /dev/null ++++ b/gst-libs/gst/gl/egl/gstglmemoryegl.c +@@ -0,0 +1,241 @@ ++/* ++ * GStreamer ++ * Copyright (C) 2012 Collabora Ltd. ++ * @author: Sebastian Dröge <sebastian.droege@collabora.co.uk> ++ * Copyright (C) 2014 Julien Isorce <julien.isorce@gmail.com> ++ * Copyright (C) 2015 Igalia ++ * Author: Gwang Yoon Hwang <yoon@igalia.com> ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Library General Public ++ * License as published by the Free Software Foundation; either ++ * version 2 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Library General Public License for more details. ++ * ++ * You should have received a copy of the GNU Library General Public ++ * License along with this library; if not, write to the ++ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, ++ * Boston, MA 02110-1301, USA. ++ */ ++ ++#ifdef HAVE_CONFIG_H ++#include "config.h" ++#endif ++ ++#include <string.h> ++ ++#include <gst/gl/egl/gstglmemoryegl.h> ++ ++static GstAllocator *_gl_memory_egl_allocator; ++ ++GST_DEBUG_CATEGORY_STATIC (GST_CAT_GL_MEMORY); ++#define GST_CAT_DEFAULT GST_CAT_GL_MEMORY ++ ++#define parent_class gst_gl_memory_egl_allocator_parent_class ++G_DEFINE_TYPE (GstGLMemoryEGLAllocator, gst_gl_memory_egl_allocator, ++ GST_TYPE_GL_MEMORY_ALLOCATOR); ++ ++gboolean ++gst_is_gl_memory_egl (GstMemory * mem) ++{ ++ return mem != NULL && mem->allocator != NULL ++ && g_type_is_a (G_OBJECT_TYPE (mem->allocator), ++ GST_TYPE_GL_MEMORY_EGL_ALLOCATOR); ++} ++ ++static GstGLMemoryEGL * ++_gl_mem_get_parent (GstGLMemoryEGL * gl_mem) ++{ ++ GstGLMemoryEGL *parent = (GstGLMemoryEGL *)gl_mem->mem.mem.mem.parent; ++ return parent ? parent : gl_mem; ++} ++ ++EGLImageKHR ++gst_gl_memory_egl_get_image (GstGLMemoryEGL * mem) ++{ ++ g_return_val_if_fail (gst_is_gl_memory_egl (GST_MEMORY_CAST (mem)), ++ EGL_NO_IMAGE_KHR); ++ return _gl_mem_get_parent(mem)->image; ++} ++ ++EGLDisplay ++gst_gl_memory_egl_get_display (GstGLMemoryEGL * mem) ++{ ++ g_return_val_if_fail (gst_is_gl_memory_egl (GST_MEMORY_CAST (mem)), NULL); ++ return GST_GL_CONTEXT_EGL(_gl_mem_get_parent(mem))->egl_display; ++} ++ ++GstVideoGLTextureOrientation ++gst_gl_memory_egl_get_orientation (GstGLMemoryEGL * mem) ++{ ++ g_return_val_if_fail (gst_is_gl_memory_egl (GST_MEMORY_CAST (mem)), ++ GST_VIDEO_GL_TEXTURE_ORIENTATION_X_NORMAL_Y_NORMAL); ++ ++ return _gl_mem_get_parent(mem)->orientation; ++} ++ ++void ++gst_gl_memory_egl_set_orientation (GstGLMemoryEGL * mem, ++ GstVideoGLTextureOrientation orientation) ++{ ++ g_return_if_fail (gst_is_gl_memory_egl (GST_MEMORY_CAST (mem))); ++ ++ _gl_mem_get_parent(mem)->orientation = orientation; ++} ++ ++static GstMemory * ++_gl_mem_alloc (GstAllocator * allocator, gsize size, ++ GstAllocationParams * params) ++{ ++ g_warning ("Use gst_gl_base_memory_allocator_alloc() to allocate from this " ++ "GstGLMemoryEGL allocator"); ++ ++ return NULL; ++} ++ ++static void ++_gl_mem_destroy (GstGLMemoryEGL * mem) ++{ ++ /* Shared memory should not destroy all the data */ ++ if (!mem->mem.mem.mem.parent) { ++ GstGLContextEGL *context = GST_GL_CONTEXT_EGL(mem->mem.mem.context); ++ context->eglDestroyImage (context->egl_display, mem->image); ++ } ++ ++ GST_GL_BASE_MEMORY_ALLOCATOR_CLASS (parent_class)->destroy ((GstGLBaseMemory ++ *) mem); ++} ++ ++static void ++_gl_mem_init (GstGLMemoryEGL * mem, GstAllocator * allocator, ++ GstMemory * parent, GstGLContext * context, GstGLTextureTarget target, ++ GstAllocationParams * params, GstVideoInfo * info, ++ guint plane, GstVideoAlignment * valign, gpointer user_data, ++ GDestroyNotify notify) ++{ ++ gst_gl_memory_init ((GstGLMemory *) mem, allocator, parent, ++ context, target, params, info, plane, valign, user_data, notify); ++} ++ ++static GstGLMemoryEGL * ++_gl_mem_egl_alloc (GstGLBaseMemoryAllocator * allocator, ++ GstGLVideoAllocationParams * params) ++{ ++ guint alloc_flags = params->parent.alloc_flags; ++ GstGLMemoryEGL *mem; ++ ++ g_return_val_if_fail (alloc_flags & GST_GL_ALLOCATION_PARAMS_ALLOC_FLAG_VIDEO, ++ NULL); ++ g_return_val_if_fail ((alloc_flags & ++ GST_GL_ALLOCATION_PARAMS_ALLOC_FLAG_WRAP_GPU_HANDLE) == 0, NULL); ++ g_return_val_if_fail ((alloc_flags & ++ GST_GL_ALLOCATION_PARAMS_ALLOC_FLAG_WRAP_SYSMEM) == 0, NULL); ++ ++ mem = g_new0 (GstGLMemoryEGL, 1); ++ mem->image = EGL_NO_IMAGE_KHR; ++ ++ _gl_mem_init (mem, GST_ALLOCATOR_CAST (allocator), NULL, ++ params->parent.context, params->target, params->parent.alloc_params, ++ params->v_info, params->plane, params->valign, params->parent.user_data, ++ params->parent.notify); ++ ++ return mem; ++} ++ ++static gboolean ++_gl_mem_create (GstGLMemoryEGL * gl_mem, GError ** error) ++{ ++ GstGLContextEGL *context = GST_GL_CONTEXT_EGL (gl_mem->mem.mem.context); ++ GstGLBaseMemoryAllocatorClass *alloc_class; ++ ++ if (!gst_gl_context_check_feature (GST_GL_CONTEXT (context), ++ "EGL_KHR_image_base")) { ++ g_set_error (error, GST_GL_CONTEXT_ERROR, GST_GL_CONTEXT_ERROR_WRONG_API, ++ "EGL_KHR_image_base is not supported"); ++ return FALSE; ++ } ++ ++ alloc_class = GST_GL_BASE_MEMORY_ALLOCATOR_CLASS (parent_class); ++ if (!alloc_class->create ((GstGLBaseMemory *) gl_mem, error)) ++ return FALSE; ++ ++ gl_mem->image = context->eglCreateImage (context->egl_display, ++ context->egl_context, EGL_GL_TEXTURE_2D_KHR, ++ (EGLClientBuffer) GSIZE_TO_POINTER (gl_mem->mem.tex_id), NULL); ++ ++ GST_TRACE ("Generating EGLImage handle:%p from a texture:%u", ++ gl_mem->image, gl_mem->mem.tex_id); ++ ++ if (eglGetError () != EGL_SUCCESS) { ++ g_set_error (error, GST_GL_CONTEXT_ERROR, GST_GL_CONTEXT_ERROR_FAILED, ++ "Failed to create EGLImage"); ++ return FALSE; ++ } ++ ++ return TRUE; ++} ++ ++static GstMemory * ++_gl_mem_copy (GstGLMemoryEGL * src, gssize offset, gssize size) ++{ ++ GST_CAT_ERROR (GST_CAT_GL_MEMORY, "GstGLMemoryEGL does not support copy"); ++ return NULL; ++} ++ ++static void ++gst_gl_memory_egl_allocator_class_init (GstGLMemoryEGLAllocatorClass * klass) ++{ ++ GstGLBaseMemoryAllocatorClass *gl_base; ++ GstGLMemoryAllocatorClass *gl_tex; ++ GstAllocatorClass *allocator_class; ++ ++ gl_tex = (GstGLMemoryAllocatorClass *) klass; ++ gl_base = (GstGLBaseMemoryAllocatorClass *) klass; ++ allocator_class = (GstAllocatorClass *) klass; ++ ++ gl_base->alloc = (GstGLBaseMemoryAllocatorAllocFunction) _gl_mem_egl_alloc; ++ gl_base->create = (GstGLBaseMemoryAllocatorCreateFunction) _gl_mem_create; ++ gl_base->destroy = (GstGLBaseMemoryAllocatorDestroyFunction) _gl_mem_destroy; ++ gl_tex->copy = (GstGLBaseMemoryAllocatorCopyFunction) _gl_mem_copy; ++ ++ allocator_class->alloc = _gl_mem_alloc; ++} ++ ++static void ++gst_gl_memory_egl_allocator_init (GstGLMemoryEGLAllocator * allocator) ++{ ++ GstAllocator *alloc = GST_ALLOCATOR_CAST (allocator); ++ ++ alloc->mem_type = GST_GL_MEMORY_EGL_ALLOCATOR_NAME; ++ ++ GST_OBJECT_FLAG_SET (allocator, GST_ALLOCATOR_FLAG_CUSTOM_ALLOC); ++} ++ ++/** ++ * gst_gl_memory_egl_init_once: ++ * ++ * Initializes the GL Memory allocator. It is safe to call this function ++ * multiple times. This must be called before any other GstGLMemoryEGL operation. ++ */ ++void ++gst_gl_memory_egl_init_once (void) ++{ ++ static volatile gsize _init = 0; ++ ++ if (g_once_init_enter (&_init)) { ++ gst_gl_memory_init_once (); ++ ++ GST_DEBUG_CATEGORY_INIT (GST_CAT_GL_MEMORY, "glmemory", 0, ++ "OpenGL Texture with EGLImage memory"); ++ ++ _gl_memory_egl_allocator = g_object_new (GST_TYPE_GL_MEMORY_EGL_ALLOCATOR, NULL); ++ ++ gst_allocator_register (GST_GL_MEMORY_EGL_ALLOCATOR_NAME, ++ gst_object_ref (_gl_memory_egl_allocator)); ++ g_once_init_leave (&_init, 1); ++ } ++} +diff --git a/gst-libs/gst/gl/egl/gstglmemoryegl.h b/gst-libs/gst/gl/egl/gstglmemoryegl.h +new file mode 100644 +index 0000000..7256d33 +--- /dev/null ++++ b/gst-libs/gst/gl/egl/gstglmemoryegl.h +@@ -0,0 +1,108 @@ ++/* ++ * GStreamer ++ * Copyright (C) 2012 Collabora Ltd. ++ * @author: Sebastian Dröge <sebastian.droege@collabora.co.uk> ++ * Copyright (C) 2014 Julien Isorce <julien.isorce@gmail.com> ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Library General Public ++ * License as published by the Free Software Foundation; either ++ * version 2 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Library General Public License for more details. ++ * ++ * You should have received a copy of the GNU Library General Public ++ * License along with this library; if not, write to the ++ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, ++ * Boston, MA 02110-1301, USA. ++ */ ++ ++#ifndef _GST_GL_MEMORY_EGL_H_ ++#define _GST_GL_MEMORY_EGL_H_ ++ ++#include <gst/gst.h> ++#include <gst/gstallocator.h> ++#include <gst/gstmemory.h> ++#include <gst/video/video.h> ++ ++#include <gst/gl/gl.h> ++#include "gstglcontext_egl.h" ++ ++#include <gst/gl/gstglmemory.h> ++ ++G_BEGIN_DECLS ++ ++#define GST_TYPE_GL_MEMORY_EGL_ALLOCATOR (gst_gl_memory_egl_allocator_get_type()) ++GType gst_gl_memory_egl_allocator_get_type(void); ++ ++#define GST_IS_GL_MEMORY_EGL_ALLOCATOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_GL_MEMORY_EGL_ALLOCATOR)) ++#define GST_IS_GL_MEMORY_EGL_ALLOCATOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_GL_MEMORY_EGL_ALLOCATOR)) ++#define GST_GL_MEMORY_EGL_ALLOCATOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_GL_MEMORY_EGL_ALLOCATOR, GstGLMemoryEGLAllocatorClass)) ++#define GST_GL_MEMORY_EGL_ALLOCATOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_GL_MEMORY_EGL_ALLOCATOR, GstGLMemoryEGLAllocator)) ++#define GST_GL_MEMORY_EGL_ALLOCATOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_GL_MEMORY_EGL_ALLOCATOR, GstGLAllocatorClass)) ++#define GST_GL_MEMORY_EGL_ALLOCATOR_CAST(obj) ((GstGLMemoryEGLAllocator *)(obj)) ++ ++typedef void (*GstEGLImageDestroyNotify) (GstGLContextEGL * context, ++ gpointer data); ++ ++typedef struct _GstEGLImageMemory GstEGLImageMemory; ++ ++ ++/** ++ * GstGLMemoryEGL: ++ * ++ * Private instance ++ */ ++struct _GstGLMemoryEGL ++{ ++ GstGLMemory mem; ++ ++ EGLImageKHR image; ++ GstVideoGLTextureOrientation orientation; ++}; ++ ++/** ++ * GST_GL_MEMORY_EGL_ALLOCATOR: ++ * ++ * The name of the GL Memory EGL allocator ++ */ ++#define GST_GL_MEMORY_EGL_ALLOCATOR_NAME "GLMemoryEGL" ++ ++void gst_gl_memory_egl_init_once (void); ++gboolean gst_is_gl_memory_egl (GstMemory * mem); ++ ++EGLImageKHR gst_gl_memory_egl_get_image (GstGLMemoryEGL * mem); ++EGLDisplay gst_gl_memory_egl_get_display (GstGLMemoryEGL * mem); ++ ++GstVideoGLTextureOrientation gst_gl_memory_egl_get_orientation ++ (GstGLMemoryEGL * mem); ++ ++void gst_gl_memory_egl_set_orientation (GstGLMemoryEGL * mem, ++ GstVideoGLTextureOrientation orientation); ++ ++/** ++ * GstGLAllocator ++ * ++ * Opaque #GstGLAllocator struct ++ */ ++struct _GstGLMemoryEGLAllocator ++{ ++ GstGLMemoryAllocator parent; ++}; ++ ++/** ++ * GstGLAllocatorClass: ++ * ++ * The #GstGLAllocatorClass only contains private data ++ */ ++struct _GstGLMemoryEGLAllocatorClass ++{ ++ GstGLMemoryAllocatorClass parent_class; ++}; ++ ++G_END_DECLS ++ ++#endif /* _GST_GL_MEMORY_EGL_H_ */ +diff --git a/gst-libs/gst/gl/gstgl_fwd.h b/gst-libs/gst/gl/gstgl_fwd.h +index fb64ff6..73e17bd 100644 +--- a/gst-libs/gst/gl/gstgl_fwd.h ++++ b/gst-libs/gst/gl/gstgl_fwd.h +@@ -55,6 +55,10 @@ typedef struct _GstGLMemoryPBO GstGLMemoryPBO; + typedef struct _GstGLMemoryPBOAllocator GstGLMemoryPBOAllocator; + typedef struct _GstGLMemoryPBOAllocatorClass GstGLMemoryPBOAllocatorClass; + ++typedef struct _GstGLMemoryEGL GstGLMemoryEGL; ++typedef struct _GstGLMemoryEGLAllocator GstGLMemoryEGLAllocator; ++typedef struct _GstGLMemoryEGLAllocatorClass GstGLMemoryEGLAllocatorClass; ++ + typedef struct _GstGLSLStage GstGLSLStage; + typedef struct _GstGLSLStagePrivate GstGLSLStagePrivate; + typedef struct _GstGLSLStageClass GstGLSLStageClass; +diff --git a/gst-libs/gst/gl/gstgldisplay.c b/gst-libs/gst/gl/gstgldisplay.c +index 60dec6a..34770d0 100644 +--- a/gst-libs/gst/gl/gstgldisplay.c ++++ b/gst-libs/gst/gl/gstgldisplay.c +@@ -68,6 +68,7 @@ + #if GST_GL_HAVE_PLATFORM_EGL + #include <gst/gl/egl/gstgldisplay_egl.h> + #include <gst/gl/egl/gsteglimagememory.h> ++#include <gst/gl/egl/gstglmemoryegl.h> + #endif + + GST_DEBUG_CATEGORY_STATIC (gst_context); +@@ -144,6 +145,7 @@ gst_gl_display_init (GstGLDisplay * display) + + #if GST_GL_HAVE_PLATFORM_EGL + gst_egl_image_memory_init (); ++ gst_gl_memory_egl_init_once (); + #endif + } + +diff --git a/gst-libs/gst/gl/gstglupload.c b/gst-libs/gst/gl/gstglupload.c +index 16ed5ea..73a9029 100644 +--- a/gst-libs/gst/gl/gstglupload.c ++++ b/gst-libs/gst/gl/gstglupload.c +@@ -29,6 +29,7 @@ + + #if GST_GL_HAVE_PLATFORM_EGL + #include "egl/gsteglimagememory.h" ++#include "egl/gstglmemoryegl.h" + #endif + + #if GST_GL_HAVE_DMABUF +@@ -301,6 +302,13 @@ _gl_memory_upload_propose_allocation (gpointer impl, GstQuery * decide_query, + context)); + gst_query_add_allocation_param (query, allocator, ¶ms); + gst_object_unref (allocator); ++ ++#if GST_GL_HAVE_PLATFORM_EGL ++ allocator = ++ GST_ALLOCATOR (gst_allocator_find (GST_GL_MEMORY_EGL_ALLOCATOR_NAME)); ++ gst_query_add_allocation_param (query, allocator, ¶ms); ++ gst_object_unref (allocator); ++#endif + } + + n_pools = gst_query_get_n_allocation_pools (query); +-- +2.5.0 + diff --git a/import-layers/yocto-poky/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0001-glimagesink-Downrank-to-marginal.patch b/import-layers/yocto-poky/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0009-glimagesink-Downrank-to-marginal.patch index 1085e95e8..c81fb0f6a 100644 --- a/import-layers/yocto-poky/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0001-glimagesink-Downrank-to-marginal.patch +++ b/import-layers/yocto-poky/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0009-glimagesink-Downrank-to-marginal.patch @@ -18,7 +18,7 @@ diff --git a/ext/gl/gstopengl.c b/ext/gl/gstopengl.c index a4b2540..0ccaacd 100644 --- a/ext/gl/gstopengl.c +++ b/ext/gl/gstopengl.c -@@ -101,7 +101,7 @@ plugin_init (GstPlugin * plugin) +@@ -118,7 +118,7 @@ plugin_init (GstPlugin * plugin) #endif if (!gst_element_register (plugin, "glimagesink", |