v4l2allocator: let bufferpool calculate image size when importing userptr
authorAurélien Zanelli <aurelien.zanelli@parrot.com>
Fri, 23 Jan 2015 09:15:46 +0000 (10:15 +0100)
committerNicolas Dufresne <nicolas.dufresne@collabora.co.uk>
Wed, 25 Feb 2015 19:24:49 +0000 (14:24 -0500)
Offset are relative to the buffer and there is no guarantee substracting
them will give us the plane size. So we let bufferpool make the math as
it is more aware of video info than allocator and pass a size array to
allocator import function.

Pointed out by Nicolas Dufresne <nicolas.dufresne@collabora.com>

https://bugzilla.gnome.org/show_bug.cgi?id=738013

sys/v4l2/gstv4l2allocator.c
sys/v4l2/gstv4l2allocator.h
sys/v4l2/gstv4l2bufferpool.c

index 4688a2a..a2c96a1 100644 (file)
@@ -1135,7 +1135,7 @@ dup_failed:
 gboolean
 gst_v4l2_allocator_import_userptr (GstV4l2Allocator * allocator,
     GstV4l2MemoryGroup * group, gsize img_size, int n_planes,
-    gpointer * data, gsize * offset)
+    gpointer * data, gsize * size)
 {
   GstV4l2Memory *mem;
   gint i;
@@ -1147,7 +1147,7 @@ gst_v4l2_allocator_import_userptr (GstV4l2Allocator * allocator,
     goto n_mem_missmatch;
 
   for (i = 0; i < group->n_mem; i++) {
-    gsize size, maxsize;
+    gsize maxsize;
 
     if (V4L2_TYPE_IS_MULTIPLANAR (allocator->type)) {
       struct v4l2_pix_format_mplane *pix = &allocator->format.fmt.pix_mp;
@@ -1156,25 +1156,19 @@ gst_v4l2_allocator_import_userptr (GstV4l2Allocator * allocator,
       maxsize = allocator->format.fmt.pix.sizeimage;
     }
 
-    if ((i + 1) == n_planes) {
-      size = img_size - offset[i];
-    } else {
-      size = offset[i + 1] - offset[i];
-    }
-
-    g_assert (size <= img_size);
+    g_assert (size[i] <= img_size);
 
     GST_LOG_OBJECT (allocator, "imported USERPTR %p plane %d size %"
-        G_GSIZE_FORMAT, data[i], i, size);
+        G_GSIZE_FORMAT, data[i], i, size[i]);
 
     mem = (GstV4l2Memory *) group->mem[i];
 
     mem->mem.maxsize = maxsize;
-    mem->mem.size = size;
+    mem->mem.size = size[i];
     mem->data = data[i];
 
     group->planes[i].length = maxsize;
-    group->planes[i].bytesused = size;
+    group->planes[i].bytesused = size[i];
     group->planes[i].m.userptr = (unsigned long) data[i];
     group->planes[i].data_offset = 0;
   }
index d51f3d1..71c64a4 100644 (file)
@@ -141,7 +141,7 @@ gboolean             gst_v4l2_allocator_import_dmabuf  (GstV4l2Allocator * alloc
 gboolean             gst_v4l2_allocator_import_userptr (GstV4l2Allocator * allocator,
                                                         GstV4l2MemoryGroup *group,
                                                         gsize img_size, int n_planes,
-                                                        gpointer * data, gsize * offset);
+                                                        gpointer * data, gsize * size);
 
 void                 gst_v4l2_allocator_flush          (GstV4l2Allocator * allocator);
 
index 52df37c..2096423 100644 (file)
@@ -219,18 +219,39 @@ gst_v4l2_buffer_pool_import_userptr (GstV4l2BufferPool * pool,
 
   if (finfo && (finfo->format != GST_VIDEO_FORMAT_UNKNOWN &&
           finfo->format != GST_VIDEO_FORMAT_ENCODED)) {
+    gsize size[GST_VIDEO_MAX_PLANES] = { 0, };
+    gint i;
+
     data->is_frame = TRUE;
 
     if (!gst_video_frame_map (&data->frame, &pool->caps_info, src, flags))
       goto invalid_buffer;
 
+    for (i = 0; i < GST_VIDEO_FORMAT_INFO_N_PLANES (finfo); i++) {
+      if (GST_VIDEO_FORMAT_INFO_IS_TILED (finfo)) {
+        gint tinfo = GST_VIDEO_FRAME_PLANE_STRIDE (&data->frame, i);
+        gint pstride;
+        guint pheight;
+
+        pstride = GST_VIDEO_TILE_X_TILES (tinfo) <<
+            GST_VIDEO_FORMAT_INFO_TILE_WS (finfo);
+
+        pheight = GST_VIDEO_TILE_Y_TILES (tinfo) <<
+            GST_VIDEO_FORMAT_INFO_TILE_HS (finfo);
+
+        size[i] = pstride * pheight;
+      } else {
+        size[i] = GST_VIDEO_FRAME_PLANE_STRIDE (&data->frame, i) *
+            GST_VIDEO_FRAME_COMP_HEIGHT (&data->frame, i);
+      }
+    }
+
     if (!gst_v4l2_allocator_import_userptr (pool->vallocator, group,
-            data->frame.info.size, finfo->n_planes, data->frame.data,
-            data->frame.info.offset))
+            data->frame.info.size, finfo->n_planes, data->frame.data, size))
       goto import_failed;
   } else {
-    gsize offset[1] = { 0 };
     gpointer ptr[1];
+    gsize size[1];
 
     data->is_frame = FALSE;
 
@@ -238,9 +259,10 @@ gst_v4l2_buffer_pool_import_userptr (GstV4l2BufferPool * pool,
       goto invalid_buffer;
 
     ptr[0] = data->map.data;
+    size[0] = data->map.size;
 
     if (!gst_v4l2_allocator_import_userptr (pool->vallocator, group,
-            data->map.size, 1, ptr, offset))
+            data->map.size, 1, ptr, size))
       goto import_failed;
   }