summaryrefslogtreecommitdiffstats
path: root/meta-rcar-gen2/recipes-multimedia/gstreamer/gstreamer1.0-omx/0010-omxvideodec-support-creating-buffers-using-sink.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-rcar-gen2/recipes-multimedia/gstreamer/gstreamer1.0-omx/0010-omxvideodec-support-creating-buffers-using-sink.patch')
-rw-r--r--meta-rcar-gen2/recipes-multimedia/gstreamer/gstreamer1.0-omx/0010-omxvideodec-support-creating-buffers-using-sink.patch186
1 files changed, 186 insertions, 0 deletions
diff --git a/meta-rcar-gen2/recipes-multimedia/gstreamer/gstreamer1.0-omx/0010-omxvideodec-support-creating-buffers-using-sink.patch b/meta-rcar-gen2/recipes-multimedia/gstreamer/gstreamer1.0-omx/0010-omxvideodec-support-creating-buffers-using-sink.patch
new file mode 100644
index 0000000..bd2b91c
--- /dev/null
+++ b/meta-rcar-gen2/recipes-multimedia/gstreamer/gstreamer1.0-omx/0010-omxvideodec-support-creating-buffers-using-sink.patch
@@ -0,0 +1,186 @@
+From 58d8ea72ec78cb17cf75c82c67a69e9bd383c3b3 Mon Sep 17 00:00:00 2001
+From: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+Date: Thu, 1 Sep 2016 20:09:03 +0300
+Subject: [PATCH 10/10] omxvideodec: support creating buffers using sink
+
+Used for zero-copy output to wayland/weston
+
+Signed-off-by: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+---
+ omx/gstomxbufferpool.c | 107 +++++++++++++++++++++++++++++++++++++++++++++---
+ omx/gstomxvideodec.c | 11 ++++-
+ 2 files changed, 111 insertions(+), 7 deletions(-)
+
+diff --git a/omx/gstomxbufferpool.c b/omx/gstomxbufferpool.c
+index eb2fe9d..60b25ef 100644
+--- a/omx/gstomxbufferpool.c
++++ b/omx/gstomxbufferpool.c
+@@ -372,6 +372,73 @@ GstOMXBuffer *gst_omx_buffer_get_omxbuffer (GstBuffer * buffer)
+ return omx_buf;
+ }
+
++#ifdef HAVE_MMNGRBUF
++static GstBuffer *
++gst_omx_buffer_pool_request_videosink_buffer_creation (GstOMXBufferPool * pool,
++ gint dmabuf_fd[GST_VIDEO_MAX_PLANES], gpointer plane_buf[GST_VIDEO_MAX_PLANES], gint stride[GST_VIDEO_MAX_PLANES])
++{
++ GstQuery *query;
++ GValue val = { 0, };
++ GstStructure *structure;
++ const GValue *value;
++ GstBuffer *buffer;
++ GArray *dmabuf_array;
++ GArray *stride_array;
++ GArray *planebuf_array;
++ gint n_planes;
++ gint i;
++
++ g_value_init (&val, G_TYPE_POINTER);
++ g_value_set_pointer (&val, (gpointer) pool->allocator);
++
++ dmabuf_array = g_array_new (FALSE, FALSE, sizeof (gint));
++ stride_array = g_array_new (FALSE, FALSE, sizeof (gint));
++ planebuf_array = g_array_new (FALSE, FALSE, sizeof (gpointer));
++
++ n_planes = GST_VIDEO_INFO_N_PLANES (&pool->video_info);
++ for (i = 0; i < n_planes; i++) {
++ g_array_append_val (dmabuf_array, dmabuf_fd[i]);
++ g_array_append_val (stride_array, stride[i]);
++ g_array_append_val (planebuf_array, plane_buf[i]);
++ }
++
++ structure = gst_structure_new ("videosink_buffer_creation_request",
++ "width", G_TYPE_INT, pool->port->port_def.format.video.nFrameWidth,
++ "height", G_TYPE_INT, pool->port->port_def.format.video.nFrameHeight,
++ "stride", G_TYPE_ARRAY, stride_array,
++ "dmabuf", G_TYPE_ARRAY, dmabuf_array,
++ "planebuf", G_TYPE_ARRAY, planebuf_array,
++ "allocator", G_TYPE_POINTER, &val,
++ "format", G_TYPE_STRING,
++ gst_video_format_to_string (pool->video_info.finfo->format),
++ "n_planes", G_TYPE_INT, n_planes, NULL);
++
++ query = gst_query_new_custom (GST_QUERY_CUSTOM, structure);
++
++ GST_DEBUG_OBJECT (pool, "send a videosink_buffer_creation_request query");
++
++ if (!gst_pad_peer_query (GST_VIDEO_DECODER_SRC_PAD (pool->element), query)) {
++ GST_ERROR_OBJECT (pool, "videosink_buffer_creation_request query failed");
++ return NULL;
++ }
++
++ value = gst_structure_get_value (structure, "buffer");
++ buffer = gst_value_get_buffer (value);
++ if (buffer == NULL) {
++ GST_ERROR_OBJECT (pool,
++ "could not get a buffer from videosink_buffer_creation query");
++ return NULL;
++ }
++
++ gst_query_unref (query);
++
++ g_array_free (dmabuf_array, TRUE);
++ g_array_free (stride_array, TRUE);
++
++ return buffer;
++}
++#endif
++
+ #if defined (HAVE_MMNGRBUF) && defined (HAVE_VIDEODEC_EXT)
+ static gboolean
+ gst_omx_buffer_pool_export_dmabuf (GstOMXBufferPool * pool,
+@@ -406,6 +473,7 @@ gst_omx_buffer_pool_create_buffer_contain_dmabuf (GstOMXBufferPool * self,
+ gint plane_size_ext[GST_VIDEO_MAX_PLANES];
+ gint dmabuf_id[GST_VIDEO_MAX_PLANES];
+ gint page_offset[GST_VIDEO_MAX_PLANES];
++ gint plane_buf[GST_VIDEO_MAX_PLANES];
+ GstBuffer *new_buf;
+ gint i;
+ gint page_size;
+@@ -450,6 +518,7 @@ gst_omx_buffer_pool_create_buffer_contain_dmabuf (GstOMXBufferPool * self,
+ else
+ plane_size[i] = stride[i] *
+ GST_VIDEO_INFO_COMP_HEIGHT (&self->video_info, i);
++ plane_buf[i] = omx_buf->omx_buf->pBuffer + offset[i];
+
+ /* When downstream plugins do mapping from dmabuf fd it requires
+ * mapping from boundary page and size align for page size so
+@@ -472,14 +541,40 @@ gst_omx_buffer_pool_create_buffer_contain_dmabuf (GstOMXBufferPool * self,
+ gst_buffer_append_memory (new_buf, mem);
+ }
+
+- g_ptr_array_add (self->buffers, new_buf);
+- gst_buffer_add_video_meta_full (new_buf, GST_VIDEO_FRAME_FLAG_NONE,
+- GST_VIDEO_INFO_FORMAT (&self->video_info),
+- GST_VIDEO_INFO_WIDTH (&self->video_info),
+- GST_VIDEO_INFO_HEIGHT (&self->video_info),
+- GST_VIDEO_INFO_N_PLANES (&self->video_info), offset, stride);
++ if (self->vsink_buf_req_supported) {
++ new_buf = gst_omx_buffer_pool_request_videosink_buffer_creation (self,
++ dmabuf_fd, plane_buf, stride);
++ if (!new_buf) {
++ GST_ERROR_OBJECT (self, "creating dmabuf using videosink failed");
++ goto err;
++ }
++ new_buf->pool = self;
++ } else {
++ new_buf = gst_buffer_new ();
++ for (i = 0; i < GST_VIDEO_INFO_N_PLANES (&self->video_info); i++) {
++ GstMemory *mem;
++ /* Set offset's information */
++ mem = gst_dmabuf_allocator_alloc (self->allocator, dmabuf_fd[i],
++ plane_size_ext[i]);
++ mem->offset = page_offset[i];
++ mem->size = plane_size[i];
++ gst_buffer_append_memory (new_buf, mem);
++ }
++
++ gst_buffer_add_video_meta_full (new_buf, GST_VIDEO_FRAME_FLAG_NONE,
++ GST_VIDEO_INFO_FORMAT (&self->video_info),
++ GST_VIDEO_INFO_WIDTH (&self->video_info),
++ GST_VIDEO_INFO_HEIGHT (&self->video_info),
++ GST_VIDEO_INFO_N_PLANES (&self->video_info), offset, stride);
++ }
+
++ GST_ERROR_OBJECT (self, "got buffer %p from pool %p",
++ new_buf, new_buf->pool);
++ g_ptr_array_add (self->buffers, new_buf);
+ return new_buf;
++
++err:
++ return NULL;
+ }
+ #endif
+
+diff --git a/omx/gstomxvideodec.c b/omx/gstomxvideodec.c
+index 25b6b30..44b706a 100644
+--- a/omx/gstomxvideodec.c
++++ b/omx/gstomxvideodec.c
+@@ -2350,6 +2350,8 @@ gst_omx_video_dec_decide_allocation (GstVideoDecoder * bdec, GstQuery * query)
+ &GST_OMX_BUFFER_POOL (self->out_port_pool)->vsink_buf_req_supported);
+ gst_object_unref (pool);
+ update_pool = TRUE;
++ GST_ERROR_OBJECT (self, "vsink_buf_req_supported %d",
++ GST_OMX_BUFFER_POOL (self->out_port_pool)->vsink_buf_req_supported);
+ }
+
+ /* Set pool parameters to our own configuration */
+@@ -2372,7 +2374,14 @@ gst_omx_video_dec_decide_allocation (GstVideoDecoder * bdec, GstQuery * query)
+ }
+
+ GST_OMX_BUFFER_POOL (self->out_port_pool)->allocating = TRUE;
+- gst_buffer_pool_set_active (self->out_port_pool, TRUE);
++ /* This now allocates all the buffers */
++ if (!gst_buffer_pool_set_active (self->out_port_pool, TRUE)) {
++ GST_INFO_OBJECT (self, "Failed to activate internal pool");
++ gst_object_unref (self->out_port_pool);
++ self->out_port_pool = NULL;
++ } else {
++ GST_OMX_BUFFER_POOL (self->out_port_pool)->allocating = FALSE;
++ }
+
+ /* This video buffer pool created below will not be used, just setting to
+ * the gstvideodecoder class through a query, because it is
+--
+1.7.10.4
+