1 From 94e6bb069cb5207761f2e4234137f2a748f984db Mon Sep 17 00:00:00 2001
2 From: Haihua Hu <b55597@freescale.com>
3 Date: Tue, 13 Oct 2015 09:33:54 +0800
4 Subject: [PATCH 13/18] Add directviv to glimagesink to improve playback
7 Content-Type: text/plain; charset=UTF-8
8 Content-Transfer-Encoding: 8bit
10 1.Add a physical buffer uploader in glupload plugin and using viv direct
11 texture to bind physical continious buffer with texture to avoid memory
12 copy from videobuffer to texture to gain good performance.
13 2.Reduce glimagesink load latency by override glimagesink ALLOCATION query to
16 Upstream-Status: Inappropriate [i.MX specific]
18 Signed-off-by: Haihua Hu <b55597@freescale.com>
19 Signed-off-by: Lyon Wang <lyon.wang@freescale.com>
21 ext/gl/gstglimagesink.c | 5 ++
22 gst-libs/gst/gl/Makefile.am | 2 +
23 gst-libs/gst/gl/gstglupload.c | 141 ++++++++++++++++++++++++++++++-
24 gst-libs/gst/gl/gstglvivdirecttexture.c | 143 ++++++++++++++++++++++++++++++++
25 gst-libs/gst/gl/gstglvivdirecttexture.h | 35 ++++++++
26 5 files changed, 323 insertions(+), 3 deletions(-)
27 create mode 100644 gst-libs/gst/gl/gstglvivdirecttexture.c
28 create mode 100644 gst-libs/gst/gl/gstglvivdirecttexture.h
30 diff --git a/ext/gl/gstglimagesink.c b/ext/gl/gstglimagesink.c
31 index 3b5e3b5..532ea6a 100644
32 --- a/ext/gl/gstglimagesink.c
33 +++ b/ext/gl/gstglimagesink.c
34 @@ -911,6 +911,11 @@ gst_glimage_sink_query (GstBaseSink * bsink, GstQuery * query)
35 res = GST_BASE_SINK_CLASS (parent_class)->query (bsink, query);
38 + case GST_QUERY_ALLOCATION:
40 + gst_glimage_sink_propose_allocation(bsink, query);
44 res = GST_BASE_SINK_CLASS (parent_class)->query (bsink, query);
46 diff --git a/gst-libs/gst/gl/Makefile.am b/gst-libs/gst/gl/Makefile.am
47 index 4bd6511..c396603 100644
48 --- a/gst-libs/gst/gl/Makefile.am
49 +++ b/gst-libs/gst/gl/Makefile.am
50 @@ -33,6 +33,7 @@ libgstgl_@GST_API_VERSION@_la_SOURCES = \
52 gstgloverlaycompositor.c \
54 + gstglvivdirecttexture.c \
55 gstglcontrolbindingproxy.c
57 libgstgl_@GST_API_VERSION@includedir = $(includedir)/gstreamer-@GST_API_VERSION@/gst/gl
58 @@ -66,6 +67,7 @@ libgstgl_@GST_API_VERSION@include_HEADERS = \
59 gstglcontrolbindingproxy.h \
62 + gstglvivdirecttexture.h \
66 diff --git a/gst-libs/gst/gl/gstglupload.c b/gst-libs/gst/gl/gstglupload.c
67 index 32e6150..99cc68a 100644
68 --- a/gst-libs/gst/gl/gstglupload.c
69 +++ b/gst-libs/gst/gl/gstglupload.c
74 +#include <gst/gl/gstglvivdirecttexture.h>
77 #include "gstglupload.h"
79 #define USING_GLES2(context) (gst_gl_context_check_gl_version (context, GST_GL_API_GLES2, 2, 0))
80 #define USING_GLES3(context) (gst_gl_context_check_gl_version (context, GST_GL_API_GLES2, 3, 0))
82 -GST_DEBUG_CATEGORY_STATIC (gst_gl_upload_debug);
83 +GST_DEBUG_CATEGORY (gst_gl_upload_debug);
84 #define GST_CAT_DEFAULT gst_gl_upload_debug
87 @@ -1169,6 +1170,140 @@ static const UploadMethod _upload_meta_upload = {
88 &_upload_meta_upload_free
91 +struct PhyBufferUpload
93 + GstGLUpload *upload;
94 + GstGLVideoAllocationParams *params;
98 +_physical_buffer_upload_new(GstGLUpload *upload)
100 + struct PhyBufferUpload *phybuffer = g_new0 (struct PhyBufferUpload, 1);
102 + phybuffer->upload = upload;
108 +_physical_buffer_upload_transform_caps(GstGLContext *context,
109 + GstPadDirection direction, GstCaps *caps)
111 + GstCapsFeatures *passthrough =
112 + gst_caps_features_from_string
113 + (GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION);
116 + if (direction == GST_PAD_SINK) {
120 + _set_caps_features_with_passthrough (caps,
121 + GST_CAPS_FEATURE_MEMORY_GL_MEMORY, passthrough);
123 + gst_caps_set_simple (ret, "format", G_TYPE_STRING, "RGBA", NULL);
124 + tmp = _caps_intersect_texture_target (ret, 1 << GST_GL_TEXTURE_TARGET_2D);
125 + gst_caps_unref (ret);
128 + ret = gst_caps_from_string (GST_VIDEO_CAPS_MAKE_WITH_FEATURES
129 + (GST_CAPS_FEATURE_MEMORY_SYSTEM_MEMORY,GST_GL_DIRECTVIV_FORMAT));
132 + gst_caps_features_free (passthrough);
137 +_physical_buffer_upload_accept(gpointer impl, GstBuffer *buffer,
138 + GstCaps *in_caps, GstCaps *out_caps)
140 + struct PhyBufferUpload *upload = impl;
141 + GstCapsFeatures *features;
143 + features = gst_caps_get_features (out_caps, 0);
144 + if (!gst_caps_features_contains (features, GST_CAPS_FEATURE_MEMORY_GL_MEMORY))
147 + if (upload->params)
148 + gst_gl_allocation_params_free ((GstGLAllocationParams *) upload->params);
149 + if (!(upload->params =
150 + gst_gl_video_allocation_params_new (upload->upload->context, NULL,
151 + &upload->upload->priv->in_info, -1, NULL,
152 + GST_GL_TEXTURE_TARGET_2D)))
155 + return gst_is_physical_buffer(buffer);
159 +_physical_buffer_upload_propose_allocation(gpointer impl, GstQuery *decide_query,
162 + gst_query_add_allocation_meta (query, GST_VIDEO_META_API_TYPE, 0);
165 +static GstGLUploadReturn
166 +_physical_buffer_upload_perform(gpointer impl, GstBuffer *buffer, GstBuffer **outbuf)
168 + struct PhyBufferUpload *phyBuffer = impl;
169 + GstGLMemoryAllocator *allocator;
170 + GstVideoInfo *info;
173 + info = &phyBuffer->upload->priv->out_info;
174 + n_mem = GST_VIDEO_INFO_N_PLANES (info);
175 + GST_LOG_OBJECT (phyBuffer->upload, "Attempting viv direct upload");
178 + GST_GL_MEMORY_ALLOCATOR (gst_allocator_find
179 + (GST_GL_MEMORY_PBO_ALLOCATOR_NAME));
181 + /* FIXME: buffer pool */
182 + *outbuf = gst_buffer_new ();
183 + gst_gl_memory_setup_buffer (allocator, *outbuf, phyBuffer->params);
184 + gst_object_unref (allocator);
186 + GstGLMemory *out_gl_mem =
187 + (GstGLMemory *) gst_buffer_peek_memory (*outbuf, 0);
189 + gst_gl_viv_direct_bind_gstbuffer(phyBuffer->upload->context, out_gl_mem->tex_id,
190 + &phyBuffer->upload->priv->in_info, buffer);
192 + gst_buffer_add_video_meta_full (*outbuf, 0,
193 + GST_VIDEO_INFO_FORMAT (info), GST_VIDEO_INFO_WIDTH (info),
194 + GST_VIDEO_INFO_HEIGHT (info), n_mem, info->offset, info->stride);
196 + return GST_GL_UPLOAD_DONE;
200 +_physical_buffer_upload_free(gpointer impl)
202 + struct PhyBufferUpload *phyBuffer = impl;
204 + if (phyBuffer->params)
205 + gst_gl_allocation_params_free ((GstGLAllocationParams *) phyBuffer->params);
210 +static GstStaticCaps _physical_buffer_upload_caps =
211 +GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE (GST_GL_DIRECTVIV_FORMAT));
213 +static const UploadMethod _physical_buffer_upload = {
216 + &_physical_buffer_upload_caps,
217 + &_physical_buffer_upload_new,
218 + &_physical_buffer_upload_transform_caps,
219 + &_physical_buffer_upload_accept,
220 + &_physical_buffer_upload_propose_allocation,
221 + &_physical_buffer_upload_perform,
222 + &_physical_buffer_upload_free
225 struct RawUploadFrame
228 @@ -1391,7 +1526,7 @@ static const UploadMethod *upload_methods[] = { &_gl_memory_upload,
229 #if GST_GL_HAVE_DMABUF
232 - &_upload_meta_upload, &_raw_data_upload
233 + &_upload_meta_upload, &_physical_buffer_upload, &_raw_data_upload
236 static GMutex upload_global_lock;
237 @@ -1514,7 +1649,7 @@ gst_gl_upload_transform_caps (GstGLContext * context, GstPadDirection direction,
241 - result = gst_caps_intersect_full (filter, tmp, GST_CAPS_INTERSECT_FIRST);
242 + result = gst_caps_intersect_full (tmp, filter, GST_CAPS_INTERSECT_FIRST);
243 gst_caps_unref (tmp);
246 diff --git a/gst-libs/gst/gl/gstglvivdirecttexture.c b/gst-libs/gst/gl/gstglvivdirecttexture.c
248 index 0000000..c19b617
250 +++ b/gst-libs/gst/gl/gstglvivdirecttexture.c
254 + * Copyright (c) 2015, Freescale Semiconductor, Inc.
256 + * This library is free software; you can redistribute it and/or
257 + * modify it under the terms of the GNU Library General Public
258 + * License as published by the Free Software Foundation; either
259 + * version 2 of the License, or (at your option) any later version.
261 + * This library is distributed in the hope that it will be useful,
262 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
263 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
264 + * Library General Public License for more details.
266 + * You should have received a copy of the GNU Library General Public
267 + * License along with this library; if not, write to the
268 + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
269 + * Boston, MA 02110-1301, USA.
272 +#ifdef HAVE_CONFIG_H
278 +GST_DEBUG_CATEGORY_EXTERN (gst_gl_upload_debug);
279 +#define GST_CAT_DEFAULT gst_gl_upload_debug
289 +} GstVivDirectTexture;
292 +gst_is_physical_buffer (GstBuffer *buffer)
297 + mem = gst_buffer_peek_memory (buffer, 0);
298 + if (!mem->allocator)
301 + return g_type_check_instance_is_a (mem->allocator, g_type_from_name("GstAllocatorPhyMem"));
305 +_do_viv_direct_tex_bind_mem (GstGLContext * context, GstVivDirectTexture * viv_tex)
307 + 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);
308 + GST_DEBUG ("Physical memory buffer, vaddr: %p, paddr: %p", viv_tex->vaddr, viv_tex->paddr);
310 + glBindTexture (GL_TEXTURE_2D, viv_tex->tex_id);
311 + glTexDirectVIVMap (GL_TEXTURE_2D, viv_tex->w, viv_tex->h, viv_tex->fmt, &viv_tex->vaddr, &viv_tex->paddr);
312 + glTexDirectInvalidateVIV (GL_TEXTURE_2D);
313 + viv_tex->ret = TRUE;
319 +gst_gl_viv_direct_bind_gstbuffer (GstGLContext * context, guint tex_id, GstVideoInfo * info, GstBuffer * buffer)
326 + gpointer *user_data;
328 + //Note: structure PhyMemBlock is copied from gst1.0-fsl-plugin/libs/allocator/gstallocatorphymem.h
336 + //Note: structure GstMemoryPhy is copied from gst1.0-fsl-plugin/libs/allocator/gstallocatorphymem.c
338 + GstMemory *mem = gst_buffer_peek_memory (buffer, 0);
339 + GstMemoryPhy *memphy = (GstMemoryPhy*) mem;
340 + PhyMemBlock *memblk = &memphy->block;
342 + GstVideoFormat fmt = GST_VIDEO_INFO_FORMAT (info);
343 + gint width, height;
344 + GstVideoMeta *vmeta = gst_buffer_get_video_meta (buffer);
345 + if (vmeta && (fmt == GST_VIDEO_FORMAT_I420 || fmt == GST_VIDEO_FORMAT_NV12)) {
346 + width = vmeta->stride[0];
347 + height = vmeta->offset[1] / width;
350 + width = GST_VIDEO_INFO_WIDTH (info);
351 + height = GST_VIDEO_INFO_HEIGHT (info);
356 + case GST_VIDEO_FORMAT_I420:
357 + viv_fmt = GL_VIV_I420;
359 + case GST_VIDEO_FORMAT_YV12:
360 + viv_fmt = GL_VIV_YV12;
362 + case GST_VIDEO_FORMAT_NV12:
363 + viv_fmt = GL_VIV_NV12;
365 + case GST_VIDEO_FORMAT_NV21:
366 + viv_fmt = GL_VIV_NV21;
368 + case GST_VIDEO_FORMAT_YUY2:
369 + viv_fmt = GL_VIV_YUY2;
371 + case GST_VIDEO_FORMAT_UYVY:
372 + viv_fmt = GL_VIV_UYVY;
374 + case GST_VIDEO_FORMAT_RGBA:
377 + case GST_VIDEO_FORMAT_BGRA:
378 + viv_fmt = GL_BGRA_EXT;
380 + case GST_VIDEO_FORMAT_RGB16:
381 + viv_fmt = GL_RGB565_OES;
384 + GST_ERROR ("Not supported format %d for viv direct texture upload.", fmt);
389 + GstVivDirectTexture viv_tex = {tex_id, width, height, viv_fmt, memblk->vaddr, memblk->paddr, FALSE};
390 + gst_gl_context_thread_add (context, (GstGLContextThreadFunc) _do_viv_direct_tex_bind_mem, &viv_tex);
392 + return viv_tex.ret;
395 diff --git a/gst-libs/gst/gl/gstglvivdirecttexture.h b/gst-libs/gst/gl/gstglvivdirecttexture.h
397 index 0000000..fa88e1a
399 +++ b/gst-libs/gst/gl/gstglvivdirecttexture.h
403 + * Copyright (c) 2015, Freescale Semiconductor, Inc.
405 + * This library is free software; you can redistribute it and/or
406 + * modify it under the terms of the GNU Library General Public
407 + * License as published by the Free Software Foundation; either
408 + * version 2 of the License, or (at your option) any later version.
410 + * This library is distributed in the hope that it will be useful,
411 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
412 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
413 + * Library General Public License for more details.
415 + * You should have received a copy of the GNU Library General Public
416 + * License along with this library; if not, write to the
417 + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
418 + * Boston, MA 02110-1301, USA.
421 +#ifndef __GST_GL_VIVDIRECT_H__
422 +#define __GST_GL_VIVDIRECT_H__
424 +#include <gst/video/video.h>
425 +#include <gst/gl/gstgl_fwd.h>
427 +#define GST_GL_DIRECTVIV_FORMAT "{RGBA, I420, YV12, NV12, NV21, YUY2, UYVY, BGRA, RGB16}"
430 +gboolean gst_is_physical_buffer (GstBuffer *buffer);
431 +gboolean gst_gl_viv_direct_bind_gstbuffer (GstGLContext * context, guint tex_id, GstVideoInfo * info, GstBuffer * buffer);
435 +#endif /* __GST_GL_VIVDIRECT_H__ */