From b87dbd9ade314e6c6575b19f01e7ae60c821af9c Mon Sep 17 00:00:00 2001 From: Yuqing Zhu Date: Tue, 1 Nov 2016 16:09:54 +0800 Subject: gstreamer1.0-plugins-bad: Support fb backend for gl plugins 1. Add fb support in glimagesink 2. Override set_render_rectangle() to support resize Signed-off-by: Yuqing Zhu Signed-off-by: Otavio Salvador --- ...iv-to-glimagesink-to-improve-playback-per.patch | 438 ------------ .../0002-Support-fb-backend-for-gl-plugins.patch | 758 +++++++++++++++++++++ ...iv-to-glimagesink-to-improve-playback-per.patch | 438 ++++++++++++ ...-glplugin-Accelerate-gldownload-with-dire.patch | 729 -------------------- ...-Fix-dependence-issue-between-gst-plugin-.patch | 74 -- ...-glplugin-Accelerate-gldownload-with-dire.patch | 729 ++++++++++++++++++++ ...-Fix-dependence-issue-between-gst-plugin-.patch | 74 ++ ...rconvert-convert-YUV-to-RGB-use-directviv.patch | 170 ----- ...rconvert-convert-YUV-to-RGB-use-directviv.patch | 170 +++++ ...rk-around-for-no-frame-when-imxplayer-use.patch | 63 -- ...colorconvert-fix-MRT-cannot-work-in-GLES3.patch | 168 ----- ...rk-around-for-no-frame-when-imxplayer-use.patch | 63 ++ ...colorconvert-fix-MRT-cannot-work-in-GLES3.patch | 168 +++++ .../gstreamer/gstreamer1.0-plugins-bad_%.bbappend | 13 +- 14 files changed, 2407 insertions(+), 1648 deletions(-) delete mode 100644 recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0002-Add-directviv-to-glimagesink-to-improve-playback-per.patch create mode 100755 recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0002-Support-fb-backend-for-gl-plugins.patch create mode 100644 recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0003-Add-directviv-to-glimagesink-to-improve-playback-per.patch delete mode 100644 recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0003-MMFMWK-6930-glplugin-Accelerate-gldownload-with-dire.patch delete mode 100755 recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0004-Fix-dependence-issue-between-gst-plugin-.patch create mode 100644 recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0004-MMFMWK-6930-glplugin-Accelerate-gldownload-with-dire.patch create mode 100755 recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0005-Fix-dependence-issue-between-gst-plugin-.patch delete mode 100644 recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0005-glcolorconvert-convert-YUV-to-RGB-use-directviv.patch create mode 100644 recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0006-glcolorconvert-convert-YUV-to-RGB-use-directviv.patch delete mode 100644 recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0006-glwindow-work-around-for-no-frame-when-imxplayer-use.patch delete mode 100755 recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0007-glplugin-glcolorconvert-fix-MRT-cannot-work-in-GLES3.patch create mode 100644 recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0007-glwindow-work-around-for-no-frame-when-imxplayer-use.patch create mode 100755 recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0008-glplugin-glcolorconvert-fix-MRT-cannot-work-in-GLES3.patch (limited to 'recipes-multimedia/gstreamer') diff --git a/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0002-Add-directviv-to-glimagesink-to-improve-playback-per.patch b/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0002-Add-directviv-to-glimagesink-to-improve-playback-per.patch deleted file mode 100644 index 43d89060d..000000000 --- a/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0002-Add-directviv-to-glimagesink-to-improve-playback-per.patch +++ /dev/null @@ -1,438 +0,0 @@ -From 94e6bb069cb5207761f2e4234137f2a748f984db Mon Sep 17 00:00:00 2001 -From: Haihua Hu -Date: Tue, 13 Oct 2015 09:33:54 +0800 -Subject: [PATCH 13/18] Add directviv to glimagesink to improve playback - performance -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -1.Add a physical buffer uploader in glupload plugin and using viv direct - texture to bind physical continious buffer with texture to avoid memory - copy from videobuffer to texture to gain good performance. -2.Reduce glimagesink load latency by override glimagesink ALLOCATION query to - avoid memory copy. - -Upstream-Status: Inappropriate [i.MX specific] - -Signed-off-by: Haihua Hu -Signed-off-by: Lyon Wang ---- - ext/gl/gstglimagesink.c | 5 ++ - gst-libs/gst/gl/Makefile.am | 2 + - gst-libs/gst/gl/gstglupload.c | 141 ++++++++++++++++++++++++++++++- - gst-libs/gst/gl/gstglvivdirecttexture.c | 143 ++++++++++++++++++++++++++++++++ - gst-libs/gst/gl/gstglvivdirecttexture.h | 35 ++++++++ - 5 files changed, 323 insertions(+), 3 deletions(-) - create mode 100644 gst-libs/gst/gl/gstglvivdirecttexture.c - create mode 100644 gst-libs/gst/gl/gstglvivdirecttexture.h - -diff --git a/ext/gl/gstglimagesink.c b/ext/gl/gstglimagesink.c -index 3b5e3b5..532ea6a 100644 ---- a/ext/gl/gstglimagesink.c -+++ b/ext/gl/gstglimagesink.c -@@ -911,6 +911,11 @@ gst_glimage_sink_query (GstBaseSink * bsink, GstQuery * query) - res = GST_BASE_SINK_CLASS (parent_class)->query (bsink, query); - break; - } -+ case GST_QUERY_ALLOCATION: -+ { -+ gst_glimage_sink_propose_allocation(bsink, query); -+ break; -+ } - default: - res = GST_BASE_SINK_CLASS (parent_class)->query (bsink, query); - break; -diff --git a/gst-libs/gst/gl/Makefile.am b/gst-libs/gst/gl/Makefile.am -index 4bd6511..c396603 100644 ---- a/gst-libs/gst/gl/Makefile.am -+++ b/gst-libs/gst/gl/Makefile.am -@@ -33,6 +33,7 @@ libgstgl_@GST_API_VERSION@_la_SOURCES = \ - gstglviewconvert.c \ - gstgloverlaycompositor.c \ - gstglquery.c \ -+ gstglvivdirecttexture.c \ - gstglcontrolbindingproxy.c - - libgstgl_@GST_API_VERSION@includedir = $(includedir)/gstreamer-@GST_API_VERSION@/gst/gl -@@ -66,6 +67,7 @@ libgstgl_@GST_API_VERSION@include_HEADERS = \ - gstglcontrolbindingproxy.h \ - gstgl_fwd.h \ - gstgl_enums.h \ -+ gstglvivdirecttexture.h \ - gl.h - - noinst_HEADERS = \ -diff --git a/gst-libs/gst/gl/gstglupload.c b/gst-libs/gst/gl/gstglupload.c -index 32e6150..99cc68a 100644 ---- a/gst-libs/gst/gl/gstglupload.c -+++ b/gst-libs/gst/gl/gstglupload.c -@@ -23,6 +23,7 @@ - #endif - - #include -+#include - - #include "gl.h" - #include "gstglupload.h" -@@ -51,7 +52,7 @@ - #define USING_GLES2(context) (gst_gl_context_check_gl_version (context, GST_GL_API_GLES2, 2, 0)) - #define USING_GLES3(context) (gst_gl_context_check_gl_version (context, GST_GL_API_GLES2, 3, 0)) - --GST_DEBUG_CATEGORY_STATIC (gst_gl_upload_debug); -+GST_DEBUG_CATEGORY (gst_gl_upload_debug); - #define GST_CAT_DEFAULT gst_gl_upload_debug - - #define DEBUG_INIT \ -@@ -1169,6 +1170,140 @@ static const UploadMethod _upload_meta_upload = { - &_upload_meta_upload_free - }; - -+struct PhyBufferUpload -+{ -+ GstGLUpload *upload; -+ GstGLVideoAllocationParams *params; -+}; -+ -+static gpointer -+_physical_buffer_upload_new(GstGLUpload *upload) -+{ -+ struct PhyBufferUpload *phybuffer = g_new0 (struct PhyBufferUpload, 1); -+ -+ phybuffer->upload = upload; -+ -+ return phybuffer; -+} -+ -+static GstCaps * -+_physical_buffer_upload_transform_caps(GstGLContext *context, -+ GstPadDirection direction, GstCaps *caps) -+{ -+ GstCapsFeatures *passthrough = -+ gst_caps_features_from_string -+ (GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION); -+ GstCaps *ret; -+ -+ if (direction == GST_PAD_SINK) { -+ GstCaps *tmp; -+ -+ ret = -+ _set_caps_features_with_passthrough (caps, -+ GST_CAPS_FEATURE_MEMORY_GL_MEMORY, passthrough); -+ -+ gst_caps_set_simple (ret, "format", G_TYPE_STRING, "RGBA", NULL); -+ tmp = _caps_intersect_texture_target (ret, 1 << GST_GL_TEXTURE_TARGET_2D); -+ gst_caps_unref (ret); -+ ret = tmp; -+ } else { -+ ret = gst_caps_from_string (GST_VIDEO_CAPS_MAKE_WITH_FEATURES -+ (GST_CAPS_FEATURE_MEMORY_SYSTEM_MEMORY,GST_GL_DIRECTVIV_FORMAT)); -+ } -+ -+ gst_caps_features_free (passthrough); -+ return ret; -+} -+ -+static gboolean -+_physical_buffer_upload_accept(gpointer impl, GstBuffer *buffer, -+ GstCaps *in_caps, GstCaps *out_caps) -+{ -+ struct PhyBufferUpload *upload = impl; -+ GstCapsFeatures *features; -+ -+ features = gst_caps_get_features (out_caps, 0); -+ if (!gst_caps_features_contains (features, GST_CAPS_FEATURE_MEMORY_GL_MEMORY)) -+ return FALSE; -+ -+ if (upload->params) -+ gst_gl_allocation_params_free ((GstGLAllocationParams *) upload->params); -+ if (!(upload->params = -+ gst_gl_video_allocation_params_new (upload->upload->context, NULL, -+ &upload->upload->priv->in_info, -1, NULL, -+ GST_GL_TEXTURE_TARGET_2D))) -+ return FALSE; -+ -+ return gst_is_physical_buffer(buffer); -+} -+ -+static void -+_physical_buffer_upload_propose_allocation(gpointer impl, GstQuery *decide_query, -+ GstQuery *query) -+{ -+ gst_query_add_allocation_meta (query, GST_VIDEO_META_API_TYPE, 0); -+} -+ -+static GstGLUploadReturn -+_physical_buffer_upload_perform(gpointer impl, GstBuffer *buffer, GstBuffer **outbuf) -+{ -+ struct PhyBufferUpload *phyBuffer = impl; -+ GstGLMemoryAllocator *allocator; -+ GstVideoInfo *info; -+ gint n_mem; -+ -+ info = &phyBuffer->upload->priv->out_info; -+ n_mem = GST_VIDEO_INFO_N_PLANES (info); -+ GST_LOG_OBJECT (phyBuffer->upload, "Attempting viv direct upload"); -+ -+ allocator = -+ GST_GL_MEMORY_ALLOCATOR (gst_allocator_find -+ (GST_GL_MEMORY_PBO_ALLOCATOR_NAME)); -+ -+ /* FIXME: buffer pool */ -+ *outbuf = gst_buffer_new (); -+ gst_gl_memory_setup_buffer (allocator, *outbuf, phyBuffer->params); -+ gst_object_unref (allocator); -+ -+ GstGLMemory *out_gl_mem = -+ (GstGLMemory *) gst_buffer_peek_memory (*outbuf, 0); -+ -+ gst_gl_viv_direct_bind_gstbuffer(phyBuffer->upload->context, out_gl_mem->tex_id, -+ &phyBuffer->upload->priv->in_info, buffer); -+ -+ gst_buffer_add_video_meta_full (*outbuf, 0, -+ GST_VIDEO_INFO_FORMAT (info), GST_VIDEO_INFO_WIDTH (info), -+ GST_VIDEO_INFO_HEIGHT (info), n_mem, info->offset, info->stride); -+ -+ return GST_GL_UPLOAD_DONE; -+} -+ -+static void -+_physical_buffer_upload_free(gpointer impl) -+{ -+ struct PhyBufferUpload *phyBuffer = impl; -+ -+ if (phyBuffer->params) -+ gst_gl_allocation_params_free ((GstGLAllocationParams *) phyBuffer->params); -+ -+ g_free(phyBuffer); -+} -+ -+static GstStaticCaps _physical_buffer_upload_caps = -+GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE (GST_GL_DIRECTVIV_FORMAT)); -+ -+static const UploadMethod _physical_buffer_upload = { -+ "Physical buffer", -+ 0, -+ &_physical_buffer_upload_caps, -+ &_physical_buffer_upload_new, -+ &_physical_buffer_upload_transform_caps, -+ &_physical_buffer_upload_accept, -+ &_physical_buffer_upload_propose_allocation, -+ &_physical_buffer_upload_perform, -+ &_physical_buffer_upload_free -+}; -+ - struct RawUploadFrame - { - gint ref_count; -@@ -1391,7 +1526,7 @@ static const UploadMethod *upload_methods[] = { &_gl_memory_upload, - #if GST_GL_HAVE_DMABUF - &_dma_buf_upload, - #endif -- &_upload_meta_upload, &_raw_data_upload -+ &_upload_meta_upload, &_physical_buffer_upload, &_raw_data_upload - }; - - static GMutex upload_global_lock; -@@ -1514,7 +1649,7 @@ gst_gl_upload_transform_caps (GstGLContext * context, GstPadDirection direction, - } - - if (filter) { -- result = gst_caps_intersect_full (filter, tmp, GST_CAPS_INTERSECT_FIRST); -+ result = gst_caps_intersect_full (tmp, filter, GST_CAPS_INTERSECT_FIRST); - gst_caps_unref (tmp); - } else { - result = tmp; -diff --git a/gst-libs/gst/gl/gstglvivdirecttexture.c b/gst-libs/gst/gl/gstglvivdirecttexture.c -new file mode 100644 -index 0000000..c19b617 ---- /dev/null -+++ b/gst-libs/gst/gl/gstglvivdirecttexture.c -@@ -0,0 +1,143 @@ -+/* -+ * GStreamer -+ * Copyright (c) 2015, Freescale Semiconductor, Inc. -+ * -+ * 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 "gl.h" -+ -+GST_DEBUG_CATEGORY_EXTERN (gst_gl_upload_debug); -+#define GST_CAT_DEFAULT gst_gl_upload_debug -+ -+typedef struct { -+ guint tex_id; -+ guint w; -+ guint h; -+ guint fmt; -+ void *vaddr; -+ guint paddr; -+ gboolean ret; -+} GstVivDirectTexture; -+ -+gboolean -+gst_is_physical_buffer (GstBuffer *buffer) -+{ -+ -+ GstMemory *mem; -+ -+ mem = gst_buffer_peek_memory (buffer, 0); -+ if (!mem->allocator) -+ return FALSE; -+ -+ return g_type_check_instance_is_a (mem->allocator, g_type_from_name("GstAllocatorPhyMem")); -+} -+ -+static void -+_do_viv_direct_tex_bind_mem (GstGLContext * context, GstVivDirectTexture * viv_tex) -+{ -+ GST_DEBUG ("viv direct upload, tex_id %d, fmt: %d, res: (%dx%d)", viv_tex->tex_id, viv_tex->fmt, viv_tex->w, viv_tex->h); -+ GST_DEBUG ("Physical memory buffer, vaddr: %p, paddr: %p", viv_tex->vaddr, viv_tex->paddr); -+ -+ glBindTexture (GL_TEXTURE_2D, viv_tex->tex_id); -+ glTexDirectVIVMap (GL_TEXTURE_2D, viv_tex->w, viv_tex->h, viv_tex->fmt, &viv_tex->vaddr, &viv_tex->paddr); -+ glTexDirectInvalidateVIV (GL_TEXTURE_2D); -+ viv_tex->ret = TRUE; -+ -+ return; -+} -+ -+gboolean -+gst_gl_viv_direct_bind_gstbuffer (GstGLContext * context, guint tex_id, GstVideoInfo * info, GstBuffer * buffer) -+{ -+ typedef struct { -+ guint8 *vaddr; -+ guint8 *paddr; -+ guint8 *caddr; -+ gsize size; -+ gpointer *user_data; -+ } PhyMemBlock; -+ //Note: structure PhyMemBlock is copied from gst1.0-fsl-plugin/libs/allocator/gstallocatorphymem.h -+ -+ typedef struct { -+ GstMemory mem; -+ guint8 *vaddr; -+ guint8 *paddr; -+ PhyMemBlock block; -+ } GstMemoryPhy; -+ //Note: structure GstMemoryPhy is copied from gst1.0-fsl-plugin/libs/allocator/gstallocatorphymem.c -+ -+ GstMemory *mem = gst_buffer_peek_memory (buffer, 0); -+ GstMemoryPhy *memphy = (GstMemoryPhy*) mem; -+ PhyMemBlock *memblk = &memphy->block; -+ -+ GstVideoFormat fmt = GST_VIDEO_INFO_FORMAT (info); -+ gint width, height; -+ GstVideoMeta *vmeta = gst_buffer_get_video_meta (buffer); -+ if (vmeta && (fmt == GST_VIDEO_FORMAT_I420 || fmt == GST_VIDEO_FORMAT_NV12)) { -+ width = vmeta->stride[0]; -+ height = vmeta->offset[1] / width; -+ } -+ else { -+ width = GST_VIDEO_INFO_WIDTH (info); -+ height = GST_VIDEO_INFO_HEIGHT (info); -+ } -+ -+ guint viv_fmt; -+ switch (fmt) { -+ case GST_VIDEO_FORMAT_I420: -+ viv_fmt = GL_VIV_I420; -+ break; -+ case GST_VIDEO_FORMAT_YV12: -+ viv_fmt = GL_VIV_YV12; -+ break; -+ case GST_VIDEO_FORMAT_NV12: -+ viv_fmt = GL_VIV_NV12; -+ break; -+ case GST_VIDEO_FORMAT_NV21: -+ viv_fmt = GL_VIV_NV21; -+ break; -+ case GST_VIDEO_FORMAT_YUY2: -+ viv_fmt = GL_VIV_YUY2; -+ break; -+ case GST_VIDEO_FORMAT_UYVY: -+ viv_fmt = GL_VIV_UYVY; -+ break; -+ case GST_VIDEO_FORMAT_RGBA: -+ viv_fmt = GL_RGBA; -+ break; -+ case GST_VIDEO_FORMAT_BGRA: -+ viv_fmt = GL_BGRA_EXT; -+ break; -+ case GST_VIDEO_FORMAT_RGB16: -+ viv_fmt = GL_RGB565_OES; -+ break; -+ default: -+ GST_ERROR ("Not supported format %d for viv direct texture upload.", fmt); -+ viv_fmt = GL_NONE; -+ return FALSE; -+ } -+ -+ GstVivDirectTexture viv_tex = {tex_id, width, height, viv_fmt, memblk->vaddr, memblk->paddr, FALSE}; -+ gst_gl_context_thread_add (context, (GstGLContextThreadFunc) _do_viv_direct_tex_bind_mem, &viv_tex); -+ -+ return viv_tex.ret; -+} -+ -diff --git a/gst-libs/gst/gl/gstglvivdirecttexture.h b/gst-libs/gst/gl/gstglvivdirecttexture.h -new file mode 100644 -index 0000000..fa88e1a ---- /dev/null -+++ b/gst-libs/gst/gl/gstglvivdirecttexture.h -@@ -0,0 +1,35 @@ -+/* -+ * GStreamer -+ * Copyright (c) 2015, Freescale Semiconductor, Inc. -+ * -+ * 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_VIVDIRECT_H__ -+#define __GST_GL_VIVDIRECT_H__ -+ -+#include -+#include -+ -+#define GST_GL_DIRECTVIV_FORMAT "{RGBA, I420, YV12, NV12, NV21, YUY2, UYVY, BGRA, RGB16}" -+G_BEGIN_DECLS -+ -+gboolean gst_is_physical_buffer (GstBuffer *buffer); -+gboolean gst_gl_viv_direct_bind_gstbuffer (GstGLContext * context, guint tex_id, GstVideoInfo * info, GstBuffer * buffer); -+ -+G_END_DECLS -+ -+#endif /* __GST_GL_VIVDIRECT_H__ */ --- -1.9.1 - diff --git a/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0002-Support-fb-backend-for-gl-plugins.patch b/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0002-Support-fb-backend-for-gl-plugins.patch new file mode 100755 index 000000000..b5b8d644a --- /dev/null +++ b/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0002-Support-fb-backend-for-gl-plugins.patch @@ -0,0 +1,758 @@ +From 230873df6cfd43ce70d9dc763d6f47415f846059 Mon Sep 17 00:00:00 2001 +From: Haihua Hu +Date: Mon, 16 Nov 2015 17:41:57 +0800 +Subject: [PATCH] Support fb backend for gl plugins +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +1.Add fb support in glimagesink +2.override set_render_rectangle() to support resize + +Upstream-Status: Inappropriate [i.MX specific] + +Signed-off-by: Haihua Hu +--- + configure.ac | 25 ++- + gst-libs/gst/gl/Makefile.am | 5 + + gst-libs/gst/gl/fb/Makefile.am | 25 +++ + gst-libs/gst/gl/fb/gstgldisplay_fb.c | 109 +++++++++++++ + gst-libs/gst/gl/fb/gstgldisplay_fb.h | 67 ++++++++ + gst-libs/gst/gl/fb/gstglwindow_fb_egl.c | 265 ++++++++++++++++++++++++++++++++ + gst-libs/gst/gl/fb/gstglwindow_fb_egl.h | 65 ++++++++ + gst-libs/gst/gl/gstgldisplay.c | 8 + + gst-libs/gst/gl/gstgldisplay.h | 1 + + gst-libs/gst/gl/gstglwindow.c | 5 + + 10 files changed, 574 insertions(+), 1 deletion(-) + create mode 100644 gst-libs/gst/gl/fb/Makefile.am + create mode 100644 gst-libs/gst/gl/fb/gstgldisplay_fb.c + create mode 100644 gst-libs/gst/gl/fb/gstgldisplay_fb.h + create mode 100644 gst-libs/gst/gl/fb/gstglwindow_fb_egl.c + create mode 100644 gst-libs/gst/gl/fb/gstglwindow_fb_egl.h + +diff --git a/configure.ac b/configure.ac +index 8d82850..537ee33 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -682,6 +682,7 @@ save_LIBS="$LIBS" + HAVE_GL=no + HAVE_GLES2=no + HAVE_WAYLAND_EGL=no ++HAV_FB_EGL=no + + HAVE_EGL_RPI=no + +@@ -718,6 +719,9 @@ case $host in + old_LIBS=$LIBS + old_CFLAGS=$CFLAGS + ++ dnl check for imx fbbackend support ++ AC_CHECK_LIB(EGL, fbGetDisplay, HAVE_FB_EGL=yes, HAVE_FB_EGL=no) ++ + dnl FIXME: Mali EGL depends on GLESv1 or GLESv2 + AC_CHECK_HEADER([EGL/fbdev_window.h], + [ +@@ -1003,6 +1007,16 @@ case $host in + fi + fi + ++ if test "x$HAVE_FB_EGL" = "xyes"; then ++ if test "x$NEED_EGL" = "xno" -o "x$HAVE_EGL" = "xno"; then ++ AC_MSG_WARN([EGL is required by the fb backend for OpenGL support]) ++ else ++ HAVE_WINDOW_FB=yes ++ GL_LIBS="$GL_LIBS" ++ GL_CFLAGS="$GL_CFLAGS" ++ fi ++ fi ++ + if test "x$HAVE_EGL_RPI" = "xyes"; then + if test "x$NEED_DISPMANX" != "xno"; then + HAVE_WINDOW_DISPMANX=yes +@@ -1017,7 +1031,7 @@ case $host in + fi + else + if test "x$NEED_EGL" != "xno"; then +- if test "x$HAVE_WINDOW_WAYLAND" = "xyes" -o "x$HAVE_WINDOW_X11" = "xyes" -o "x$HAVE_WINDOW_DISPMANX" = "xyes"; then ++ if test "x$HAVE_WINDOW_WAYLAND" = "xyes" -o "x$HAVE_WINDOW_X11" = "xyes" -o "x$HAVE_WINDOW_DISPMANX" = "xyes" -o "x$HAVE_WINDOW_FB" = "xyes"; then + GL_LIBS="$GL_LIBS -lEGL $EGL_LIBS" + GL_CFLAGS="$GL_CFLAGS $EGL_CFLAGS" + USE_EGL=yes +@@ -1166,6 +1180,7 @@ GST_GL_HAVE_WINDOW_WAYLAND=0 + GST_GL_HAVE_WINDOW_ANDROID=0 + GST_GL_HAVE_WINDOW_DISPMANX=0 + GST_GL_HAVE_WINDOW_EAGL=0 ++GST_GL_HAVE_WINDOW_FB=0 + + if test "x$HAVE_WINDOW_X11" = "xyes"; then + GL_WINDOWS="x11 $GL_WINDOWS" +@@ -1195,6 +1210,10 @@ if test "x$HAVE_WINDOW_EAGL" = "xyes"; then + GL_WINDOWS="eagl $GL_WINDOWS" + GST_GL_HAVE_WINDOW_EAGL=1 + fi ++if test "x$HAVE_WINDOW_FB" = "xyes"; then ++ GL_WINDOWS="fb $GL_WINDOWS" ++ GST_GL_HAVE_WINDOW_FB=1 ++fi + + GL_CONFIG_DEFINES="$GL_CONFIG_DEFINES + #define GST_GL_HAVE_WINDOW_X11 $GST_GL_HAVE_WINDOW_X11 +@@ -1204,6 +1223,7 @@ GL_CONFIG_DEFINES="$GL_CONFIG_DEFINES + #define GST_GL_HAVE_WINDOW_ANDROID $GST_GL_HAVE_WINDOW_ANDROID + #define GST_GL_HAVE_WINDOW_DISPMANX $GST_GL_HAVE_WINDOW_DISPMANX + #define GST_GL_HAVE_WINDOW_EAGL $GST_GL_HAVE_WINDOW_EAGL ++#define GST_GL_HAVE_WINDOW_FB $GST_GL_HAVE_WINDOW_FB + " + + dnl PLATFORM's +@@ -1279,6 +1299,7 @@ if test "x$GL_APIS" = "x" -o "x$GL_PLATFORMS" = "x" -o "x$GL_WINDOWS" = "x"; the + HAVE_WINDOW_ANDROID=no + HAVE_WINDOW_COCOA=no + HAVE_WINDOW_EAGL=no ++ HAVE_WINDOW_FB=no + fi + + AC_SUBST(GL_LIBS) +@@ -1294,6 +1315,7 @@ AM_CONDITIONAL(HAVE_WINDOW_DISPMANX, test "x$HAVE_WINDOW_DISPMANX" = "xyes") + AM_CONDITIONAL(HAVE_WINDOW_WAYLAND, test "x$HAVE_WINDOW_WAYLAND" = "xyes") + AM_CONDITIONAL(HAVE_WINDOW_ANDROID, test "x$HAVE_WINDOW_ANDROID" = "xyes") + AM_CONDITIONAL(HAVE_WINDOW_EAGL, test "x$HAVE_WINDOW_EAGL" = "xyes") ++AM_CONDITIONAL(HAVE_WINDOW_FB, test "x$HAVE_WINDOW_FB" = "xyes") + + AM_CONDITIONAL(USE_OPENGL, test "x$USE_OPENGL" = "xyes") + AM_CONDITIONAL(USE_GLES2, test "x$USE_GLES2" = "xyes") +@@ -3580,6 +3602,7 @@ gst-libs/gst/gl/egl/Makefile + gst-libs/gst/gl/wayland/Makefile + gst-libs/gst/gl/win32/Makefile + gst-libs/gst/gl/x11/Makefile ++gst-libs/gst/gl/fb/Makefile + gst-libs/gst/insertbin/Makefile + gst-libs/gst/interfaces/Makefile + gst-libs/gst/codecparsers/Makefile +diff --git a/gst-libs/gst/gl/Makefile.am b/gst-libs/gst/gl/Makefile.am +index f1cb9e1..4bd6511 100644 +--- a/gst-libs/gst/gl/Makefile.am ++++ b/gst-libs/gst/gl/Makefile.am +@@ -117,6 +117,11 @@ SUBDIRS += eagl + libgstgl_@GST_API_VERSION@_la_LIBADD += eagl/libgstgl-eagl.la + endif + ++if HAVE_WINDOW_FB ++SUBDIRS += fb ++libgstgl_@GST_API_VERSION@_la_LIBADD += fb/libgstgl-fb.la ++endif ++ + if USE_EGL + SUBDIRS += egl + libgstgl_@GST_API_VERSION@_la_LIBADD += egl/libgstgl-egl.la +diff --git a/gst-libs/gst/gl/fb/Makefile.am b/gst-libs/gst/gl/fb/Makefile.am +new file mode 100644 +index 0000000..8e4656c +--- /dev/null ++++ b/gst-libs/gst/gl/fb/Makefile.am +@@ -0,0 +1,25 @@ ++## Process this file with automake to produce Makefile.in ++ ++noinst_LTLIBRARIES = libgstgl-fb.la ++ ++libgstgl_fb_la_SOURCES = \ ++ gstgldisplay_fb.c \ ++ gstglwindow_fb_egl.c ++ ++noinst_HEADERS = \ ++ gstgldisplay_fb.h \ ++ gstglwindow_fb_egl.h ++ ++libgstgl_fbincludedir = $(includedir)/gstreamer-@GST_API_VERSION@/gst/gl/fb ++ ++libgstgl_fb_la_CFLAGS = \ ++ -I$(top_srcdir)/gst-libs \ ++ -I$(top_builddir)/gst-libs \ ++ $(GL_CFLAGS) \ ++ $(GST_PLUGINS_BASE_CFLAGS) \ ++ $(GST_BASE_CFLAGS) \ ++ $(GST_CFLAGS) ++ ++libgstgl_fb_la_LDFLAGS = \ ++ $(GST_LIB_LDFLAGS) \ ++ $(GST_ALL_LDFLAGS) +diff --git a/gst-libs/gst/gl/fb/gstgldisplay_fb.c b/gst-libs/gst/gl/fb/gstgldisplay_fb.c +new file mode 100644 +index 0000000..3be9756 +--- /dev/null ++++ b/gst-libs/gst/gl/fb/gstgldisplay_fb.c +@@ -0,0 +1,109 @@ ++/* ++ * GStreamer ++ * Copyright (C) 2014 Matthew Waters ++ * ++ * 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 ++ ++GST_DEBUG_CATEGORY_STATIC (gst_gl_display_debug); ++#define GST_CAT_DEFAULT gst_gl_display_debug ++ ++G_DEFINE_TYPE (GstGLDisplayFB, gst_gl_display_fb, GST_TYPE_GL_DISPLAY); ++ ++static void gst_gl_display_fb_finalize (GObject * object); ++static guintptr gst_gl_display_fb_get_handle (GstGLDisplay * display); ++ ++static void ++gst_gl_display_fb_class_init (GstGLDisplayFBClass * klass) ++{ ++ GST_GL_DISPLAY_CLASS (klass)->get_handle = ++ GST_DEBUG_FUNCPTR (gst_gl_display_fb_get_handle); ++ ++ G_OBJECT_CLASS (klass)->finalize = gst_gl_display_fb_finalize; ++} ++ ++static void ++gst_gl_display_fb_init (GstGLDisplayFB * display_fb) ++{ ++ GstGLDisplay *display = (GstGLDisplay *) display_fb; ++ ++ display->type = GST_GL_DISPLAY_TYPE_FB; ++ display_fb->name = NULL; ++ display_fb->disp_idx = 0; ++ display_fb->display = NULL; ++} ++ ++static void ++gst_gl_display_fb_finalize (GObject * object) ++{ ++ GstGLDisplayFB *display_fb = GST_GL_DISPLAY_FB (object); ++ ++ if (display_fb->name) ++ g_free (display_fb->name); ++ ++ if (display_fb->display) ++ fbDestroyDisplay (display_fb->display); ++ ++ G_OBJECT_CLASS (gst_gl_display_fb_parent_class)->finalize (object); ++} ++ ++/** ++ * gst_gl_display_fb_new: ++ * @name: (allow-none): a display name ++ * ++ * Create a new #GstGLDisplayFB from the x11 display name. See XOpenDisplay() ++ * for details on what is a valid name. ++ * ++ * Returns: (transfer full): a new #GstGLDisplayFB or %NULL ++ */ ++GstGLDisplayFB * ++gst_gl_display_fb_new (gchar *name) ++{ ++ GstGLDisplayFB *display; ++ const gchar *fb_name = NULL; ++ ++ GST_DEBUG_CATEGORY_GET (gst_gl_display_debug, "gldisplay"); ++ GST_DEBUG ("creating Fb EGL display"); ++ ++ fb_name = name; ++ if (!fb_name) fb_name = "fb0"; ++ ++ display = g_object_new (GST_TYPE_GL_DISPLAY_FB, NULL); ++ display->name = g_strdup (fb_name); ++ sscanf (display->name, "fb%d", &display->disp_idx); ++ display->display = fbGetDisplayByIndex (display->disp_idx); ++ if (!display->display) { ++ GST_ERROR ("Failed to open FB display, \'%s\'", fb_name); ++ return NULL; ++ } ++ ++ GST_DEBUG ("Created fb EGL display %d", display->display); ++ ++ return display; ++} ++ ++static guintptr ++gst_gl_display_fb_get_handle (GstGLDisplay * display) ++{ ++ GST_DEBUG ("Get fb EGL display %d", GST_GL_DISPLAY_FB (display)->display); ++ return (guintptr) GST_GL_DISPLAY_FB (display)->display; ++} +diff --git a/gst-libs/gst/gl/fb/gstgldisplay_fb.h b/gst-libs/gst/gl/fb/gstgldisplay_fb.h +new file mode 100644 +index 0000000..62987c1 +--- /dev/null ++++ b/gst-libs/gst/gl/fb/gstgldisplay_fb.h +@@ -0,0 +1,67 @@ ++/* ++ * GStreamer ++ * Copyright (C) 2014 Matthew Waters ++ * ++ * 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_DISPLAY_FB_H__ ++#define __GST_GL_DISPLAY_FB_H__ ++ ++#include ++#include ++#include ++ ++G_BEGIN_DECLS ++ ++GType gst_gl_display_fb_get_type (void); ++ ++#define GST_TYPE_GL_DISPLAY_FB (gst_gl_display_fb_get_type()) ++#define GST_GL_DISPLAY_FB(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_GL_DISPLAY_FB,GstGLDisplayFB)) ++#define GST_GL_DISPLAY_FB_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GST_TYPE_GL_DISPLAY_FB,GstGLDisplayFBClass)) ++#define GST_IS_GL_DISPLAY_FB(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_GL_DISPLAY_FB)) ++#define GST_IS_GL_DISPLAY_FB_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GST_TYPE_GL_DISPLAY_FB)) ++#define GST_GL_DISPLAY_FB_CAST(obj) ((GstGLDisplayFB*)(obj)) ++ ++typedef struct _GstGLDisplayFB GstGLDisplayFB; ++typedef struct _GstGLDisplayFBClass GstGLDisplayFBClass; ++ ++/** ++ * GstGLDisplayFB: ++ * ++ * the contents of a #GstGLDisplayFB are private and should only be accessed ++ * through the provided API ++ */ ++struct _GstGLDisplayFB ++{ ++ GstGLDisplay parent; ++ ++ /* */ ++ gchar *name; ++ gint disp_idx; ++ EGLNativeDisplayType display; ++}; ++ ++struct _GstGLDisplayFBClass ++{ ++ GstGLDisplayClass object_class; ++}; ++ ++GstGLDisplayFB *gst_gl_display_fb_new (gchar *name); ++ ++G_END_DECLS ++ ++#endif /* __GST_GL_DISPLAY_FB_H__ */ +diff --git a/gst-libs/gst/gl/fb/gstglwindow_fb_egl.c b/gst-libs/gst/gl/fb/gstglwindow_fb_egl.c +new file mode 100644 +index 0000000..a068e30 +--- /dev/null ++++ b/gst-libs/gst/gl/fb/gstglwindow_fb_egl.c +@@ -0,0 +1,265 @@ ++/* ++ * GStreamer ++ * Copyright (C) 2008 Julien Isorce ++ * Copyright (C) 2012 Matthew Waters ++ * ++ * 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. ++ */ ++ ++#include "../gstgl_fwd.h" ++#include ++ ++#include "gstglwindow_fb_egl.h" ++ ++#define GST_CAT_DEFAULT gst_gl_window_debug ++ ++#define gst_gl_window_fb_egl_parent_class parent_class ++G_DEFINE_TYPE (GstGLWindowFbEGL, gst_gl_window_fb_egl, ++ GST_GL_TYPE_WINDOW); ++ ++static guintptr gst_gl_window_fb_egl_get_window_handle (GstGLWindow * ++ window); ++static void gst_gl_window_fb_egl_set_window_handle (GstGLWindow * window, ++ guintptr handle); ++static void gst_gl_window_fb_egl_draw (GstGLWindow * window); ++static void gst_gl_window_fb_egl_close (GstGLWindow * window); ++static gboolean gst_gl_window_fb_egl_open (GstGLWindow * window, ++ GError ** error); ++static gboolean ++gst_gl_window_fb_egl_set_render_rectangle(GstGLWindow * window, ++ guint x, guint y, guint width, guint height); ++ ++static void ++gst_gl_window_fb_egl_class_init (GstGLWindowFbEGLClass * klass) ++{ ++ GstGLWindowClass *window_class = (GstGLWindowClass *) klass; ++ ++ window_class->get_window_handle = ++ GST_DEBUG_FUNCPTR (gst_gl_window_fb_egl_get_window_handle); ++ window_class->set_window_handle = ++ GST_DEBUG_FUNCPTR (gst_gl_window_fb_egl_set_window_handle); ++ window_class->draw = GST_DEBUG_FUNCPTR (gst_gl_window_fb_egl_draw); ++ window_class->close = GST_DEBUG_FUNCPTR (gst_gl_window_fb_egl_close); ++ window_class->open = GST_DEBUG_FUNCPTR (gst_gl_window_fb_egl_open); ++ window_class->set_render_rectangle = ++ GST_DEBUG_FUNCPTR (gst_gl_window_fb_egl_set_render_rectangle); ++} ++ ++static void ++gst_gl_window_fb_egl_init (GstGLWindowFbEGL * window) ++{ ++ GstGLWindowFbEGL *window_egl; ++ ++ window_egl = GST_GL_WINDOW_FB_EGL (window); ++ ++ window_egl->width = 0; ++ window_egl->height = 0; ++ window_egl->default_fullscreen = TRUE; ++ window_egl->display = 0; ++} ++ ++/* Must be called in the gl thread */ ++GstGLWindowFbEGL * ++gst_gl_window_fb_egl_new (GstGLDisplay * display) ++{ ++ GstGLWindowFbEGL *window; ++ const gchar *fb_name = NULL; ++ ++ if (!display) ++ return NULL; ++ ++ window = g_object_new (GST_GL_TYPE_WINDOW_FB_EGL, NULL); ++ window->display = gst_gl_display_get_handle (display); ++ if (!window->display) { ++ GST_ERROR ("failed to get display for egl window"); ++ return NULL; ++ } ++ ++ return window; ++} ++ ++static void ++gst_gl_window_fb_egl_close (GstGLWindow * window) ++{ ++ GstGLWindowFbEGL *window_egl; ++ ++ window_egl = GST_GL_WINDOW_FB_EGL (window); ++ ++ if (window_egl->win_id) { ++ fbDestroyWindow (window_egl->win_id); ++ } ++ ++ GST_GL_WINDOW_CLASS (parent_class)->close (window); ++} ++ ++static gboolean ++gst_gl_window_fb_egl_open (GstGLWindow * window, GError ** error) ++{ ++ GstGLWindowFbEGL *window_egl; ++ ++ window_egl = GST_GL_WINDOW_FB_EGL (window); ++ ++ if (!window_egl->display) { ++ GST_ERROR ("No display for window_egl."); ++ return FALSE; ++ } ++ ++ window_egl->win_id = fbCreateWindow (window_egl->display, -1, -1, 0, 0); ++ if (!window_egl->win_id) { ++ GST_ERROR ("Failed to create window_egl"); ++ return FALSE; ++ } ++ ++ fbGetDisplayGeometry (window_egl->display, &window_egl->width, &window_egl->height); ++ window_egl->req_width = window_egl->width; ++ window_egl->req_height = window_egl->height; ++ GST_DEBUG ("Open FB display succesfully, resolution is (%dx%d),display %d, window %d.", ++ window_egl->width, window_egl->height, window_egl->display, window_egl->win_id); ++ ++ if (!GST_GL_WINDOW_CLASS (parent_class)->open (window, error)) ++ return FALSE; ++ ++ return TRUE; ++} ++static guintptr ++gst_gl_window_fb_egl_get_window_handle (GstGLWindow * window) ++{ ++ GST_DEBUG ("fb egl get window: %d", GST_GL_WINDOW_FB_EGL (window)->win_id); ++ return (guintptr) GST_GL_WINDOW_FB_EGL (window)->win_id; ++} ++ ++static void ++gst_gl_window_fb_egl_set_window_handle (GstGLWindow * window, ++ guintptr handle) ++{ ++} ++ ++static void ++draw_cb (gpointer data) ++{ ++ GstGLWindowFbEGL *window_egl = (GstGLWindowFbEGL *)data; ++ GstGLWindow *window = GST_GL_WINDOW (window_egl); ++ GstGLContext *context = gst_gl_window_get_context (window); ++ GstGLContextClass *context_class = GST_GL_CONTEXT_GET_CLASS (context); ++ ++ /* default full screen */ ++ if (window_egl->default_fullscreen && window->resize) { ++ window->resize (window->resize_data, window_egl->width, window_egl->height); ++ window_egl->default_fullscreen = FALSE; ++ } ++ ++ if (window->draw) ++ window->draw (window->draw_data); ++ ++ GST_DEBUG ("####### draw data"); ++ context_class->swap_buffers (context); ++ ++ gst_object_unref (context); ++} ++ ++static void ++gst_gl_window_fb_egl_draw (GstGLWindow * window) ++{ ++ gst_gl_window_send_message (window, (GstGLWindowCB) draw_cb, window); ++} ++ ++static gboolean ++_calculate_viewport_coordinates(GstVideoRectangle *req, GstVideoRectangle *result, ++ guint display_width, guint display_height) ++{ ++ if(!req || !result || req->w < 1 || req->h < 1) ++ return FALSE; ++ ++ result->x = req->x; ++ result->y = display_height - (req->y + req->h); ++ result->w = req->w; ++ result->h = req->h; ++ ++ return TRUE; ++} ++ ++struct SetRenderRectangle ++{ ++ GstGLWindowFbEGL *window_egl; ++ GstVideoRectangle rect; ++}; ++ ++static void ++_free_set_render_rectangle (struct SetRenderRectangle *render) ++{ ++ if (render) { ++ if (render->window_egl) ++ gst_object_unref (render->window_egl); ++ g_free (render); ++ } ++} ++ ++static void ++_set_render_rectangle (gpointer data) ++{ ++ const GstGLFuncs *gl; ++ GstGLContext *context; ++ GstVideoRectangle result, video_rect, tmp_res; ++ struct SetRenderRectangle *render = data; ++ GstGLWindow *window = GST_GL_WINDOW (render->window_egl); ++ ++ context = gst_gl_window_get_context(window); ++ gl = context->gl_vtable; ++ ++ GST_LOG_OBJECT (render->window_egl, "setting render rectangle %i,%i+%ix%i", ++ render->rect.x, render->rect.y, render->rect.w, render->rect.h); ++ ++ video_rect.x = render->rect.x; ++ video_rect.y = render->rect.y; ++ video_rect.w = GST_VIDEO_SINK_WIDTH(window->resize_data); ++ video_rect.h = GST_VIDEO_SINK_HEIGHT(window->resize_data); ++ ++ gst_video_sink_center_rect(video_rect, render->rect, &tmp_res, TRUE); ++ ++ GST_LOG_OBJECT (render->window_egl, "set center render rectangle %i,%i+%ix%i", ++ tmp_res.x, tmp_res.y, tmp_res.w, tmp_res.h); ++ ++ /* need to transform screen coordinate to viewport coordinate */ ++ if( _calculate_viewport_coordinates(&tmp_res, &result, ++ render->window_egl->width, render->window_egl->height)){ ++ GST_LOG_OBJECT (render->window_egl, "viewport render rectangle %i,%i+%ix%i", ++ result.x, result.y, result.w, result.h); ++ gl->Viewport(result.x, result.y, result.w, result.h); ++ } ++ ++ if(context) ++ gst_object_unref(context); ++} ++ ++static gboolean ++gst_gl_window_fb_egl_set_render_rectangle(GstGLWindow * window, ++ guint x, guint y, guint width, guint height) ++{ ++ GstGLWindowFbEGL *window_egl = GST_GL_WINDOW_FB_EGL (window); ++ struct SetRenderRectangle *render; ++ ++ render = g_new0 (struct SetRenderRectangle, 1); ++ render->window_egl = gst_object_ref (window_egl); ++ render->rect.x = x; ++ render->rect.y = y; ++ render->rect.w = width; ++ render->rect.h = height; ++ ++ gst_gl_window_send_message_async (window, ++ (GstGLWindowCB) _set_render_rectangle, render, ++ (GDestroyNotify) _free_set_render_rectangle); ++ return TRUE; ++} +diff --git a/gst-libs/gst/gl/fb/gstglwindow_fb_egl.h b/gst-libs/gst/gl/fb/gstglwindow_fb_egl.h +new file mode 100644 +index 0000000..216e421 +--- /dev/null ++++ b/gst-libs/gst/gl/fb/gstglwindow_fb_egl.h +@@ -0,0 +1,65 @@ ++/* ++ * GStreamer ++ * Copyright (C) 2012 Matthew Waters ++ * ++ * 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_WINDOW_FB_EGL_H__ ++#define __GST_GL_WINDOW_FB_EGL_H__ ++ ++#include ++#include "EGL/eglplatform.h" ++ ++G_BEGIN_DECLS ++ ++#define GST_GL_TYPE_WINDOW_FB_EGL (gst_gl_window_fb_egl_get_type()) ++#define GST_GL_WINDOW_FB_EGL(o) (G_TYPE_CHECK_INSTANCE_CAST((o), GST_GL_TYPE_WINDOW_FB_EGL, GstGLWindowFbEGL)) ++#define GST_GL_WINDOW_FB_EGL_CLASS(k) (G_TYPE_CHECK_CLASS((k), GST_GL_TYPE_WINDOW_FB_EGL, GstGLWindowFbEGLClass)) ++#define GST_GL_IS_WINDOW_FB_EGL(o) (G_TYPE_CHECK_INSTANCE_TYPE((o), GST_GL_TYPE_WINDOW_FB_EGL)) ++#define GST_GL_IS_WINDOW_FB_EGL_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE((k), GST_GL_TYPE_WINDOW_FB_EGL)) ++#define GST_GL_WINDOW_FB_EGL_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS((o), GST_GL_TYPE_WINDOW_FB_EGL, GstGLWindowFbEGL_Class)) ++ ++typedef struct _GstGLWindowFbEGL GstGLWindowFbEGL; ++typedef struct _GstGLWindowFbEGLClass GstGLWindowFbEGLClass; ++ ++struct _GstGLWindowFbEGL { ++ /*< private >*/ ++ GstGLWindow parent; ++ ++ /* */ ++ gint width, req_width; ++ gint height, req_height; ++ gboolean default_fullscreen; ++ EGLNativeDisplayType display; ++ EGLNativeWindowType win_id; ++}; ++ ++struct _GstGLWindowFbEGLClass { ++ /*< private >*/ ++ GstGLWindowClass parent_class; ++ ++ /*< private >*/ ++ gpointer _reserved[GST_PADDING]; ++}; ++ ++GType gst_gl_window_fb_egl_get_type (void); ++ ++GstGLWindowFbEGL * gst_gl_window_fb_egl_new (GstGLDisplay * display); ++ ++G_END_DECLS ++ ++#endif /* __GST_GL_WINDOW_FB_EGL_H__ */ +diff --git a/gst-libs/gst/gl/gstgldisplay.c b/gst-libs/gst/gl/gstgldisplay.c +index 5cae2f4..0213d60 100644 +--- a/gst-libs/gst/gl/gstgldisplay.c ++++ b/gst-libs/gst/gl/gstgldisplay.c +@@ -205,6 +205,14 @@ gst_gl_display_new (void) + if (!display && (!user_choice || g_strstr_len (user_choice, 7, "wayland"))) + display = GST_GL_DISPLAY (gst_gl_display_wayland_new (NULL)); + #endif ++#if GST_GL_HAVE_WINDOW_FB ++ if (!display && (!user_choice || g_strstr_len (user_choice, 2, "fb"))) { ++ const gchar *fb_name = NULL; ++ fb_name = g_getenv ("GST_GL_FB"); ++ if (!fb_name) fb_name = "fb0"; ++ display = GST_GL_DISPLAY (gst_gl_display_fb_new (fb_name)); ++ } ++#endif + #if GST_GL_HAVE_PLATFORM_EGL + if (!display && (!platform_choice + || g_strstr_len (platform_choice, 3, "egl"))) +diff --git a/gst-libs/gst/gl/gstgldisplay.h b/gst-libs/gst/gl/gstgldisplay.h +index 7f49a44..c5bc985 100644 +--- a/gst-libs/gst/gl/gstgldisplay.h ++++ b/gst-libs/gst/gl/gstgldisplay.h +@@ -60,6 +60,7 @@ typedef enum + GST_GL_DISPLAY_TYPE_WIN32 = (1 << 3), + GST_GL_DISPLAY_TYPE_DISPMANX = (1 << 4), + GST_GL_DISPLAY_TYPE_EGL = (1 << 5), ++ GST_GL_DISPLAY_TYPE_FB = (1 << 6), + + GST_GL_DISPLAY_TYPE_ANY = G_MAXUINT32 + } GstGLDisplayType; +diff --git a/gst-libs/gst/gl/gstglwindow.c b/gst-libs/gst/gl/gstglwindow.c +index 695f4c4..7b20ff4 100644 +--- a/gst-libs/gst/gl/gstglwindow.c ++++ b/gst-libs/gst/gl/gstglwindow.c +@@ -302,6 +302,11 @@ gst_gl_window_new (GstGLDisplay * display) + if (!window && (!user_choice || g_strstr_len (user_choice, 4, "eagl"))) + window = GST_GL_WINDOW (gst_gl_window_eagl_new (display)); + #endif ++#if GST_GL_HAVE_WINDOW_FB ++ if (!window && (!user_choice || g_strstr_len (user_choice, 2, "fb"))) ++ window = GST_GL_WINDOW (gst_gl_window_fb_egl_new (display)); ++#endif ++ + if (!window) { + /* subclass returned a NULL window */ + GST_WARNING ("Could not create window. user specified %s, creating dummy" +-- +1.9.1 + diff --git a/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0003-Add-directviv-to-glimagesink-to-improve-playback-per.patch b/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0003-Add-directviv-to-glimagesink-to-improve-playback-per.patch new file mode 100644 index 000000000..43d89060d --- /dev/null +++ b/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0003-Add-directviv-to-glimagesink-to-improve-playback-per.patch @@ -0,0 +1,438 @@ +From 94e6bb069cb5207761f2e4234137f2a748f984db Mon Sep 17 00:00:00 2001 +From: Haihua Hu +Date: Tue, 13 Oct 2015 09:33:54 +0800 +Subject: [PATCH 13/18] Add directviv to glimagesink to improve playback + performance +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +1.Add a physical buffer uploader in glupload plugin and using viv direct + texture to bind physical continious buffer with texture to avoid memory + copy from videobuffer to texture to gain good performance. +2.Reduce glimagesink load latency by override glimagesink ALLOCATION query to + avoid memory copy. + +Upstream-Status: Inappropriate [i.MX specific] + +Signed-off-by: Haihua Hu +Signed-off-by: Lyon Wang +--- + ext/gl/gstglimagesink.c | 5 ++ + gst-libs/gst/gl/Makefile.am | 2 + + gst-libs/gst/gl/gstglupload.c | 141 ++++++++++++++++++++++++++++++- + gst-libs/gst/gl/gstglvivdirecttexture.c | 143 ++++++++++++++++++++++++++++++++ + gst-libs/gst/gl/gstglvivdirecttexture.h | 35 ++++++++ + 5 files changed, 323 insertions(+), 3 deletions(-) + create mode 100644 gst-libs/gst/gl/gstglvivdirecttexture.c + create mode 100644 gst-libs/gst/gl/gstglvivdirecttexture.h + +diff --git a/ext/gl/gstglimagesink.c b/ext/gl/gstglimagesink.c +index 3b5e3b5..532ea6a 100644 +--- a/ext/gl/gstglimagesink.c ++++ b/ext/gl/gstglimagesink.c +@@ -911,6 +911,11 @@ gst_glimage_sink_query (GstBaseSink * bsink, GstQuery * query) + res = GST_BASE_SINK_CLASS (parent_class)->query (bsink, query); + break; + } ++ case GST_QUERY_ALLOCATION: ++ { ++ gst_glimage_sink_propose_allocation(bsink, query); ++ break; ++ } + default: + res = GST_BASE_SINK_CLASS (parent_class)->query (bsink, query); + break; +diff --git a/gst-libs/gst/gl/Makefile.am b/gst-libs/gst/gl/Makefile.am +index 4bd6511..c396603 100644 +--- a/gst-libs/gst/gl/Makefile.am ++++ b/gst-libs/gst/gl/Makefile.am +@@ -33,6 +33,7 @@ libgstgl_@GST_API_VERSION@_la_SOURCES = \ + gstglviewconvert.c \ + gstgloverlaycompositor.c \ + gstglquery.c \ ++ gstglvivdirecttexture.c \ + gstglcontrolbindingproxy.c + + libgstgl_@GST_API_VERSION@includedir = $(includedir)/gstreamer-@GST_API_VERSION@/gst/gl +@@ -66,6 +67,7 @@ libgstgl_@GST_API_VERSION@include_HEADERS = \ + gstglcontrolbindingproxy.h \ + gstgl_fwd.h \ + gstgl_enums.h \ ++ gstglvivdirecttexture.h \ + gl.h + + noinst_HEADERS = \ +diff --git a/gst-libs/gst/gl/gstglupload.c b/gst-libs/gst/gl/gstglupload.c +index 32e6150..99cc68a 100644 +--- a/gst-libs/gst/gl/gstglupload.c ++++ b/gst-libs/gst/gl/gstglupload.c +@@ -23,6 +23,7 @@ + #endif + + #include ++#include + + #include "gl.h" + #include "gstglupload.h" +@@ -51,7 +52,7 @@ + #define USING_GLES2(context) (gst_gl_context_check_gl_version (context, GST_GL_API_GLES2, 2, 0)) + #define USING_GLES3(context) (gst_gl_context_check_gl_version (context, GST_GL_API_GLES2, 3, 0)) + +-GST_DEBUG_CATEGORY_STATIC (gst_gl_upload_debug); ++GST_DEBUG_CATEGORY (gst_gl_upload_debug); + #define GST_CAT_DEFAULT gst_gl_upload_debug + + #define DEBUG_INIT \ +@@ -1169,6 +1170,140 @@ static const UploadMethod _upload_meta_upload = { + &_upload_meta_upload_free + }; + ++struct PhyBufferUpload ++{ ++ GstGLUpload *upload; ++ GstGLVideoAllocationParams *params; ++}; ++ ++static gpointer ++_physical_buffer_upload_new(GstGLUpload *upload) ++{ ++ struct PhyBufferUpload *phybuffer = g_new0 (struct PhyBufferUpload, 1); ++ ++ phybuffer->upload = upload; ++ ++ return phybuffer; ++} ++ ++static GstCaps * ++_physical_buffer_upload_transform_caps(GstGLContext *context, ++ GstPadDirection direction, GstCaps *caps) ++{ ++ GstCapsFeatures *passthrough = ++ gst_caps_features_from_string ++ (GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION); ++ GstCaps *ret; ++ ++ if (direction == GST_PAD_SINK) { ++ GstCaps *tmp; ++ ++ ret = ++ _set_caps_features_with_passthrough (caps, ++ GST_CAPS_FEATURE_MEMORY_GL_MEMORY, passthrough); ++ ++ gst_caps_set_simple (ret, "format", G_TYPE_STRING, "RGBA", NULL); ++ tmp = _caps_intersect_texture_target (ret, 1 << GST_GL_TEXTURE_TARGET_2D); ++ gst_caps_unref (ret); ++ ret = tmp; ++ } else { ++ ret = gst_caps_from_string (GST_VIDEO_CAPS_MAKE_WITH_FEATURES ++ (GST_CAPS_FEATURE_MEMORY_SYSTEM_MEMORY,GST_GL_DIRECTVIV_FORMAT)); ++ } ++ ++ gst_caps_features_free (passthrough); ++ return ret; ++} ++ ++static gboolean ++_physical_buffer_upload_accept(gpointer impl, GstBuffer *buffer, ++ GstCaps *in_caps, GstCaps *out_caps) ++{ ++ struct PhyBufferUpload *upload = impl; ++ GstCapsFeatures *features; ++ ++ features = gst_caps_get_features (out_caps, 0); ++ if (!gst_caps_features_contains (features, GST_CAPS_FEATURE_MEMORY_GL_MEMORY)) ++ return FALSE; ++ ++ if (upload->params) ++ gst_gl_allocation_params_free ((GstGLAllocationParams *) upload->params); ++ if (!(upload->params = ++ gst_gl_video_allocation_params_new (upload->upload->context, NULL, ++ &upload->upload->priv->in_info, -1, NULL, ++ GST_GL_TEXTURE_TARGET_2D))) ++ return FALSE; ++ ++ return gst_is_physical_buffer(buffer); ++} ++ ++static void ++_physical_buffer_upload_propose_allocation(gpointer impl, GstQuery *decide_query, ++ GstQuery *query) ++{ ++ gst_query_add_allocation_meta (query, GST_VIDEO_META_API_TYPE, 0); ++} ++ ++static GstGLUploadReturn ++_physical_buffer_upload_perform(gpointer impl, GstBuffer *buffer, GstBuffer **outbuf) ++{ ++ struct PhyBufferUpload *phyBuffer = impl; ++ GstGLMemoryAllocator *allocator; ++ GstVideoInfo *info; ++ gint n_mem; ++ ++ info = &phyBuffer->upload->priv->out_info; ++ n_mem = GST_VIDEO_INFO_N_PLANES (info); ++ GST_LOG_OBJECT (phyBuffer->upload, "Attempting viv direct upload"); ++ ++ allocator = ++ GST_GL_MEMORY_ALLOCATOR (gst_allocator_find ++ (GST_GL_MEMORY_PBO_ALLOCATOR_NAME)); ++ ++ /* FIXME: buffer pool */ ++ *outbuf = gst_buffer_new (); ++ gst_gl_memory_setup_buffer (allocator, *outbuf, phyBuffer->params); ++ gst_object_unref (allocator); ++ ++ GstGLMemory *out_gl_mem = ++ (GstGLMemory *) gst_buffer_peek_memory (*outbuf, 0); ++ ++ gst_gl_viv_direct_bind_gstbuffer(phyBuffer->upload->context, out_gl_mem->tex_id, ++ &phyBuffer->upload->priv->in_info, buffer); ++ ++ gst_buffer_add_video_meta_full (*outbuf, 0, ++ GST_VIDEO_INFO_FORMAT (info), GST_VIDEO_INFO_WIDTH (info), ++ GST_VIDEO_INFO_HEIGHT (info), n_mem, info->offset, info->stride); ++ ++ return GST_GL_UPLOAD_DONE; ++} ++ ++static void ++_physical_buffer_upload_free(gpointer impl) ++{ ++ struct PhyBufferUpload *phyBuffer = impl; ++ ++ if (phyBuffer->params) ++ gst_gl_allocation_params_free ((GstGLAllocationParams *) phyBuffer->params); ++ ++ g_free(phyBuffer); ++} ++ ++static GstStaticCaps _physical_buffer_upload_caps = ++GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE (GST_GL_DIRECTVIV_FORMAT)); ++ ++static const UploadMethod _physical_buffer_upload = { ++ "Physical buffer", ++ 0, ++ &_physical_buffer_upload_caps, ++ &_physical_buffer_upload_new, ++ &_physical_buffer_upload_transform_caps, ++ &_physical_buffer_upload_accept, ++ &_physical_buffer_upload_propose_allocation, ++ &_physical_buffer_upload_perform, ++ &_physical_buffer_upload_free ++}; ++ + struct RawUploadFrame + { + gint ref_count; +@@ -1391,7 +1526,7 @@ static const UploadMethod *upload_methods[] = { &_gl_memory_upload, + #if GST_GL_HAVE_DMABUF + &_dma_buf_upload, + #endif +- &_upload_meta_upload, &_raw_data_upload ++ &_upload_meta_upload, &_physical_buffer_upload, &_raw_data_upload + }; + + static GMutex upload_global_lock; +@@ -1514,7 +1649,7 @@ gst_gl_upload_transform_caps (GstGLContext * context, GstPadDirection direction, + } + + if (filter) { +- result = gst_caps_intersect_full (filter, tmp, GST_CAPS_INTERSECT_FIRST); ++ result = gst_caps_intersect_full (tmp, filter, GST_CAPS_INTERSECT_FIRST); + gst_caps_unref (tmp); + } else { + result = tmp; +diff --git a/gst-libs/gst/gl/gstglvivdirecttexture.c b/gst-libs/gst/gl/gstglvivdirecttexture.c +new file mode 100644 +index 0000000..c19b617 +--- /dev/null ++++ b/gst-libs/gst/gl/gstglvivdirecttexture.c +@@ -0,0 +1,143 @@ ++/* ++ * GStreamer ++ * Copyright (c) 2015, Freescale Semiconductor, Inc. ++ * ++ * 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 "gl.h" ++ ++GST_DEBUG_CATEGORY_EXTERN (gst_gl_upload_debug); ++#define GST_CAT_DEFAULT gst_gl_upload_debug ++ ++typedef struct { ++ guint tex_id; ++ guint w; ++ guint h; ++ guint fmt; ++ void *vaddr; ++ guint paddr; ++ gboolean ret; ++} GstVivDirectTexture; ++ ++gboolean ++gst_is_physical_buffer (GstBuffer *buffer) ++{ ++ ++ GstMemory *mem; ++ ++ mem = gst_buffer_peek_memory (buffer, 0); ++ if (!mem->allocator) ++ return FALSE; ++ ++ return g_type_check_instance_is_a (mem->allocator, g_type_from_name("GstAllocatorPhyMem")); ++} ++ ++static void ++_do_viv_direct_tex_bind_mem (GstGLContext * context, GstVivDirectTexture * viv_tex) ++{ ++ GST_DEBUG ("viv direct upload, tex_id %d, fmt: %d, res: (%dx%d)", viv_tex->tex_id, viv_tex->fmt, viv_tex->w, viv_tex->h); ++ GST_DEBUG ("Physical memory buffer, vaddr: %p, paddr: %p", viv_tex->vaddr, viv_tex->paddr); ++ ++ glBindTexture (GL_TEXTURE_2D, viv_tex->tex_id); ++ glTexDirectVIVMap (GL_TEXTURE_2D, viv_tex->w, viv_tex->h, viv_tex->fmt, &viv_tex->vaddr, &viv_tex->paddr); ++ glTexDirectInvalidateVIV (GL_TEXTURE_2D); ++ viv_tex->ret = TRUE; ++ ++ return; ++} ++ ++gboolean ++gst_gl_viv_direct_bind_gstbuffer (GstGLContext * context, guint tex_id, GstVideoInfo * info, GstBuffer * buffer) ++{ ++ typedef struct { ++ guint8 *vaddr; ++ guint8 *paddr; ++ guint8 *caddr; ++ gsize size; ++ gpointer *user_data; ++ } PhyMemBlock; ++ //Note: structure PhyMemBlock is copied from gst1.0-fsl-plugin/libs/allocator/gstallocatorphymem.h ++ ++ typedef struct { ++ GstMemory mem; ++ guint8 *vaddr; ++ guint8 *paddr; ++ PhyMemBlock block; ++ } GstMemoryPhy; ++ //Note: structure GstMemoryPhy is copied from gst1.0-fsl-plugin/libs/allocator/gstallocatorphymem.c ++ ++ GstMemory *mem = gst_buffer_peek_memory (buffer, 0); ++ GstMemoryPhy *memphy = (GstMemoryPhy*) mem; ++ PhyMemBlock *memblk = &memphy->block; ++ ++ GstVideoFormat fmt = GST_VIDEO_INFO_FORMAT (info); ++ gint width, height; ++ GstVideoMeta *vmeta = gst_buffer_get_video_meta (buffer); ++ if (vmeta && (fmt == GST_VIDEO_FORMAT_I420 || fmt == GST_VIDEO_FORMAT_NV12)) { ++ width = vmeta->stride[0]; ++ height = vmeta->offset[1] / width; ++ } ++ else { ++ width = GST_VIDEO_INFO_WIDTH (info); ++ height = GST_VIDEO_INFO_HEIGHT (info); ++ } ++ ++ guint viv_fmt; ++ switch (fmt) { ++ case GST_VIDEO_FORMAT_I420: ++ viv_fmt = GL_VIV_I420; ++ break; ++ case GST_VIDEO_FORMAT_YV12: ++ viv_fmt = GL_VIV_YV12; ++ break; ++ case GST_VIDEO_FORMAT_NV12: ++ viv_fmt = GL_VIV_NV12; ++ break; ++ case GST_VIDEO_FORMAT_NV21: ++ viv_fmt = GL_VIV_NV21; ++ break; ++ case GST_VIDEO_FORMAT_YUY2: ++ viv_fmt = GL_VIV_YUY2; ++ break; ++ case GST_VIDEO_FORMAT_UYVY: ++ viv_fmt = GL_VIV_UYVY; ++ break; ++ case GST_VIDEO_FORMAT_RGBA: ++ viv_fmt = GL_RGBA; ++ break; ++ case GST_VIDEO_FORMAT_BGRA: ++ viv_fmt = GL_BGRA_EXT; ++ break; ++ case GST_VIDEO_FORMAT_RGB16: ++ viv_fmt = GL_RGB565_OES; ++ break; ++ default: ++ GST_ERROR ("Not supported format %d for viv direct texture upload.", fmt); ++ viv_fmt = GL_NONE; ++ return FALSE; ++ } ++ ++ GstVivDirectTexture viv_tex = {tex_id, width, height, viv_fmt, memblk->vaddr, memblk->paddr, FALSE}; ++ gst_gl_context_thread_add (context, (GstGLContextThreadFunc) _do_viv_direct_tex_bind_mem, &viv_tex); ++ ++ return viv_tex.ret; ++} ++ +diff --git a/gst-libs/gst/gl/gstglvivdirecttexture.h b/gst-libs/gst/gl/gstglvivdirecttexture.h +new file mode 100644 +index 0000000..fa88e1a +--- /dev/null ++++ b/gst-libs/gst/gl/gstglvivdirecttexture.h +@@ -0,0 +1,35 @@ ++/* ++ * GStreamer ++ * Copyright (c) 2015, Freescale Semiconductor, Inc. ++ * ++ * 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_VIVDIRECT_H__ ++#define __GST_GL_VIVDIRECT_H__ ++ ++#include ++#include ++ ++#define GST_GL_DIRECTVIV_FORMAT "{RGBA, I420, YV12, NV12, NV21, YUY2, UYVY, BGRA, RGB16}" ++G_BEGIN_DECLS ++ ++gboolean gst_is_physical_buffer (GstBuffer *buffer); ++gboolean gst_gl_viv_direct_bind_gstbuffer (GstGLContext * context, guint tex_id, GstVideoInfo * info, GstBuffer * buffer); ++ ++G_END_DECLS ++ ++#endif /* __GST_GL_VIVDIRECT_H__ */ +-- +1.9.1 + diff --git a/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0003-MMFMWK-6930-glplugin-Accelerate-gldownload-with-dire.patch b/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0003-MMFMWK-6930-glplugin-Accelerate-gldownload-with-dire.patch deleted file mode 100644 index 1cead36d4..000000000 --- a/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0003-MMFMWK-6930-glplugin-Accelerate-gldownload-with-dire.patch +++ /dev/null @@ -1,729 +0,0 @@ -From 05bbd82dd527afa44d6b403b02a0dbd198c96859 Mon Sep 17 00:00:00 2001 -From: Jian Li -Date: Fri, 6 Nov 2015 15:00:19 +0800 -Subject: [PATCH 14/18] MMFMWK-6930 [glplugin] Accelerate gldownload with - directviv API -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -1) Propose a physical buffer pool to upstream in gldownload -2) Bind the physical buffer with texture via dirctviv -3) In gldownload, wrap the physical buffer to gstbuffer, pass to - downstream plugins. - -Upstream-Status: Inappropriate [i.MX specific] - -Signed-off-by: Jian Li -Signed-off-by: Lyon Wang ---- - ext/gl/gstgldownloadelement.c | 91 ++++++++++++ - gst-libs/gst/gl/Makefile.am | 4 + - gst-libs/gst/gl/gstglbufferpool.c | 12 ++ - gst-libs/gst/gl/gstglphymemory.c | 254 ++++++++++++++++++++++++++++++++ - gst-libs/gst/gl/gstglphymemory.h | 43 ++++++ - gst-libs/gst/gl/gstglvivdirecttexture.c | 147 +++++++++--------- - gst-libs/gst/gl/gstglvivdirecttexture.h | 3 + - 7 files changed, 484 insertions(+), 70 deletions(-) - create mode 100644 gst-libs/gst/gl/gstglphymemory.c - create mode 100644 gst-libs/gst/gl/gstglphymemory.h - -diff --git a/ext/gl/gstgldownloadelement.c b/ext/gl/gstgldownloadelement.c -index ff931fa..9ea0146 100644 ---- a/ext/gl/gstgldownloadelement.c -+++ b/ext/gl/gstgldownloadelement.c -@@ -23,6 +23,7 @@ - #endif - - #include -+#include - #include "gstgldownloadelement.h" - - GST_DEBUG_CATEGORY_STATIC (gst_gl_download_element_debug); -@@ -45,6 +46,8 @@ gst_gl_download_element_prepare_output_buffer (GstBaseTransform * bt, - GstBuffer * buffer, GstBuffer ** outbuf); - static GstFlowReturn gst_gl_download_element_transform (GstBaseTransform * bt, - GstBuffer * buffer, GstBuffer * outbuf); -+static gboolean gst_gl_download_element_propose_allocation (GstBaseTransform * -+ bt, GstQuery * decide_query, GstQuery * query); - - static GstStaticPadTemplate gst_gl_download_element_src_pad_template = - GST_STATIC_PAD_TEMPLATE ("src", -@@ -70,6 +73,7 @@ gst_gl_download_element_class_init (GstGLDownloadElementClass * klass) - bt_class->prepare_output_buffer = - gst_gl_download_element_prepare_output_buffer; - bt_class->transform = gst_gl_download_element_transform; -+ bt_class->propose_allocation = gst_gl_download_element_propose_allocation; - - bt_class->passthrough_on_same_caps = TRUE; - -@@ -160,9 +164,24 @@ static GstFlowReturn - gst_gl_download_element_prepare_output_buffer (GstBaseTransform * bt, - GstBuffer * inbuf, GstBuffer ** outbuf) - { -+ GstGLDownloadElement *download = GST_GL_DOWNLOAD_ELEMENT (bt); - GstCaps *src_caps = gst_pad_get_current_caps (bt->srcpad); - GstCapsFeatures *features = NULL; - gint i, n; -+ GstGLMemory *glmem; -+ -+ glmem = gst_buffer_peek_memory (inbuf, 0); -+ if (gst_is_gl_physical_memory (glmem)) { -+ GstGLContext *context = GST_GL_BASE_FILTER (bt)->context; -+ GstVideoInfo info; -+ -+ gst_video_info_from_caps (&info, src_caps); -+ *outbuf = gst_gl_phymem_buffer_to_gstbuffer (context, &info, inbuf); -+ -+ GST_DEBUG_OBJECT (download, "gl download with direct viv."); -+ -+ return GST_FLOW_OK; -+ } - - *outbuf = inbuf; - -@@ -194,3 +213,75 @@ gst_gl_download_element_transform (GstBaseTransform * bt, - { - return GST_FLOW_OK; - } -+ -+static gboolean -+gst_gl_download_element_propose_allocation (GstBaseTransform * bt, -+ GstQuery * decide_query, GstQuery * query) -+{ -+ GstGLContext *context = GST_GL_BASE_FILTER (bt)->context; -+ GstGLDownloadElement *download = GST_GL_DOWNLOAD_ELEMENT (bt); -+ GstAllocationParams params; -+ GstAllocator *allocator = NULL; -+ GstBufferPool *pool = NULL; -+ guint n_pools, i; -+ GstVideoInfo info; -+ GstCaps *caps; -+ GstStructure *config; -+ gsize size; -+ -+ gst_query_parse_allocation (query, &caps, NULL); -+ if (!gst_video_info_from_caps (&info, caps)) { -+ GST_WARNING_OBJECT (bt, "invalid caps specified"); -+ return FALSE; -+ } -+ -+ GST_DEBUG_OBJECT (bt, "video format is %s", gst_video_format_to_string (GST_VIDEO_INFO_FORMAT (&info))); -+ -+ gst_allocation_params_init (¶ms); -+ if (gst_is_gl_physical_memory_supported_fmt (&info)) { -+ allocator = gst_phy_mem_allocator_obtain (); -+ GST_DEBUG_OBJECT (bt, "obtain physical memory allocator %p.", allocator); -+ } -+ -+ if (!allocator) -+ allocator = gst_allocator_find (GST_GL_MEMORY_ALLOCATOR_NAME); -+ -+ if (!allocator) { -+ GST_ERROR_OBJECT (bt, "Can't obtain physical memory allocator."); -+ return FALSE; -+ } -+ -+ gst_query_add_allocation_param (query, allocator, ¶ms); -+ gst_object_unref (allocator); -+ -+ n_pools = gst_query_get_n_allocation_pools (query); -+ for (i = 0; i < n_pools; i++) { -+ gst_query_parse_nth_allocation_pool (query, i, &pool, NULL, NULL, NULL); -+ gst_object_unref (pool); -+ pool = NULL; -+ } -+ -+ //new buffer pool -+ pool = gst_gl_buffer_pool_new (context); -+ config = gst_buffer_pool_get_config (pool); -+ -+ /* the normal size of a frame */ -+ size = info.size; -+ gst_buffer_pool_config_set_params (config, caps, size, 0, 0); -+ gst_buffer_pool_config_add_option (config, GST_BUFFER_POOL_OPTION_GL_SYNC_META); -+ -+ if (!gst_buffer_pool_set_config (pool, config)) { -+ gst_object_unref (pool); -+ GST_WARNING_OBJECT (bt, "failed setting config"); -+ return FALSE; -+ } -+ -+ GST_DEBUG_OBJECT (download, "create pool %p", pool); -+ -+ //propose 3 buffers for better performance -+ gst_query_add_allocation_pool (query, pool, size, 3, 0); -+ -+ gst_object_unref (pool); -+ -+ return TRUE; -+} -diff --git a/gst-libs/gst/gl/Makefile.am b/gst-libs/gst/gl/Makefile.am -index c396603..5c05230 100644 ---- a/gst-libs/gst/gl/Makefile.am -+++ b/gst-libs/gst/gl/Makefile.am -@@ -34,6 +34,7 @@ libgstgl_@GST_API_VERSION@_la_SOURCES = \ - gstgloverlaycompositor.c \ - gstglquery.c \ - gstglvivdirecttexture.c \ -+ gstglphymemory.c \ - gstglcontrolbindingproxy.c - - libgstgl_@GST_API_VERSION@includedir = $(includedir)/gstreamer-@GST_API_VERSION@/gst/gl -@@ -68,6 +69,7 @@ libgstgl_@GST_API_VERSION@include_HEADERS = \ - gstgl_fwd.h \ - gstgl_enums.h \ - gstglvivdirecttexture.h \ -+ gstglphymemory.h \ - gl.h - - noinst_HEADERS = \ -@@ -84,6 +86,8 @@ libgstgl_@GST_API_VERSION@_la_LIBADD = \ - $(GST_LIBS) \ - $(GL_LIBS) - -+libgstgl_@GST_API_VERSION@_la_LIBADD += -lgstfsl-$(GST_API_VERSION) -+ - if HAVE_WINDOW_WIN32 - SUBDIRS += win32 - libgstgl_@GST_API_VERSION@_la_LIBADD += win32/libgstgl-win32.la -diff --git a/gst-libs/gst/gl/gstglbufferpool.c b/gst-libs/gst/gl/gstglbufferpool.c -index 90536b0..71c726a 100644 ---- a/gst-libs/gst/gl/gstglbufferpool.c -+++ b/gst-libs/gst/gl/gstglbufferpool.c -@@ -30,6 +30,8 @@ - #include - #endif - -+#include -+ - /** - * SECTION:gstglbufferpool - * @short_description: buffer pool for #GstGLMemory objects -@@ -290,6 +292,16 @@ gst_gl_buffer_pool_alloc (GstBufferPool * pool, GstBuffer ** buffer, - } - #endif - -+ if ((g_strcmp0 (priv->allocator->mem_type, GST_GL_PHY_MEM_ALLOCATOR) == 0)) { -+ GstAllocator* allocator = (GstAllocator*) gst_phy_mem_allocator_obtain (); -+ if (!gst_gl_physical_memory_setup_buffer (allocator, buf, priv->gl_params)) { -+ GST_ERROR_OBJECT (pool, "Can't create physcial buffer."); -+ return GST_FLOW_ERROR; -+ } -+ *buffer = buf; -+ return GST_FLOW_OK; -+ } -+ - alloc = GST_GL_MEMORY_ALLOCATOR (priv->allocator); - if (!gst_gl_memory_setup_buffer (alloc, buf, priv->gl_params)) - goto mem_create_failed; -diff --git a/gst-libs/gst/gl/gstglphymemory.c b/gst-libs/gst/gl/gstglphymemory.c -new file mode 100644 -index 0000000..52ae41f ---- /dev/null -+++ b/gst-libs/gst/gl/gstglphymemory.c -@@ -0,0 +1,254 @@ -+/* -+ * GStreamer -+ * Copyright (c) 2015, Freescale Semiconductor, Inc. -+ * -+ * 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 "gstglvivdirecttexture.h" -+#include "gstglphymemory.h" -+#include "g2d.h" -+ -+GST_DEBUG_CATEGORY_STATIC (GST_CAT_GL_PHY_MEMORY); -+#define GST_CAT_DEFAULT GST_CAT_GL_PHY_MEMORY -+ -+typedef struct _GstPhyMemAllocator GstPhyMemAllocator; -+typedef struct _GstPhyMemAllocatorClass GstPhyMemAllocatorClass; -+ -+struct _GstPhyMemAllocator -+{ -+ GstAllocatorPhyMem parent; -+}; -+ -+struct _GstPhyMemAllocatorClass -+{ -+ GstAllocatorPhyMemClass parent_class; -+}; -+ -+GType gst_phy_mem_allocator_get_type (void); -+G_DEFINE_TYPE (GstPhyMemAllocator, gst_phy_mem_allocator, GST_TYPE_ALLOCATOR_PHYMEM); -+ -+static int -+alloc_phymem (GstAllocatorPhyMem *allocator, PhyMemBlock *memblk) -+{ -+ struct g2d_buf *pbuf = NULL; -+ -+ memblk->size = PAGE_ALIGN(memblk->size); -+ -+ pbuf = g2d_alloc (memblk->size, 0); -+ if (!pbuf) { -+ GST_ERROR("G2D allocate %u bytes memory failed: %s", -+ memblk->size, strerror(errno)); -+ return -1; -+ } -+ -+ memblk->vaddr = (guchar*) pbuf->buf_vaddr; -+ memblk->paddr = (guchar*) pbuf->buf_paddr; -+ memblk->user_data = (gpointer) pbuf; -+ GST_DEBUG("G2D allocated memory (%p)", memblk->paddr); -+ -+ return 1; -+} -+ -+static int -+free_phymem (GstAllocatorPhyMem *allocator, PhyMemBlock *memblk) -+{ -+ GST_DEBUG("G2D free memory (%p)", memblk->paddr); -+ gint ret = g2d_free ((struct g2d_buf*)(memblk->user_data)); -+ memblk->user_data = NULL; -+ memblk->vaddr = NULL; -+ memblk->paddr = NULL; -+ memblk->size = 0; -+ -+ return ret; -+} -+ -+static void -+gst_phy_mem_allocator_class_init (GstPhyMemAllocatorClass * klass) -+{ -+ GstAllocatorPhyMemClass *phy_allocator_klass = (GstAllocatorPhyMemClass *) klass; -+ -+ phy_allocator_klass->alloc_phymem = alloc_phymem; -+ phy_allocator_klass->free_phymem = free_phymem; -+} -+ -+static void -+gst_phy_mem_allocator_init (GstPhyMemAllocator * allocator) -+{ -+ GstAllocator *alloc = GST_ALLOCATOR_CAST (allocator); -+ -+ alloc->mem_type = GST_GL_PHY_MEM_ALLOCATOR; -+} -+ -+ -+static gpointer -+gst_phy_mem_allocator_init_instance (gpointer data) -+{ -+ GstAllocator *allocator = -+ g_object_new (gst_phy_mem_allocator_get_type (), NULL); -+ -+ GST_DEBUG_CATEGORY_INIT (GST_CAT_GL_PHY_MEMORY, "glphymemory", 0, -+ "GLPhysical Memory"); -+ -+ gst_allocator_register (GST_GL_PHY_MEM_ALLOCATOR, gst_object_ref (allocator)); -+ -+ return allocator; -+} -+ -+static void -+_finish_texture (GstGLContext * ctx, gpointer *data) -+{ -+ GstGLFuncs *gl = ctx->gl_vtable; -+ -+ gl->Finish (); -+} -+ -+static void -+gst_gl_phy_mem_destroy (GstMemory *mem) -+{ -+ gst_memory_unref (mem); -+} -+ -+ -+GstAllocator * -+gst_phy_mem_allocator_obtain (void) -+{ -+ static GOnce once = G_ONCE_INIT; -+ -+ g_once (&once, gst_phy_mem_allocator_init_instance, NULL); -+ -+ g_return_val_if_fail (once.retval != NULL, NULL); -+ -+ return (GstAllocator *) (g_object_ref (once.retval)); -+} -+ -+gboolean -+gst_is_gl_physical_memory (GstMemory * mem) -+{ -+ GstGLBaseMemory *glmem; -+ g_return_val_if_fail (gst_is_gl_memory (mem), FALSE); -+ -+ glmem = (GstGLBaseMemory*) mem; -+ -+ if (glmem->user_data -+ && GST_IS_MINI_OBJECT_TYPE(glmem->user_data, GST_TYPE_MEMORY)) -+ return gst_memory_is_type ((GstMemory*)glmem->user_data, GST_GL_PHY_MEM_ALLOCATOR); -+ else -+ return FALSE; -+} -+ -+gboolean -+gst_is_gl_physical_memory_supported_fmt (GstVideoInfo * info) -+{ -+ if (GST_VIDEO_INFO_IS_RGB(info) -+ && gst_gl_is_directviv_supported_format (GST_VIDEO_INFO_FORMAT (info))) { -+ return TRUE; -+ } -+ else -+ return FALSE; -+} -+ -+gboolean -+gst_gl_physical_memory_setup_buffer (GstAllocator * allocator, GstBuffer *buffer, -+ GstGLVideoAllocationParams * params) -+{ -+ GstGLBaseMemoryAllocator *gl_alloc; -+ GstMemory *mem = NULL; -+ PhyMemBlock *memblk = NULL; -+ GstGLMemory *glmem = NULL; -+ gsize size; -+ -+ GstVideoInfo * info = params->v_info; -+ GstVideoAlignment * valign = params->valign; -+ -+ GST_DEBUG ("glphymemory setup buffer format %s", gst_video_format_to_string (GST_VIDEO_INFO_FORMAT (info))); -+ -+ if (!gst_is_gl_physical_memory_supported_fmt (info)) { -+ GST_DEBUG ("Not support format."); -+ return FALSE; -+ } -+ -+ //allocator = (GstAllocator*) gst_phy_mem_allocator_obtain (); -+ size = gst_gl_get_plane_data_size (info, valign, 0); -+ mem = gst_allocator_alloc (allocator, size, params->parent.alloc_params); -+ if (!mem) { -+ GST_DEBUG ("Can't allocate physical memory size %d", size); -+ return FALSE; -+ } -+ -+ memblk = gst_memory_query_phymem_block (mem); -+ if (!memblk) { -+ GST_ERROR("Can't find physic memory block."); -+ return FALSE; -+ } -+ -+ gl_alloc = -+ GST_GL_BASE_MEMORY_ALLOCATOR (gst_gl_memory_allocator_get_default -+ (params->parent.context)); -+ -+ params->plane = 0; -+ params->parent.user_data = mem; -+ params->parent.notify = gst_gl_phy_mem_destroy; -+ -+ glmem = (GstGLMemory *)gst_gl_base_memory_alloc (gl_alloc, (GstGLAllocationParams *) params); -+ if (!glmem) { -+ GST_ERROR("Can't get gl memory."); -+ return FALSE; -+ } -+ -+ gst_buffer_append_memory (buffer, (GstMemory *) glmem); -+ -+ gst_buffer_add_video_meta_full (buffer, 0, -+ GST_VIDEO_INFO_FORMAT (info), GST_VIDEO_INFO_WIDTH (info), -+ GST_VIDEO_INFO_HEIGHT (info), 1, info->offset, info->stride); -+ -+ gst_gl_viv_direct_bind_data(params->parent.context, glmem->tex_id, -+ GST_VIDEO_INFO_FORMAT (info), GST_VIDEO_INFO_WIDTH (info), -+ GST_VIDEO_INFO_HEIGHT (info), memblk->vaddr, memblk->paddr); -+ -+ return TRUE; -+} -+ -+GstBuffer * -+gst_gl_phymem_buffer_to_gstbuffer (GstGLContext * ctx, -+ GstVideoInfo * info, GstBuffer *glbuf) -+{ -+ GstBuffer *buf; -+ GstGLBaseMemory *glmem; -+ -+ gst_gl_context_thread_add (ctx, (GstGLContextThreadFunc) _finish_texture, NULL); -+ -+ glmem = gst_buffer_peek_memory (glbuf, 0); -+ -+ buf = gst_buffer_new (); -+ gst_buffer_append_memory (buf, (GstMemory *) glmem->user_data); -+ gst_memory_ref ((GstMemory *)glmem->user_data); -+ -+ gst_buffer_add_video_meta_full (buf, 0, -+ GST_VIDEO_INFO_FORMAT (info), GST_VIDEO_INFO_WIDTH (info), -+ GST_VIDEO_INFO_HEIGHT (info), 1, info->offset, info->stride); -+ GST_BUFFER_FLAGS (buf) = GST_BUFFER_FLAGS (glbuf); -+ GST_BUFFER_PTS (buf) = GST_BUFFER_PTS (glbuf); -+ GST_BUFFER_DTS (buf) = GST_BUFFER_DTS (glbuf); -+ GST_BUFFER_DURATION (buf) = GST_BUFFER_DURATION (glbuf); -+ -+ return buf; -+} -+ -diff --git a/gst-libs/gst/gl/gstglphymemory.h b/gst-libs/gst/gl/gstglphymemory.h -new file mode 100644 -index 0000000..b1a69e7 ---- /dev/null -+++ b/gst-libs/gst/gl/gstglphymemory.h -@@ -0,0 +1,43 @@ -+/* -+ * GStreamer -+ * Copyright (c) 2015, Freescale Semiconductor, Inc. -+ * -+ * 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_PHY_MEMORY_H_ -+#define _GST_GL_PHY_MEMORY_H_ -+ -+#include -+#include -+#include -+#include -+ -+#include -+ -+G_BEGIN_DECLS -+ -+#define GST_GL_PHY_MEM_ALLOCATOR "GLPhyMemory" -+ -+GstAllocator *gst_phy_mem_allocator_obtain (void); -+gboolean gst_is_gl_physical_memory (GstMemory * mem); -+gboolean gst_is_gl_physical_memory_supported_fmt (GstVideoInfo * info); -+gboolean gst_gl_physical_memory_setup_buffer (GstAllocator * allocator, GstBuffer *buffer, GstGLVideoAllocationParams * params); -+GstBuffer * gst_gl_phymem_buffer_to_gstbuffer (GstGLContext * ctx, GstVideoInfo * info, GstBuffer *glbuf); -+ -+G_END_DECLS -+ -+#endif /* _GST_GL_PHY_MEMORY_H_ */ -diff --git a/gst-libs/gst/gl/gstglvivdirecttexture.c b/gst-libs/gst/gl/gstglvivdirecttexture.c -index c19b617..e8e0b82 100644 ---- a/gst-libs/gst/gl/gstglvivdirecttexture.c -+++ b/gst-libs/gst/gl/gstglvivdirecttexture.c -@@ -22,6 +22,7 @@ - #include "config.h" - #endif - -+#include - #include "gl.h" - - GST_DEBUG_CATEGORY_EXTERN (gst_gl_upload_debug); -@@ -37,17 +38,28 @@ typedef struct { - gboolean ret; - } GstVivDirectTexture; - -+typedef struct { -+ GstVideoFormat gst_fmt; -+ guint viv_fmt; -+} VIV_FMT_MAP; -+ -+static VIV_FMT_MAP viv_fmt_map_table[] = { -+ {GST_VIDEO_FORMAT_I420, GL_VIV_I420}, -+ {GST_VIDEO_FORMAT_YV12, GL_VIV_YV12}, -+ {GST_VIDEO_FORMAT_NV12, GL_VIV_NV12}, -+ {GST_VIDEO_FORMAT_NV21, GL_VIV_NV21}, -+ {GST_VIDEO_FORMAT_YUY2, GL_VIV_YUY2}, -+ {GST_VIDEO_FORMAT_UYVY, GL_VIV_UYVY}, -+ {GST_VIDEO_FORMAT_RGBA, GL_RGBA}, -+ {GST_VIDEO_FORMAT_RGBx, GL_RGBA}, -+ {GST_VIDEO_FORMAT_BGRA, GL_BGRA_EXT}, -+ {GST_VIDEO_FORMAT_RGB16, GL_RGB565_OES} -+}; -+ - gboolean - gst_is_physical_buffer (GstBuffer *buffer) - { -- -- GstMemory *mem; -- -- mem = gst_buffer_peek_memory (buffer, 0); -- if (!mem->allocator) -- return FALSE; -- -- return g_type_check_instance_is_a (mem->allocator, g_type_from_name("GstAllocatorPhyMem")); -+ return gst_buffer_is_phymem (buffer); - } - - static void -@@ -65,32 +77,64 @@ _do_viv_direct_tex_bind_mem (GstGLContext * context, GstVivDirectTexture * viv_t - } - - gboolean -+gst_gl_is_directviv_supported_format (GstVideoFormat fmt) -+{ -+ gint i; -+ gboolean ret = FALSE; -+ -+ for (i=0; iblock; -- -- GstVideoFormat fmt = GST_VIDEO_INFO_FORMAT (info); -+ PhyMemBlock *memblk; -+ GstVideoMeta *vmeta; -+ GstVideoFormat fmt; - gint width, height; -- GstVideoMeta *vmeta = gst_buffer_get_video_meta (buffer); -+ -+ memblk = gst_buffer_query_phymem_block (buffer); -+ if (!memblk) -+ return FALSE; -+ -+ width = GST_VIDEO_INFO_WIDTH (info); -+ height = GST_VIDEO_INFO_HEIGHT (info); -+ -+ vmeta = gst_buffer_get_video_meta (buffer); -+ fmt = GST_VIDEO_INFO_FORMAT (info); - if (vmeta && (fmt == GST_VIDEO_FORMAT_I420 || fmt == GST_VIDEO_FORMAT_NV12)) { - width = vmeta->stride[0]; - height = vmeta->offset[1] / width; -@@ -100,44 +144,7 @@ gst_gl_viv_direct_bind_gstbuffer (GstGLContext * context, guint tex_id, GstVideo - height = GST_VIDEO_INFO_HEIGHT (info); - } - -- guint viv_fmt; -- switch (fmt) { -- case GST_VIDEO_FORMAT_I420: -- viv_fmt = GL_VIV_I420; -- break; -- case GST_VIDEO_FORMAT_YV12: -- viv_fmt = GL_VIV_YV12; -- break; -- case GST_VIDEO_FORMAT_NV12: -- viv_fmt = GL_VIV_NV12; -- break; -- case GST_VIDEO_FORMAT_NV21: -- viv_fmt = GL_VIV_NV21; -- break; -- case GST_VIDEO_FORMAT_YUY2: -- viv_fmt = GL_VIV_YUY2; -- break; -- case GST_VIDEO_FORMAT_UYVY: -- viv_fmt = GL_VIV_UYVY; -- break; -- case GST_VIDEO_FORMAT_RGBA: -- viv_fmt = GL_RGBA; -- break; -- case GST_VIDEO_FORMAT_BGRA: -- viv_fmt = GL_BGRA_EXT; -- break; -- case GST_VIDEO_FORMAT_RGB16: -- viv_fmt = GL_RGB565_OES; -- break; -- default: -- GST_ERROR ("Not supported format %d for viv direct texture upload.", fmt); -- viv_fmt = GL_NONE; -- return FALSE; -- } -- -- GstVivDirectTexture viv_tex = {tex_id, width, height, viv_fmt, memblk->vaddr, memblk->paddr, FALSE}; -- gst_gl_context_thread_add (context, (GstGLContextThreadFunc) _do_viv_direct_tex_bind_mem, &viv_tex); -- -- return viv_tex.ret; -+ return gst_gl_viv_direct_bind_data (context, tex_id, fmt, width, height, memblk->vaddr, memblk->paddr); - } - -+ -diff --git a/gst-libs/gst/gl/gstglvivdirecttexture.h b/gst-libs/gst/gl/gstglvivdirecttexture.h -index fa88e1a..9a2d123 100644 ---- a/gst-libs/gst/gl/gstglvivdirecttexture.h -+++ b/gst-libs/gst/gl/gstglvivdirecttexture.h -@@ -28,6 +28,9 @@ - G_BEGIN_DECLS - - gboolean gst_is_physical_buffer (GstBuffer *buffer); -+gboolean gst_gl_is_directviv_supported_format (GstVideoFormat fmt); -+gboolean gst_gl_viv_direct_bind_data (GstGLContext * context, guint tex_id, GstVideoFormat fmt, gint width, gint height, -+ gpointer * vaddr, gpointer *paddr); - gboolean gst_gl_viv_direct_bind_gstbuffer (GstGLContext * context, guint tex_id, GstVideoInfo * info, GstBuffer * buffer); - - G_END_DECLS --- -1.9.1 - diff --git a/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0004-Fix-dependence-issue-between-gst-plugin-.patch b/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0004-Fix-dependence-issue-between-gst-plugin-.patch deleted file mode 100755 index 44633cf91..000000000 --- a/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0004-Fix-dependence-issue-between-gst-plugin-.patch +++ /dev/null @@ -1,74 +0,0 @@ -From 4f73ba8dde190b0e2d3a7a16b394762f7459ca31 Mon Sep 17 00:00:00 2001 -From: Haihua Hu -Date: Fri, 5 Aug 2016 17:04:02 +0800 -Subject: [PATCH] [MMFMWK-7259]Fix dependence issue between gst-plugin-bad and - imx-gst1.0-plugin - -Change dependence to gst-plugin-base since we have move physical memory allocator -to gst-plugin-base - -Upstream-Status: Inappropriate [i.MX specific] - -Signed-off-by: Haihua Hu ---- - gst-libs/gst/gl/Makefile.am | 2 +- - gst-libs/gst/gl/gstglphymemory.c | 2 +- - gst-libs/gst/gl/gstglphymemory.h | 2 +- - gst-libs/gst/gl/gstglvivdirecttexture.c | 2 +- - 4 files changed, 4 insertions(+), 4 deletions(-) - -diff --git a/gst-libs/gst/gl/Makefile.am b/gst-libs/gst/gl/Makefile.am -index 5c05230..55f8a20 100644 ---- a/gst-libs/gst/gl/Makefile.am -+++ b/gst-libs/gst/gl/Makefile.am -@@ -86,7 +86,7 @@ libgstgl_@GST_API_VERSION@_la_LIBADD = \ - $(GST_LIBS) \ - $(GL_LIBS) - --libgstgl_@GST_API_VERSION@_la_LIBADD += -lgstfsl-$(GST_API_VERSION) -+libgstgl_@GST_API_VERSION@_la_LIBADD += -lg2d - - if HAVE_WINDOW_WIN32 - SUBDIRS += win32 -diff --git a/gst-libs/gst/gl/gstglphymemory.c b/gst-libs/gst/gl/gstglphymemory.c -index 52ae41f..e28546c 100644 ---- a/gst-libs/gst/gl/gstglphymemory.c -+++ b/gst-libs/gst/gl/gstglphymemory.c -@@ -24,7 +24,7 @@ - - #include "gstglvivdirecttexture.h" - #include "gstglphymemory.h" --#include "g2d.h" -+#include - - GST_DEBUG_CATEGORY_STATIC (GST_CAT_GL_PHY_MEMORY); - #define GST_CAT_DEFAULT GST_CAT_GL_PHY_MEMORY -diff --git a/gst-libs/gst/gl/gstglphymemory.h b/gst-libs/gst/gl/gstglphymemory.h -index b1a69e7..ebb9911 100644 ---- a/gst-libs/gst/gl/gstglphymemory.h -+++ b/gst-libs/gst/gl/gstglphymemory.h -@@ -24,7 +24,7 @@ - #include - #include - #include --#include -+#include - - #include - -diff --git a/gst-libs/gst/gl/gstglvivdirecttexture.c b/gst-libs/gst/gl/gstglvivdirecttexture.c -index e8e0b82..242b7c0 100644 ---- a/gst-libs/gst/gl/gstglvivdirecttexture.c -+++ b/gst-libs/gst/gl/gstglvivdirecttexture.c -@@ -22,7 +22,7 @@ - #include "config.h" - #endif - --#include -+#include - #include "gl.h" - - GST_DEBUG_CATEGORY_EXTERN (gst_gl_upload_debug); --- -1.9.1 - diff --git a/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0004-MMFMWK-6930-glplugin-Accelerate-gldownload-with-dire.patch b/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0004-MMFMWK-6930-glplugin-Accelerate-gldownload-with-dire.patch new file mode 100644 index 000000000..1cead36d4 --- /dev/null +++ b/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0004-MMFMWK-6930-glplugin-Accelerate-gldownload-with-dire.patch @@ -0,0 +1,729 @@ +From 05bbd82dd527afa44d6b403b02a0dbd198c96859 Mon Sep 17 00:00:00 2001 +From: Jian Li +Date: Fri, 6 Nov 2015 15:00:19 +0800 +Subject: [PATCH 14/18] MMFMWK-6930 [glplugin] Accelerate gldownload with + directviv API +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +1) Propose a physical buffer pool to upstream in gldownload +2) Bind the physical buffer with texture via dirctviv +3) In gldownload, wrap the physical buffer to gstbuffer, pass to + downstream plugins. + +Upstream-Status: Inappropriate [i.MX specific] + +Signed-off-by: Jian Li +Signed-off-by: Lyon Wang +--- + ext/gl/gstgldownloadelement.c | 91 ++++++++++++ + gst-libs/gst/gl/Makefile.am | 4 + + gst-libs/gst/gl/gstglbufferpool.c | 12 ++ + gst-libs/gst/gl/gstglphymemory.c | 254 ++++++++++++++++++++++++++++++++ + gst-libs/gst/gl/gstglphymemory.h | 43 ++++++ + gst-libs/gst/gl/gstglvivdirecttexture.c | 147 +++++++++--------- + gst-libs/gst/gl/gstglvivdirecttexture.h | 3 + + 7 files changed, 484 insertions(+), 70 deletions(-) + create mode 100644 gst-libs/gst/gl/gstglphymemory.c + create mode 100644 gst-libs/gst/gl/gstglphymemory.h + +diff --git a/ext/gl/gstgldownloadelement.c b/ext/gl/gstgldownloadelement.c +index ff931fa..9ea0146 100644 +--- a/ext/gl/gstgldownloadelement.c ++++ b/ext/gl/gstgldownloadelement.c +@@ -23,6 +23,7 @@ + #endif + + #include ++#include + #include "gstgldownloadelement.h" + + GST_DEBUG_CATEGORY_STATIC (gst_gl_download_element_debug); +@@ -45,6 +46,8 @@ gst_gl_download_element_prepare_output_buffer (GstBaseTransform * bt, + GstBuffer * buffer, GstBuffer ** outbuf); + static GstFlowReturn gst_gl_download_element_transform (GstBaseTransform * bt, + GstBuffer * buffer, GstBuffer * outbuf); ++static gboolean gst_gl_download_element_propose_allocation (GstBaseTransform * ++ bt, GstQuery * decide_query, GstQuery * query); + + static GstStaticPadTemplate gst_gl_download_element_src_pad_template = + GST_STATIC_PAD_TEMPLATE ("src", +@@ -70,6 +73,7 @@ gst_gl_download_element_class_init (GstGLDownloadElementClass * klass) + bt_class->prepare_output_buffer = + gst_gl_download_element_prepare_output_buffer; + bt_class->transform = gst_gl_download_element_transform; ++ bt_class->propose_allocation = gst_gl_download_element_propose_allocation; + + bt_class->passthrough_on_same_caps = TRUE; + +@@ -160,9 +164,24 @@ static GstFlowReturn + gst_gl_download_element_prepare_output_buffer (GstBaseTransform * bt, + GstBuffer * inbuf, GstBuffer ** outbuf) + { ++ GstGLDownloadElement *download = GST_GL_DOWNLOAD_ELEMENT (bt); + GstCaps *src_caps = gst_pad_get_current_caps (bt->srcpad); + GstCapsFeatures *features = NULL; + gint i, n; ++ GstGLMemory *glmem; ++ ++ glmem = gst_buffer_peek_memory (inbuf, 0); ++ if (gst_is_gl_physical_memory (glmem)) { ++ GstGLContext *context = GST_GL_BASE_FILTER (bt)->context; ++ GstVideoInfo info; ++ ++ gst_video_info_from_caps (&info, src_caps); ++ *outbuf = gst_gl_phymem_buffer_to_gstbuffer (context, &info, inbuf); ++ ++ GST_DEBUG_OBJECT (download, "gl download with direct viv."); ++ ++ return GST_FLOW_OK; ++ } + + *outbuf = inbuf; + +@@ -194,3 +213,75 @@ gst_gl_download_element_transform (GstBaseTransform * bt, + { + return GST_FLOW_OK; + } ++ ++static gboolean ++gst_gl_download_element_propose_allocation (GstBaseTransform * bt, ++ GstQuery * decide_query, GstQuery * query) ++{ ++ GstGLContext *context = GST_GL_BASE_FILTER (bt)->context; ++ GstGLDownloadElement *download = GST_GL_DOWNLOAD_ELEMENT (bt); ++ GstAllocationParams params; ++ GstAllocator *allocator = NULL; ++ GstBufferPool *pool = NULL; ++ guint n_pools, i; ++ GstVideoInfo info; ++ GstCaps *caps; ++ GstStructure *config; ++ gsize size; ++ ++ gst_query_parse_allocation (query, &caps, NULL); ++ if (!gst_video_info_from_caps (&info, caps)) { ++ GST_WARNING_OBJECT (bt, "invalid caps specified"); ++ return FALSE; ++ } ++ ++ GST_DEBUG_OBJECT (bt, "video format is %s", gst_video_format_to_string (GST_VIDEO_INFO_FORMAT (&info))); ++ ++ gst_allocation_params_init (¶ms); ++ if (gst_is_gl_physical_memory_supported_fmt (&info)) { ++ allocator = gst_phy_mem_allocator_obtain (); ++ GST_DEBUG_OBJECT (bt, "obtain physical memory allocator %p.", allocator); ++ } ++ ++ if (!allocator) ++ allocator = gst_allocator_find (GST_GL_MEMORY_ALLOCATOR_NAME); ++ ++ if (!allocator) { ++ GST_ERROR_OBJECT (bt, "Can't obtain physical memory allocator."); ++ return FALSE; ++ } ++ ++ gst_query_add_allocation_param (query, allocator, ¶ms); ++ gst_object_unref (allocator); ++ ++ n_pools = gst_query_get_n_allocation_pools (query); ++ for (i = 0; i < n_pools; i++) { ++ gst_query_parse_nth_allocation_pool (query, i, &pool, NULL, NULL, NULL); ++ gst_object_unref (pool); ++ pool = NULL; ++ } ++ ++ //new buffer pool ++ pool = gst_gl_buffer_pool_new (context); ++ config = gst_buffer_pool_get_config (pool); ++ ++ /* the normal size of a frame */ ++ size = info.size; ++ gst_buffer_pool_config_set_params (config, caps, size, 0, 0); ++ gst_buffer_pool_config_add_option (config, GST_BUFFER_POOL_OPTION_GL_SYNC_META); ++ ++ if (!gst_buffer_pool_set_config (pool, config)) { ++ gst_object_unref (pool); ++ GST_WARNING_OBJECT (bt, "failed setting config"); ++ return FALSE; ++ } ++ ++ GST_DEBUG_OBJECT (download, "create pool %p", pool); ++ ++ //propose 3 buffers for better performance ++ gst_query_add_allocation_pool (query, pool, size, 3, 0); ++ ++ gst_object_unref (pool); ++ ++ return TRUE; ++} +diff --git a/gst-libs/gst/gl/Makefile.am b/gst-libs/gst/gl/Makefile.am +index c396603..5c05230 100644 +--- a/gst-libs/gst/gl/Makefile.am ++++ b/gst-libs/gst/gl/Makefile.am +@@ -34,6 +34,7 @@ libgstgl_@GST_API_VERSION@_la_SOURCES = \ + gstgloverlaycompositor.c \ + gstglquery.c \ + gstglvivdirecttexture.c \ ++ gstglphymemory.c \ + gstglcontrolbindingproxy.c + + libgstgl_@GST_API_VERSION@includedir = $(includedir)/gstreamer-@GST_API_VERSION@/gst/gl +@@ -68,6 +69,7 @@ libgstgl_@GST_API_VERSION@include_HEADERS = \ + gstgl_fwd.h \ + gstgl_enums.h \ + gstglvivdirecttexture.h \ ++ gstglphymemory.h \ + gl.h + + noinst_HEADERS = \ +@@ -84,6 +86,8 @@ libgstgl_@GST_API_VERSION@_la_LIBADD = \ + $(GST_LIBS) \ + $(GL_LIBS) + ++libgstgl_@GST_API_VERSION@_la_LIBADD += -lgstfsl-$(GST_API_VERSION) ++ + if HAVE_WINDOW_WIN32 + SUBDIRS += win32 + libgstgl_@GST_API_VERSION@_la_LIBADD += win32/libgstgl-win32.la +diff --git a/gst-libs/gst/gl/gstglbufferpool.c b/gst-libs/gst/gl/gstglbufferpool.c +index 90536b0..71c726a 100644 +--- a/gst-libs/gst/gl/gstglbufferpool.c ++++ b/gst-libs/gst/gl/gstglbufferpool.c +@@ -30,6 +30,8 @@ + #include + #endif + ++#include ++ + /** + * SECTION:gstglbufferpool + * @short_description: buffer pool for #GstGLMemory objects +@@ -290,6 +292,16 @@ gst_gl_buffer_pool_alloc (GstBufferPool * pool, GstBuffer ** buffer, + } + #endif + ++ if ((g_strcmp0 (priv->allocator->mem_type, GST_GL_PHY_MEM_ALLOCATOR) == 0)) { ++ GstAllocator* allocator = (GstAllocator*) gst_phy_mem_allocator_obtain (); ++ if (!gst_gl_physical_memory_setup_buffer (allocator, buf, priv->gl_params)) { ++ GST_ERROR_OBJECT (pool, "Can't create physcial buffer."); ++ return GST_FLOW_ERROR; ++ } ++ *buffer = buf; ++ return GST_FLOW_OK; ++ } ++ + alloc = GST_GL_MEMORY_ALLOCATOR (priv->allocator); + if (!gst_gl_memory_setup_buffer (alloc, buf, priv->gl_params)) + goto mem_create_failed; +diff --git a/gst-libs/gst/gl/gstglphymemory.c b/gst-libs/gst/gl/gstglphymemory.c +new file mode 100644 +index 0000000..52ae41f +--- /dev/null ++++ b/gst-libs/gst/gl/gstglphymemory.c +@@ -0,0 +1,254 @@ ++/* ++ * GStreamer ++ * Copyright (c) 2015, Freescale Semiconductor, Inc. ++ * ++ * 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 "gstglvivdirecttexture.h" ++#include "gstglphymemory.h" ++#include "g2d.h" ++ ++GST_DEBUG_CATEGORY_STATIC (GST_CAT_GL_PHY_MEMORY); ++#define GST_CAT_DEFAULT GST_CAT_GL_PHY_MEMORY ++ ++typedef struct _GstPhyMemAllocator GstPhyMemAllocator; ++typedef struct _GstPhyMemAllocatorClass GstPhyMemAllocatorClass; ++ ++struct _GstPhyMemAllocator ++{ ++ GstAllocatorPhyMem parent; ++}; ++ ++struct _GstPhyMemAllocatorClass ++{ ++ GstAllocatorPhyMemClass parent_class; ++}; ++ ++GType gst_phy_mem_allocator_get_type (void); ++G_DEFINE_TYPE (GstPhyMemAllocator, gst_phy_mem_allocator, GST_TYPE_ALLOCATOR_PHYMEM); ++ ++static int ++alloc_phymem (GstAllocatorPhyMem *allocator, PhyMemBlock *memblk) ++{ ++ struct g2d_buf *pbuf = NULL; ++ ++ memblk->size = PAGE_ALIGN(memblk->size); ++ ++ pbuf = g2d_alloc (memblk->size, 0); ++ if (!pbuf) { ++ GST_ERROR("G2D allocate %u bytes memory failed: %s", ++ memblk->size, strerror(errno)); ++ return -1; ++ } ++ ++ memblk->vaddr = (guchar*) pbuf->buf_vaddr; ++ memblk->paddr = (guchar*) pbuf->buf_paddr; ++ memblk->user_data = (gpointer) pbuf; ++ GST_DEBUG("G2D allocated memory (%p)", memblk->paddr); ++ ++ return 1; ++} ++ ++static int ++free_phymem (GstAllocatorPhyMem *allocator, PhyMemBlock *memblk) ++{ ++ GST_DEBUG("G2D free memory (%p)", memblk->paddr); ++ gint ret = g2d_free ((struct g2d_buf*)(memblk->user_data)); ++ memblk->user_data = NULL; ++ memblk->vaddr = NULL; ++ memblk->paddr = NULL; ++ memblk->size = 0; ++ ++ return ret; ++} ++ ++static void ++gst_phy_mem_allocator_class_init (GstPhyMemAllocatorClass * klass) ++{ ++ GstAllocatorPhyMemClass *phy_allocator_klass = (GstAllocatorPhyMemClass *) klass; ++ ++ phy_allocator_klass->alloc_phymem = alloc_phymem; ++ phy_allocator_klass->free_phymem = free_phymem; ++} ++ ++static void ++gst_phy_mem_allocator_init (GstPhyMemAllocator * allocator) ++{ ++ GstAllocator *alloc = GST_ALLOCATOR_CAST (allocator); ++ ++ alloc->mem_type = GST_GL_PHY_MEM_ALLOCATOR; ++} ++ ++ ++static gpointer ++gst_phy_mem_allocator_init_instance (gpointer data) ++{ ++ GstAllocator *allocator = ++ g_object_new (gst_phy_mem_allocator_get_type (), NULL); ++ ++ GST_DEBUG_CATEGORY_INIT (GST_CAT_GL_PHY_MEMORY, "glphymemory", 0, ++ "GLPhysical Memory"); ++ ++ gst_allocator_register (GST_GL_PHY_MEM_ALLOCATOR, gst_object_ref (allocator)); ++ ++ return allocator; ++} ++ ++static void ++_finish_texture (GstGLContext * ctx, gpointer *data) ++{ ++ GstGLFuncs *gl = ctx->gl_vtable; ++ ++ gl->Finish (); ++} ++ ++static void ++gst_gl_phy_mem_destroy (GstMemory *mem) ++{ ++ gst_memory_unref (mem); ++} ++ ++ ++GstAllocator * ++gst_phy_mem_allocator_obtain (void) ++{ ++ static GOnce once = G_ONCE_INIT; ++ ++ g_once (&once, gst_phy_mem_allocator_init_instance, NULL); ++ ++ g_return_val_if_fail (once.retval != NULL, NULL); ++ ++ return (GstAllocator *) (g_object_ref (once.retval)); ++} ++ ++gboolean ++gst_is_gl_physical_memory (GstMemory * mem) ++{ ++ GstGLBaseMemory *glmem; ++ g_return_val_if_fail (gst_is_gl_memory (mem), FALSE); ++ ++ glmem = (GstGLBaseMemory*) mem; ++ ++ if (glmem->user_data ++ && GST_IS_MINI_OBJECT_TYPE(glmem->user_data, GST_TYPE_MEMORY)) ++ return gst_memory_is_type ((GstMemory*)glmem->user_data, GST_GL_PHY_MEM_ALLOCATOR); ++ else ++ return FALSE; ++} ++ ++gboolean ++gst_is_gl_physical_memory_supported_fmt (GstVideoInfo * info) ++{ ++ if (GST_VIDEO_INFO_IS_RGB(info) ++ && gst_gl_is_directviv_supported_format (GST_VIDEO_INFO_FORMAT (info))) { ++ return TRUE; ++ } ++ else ++ return FALSE; ++} ++ ++gboolean ++gst_gl_physical_memory_setup_buffer (GstAllocator * allocator, GstBuffer *buffer, ++ GstGLVideoAllocationParams * params) ++{ ++ GstGLBaseMemoryAllocator *gl_alloc; ++ GstMemory *mem = NULL; ++ PhyMemBlock *memblk = NULL; ++ GstGLMemory *glmem = NULL; ++ gsize size; ++ ++ GstVideoInfo * info = params->v_info; ++ GstVideoAlignment * valign = params->valign; ++ ++ GST_DEBUG ("glphymemory setup buffer format %s", gst_video_format_to_string (GST_VIDEO_INFO_FORMAT (info))); ++ ++ if (!gst_is_gl_physical_memory_supported_fmt (info)) { ++ GST_DEBUG ("Not support format."); ++ return FALSE; ++ } ++ ++ //allocator = (GstAllocator*) gst_phy_mem_allocator_obtain (); ++ size = gst_gl_get_plane_data_size (info, valign, 0); ++ mem = gst_allocator_alloc (allocator, size, params->parent.alloc_params); ++ if (!mem) { ++ GST_DEBUG ("Can't allocate physical memory size %d", size); ++ return FALSE; ++ } ++ ++ memblk = gst_memory_query_phymem_block (mem); ++ if (!memblk) { ++ GST_ERROR("Can't find physic memory block."); ++ return FALSE; ++ } ++ ++ gl_alloc = ++ GST_GL_BASE_MEMORY_ALLOCATOR (gst_gl_memory_allocator_get_default ++ (params->parent.context)); ++ ++ params->plane = 0; ++ params->parent.user_data = mem; ++ params->parent.notify = gst_gl_phy_mem_destroy; ++ ++ glmem = (GstGLMemory *)gst_gl_base_memory_alloc (gl_alloc, (GstGLAllocationParams *) params); ++ if (!glmem) { ++ GST_ERROR("Can't get gl memory."); ++ return FALSE; ++ } ++ ++ gst_buffer_append_memory (buffer, (GstMemory *) glmem); ++ ++ gst_buffer_add_video_meta_full (buffer, 0, ++ GST_VIDEO_INFO_FORMAT (info), GST_VIDEO_INFO_WIDTH (info), ++ GST_VIDEO_INFO_HEIGHT (info), 1, info->offset, info->stride); ++ ++ gst_gl_viv_direct_bind_data(params->parent.context, glmem->tex_id, ++ GST_VIDEO_INFO_FORMAT (info), GST_VIDEO_INFO_WIDTH (info), ++ GST_VIDEO_INFO_HEIGHT (info), memblk->vaddr, memblk->paddr); ++ ++ return TRUE; ++} ++ ++GstBuffer * ++gst_gl_phymem_buffer_to_gstbuffer (GstGLContext * ctx, ++ GstVideoInfo * info, GstBuffer *glbuf) ++{ ++ GstBuffer *buf; ++ GstGLBaseMemory *glmem; ++ ++ gst_gl_context_thread_add (ctx, (GstGLContextThreadFunc) _finish_texture, NULL); ++ ++ glmem = gst_buffer_peek_memory (glbuf, 0); ++ ++ buf = gst_buffer_new (); ++ gst_buffer_append_memory (buf, (GstMemory *) glmem->user_data); ++ gst_memory_ref ((GstMemory *)glmem->user_data); ++ ++ gst_buffer_add_video_meta_full (buf, 0, ++ GST_VIDEO_INFO_FORMAT (info), GST_VIDEO_INFO_WIDTH (info), ++ GST_VIDEO_INFO_HEIGHT (info), 1, info->offset, info->stride); ++ GST_BUFFER_FLAGS (buf) = GST_BUFFER_FLAGS (glbuf); ++ GST_BUFFER_PTS (buf) = GST_BUFFER_PTS (glbuf); ++ GST_BUFFER_DTS (buf) = GST_BUFFER_DTS (glbuf); ++ GST_BUFFER_DURATION (buf) = GST_BUFFER_DURATION (glbuf); ++ ++ return buf; ++} ++ +diff --git a/gst-libs/gst/gl/gstglphymemory.h b/gst-libs/gst/gl/gstglphymemory.h +new file mode 100644 +index 0000000..b1a69e7 +--- /dev/null ++++ b/gst-libs/gst/gl/gstglphymemory.h +@@ -0,0 +1,43 @@ ++/* ++ * GStreamer ++ * Copyright (c) 2015, Freescale Semiconductor, Inc. ++ * ++ * 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_PHY_MEMORY_H_ ++#define _GST_GL_PHY_MEMORY_H_ ++ ++#include ++#include ++#include ++#include ++ ++#include ++ ++G_BEGIN_DECLS ++ ++#define GST_GL_PHY_MEM_ALLOCATOR "GLPhyMemory" ++ ++GstAllocator *gst_phy_mem_allocator_obtain (void); ++gboolean gst_is_gl_physical_memory (GstMemory * mem); ++gboolean gst_is_gl_physical_memory_supported_fmt (GstVideoInfo * info); ++gboolean gst_gl_physical_memory_setup_buffer (GstAllocator * allocator, GstBuffer *buffer, GstGLVideoAllocationParams * params); ++GstBuffer * gst_gl_phymem_buffer_to_gstbuffer (GstGLContext * ctx, GstVideoInfo * info, GstBuffer *glbuf); ++ ++G_END_DECLS ++ ++#endif /* _GST_GL_PHY_MEMORY_H_ */ +diff --git a/gst-libs/gst/gl/gstglvivdirecttexture.c b/gst-libs/gst/gl/gstglvivdirecttexture.c +index c19b617..e8e0b82 100644 +--- a/gst-libs/gst/gl/gstglvivdirecttexture.c ++++ b/gst-libs/gst/gl/gstglvivdirecttexture.c +@@ -22,6 +22,7 @@ + #include "config.h" + #endif + ++#include + #include "gl.h" + + GST_DEBUG_CATEGORY_EXTERN (gst_gl_upload_debug); +@@ -37,17 +38,28 @@ typedef struct { + gboolean ret; + } GstVivDirectTexture; + ++typedef struct { ++ GstVideoFormat gst_fmt; ++ guint viv_fmt; ++} VIV_FMT_MAP; ++ ++static VIV_FMT_MAP viv_fmt_map_table[] = { ++ {GST_VIDEO_FORMAT_I420, GL_VIV_I420}, ++ {GST_VIDEO_FORMAT_YV12, GL_VIV_YV12}, ++ {GST_VIDEO_FORMAT_NV12, GL_VIV_NV12}, ++ {GST_VIDEO_FORMAT_NV21, GL_VIV_NV21}, ++ {GST_VIDEO_FORMAT_YUY2, GL_VIV_YUY2}, ++ {GST_VIDEO_FORMAT_UYVY, GL_VIV_UYVY}, ++ {GST_VIDEO_FORMAT_RGBA, GL_RGBA}, ++ {GST_VIDEO_FORMAT_RGBx, GL_RGBA}, ++ {GST_VIDEO_FORMAT_BGRA, GL_BGRA_EXT}, ++ {GST_VIDEO_FORMAT_RGB16, GL_RGB565_OES} ++}; ++ + gboolean + gst_is_physical_buffer (GstBuffer *buffer) + { +- +- GstMemory *mem; +- +- mem = gst_buffer_peek_memory (buffer, 0); +- if (!mem->allocator) +- return FALSE; +- +- return g_type_check_instance_is_a (mem->allocator, g_type_from_name("GstAllocatorPhyMem")); ++ return gst_buffer_is_phymem (buffer); + } + + static void +@@ -65,32 +77,64 @@ _do_viv_direct_tex_bind_mem (GstGLContext * context, GstVivDirectTexture * viv_t + } + + gboolean ++gst_gl_is_directviv_supported_format (GstVideoFormat fmt) ++{ ++ gint i; ++ gboolean ret = FALSE; ++ ++ for (i=0; iblock; +- +- GstVideoFormat fmt = GST_VIDEO_INFO_FORMAT (info); ++ PhyMemBlock *memblk; ++ GstVideoMeta *vmeta; ++ GstVideoFormat fmt; + gint width, height; +- GstVideoMeta *vmeta = gst_buffer_get_video_meta (buffer); ++ ++ memblk = gst_buffer_query_phymem_block (buffer); ++ if (!memblk) ++ return FALSE; ++ ++ width = GST_VIDEO_INFO_WIDTH (info); ++ height = GST_VIDEO_INFO_HEIGHT (info); ++ ++ vmeta = gst_buffer_get_video_meta (buffer); ++ fmt = GST_VIDEO_INFO_FORMAT (info); + if (vmeta && (fmt == GST_VIDEO_FORMAT_I420 || fmt == GST_VIDEO_FORMAT_NV12)) { + width = vmeta->stride[0]; + height = vmeta->offset[1] / width; +@@ -100,44 +144,7 @@ gst_gl_viv_direct_bind_gstbuffer (GstGLContext * context, guint tex_id, GstVideo + height = GST_VIDEO_INFO_HEIGHT (info); + } + +- guint viv_fmt; +- switch (fmt) { +- case GST_VIDEO_FORMAT_I420: +- viv_fmt = GL_VIV_I420; +- break; +- case GST_VIDEO_FORMAT_YV12: +- viv_fmt = GL_VIV_YV12; +- break; +- case GST_VIDEO_FORMAT_NV12: +- viv_fmt = GL_VIV_NV12; +- break; +- case GST_VIDEO_FORMAT_NV21: +- viv_fmt = GL_VIV_NV21; +- break; +- case GST_VIDEO_FORMAT_YUY2: +- viv_fmt = GL_VIV_YUY2; +- break; +- case GST_VIDEO_FORMAT_UYVY: +- viv_fmt = GL_VIV_UYVY; +- break; +- case GST_VIDEO_FORMAT_RGBA: +- viv_fmt = GL_RGBA; +- break; +- case GST_VIDEO_FORMAT_BGRA: +- viv_fmt = GL_BGRA_EXT; +- break; +- case GST_VIDEO_FORMAT_RGB16: +- viv_fmt = GL_RGB565_OES; +- break; +- default: +- GST_ERROR ("Not supported format %d for viv direct texture upload.", fmt); +- viv_fmt = GL_NONE; +- return FALSE; +- } +- +- GstVivDirectTexture viv_tex = {tex_id, width, height, viv_fmt, memblk->vaddr, memblk->paddr, FALSE}; +- gst_gl_context_thread_add (context, (GstGLContextThreadFunc) _do_viv_direct_tex_bind_mem, &viv_tex); +- +- return viv_tex.ret; ++ return gst_gl_viv_direct_bind_data (context, tex_id, fmt, width, height, memblk->vaddr, memblk->paddr); + } + ++ +diff --git a/gst-libs/gst/gl/gstglvivdirecttexture.h b/gst-libs/gst/gl/gstglvivdirecttexture.h +index fa88e1a..9a2d123 100644 +--- a/gst-libs/gst/gl/gstglvivdirecttexture.h ++++ b/gst-libs/gst/gl/gstglvivdirecttexture.h +@@ -28,6 +28,9 @@ + G_BEGIN_DECLS + + gboolean gst_is_physical_buffer (GstBuffer *buffer); ++gboolean gst_gl_is_directviv_supported_format (GstVideoFormat fmt); ++gboolean gst_gl_viv_direct_bind_data (GstGLContext * context, guint tex_id, GstVideoFormat fmt, gint width, gint height, ++ gpointer * vaddr, gpointer *paddr); + gboolean gst_gl_viv_direct_bind_gstbuffer (GstGLContext * context, guint tex_id, GstVideoInfo * info, GstBuffer * buffer); + + G_END_DECLS +-- +1.9.1 + diff --git a/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0005-Fix-dependence-issue-between-gst-plugin-.patch b/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0005-Fix-dependence-issue-between-gst-plugin-.patch new file mode 100755 index 000000000..44633cf91 --- /dev/null +++ b/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0005-Fix-dependence-issue-between-gst-plugin-.patch @@ -0,0 +1,74 @@ +From 4f73ba8dde190b0e2d3a7a16b394762f7459ca31 Mon Sep 17 00:00:00 2001 +From: Haihua Hu +Date: Fri, 5 Aug 2016 17:04:02 +0800 +Subject: [PATCH] [MMFMWK-7259]Fix dependence issue between gst-plugin-bad and + imx-gst1.0-plugin + +Change dependence to gst-plugin-base since we have move physical memory allocator +to gst-plugin-base + +Upstream-Status: Inappropriate [i.MX specific] + +Signed-off-by: Haihua Hu +--- + gst-libs/gst/gl/Makefile.am | 2 +- + gst-libs/gst/gl/gstglphymemory.c | 2 +- + gst-libs/gst/gl/gstglphymemory.h | 2 +- + gst-libs/gst/gl/gstglvivdirecttexture.c | 2 +- + 4 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/gst-libs/gst/gl/Makefile.am b/gst-libs/gst/gl/Makefile.am +index 5c05230..55f8a20 100644 +--- a/gst-libs/gst/gl/Makefile.am ++++ b/gst-libs/gst/gl/Makefile.am +@@ -86,7 +86,7 @@ libgstgl_@GST_API_VERSION@_la_LIBADD = \ + $(GST_LIBS) \ + $(GL_LIBS) + +-libgstgl_@GST_API_VERSION@_la_LIBADD += -lgstfsl-$(GST_API_VERSION) ++libgstgl_@GST_API_VERSION@_la_LIBADD += -lg2d + + if HAVE_WINDOW_WIN32 + SUBDIRS += win32 +diff --git a/gst-libs/gst/gl/gstglphymemory.c b/gst-libs/gst/gl/gstglphymemory.c +index 52ae41f..e28546c 100644 +--- a/gst-libs/gst/gl/gstglphymemory.c ++++ b/gst-libs/gst/gl/gstglphymemory.c +@@ -24,7 +24,7 @@ + + #include "gstglvivdirecttexture.h" + #include "gstglphymemory.h" +-#include "g2d.h" ++#include + + GST_DEBUG_CATEGORY_STATIC (GST_CAT_GL_PHY_MEMORY); + #define GST_CAT_DEFAULT GST_CAT_GL_PHY_MEMORY +diff --git a/gst-libs/gst/gl/gstglphymemory.h b/gst-libs/gst/gl/gstglphymemory.h +index b1a69e7..ebb9911 100644 +--- a/gst-libs/gst/gl/gstglphymemory.h ++++ b/gst-libs/gst/gl/gstglphymemory.h +@@ -24,7 +24,7 @@ + #include + #include + #include +-#include ++#include + + #include + +diff --git a/gst-libs/gst/gl/gstglvivdirecttexture.c b/gst-libs/gst/gl/gstglvivdirecttexture.c +index e8e0b82..242b7c0 100644 +--- a/gst-libs/gst/gl/gstglvivdirecttexture.c ++++ b/gst-libs/gst/gl/gstglvivdirecttexture.c +@@ -22,7 +22,7 @@ + #include "config.h" + #endif + +-#include ++#include + #include "gl.h" + + GST_DEBUG_CATEGORY_EXTERN (gst_gl_upload_debug); +-- +1.9.1 + diff --git a/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0005-glcolorconvert-convert-YUV-to-RGB-use-directviv.patch b/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0005-glcolorconvert-convert-YUV-to-RGB-use-directviv.patch deleted file mode 100644 index aac204d13..000000000 --- a/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0005-glcolorconvert-convert-YUV-to-RGB-use-directviv.patch +++ /dev/null @@ -1,170 +0,0 @@ -From 67d11594e693b60797c2bae1bcfa4e8bafcf4c9a Mon Sep 17 00:00:00 2001 -From: Haihua Hu -Date: Thu, 25 Feb 2016 13:53:20 +0800 -Subject: [PATCH 17/18] glcolorconvert: convert YUV to RGB use directviv - -Add a property "disable_passthrough" in glcolorconvert for enable/disable passthrough. -When need convert YUV to RGB with directviv, set it to be TRUE. - -Upstream-Status: Inappropriate [i.MX specific] - -Signed-off-by: Haihua Hu - -Conflicts: - gst-libs/gst/gl/gstglcolorconvert.c - -Signed-off-by: Lyon Wang ---- - ext/gl/gstglcolorconvertelement.c | 70 +++++++++++++++++++++++++++++++++++++ - ext/gl/gstglcolorconvertelement.h | 1 + - gst-libs/gst/gl/gstglcolorconvert.c | 6 +++- - 3 files changed, 76 insertions(+), 1 deletion(-) - -diff --git a/ext/gl/gstglcolorconvertelement.c b/ext/gl/gstglcolorconvertelement.c -index bd4fbeb..9108b0a 100644 ---- a/ext/gl/gstglcolorconvertelement.c -+++ b/ext/gl/gstglcolorconvertelement.c -@@ -35,6 +35,14 @@ G_DEFINE_TYPE_WITH_CODE (GstGLColorConvertElement, gst_gl_color_convert_element, - "glconvertelement", 0, "convert"); - ); - -+enum -+{ -+ GL_COLOR_CONVERT_PROP_0, -+ GL_COLOR_CONVERT_PROP_DISABLE_PASSTHROUGH -+}; -+ -+#define DISABLE_PASSTHROUGH_DAFAULT FALSE -+ - static gboolean gst_gl_color_convert_element_set_caps (GstBaseTransform * bt, - GstCaps * in_caps, GstCaps * out_caps); - static GstCaps *gst_gl_color_convert_element_transform_caps (GstBaseTransform * -@@ -54,6 +62,15 @@ static GstFlowReturn gst_gl_color_convert_element_transform (GstBaseTransform * - static GstCaps *gst_gl_color_convert_element_fixate_caps (GstBaseTransform * - bt, GstPadDirection direction, GstCaps * caps, GstCaps * othercaps); - -+static void gst_gl_color_convert_set_property (GObject *object, -+ guint prop_id, -+ const GValue *value, -+ GParamSpec *pspec); -+static void gst_gl_color_convert_get_property (GObject *object, -+ guint prop_id, -+ GValue *value, -+ GParamSpec *pspec); -+ - static GstStaticPadTemplate gst_gl_color_convert_element_src_pad_template = - GST_STATIC_PAD_TEMPLATE ("src", - GST_PAD_SRC, -@@ -89,6 +106,10 @@ gst_gl_color_convert_element_class_init (GstGLColorConvertElementClass * klass) - { - GstBaseTransformClass *bt_class = GST_BASE_TRANSFORM_CLASS (klass); - GstElementClass *element_class = GST_ELEMENT_CLASS (klass); -+ GObjectClass *object_class = G_OBJECT_CLASS (klass); -+ -+ object_class->set_property = gst_gl_color_convert_set_property; -+ object_class->get_property = gst_gl_color_convert_get_property; - - bt_class->transform_caps = gst_gl_color_convert_element_transform_caps; - bt_class->set_caps = gst_gl_color_convert_element_set_caps; -@@ -110,6 +131,13 @@ gst_gl_color_convert_element_class_init (GstGLColorConvertElementClass * klass) - gst_static_pad_template_get - (&gst_gl_color_convert_element_sink_pad_template)); - -+ g_object_class_install_property (object_class, GL_COLOR_CONVERT_PROP_DISABLE_PASSTHROUGH, -+ g_param_spec_boolean ("disable_passthrough", -+ "Disable passthrough", -+ "Disable passthrough mode", -+ DISABLE_PASSTHROUGH_DAFAULT, -+ G_PARAM_READWRITE)); -+ - gst_element_class_set_metadata (element_class, - "OpenGL color converter", "Filter/Converter/Video", - "Converts between color spaces using OpenGL shaders", -@@ -121,6 +149,41 @@ gst_gl_color_convert_element_init (GstGLColorConvertElement * convert) - { - gst_base_transform_set_prefer_passthrough (GST_BASE_TRANSFORM (convert), - TRUE); -+ convert->disable_passthrough = FALSE; -+} -+ -+static void -+gst_gl_color_convert_set_property (GObject *object, -+ guint prop_id, -+ const GValue *value, -+ GParamSpec *pspec) -+{ -+ GstGLColorConvertElement *convert = GST_GL_COLOR_CONVERT_ELEMENT (object); -+ switch (prop_id) { -+ case GL_COLOR_CONVERT_PROP_DISABLE_PASSTHROUGH: -+ convert->disable_passthrough = g_value_get_boolean (value); -+ break; -+ default: -+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); -+ break; -+ } -+} -+ -+static void -+gst_gl_color_convert_get_property (GObject *object, -+ guint prop_id, -+ GValue *value, -+ GParamSpec *pspec) -+{ -+ GstGLColorConvertElement *convert = GST_GL_COLOR_CONVERT_ELEMENT (object); -+ switch (prop_id) { -+ case GL_COLOR_CONVERT_PROP_DISABLE_PASSTHROUGH: -+ g_value_set_boolean (value, convert->disable_passthrough); -+ break; -+ default: -+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); -+ break; -+ } - } - - static gboolean -@@ -135,6 +198,13 @@ gst_gl_color_convert_element_set_caps (GstBaseTransform * bt, - if (convert->convert) - gst_gl_color_convert_set_caps (convert->convert, in_caps, out_caps); - -+ if(gst_base_transform_is_passthrough (bt) && convert->disable_passthrough){ -+ /* if in passthrough mode and disable_passthrough is set to true, -+ * set passthrough to FALSE*/ -+ GST_DEBUG_OBJECT(convert, "Disable passthrough mode"); -+ gst_base_transform_set_passthrough(bt, FALSE); -+ } -+ - return TRUE; - } - -diff --git a/ext/gl/gstglcolorconvertelement.h b/ext/gl/gstglcolorconvertelement.h -index 2a0dd1d..5cdbd3a 100644 ---- a/ext/gl/gstglcolorconvertelement.h -+++ b/ext/gl/gstglcolorconvertelement.h -@@ -47,6 +47,7 @@ struct _GstGLColorConvertElement - GstGLColorConvert *convert; - GstCaps *in_caps; - GstCaps *out_caps; -+ gboolean disable_passthrough; - }; - - struct _GstGLColorConvertElementClass -diff --git a/gst-libs/gst/gl/gstglcolorconvert.c b/gst-libs/gst/gl/gstglcolorconvert.c -index eb3b4a8..4ed947e 100644 ---- a/gst-libs/gst/gl/gstglcolorconvert.c -+++ b/gst-libs/gst/gl/gstglcolorconvert.c -@@ -700,7 +700,11 @@ _gst_gl_color_convert_set_caps_unlocked (GstGLColorConvert * convert, - convert->priv->to_texture_target = to_target; - convert->initted = FALSE; - -- convert->passthrough = passthrough; -+ /* We may disable passthrough via an external property -+ * By the way, when glconvertelement is in passthrough mode, -+ * the plugin will not call gst_gl_color_convert_perform().*/ -+ -+ //convert->passthrough = passthrough; - #ifndef GST_DISABLE_GST_DEBUG - if (G_UNLIKELY (convert->passthrough)) - GST_DEBUG_OBJECT (convert, --- -1.9.1 - diff --git a/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0006-glcolorconvert-convert-YUV-to-RGB-use-directviv.patch b/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0006-glcolorconvert-convert-YUV-to-RGB-use-directviv.patch new file mode 100644 index 000000000..aac204d13 --- /dev/null +++ b/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0006-glcolorconvert-convert-YUV-to-RGB-use-directviv.patch @@ -0,0 +1,170 @@ +From 67d11594e693b60797c2bae1bcfa4e8bafcf4c9a Mon Sep 17 00:00:00 2001 +From: Haihua Hu +Date: Thu, 25 Feb 2016 13:53:20 +0800 +Subject: [PATCH 17/18] glcolorconvert: convert YUV to RGB use directviv + +Add a property "disable_passthrough" in glcolorconvert for enable/disable passthrough. +When need convert YUV to RGB with directviv, set it to be TRUE. + +Upstream-Status: Inappropriate [i.MX specific] + +Signed-off-by: Haihua Hu + +Conflicts: + gst-libs/gst/gl/gstglcolorconvert.c + +Signed-off-by: Lyon Wang +--- + ext/gl/gstglcolorconvertelement.c | 70 +++++++++++++++++++++++++++++++++++++ + ext/gl/gstglcolorconvertelement.h | 1 + + gst-libs/gst/gl/gstglcolorconvert.c | 6 +++- + 3 files changed, 76 insertions(+), 1 deletion(-) + +diff --git a/ext/gl/gstglcolorconvertelement.c b/ext/gl/gstglcolorconvertelement.c +index bd4fbeb..9108b0a 100644 +--- a/ext/gl/gstglcolorconvertelement.c ++++ b/ext/gl/gstglcolorconvertelement.c +@@ -35,6 +35,14 @@ G_DEFINE_TYPE_WITH_CODE (GstGLColorConvertElement, gst_gl_color_convert_element, + "glconvertelement", 0, "convert"); + ); + ++enum ++{ ++ GL_COLOR_CONVERT_PROP_0, ++ GL_COLOR_CONVERT_PROP_DISABLE_PASSTHROUGH ++}; ++ ++#define DISABLE_PASSTHROUGH_DAFAULT FALSE ++ + static gboolean gst_gl_color_convert_element_set_caps (GstBaseTransform * bt, + GstCaps * in_caps, GstCaps * out_caps); + static GstCaps *gst_gl_color_convert_element_transform_caps (GstBaseTransform * +@@ -54,6 +62,15 @@ static GstFlowReturn gst_gl_color_convert_element_transform (GstBaseTransform * + static GstCaps *gst_gl_color_convert_element_fixate_caps (GstBaseTransform * + bt, GstPadDirection direction, GstCaps * caps, GstCaps * othercaps); + ++static void gst_gl_color_convert_set_property (GObject *object, ++ guint prop_id, ++ const GValue *value, ++ GParamSpec *pspec); ++static void gst_gl_color_convert_get_property (GObject *object, ++ guint prop_id, ++ GValue *value, ++ GParamSpec *pspec); ++ + static GstStaticPadTemplate gst_gl_color_convert_element_src_pad_template = + GST_STATIC_PAD_TEMPLATE ("src", + GST_PAD_SRC, +@@ -89,6 +106,10 @@ gst_gl_color_convert_element_class_init (GstGLColorConvertElementClass * klass) + { + GstBaseTransformClass *bt_class = GST_BASE_TRANSFORM_CLASS (klass); + GstElementClass *element_class = GST_ELEMENT_CLASS (klass); ++ GObjectClass *object_class = G_OBJECT_CLASS (klass); ++ ++ object_class->set_property = gst_gl_color_convert_set_property; ++ object_class->get_property = gst_gl_color_convert_get_property; + + bt_class->transform_caps = gst_gl_color_convert_element_transform_caps; + bt_class->set_caps = gst_gl_color_convert_element_set_caps; +@@ -110,6 +131,13 @@ gst_gl_color_convert_element_class_init (GstGLColorConvertElementClass * klass) + gst_static_pad_template_get + (&gst_gl_color_convert_element_sink_pad_template)); + ++ g_object_class_install_property (object_class, GL_COLOR_CONVERT_PROP_DISABLE_PASSTHROUGH, ++ g_param_spec_boolean ("disable_passthrough", ++ "Disable passthrough", ++ "Disable passthrough mode", ++ DISABLE_PASSTHROUGH_DAFAULT, ++ G_PARAM_READWRITE)); ++ + gst_element_class_set_metadata (element_class, + "OpenGL color converter", "Filter/Converter/Video", + "Converts between color spaces using OpenGL shaders", +@@ -121,6 +149,41 @@ gst_gl_color_convert_element_init (GstGLColorConvertElement * convert) + { + gst_base_transform_set_prefer_passthrough (GST_BASE_TRANSFORM (convert), + TRUE); ++ convert->disable_passthrough = FALSE; ++} ++ ++static void ++gst_gl_color_convert_set_property (GObject *object, ++ guint prop_id, ++ const GValue *value, ++ GParamSpec *pspec) ++{ ++ GstGLColorConvertElement *convert = GST_GL_COLOR_CONVERT_ELEMENT (object); ++ switch (prop_id) { ++ case GL_COLOR_CONVERT_PROP_DISABLE_PASSTHROUGH: ++ convert->disable_passthrough = g_value_get_boolean (value); ++ break; ++ default: ++ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); ++ break; ++ } ++} ++ ++static void ++gst_gl_color_convert_get_property (GObject *object, ++ guint prop_id, ++ GValue *value, ++ GParamSpec *pspec) ++{ ++ GstGLColorConvertElement *convert = GST_GL_COLOR_CONVERT_ELEMENT (object); ++ switch (prop_id) { ++ case GL_COLOR_CONVERT_PROP_DISABLE_PASSTHROUGH: ++ g_value_set_boolean (value, convert->disable_passthrough); ++ break; ++ default: ++ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); ++ break; ++ } + } + + static gboolean +@@ -135,6 +198,13 @@ gst_gl_color_convert_element_set_caps (GstBaseTransform * bt, + if (convert->convert) + gst_gl_color_convert_set_caps (convert->convert, in_caps, out_caps); + ++ if(gst_base_transform_is_passthrough (bt) && convert->disable_passthrough){ ++ /* if in passthrough mode and disable_passthrough is set to true, ++ * set passthrough to FALSE*/ ++ GST_DEBUG_OBJECT(convert, "Disable passthrough mode"); ++ gst_base_transform_set_passthrough(bt, FALSE); ++ } ++ + return TRUE; + } + +diff --git a/ext/gl/gstglcolorconvertelement.h b/ext/gl/gstglcolorconvertelement.h +index 2a0dd1d..5cdbd3a 100644 +--- a/ext/gl/gstglcolorconvertelement.h ++++ b/ext/gl/gstglcolorconvertelement.h +@@ -47,6 +47,7 @@ struct _GstGLColorConvertElement + GstGLColorConvert *convert; + GstCaps *in_caps; + GstCaps *out_caps; ++ gboolean disable_passthrough; + }; + + struct _GstGLColorConvertElementClass +diff --git a/gst-libs/gst/gl/gstglcolorconvert.c b/gst-libs/gst/gl/gstglcolorconvert.c +index eb3b4a8..4ed947e 100644 +--- a/gst-libs/gst/gl/gstglcolorconvert.c ++++ b/gst-libs/gst/gl/gstglcolorconvert.c +@@ -700,7 +700,11 @@ _gst_gl_color_convert_set_caps_unlocked (GstGLColorConvert * convert, + convert->priv->to_texture_target = to_target; + convert->initted = FALSE; + +- convert->passthrough = passthrough; ++ /* We may disable passthrough via an external property ++ * By the way, when glconvertelement is in passthrough mode, ++ * the plugin will not call gst_gl_color_convert_perform().*/ ++ ++ //convert->passthrough = passthrough; + #ifndef GST_DISABLE_GST_DEBUG + if (G_UNLIKELY (convert->passthrough)) + GST_DEBUG_OBJECT (convert, +-- +1.9.1 + diff --git a/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0006-glwindow-work-around-for-no-frame-when-imxplayer-use.patch b/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0006-glwindow-work-around-for-no-frame-when-imxplayer-use.patch deleted file mode 100644 index de53df428..000000000 --- a/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0006-glwindow-work-around-for-no-frame-when-imxplayer-use.patch +++ /dev/null @@ -1,63 +0,0 @@ -From 61b6bc77cb939a778e2ddfee68d0378680f69f71 Mon Sep 17 00:00:00 2001 -From: Haihua Hu -Date: Wed, 9 Mar 2016 13:00:39 +0800 -Subject: [PATCH 18/18] glwindow: work around for no frame when imxplayer use - glimagesink - -change parent window of internal_window in window_show function. - -Upstream-Status: Inappropriate [i.MX specific] - -Signed-off-by: Haihua Hu -Signed-off-by: Lyon Wang ---- - gst-libs/gst/gl/x11/gstglwindow_x11.c | 14 +++++++++++--- - 1 file changed, 11 insertions(+), 3 deletions(-) - -diff --git a/gst-libs/gst/gl/x11/gstglwindow_x11.c b/gst-libs/gst/gl/x11/gstglwindow_x11.c -index a330825..67160f6 100644 ---- a/gst-libs/gst/gl/x11/gstglwindow_x11.c -+++ b/gst-libs/gst/gl/x11/gstglwindow_x11.c -@@ -322,13 +322,13 @@ gst_gl_window_x11_set_window_handle (GstGLWindow * window, guintptr id) - g_main_context_get_thread_default ()); - } - -- XGetWindowAttributes (window_x11->device, window_x11->parent_win, &attr); -+ /*XGetWindowAttributes (window_x11->device, window_x11->parent_win, &attr); - - XResizeWindow (window_x11->device, window_x11->internal_win_id, - attr.width, attr.height); - - XReparentWindow (window_x11->device, window_x11->internal_win_id, -- window_x11->parent_win, 0, 0); -+ window_x11->parent_win, 0, 0);*/ - - XSync (window_x11->device, FALSE); - } -@@ -359,7 +359,7 @@ _show_window (GstGLWindow * window) - GstGLWindowX11 *window_x11 = GST_GL_WINDOW_X11 (window); - guint width = window_x11->priv->preferred_width; - guint height = window_x11->priv->preferred_height; -- XWindowAttributes attr; -+ XWindowAttributes attr, parent_attr; - - XGetWindowAttributes (window_x11->device, window_x11->internal_win_id, &attr); - -@@ -371,6 +371,14 @@ _show_window (GstGLWindow * window) - XResizeWindow (window_x11->device, window_x11->internal_win_id, - attr.width, attr.height); - XSync (window_x11->device, FALSE); -+ }else{ -+ XGetWindowAttributes (window_x11->device, window_x11->parent_win, &parent_attr); -+ -+ XResizeWindow (window_x11->device, window_x11->internal_win_id, -+ parent_attr.width, parent_attr.height); -+ -+ XReparentWindow (window_x11->device, window_x11->internal_win_id, -+ window_x11->parent_win, 0, 0); - } - - XMapWindow (window_x11->device, window_x11->internal_win_id); --- -1.9.1 - diff --git a/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0007-glplugin-glcolorconvert-fix-MRT-cannot-work-in-GLES3.patch b/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0007-glplugin-glcolorconvert-fix-MRT-cannot-work-in-GLES3.patch deleted file mode 100755 index d4858328f..000000000 --- a/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0007-glplugin-glcolorconvert-fix-MRT-cannot-work-in-GLES3.patch +++ /dev/null @@ -1,168 +0,0 @@ -From 5b4e2d726602b0c92b789fce0dc85a1f0c860bbc Mon Sep 17 00:00:00 2001 -From: Haihua Hu -Date: Wed, 20 Apr 2016 16:38:31 +0800 -Subject: [PATCH 3/6] [glplugin] glcolorconvert: fix MRT cannot work in GLES3.0 - -1. Add #ifdefine Marco to avoid redefinition of GL_COLOR_ATTACHMENT(1,2). -2. Change to use glBlitFramebuffer for textures copy. glCopyTexImage2D - cannot work because we cannot get texture internal format. - -Upstream-Status: Inappropriate [i.MX specific] - -Signed-off-by: Haihua Hu ---- - gst-libs/gst/gl/glprototypes/fbo.h | 6 +-- - gst-libs/gst/gl/glprototypes/gstgl_gles2compat.h | 7 +-- - gst-libs/gst/gl/gstglcolorconvert.c | 2 +- - gst-libs/gst/gl/gstglmemory.c | 54 +++++++++++++++++++++--- - 4 files changed, 55 insertions(+), 14 deletions(-) - -diff --git a/gst-libs/gst/gl/glprototypes/fbo.h b/gst-libs/gst/gl/glprototypes/fbo.h -index d142483..789f289 100644 ---- a/gst-libs/gst/gl/glprototypes/fbo.h -+++ b/gst-libs/gst/gl/glprototypes/fbo.h -@@ -102,9 +102,9 @@ GST_GL_EXT_FUNCTION (GLboolean, IsFramebuffer, - GST_GL_EXT_END () - - GST_GL_EXT_BEGIN (offscreen_blit, -- GST_GL_API_NONE, -- 255, 255, -- 255, 255, /* not in either GLES */ -+ GST_GL_API_OPENGL3 | GST_GL_API_GLES2, -+ 3, 0, -+ 3, 0,/* enable to avoid using glCopyTexImage2D for texture copying */ - "EXT\0ANGLE\0", - "framebuffer_blit\0") - GST_GL_EXT_FUNCTION (void, BlitFramebuffer, -diff --git a/gst-libs/gst/gl/glprototypes/gstgl_gles2compat.h b/gst-libs/gst/gl/glprototypes/gstgl_gles2compat.h -index d282990..1980476 100644 ---- a/gst-libs/gst/gl/glprototypes/gstgl_gles2compat.h -+++ b/gst-libs/gst/gl/glprototypes/gstgl_gles2compat.h -@@ -34,9 +34,10 @@ G_BEGIN_DECLS - //END FIXME - - /* UNSUPPORTED */ -- --#define GL_COLOR_ATTACHMENT1 0 --#define GL_COLOR_ATTACHMENT2 0 -+#ifndef GL_COLOR_ATTACHMENT1 -+#define GL_COLOR_ATTACHMENT1 0x8CE1 -+#define GL_COLOR_ATTACHMENT2 0x8CE2 -+#endif - #ifndef GL_TEXTURE_ENV - #define GL_TEXTURE_ENV 0 - #endif -diff --git a/gst-libs/gst/gl/gstglcolorconvert.c b/gst-libs/gst/gl/gstglcolorconvert.c -index 4ed947e..490ec54 100644 ---- a/gst-libs/gst/gl/gstglcolorconvert.c -+++ b/gst-libs/gst/gl/gstglcolorconvert.c -@@ -2075,7 +2075,7 @@ _init_convert (GstGLColorConvert * convert) - } - - /* Requires reading from a RG/LA framebuffer... */ -- if (USING_GLES2 (convert->context) && -+ if (!USING_GLES3 (convert->context) && - (GST_VIDEO_INFO_FORMAT (&convert->out_info) == GST_VIDEO_FORMAT_YUY2 || - GST_VIDEO_INFO_FORMAT (&convert->out_info) == - GST_VIDEO_FORMAT_UYVY)) { -diff --git a/gst-libs/gst/gl/gstglmemory.c b/gst-libs/gst/gl/gstglmemory.c -index 402fd4d..f2706ea 100644 ---- a/gst-libs/gst/gl/gstglmemory.c -+++ b/gst-libs/gst/gl/gstglmemory.c -@@ -69,6 +69,12 @@ GST_DEBUG_CATEGORY_STATIC (GST_CAT_GL_MEMORY); - #ifndef GL_TEXTURE_EXTERNAL_OES - #define GL_TEXTURE_EXTERNAL_OES 0x8D65 - #endif -+#ifndef GL_READ_FRAMEBUFFER -+#define GL_READ_FRAMEBUFFER 0x8CA8 -+#endif -+#ifndef GL_DRAW_FRAMEBUFFER -+#define GL_DRAW_FRAMEBUFFER 0x8CA9 -+#endif - - G_DEFINE_TYPE (GstGLMemoryAllocator, gst_gl_memory_allocator, - GST_TYPE_GL_BASE_MEMORY_ALLOCATOR); -@@ -608,7 +614,7 @@ gst_gl_memory_copy_teximage (GstGLMemory * src, guint tex_id, - guint out_gl_format, out_tex_target; - GstMapInfo sinfo; - guint src_tex_id; -- guint fbo; -+ guint fbo[2]; - - gl = src->mem.context->gl_vtable; - out_tex_target = gst_gl_texture_target_to_gl (out_target); -@@ -632,31 +638,65 @@ gst_gl_memory_copy_teximage (GstGLMemory * src, guint tex_id, - - /* FIXME: try and avoid creating and destroying fbo's every copy... */ - /* create a framebuffer object */ -- gl->GenFramebuffers (1, &fbo); -- gl->BindFramebuffer (GL_FRAMEBUFFER, fbo); -+ gl->GenFramebuffers (2, &fbo[0]); -+ gl->BindFramebuffer (GL_READ_FRAMEBUFFER, fbo[0]); - -- gl->FramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, -+ gl->FramebufferTexture2D (GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, - gst_gl_texture_target_to_gl (src->tex_target), src_tex_id, 0); - --// if (!gst_gl_context_check_framebuffer_status (src->context)) --// goto fbo_error; -+ if (!gst_gl_context_check_framebuffer_status (src->mem.context)) -+ goto fbo_error; -+ -+ gl->BindFramebuffer (GL_DRAW_FRAMEBUFFER, fbo[1]); -+ -+ gl->FramebufferTexture2D (GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, -+ gst_gl_texture_target_to_gl (src->tex_target), tex_id, 0); - -+ if (!gst_gl_context_check_framebuffer_status (src->mem.context)) -+ goto fbo_error; -+ -+ /* - gl->BindTexture (out_tex_target, tex_id); - gst_gl_query_start_log (GST_GL_BASE_MEMORY_CAST (src)->query, - GST_CAT_GL_MEMORY, GST_LEVEL_LOG, NULL, "%s", "CopyTexImage2D took"); - gl->CopyTexImage2D (out_tex_target, 0, out_gl_format, 0, 0, out_width, - out_height, 0); - gst_gl_query_end (GST_GL_BASE_MEMORY_CAST (src)->query); -+ */ -+ -+ /* -+ * glCopyTexImage2D cannot work without internal_format -+ * we cannot get the internal_format in this function -+ * so use glBlitFramebuffer for texture copy -+ */ -+ GST_CAT_LOG(GST_CAT_GL_MEMORY,"Use BlitFramebuffer copy texture %d into %d", -+ src_tex_id, tex_id); -+ gl->ReadBuffer ( GL_COLOR_ATTACHMENT0 ); -+ gl->BlitFramebuffer ( 0, 0, out_width, out_height, -+ 0, 0, out_width, out_height, -+ GL_COLOR_BUFFER_BIT, GL_LINEAR ); - - gl->BindTexture (out_tex_target, 0); - gl->BindFramebuffer (GL_FRAMEBUFFER, 0); - -- gl->DeleteFramebuffers (1, &fbo); -+ gl->DeleteFramebuffers (2, &fbo[0]); - - gst_memory_unmap (GST_MEMORY_CAST (src), &sinfo); - - return TRUE; - -+fbo_error: -+ { -+ gl->BindTexture (out_tex_target, 0); -+ gl->BindFramebuffer (GL_FRAMEBUFFER, 0); -+ -+ gl->DeleteFramebuffers (2, &fbo[0]); -+ -+ gst_memory_unmap (GST_MEMORY_CAST (src), &sinfo); -+ -+ return FALSE; -+ } -+ - error: - return FALSE; - } --- -1.9.1 - diff --git a/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0007-glwindow-work-around-for-no-frame-when-imxplayer-use.patch b/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0007-glwindow-work-around-for-no-frame-when-imxplayer-use.patch new file mode 100644 index 000000000..de53df428 --- /dev/null +++ b/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0007-glwindow-work-around-for-no-frame-when-imxplayer-use.patch @@ -0,0 +1,63 @@ +From 61b6bc77cb939a778e2ddfee68d0378680f69f71 Mon Sep 17 00:00:00 2001 +From: Haihua Hu +Date: Wed, 9 Mar 2016 13:00:39 +0800 +Subject: [PATCH 18/18] glwindow: work around for no frame when imxplayer use + glimagesink + +change parent window of internal_window in window_show function. + +Upstream-Status: Inappropriate [i.MX specific] + +Signed-off-by: Haihua Hu +Signed-off-by: Lyon Wang +--- + gst-libs/gst/gl/x11/gstglwindow_x11.c | 14 +++++++++++--- + 1 file changed, 11 insertions(+), 3 deletions(-) + +diff --git a/gst-libs/gst/gl/x11/gstglwindow_x11.c b/gst-libs/gst/gl/x11/gstglwindow_x11.c +index a330825..67160f6 100644 +--- a/gst-libs/gst/gl/x11/gstglwindow_x11.c ++++ b/gst-libs/gst/gl/x11/gstglwindow_x11.c +@@ -322,13 +322,13 @@ gst_gl_window_x11_set_window_handle (GstGLWindow * window, guintptr id) + g_main_context_get_thread_default ()); + } + +- XGetWindowAttributes (window_x11->device, window_x11->parent_win, &attr); ++ /*XGetWindowAttributes (window_x11->device, window_x11->parent_win, &attr); + + XResizeWindow (window_x11->device, window_x11->internal_win_id, + attr.width, attr.height); + + XReparentWindow (window_x11->device, window_x11->internal_win_id, +- window_x11->parent_win, 0, 0); ++ window_x11->parent_win, 0, 0);*/ + + XSync (window_x11->device, FALSE); + } +@@ -359,7 +359,7 @@ _show_window (GstGLWindow * window) + GstGLWindowX11 *window_x11 = GST_GL_WINDOW_X11 (window); + guint width = window_x11->priv->preferred_width; + guint height = window_x11->priv->preferred_height; +- XWindowAttributes attr; ++ XWindowAttributes attr, parent_attr; + + XGetWindowAttributes (window_x11->device, window_x11->internal_win_id, &attr); + +@@ -371,6 +371,14 @@ _show_window (GstGLWindow * window) + XResizeWindow (window_x11->device, window_x11->internal_win_id, + attr.width, attr.height); + XSync (window_x11->device, FALSE); ++ }else{ ++ XGetWindowAttributes (window_x11->device, window_x11->parent_win, &parent_attr); ++ ++ XResizeWindow (window_x11->device, window_x11->internal_win_id, ++ parent_attr.width, parent_attr.height); ++ ++ XReparentWindow (window_x11->device, window_x11->internal_win_id, ++ window_x11->parent_win, 0, 0); + } + + XMapWindow (window_x11->device, window_x11->internal_win_id); +-- +1.9.1 + diff --git a/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0008-glplugin-glcolorconvert-fix-MRT-cannot-work-in-GLES3.patch b/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0008-glplugin-glcolorconvert-fix-MRT-cannot-work-in-GLES3.patch new file mode 100755 index 000000000..d4858328f --- /dev/null +++ b/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0008-glplugin-glcolorconvert-fix-MRT-cannot-work-in-GLES3.patch @@ -0,0 +1,168 @@ +From 5b4e2d726602b0c92b789fce0dc85a1f0c860bbc Mon Sep 17 00:00:00 2001 +From: Haihua Hu +Date: Wed, 20 Apr 2016 16:38:31 +0800 +Subject: [PATCH 3/6] [glplugin] glcolorconvert: fix MRT cannot work in GLES3.0 + +1. Add #ifdefine Marco to avoid redefinition of GL_COLOR_ATTACHMENT(1,2). +2. Change to use glBlitFramebuffer for textures copy. glCopyTexImage2D + cannot work because we cannot get texture internal format. + +Upstream-Status: Inappropriate [i.MX specific] + +Signed-off-by: Haihua Hu +--- + gst-libs/gst/gl/glprototypes/fbo.h | 6 +-- + gst-libs/gst/gl/glprototypes/gstgl_gles2compat.h | 7 +-- + gst-libs/gst/gl/gstglcolorconvert.c | 2 +- + gst-libs/gst/gl/gstglmemory.c | 54 +++++++++++++++++++++--- + 4 files changed, 55 insertions(+), 14 deletions(-) + +diff --git a/gst-libs/gst/gl/glprototypes/fbo.h b/gst-libs/gst/gl/glprototypes/fbo.h +index d142483..789f289 100644 +--- a/gst-libs/gst/gl/glprototypes/fbo.h ++++ b/gst-libs/gst/gl/glprototypes/fbo.h +@@ -102,9 +102,9 @@ GST_GL_EXT_FUNCTION (GLboolean, IsFramebuffer, + GST_GL_EXT_END () + + GST_GL_EXT_BEGIN (offscreen_blit, +- GST_GL_API_NONE, +- 255, 255, +- 255, 255, /* not in either GLES */ ++ GST_GL_API_OPENGL3 | GST_GL_API_GLES2, ++ 3, 0, ++ 3, 0,/* enable to avoid using glCopyTexImage2D for texture copying */ + "EXT\0ANGLE\0", + "framebuffer_blit\0") + GST_GL_EXT_FUNCTION (void, BlitFramebuffer, +diff --git a/gst-libs/gst/gl/glprototypes/gstgl_gles2compat.h b/gst-libs/gst/gl/glprototypes/gstgl_gles2compat.h +index d282990..1980476 100644 +--- a/gst-libs/gst/gl/glprototypes/gstgl_gles2compat.h ++++ b/gst-libs/gst/gl/glprototypes/gstgl_gles2compat.h +@@ -34,9 +34,10 @@ G_BEGIN_DECLS + //END FIXME + + /* UNSUPPORTED */ +- +-#define GL_COLOR_ATTACHMENT1 0 +-#define GL_COLOR_ATTACHMENT2 0 ++#ifndef GL_COLOR_ATTACHMENT1 ++#define GL_COLOR_ATTACHMENT1 0x8CE1 ++#define GL_COLOR_ATTACHMENT2 0x8CE2 ++#endif + #ifndef GL_TEXTURE_ENV + #define GL_TEXTURE_ENV 0 + #endif +diff --git a/gst-libs/gst/gl/gstglcolorconvert.c b/gst-libs/gst/gl/gstglcolorconvert.c +index 4ed947e..490ec54 100644 +--- a/gst-libs/gst/gl/gstglcolorconvert.c ++++ b/gst-libs/gst/gl/gstglcolorconvert.c +@@ -2075,7 +2075,7 @@ _init_convert (GstGLColorConvert * convert) + } + + /* Requires reading from a RG/LA framebuffer... */ +- if (USING_GLES2 (convert->context) && ++ if (!USING_GLES3 (convert->context) && + (GST_VIDEO_INFO_FORMAT (&convert->out_info) == GST_VIDEO_FORMAT_YUY2 || + GST_VIDEO_INFO_FORMAT (&convert->out_info) == + GST_VIDEO_FORMAT_UYVY)) { +diff --git a/gst-libs/gst/gl/gstglmemory.c b/gst-libs/gst/gl/gstglmemory.c +index 402fd4d..f2706ea 100644 +--- a/gst-libs/gst/gl/gstglmemory.c ++++ b/gst-libs/gst/gl/gstglmemory.c +@@ -69,6 +69,12 @@ GST_DEBUG_CATEGORY_STATIC (GST_CAT_GL_MEMORY); + #ifndef GL_TEXTURE_EXTERNAL_OES + #define GL_TEXTURE_EXTERNAL_OES 0x8D65 + #endif ++#ifndef GL_READ_FRAMEBUFFER ++#define GL_READ_FRAMEBUFFER 0x8CA8 ++#endif ++#ifndef GL_DRAW_FRAMEBUFFER ++#define GL_DRAW_FRAMEBUFFER 0x8CA9 ++#endif + + G_DEFINE_TYPE (GstGLMemoryAllocator, gst_gl_memory_allocator, + GST_TYPE_GL_BASE_MEMORY_ALLOCATOR); +@@ -608,7 +614,7 @@ gst_gl_memory_copy_teximage (GstGLMemory * src, guint tex_id, + guint out_gl_format, out_tex_target; + GstMapInfo sinfo; + guint src_tex_id; +- guint fbo; ++ guint fbo[2]; + + gl = src->mem.context->gl_vtable; + out_tex_target = gst_gl_texture_target_to_gl (out_target); +@@ -632,31 +638,65 @@ gst_gl_memory_copy_teximage (GstGLMemory * src, guint tex_id, + + /* FIXME: try and avoid creating and destroying fbo's every copy... */ + /* create a framebuffer object */ +- gl->GenFramebuffers (1, &fbo); +- gl->BindFramebuffer (GL_FRAMEBUFFER, fbo); ++ gl->GenFramebuffers (2, &fbo[0]); ++ gl->BindFramebuffer (GL_READ_FRAMEBUFFER, fbo[0]); + +- gl->FramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, ++ gl->FramebufferTexture2D (GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, + gst_gl_texture_target_to_gl (src->tex_target), src_tex_id, 0); + +-// if (!gst_gl_context_check_framebuffer_status (src->context)) +-// goto fbo_error; ++ if (!gst_gl_context_check_framebuffer_status (src->mem.context)) ++ goto fbo_error; ++ ++ gl->BindFramebuffer (GL_DRAW_FRAMEBUFFER, fbo[1]); ++ ++ gl->FramebufferTexture2D (GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, ++ gst_gl_texture_target_to_gl (src->tex_target), tex_id, 0); + ++ if (!gst_gl_context_check_framebuffer_status (src->mem.context)) ++ goto fbo_error; ++ ++ /* + gl->BindTexture (out_tex_target, tex_id); + gst_gl_query_start_log (GST_GL_BASE_MEMORY_CAST (src)->query, + GST_CAT_GL_MEMORY, GST_LEVEL_LOG, NULL, "%s", "CopyTexImage2D took"); + gl->CopyTexImage2D (out_tex_target, 0, out_gl_format, 0, 0, out_width, + out_height, 0); + gst_gl_query_end (GST_GL_BASE_MEMORY_CAST (src)->query); ++ */ ++ ++ /* ++ * glCopyTexImage2D cannot work without internal_format ++ * we cannot get the internal_format in this function ++ * so use glBlitFramebuffer for texture copy ++ */ ++ GST_CAT_LOG(GST_CAT_GL_MEMORY,"Use BlitFramebuffer copy texture %d into %d", ++ src_tex_id, tex_id); ++ gl->ReadBuffer ( GL_COLOR_ATTACHMENT0 ); ++ gl->BlitFramebuffer ( 0, 0, out_width, out_height, ++ 0, 0, out_width, out_height, ++ GL_COLOR_BUFFER_BIT, GL_LINEAR ); + + gl->BindTexture (out_tex_target, 0); + gl->BindFramebuffer (GL_FRAMEBUFFER, 0); + +- gl->DeleteFramebuffers (1, &fbo); ++ gl->DeleteFramebuffers (2, &fbo[0]); + + gst_memory_unmap (GST_MEMORY_CAST (src), &sinfo); + + return TRUE; + ++fbo_error: ++ { ++ gl->BindTexture (out_tex_target, 0); ++ gl->BindFramebuffer (GL_FRAMEBUFFER, 0); ++ ++ gl->DeleteFramebuffers (2, &fbo[0]); ++ ++ gst_memory_unmap (GST_MEMORY_CAST (src), &sinfo); ++ ++ return FALSE; ++ } ++ + error: + return FALSE; + } +-- +1.9.1 + diff --git a/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad_%.bbappend b/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad_%.bbappend index c663d94be..9ee82a851 100644 --- a/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad_%.bbappend +++ b/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad_%.bbappend @@ -12,12 +12,13 @@ PACKAGECONFIG_GL_imxgpu3d = "${@bb.utils.contains('DISTRO_FEATURES', 'opengl', ' SRC_URI_append_imxgpu3d = " \ file://0001-glplugin-Change-wayland-default-res-to-1024x768.patch \ - file://0002-Add-directviv-to-glimagesink-to-improve-playback-per.patch \ - file://0003-MMFMWK-6930-glplugin-Accelerate-gldownload-with-dire.patch \ - file://0004-Fix-dependence-issue-between-gst-plugin-.patch \ - file://0005-glcolorconvert-convert-YUV-to-RGB-use-directviv.patch \ - file://0006-glwindow-work-around-for-no-frame-when-imxplayer-use.patch \ - file://0007-glplugin-glcolorconvert-fix-MRT-cannot-work-in-GLES3.patch \ + file://0002-Support-fb-backend-for-gl-plugins.patch \ + file://0003-Add-directviv-to-glimagesink-to-improve-playback-per.patch \ + file://0004-MMFMWK-6930-glplugin-Accelerate-gldownload-with-dire.patch \ + file://0005-Fix-dependence-issue-between-gst-plugin-.patch \ + file://0006-glcolorconvert-convert-YUV-to-RGB-use-directviv.patch \ + file://0007-glwindow-work-around-for-no-frame-when-imxplayer-use.patch \ + file://0008-glplugin-glcolorconvert-fix-MRT-cannot-work-in-GLES3.patch \ " -- cgit v1.2.3-54-g00ecf