Skip to content

Commit 54a5b52

Browse files
krajKaran Tandel
authored and
Karan Tandel
committed
v4l2: Reuse right buffer index when dmabuf import mode
1 parent 143d24f commit 54a5b52

File tree

4 files changed

+144
-16
lines changed

4 files changed

+144
-16
lines changed

subprojects/gst-plugins-good/sys/v4l2/gstv4l2allocator.c

+96-2
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,8 @@ gst_v4l2_allocator_release (GstV4l2Allocator * allocator, GstV4l2Memory * mem)
357357

358358
switch (allocator->memory) {
359359
case V4L2_MEMORY_DMABUF:
360+
if (V4L2_TYPE_IS_CAPTURE(allocator->obj->type) && (allocator->obj->mode == GST_V4L2_IO_DMABUF_IMPORT))
361+
break;
360362
mem->dmafd = -1;
361363
break;
362364
case V4L2_MEMORY_USERPTR:
@@ -395,8 +397,10 @@ gst_v4l2_allocator_free (GstAllocator * gallocator, GstMemory * gmem)
395397
obj->munmap (mem->data, group->planes[mem->plane].length);
396398
}
397399

398-
if (allocator->memory == V4L2_MEMORY_MMAP && mem->dmafd >= 0)
400+
if (allocator->memory == V4L2_MEMORY_MMAP && mem->dmafd >= 0){
399401
close (mem->dmafd);
402+
GST_LOG_OBJECT (allocator, "close fd: %d", mem->dmafd);
403+
}
400404
}
401405

402406
g_slice_free (GstV4l2Memory, mem);
@@ -1021,6 +1025,91 @@ gst_v4l2_allocator_alloc_dmabufin (GstV4l2Allocator * allocator)
10211025
return group;
10221026
}
10231027

1028+
GstV4l2MemoryGroup *
1029+
gst_v4l2_allocator_alloc_dmabufin_capture (GstV4l2Allocator * allocator,
1030+
GstAllocator * dmabuf_allocator, GstBuffer* downstream_buffer)
1031+
{
1032+
GstV4l2Object *obj = allocator->obj;
1033+
GstV4l2MemoryGroup *group;
1034+
gint i;
1035+
1036+
g_return_val_if_fail (allocator->memory == V4L2_MEMORY_DMABUF, NULL);
1037+
1038+
group = gst_v4l2_allocator_alloc (allocator);
1039+
1040+
if (group == NULL)
1041+
return NULL;
1042+
1043+
for (i = 0; i < group->n_mem; i++) {
1044+
GstV4l2Memory *mem;
1045+
GstMemory *dma_mem;
1046+
gsize size, offset, maxsize;
1047+
1048+
1049+
if (group->mem[i] == NULL) {
1050+
dma_mem = gst_buffer_peek_memory (downstream_buffer, i);
1051+
int downstream_fd = gst_dmabuf_memory_get_fd (dma_mem);
1052+
1053+
GST_LOG_OBJECT (allocator, "import DMABUF fd %d into fd %i plane %d",
1054+
downstream_fd, downstream_fd, i);
1055+
1056+
group->planes[i].m.fd = downstream_fd;
1057+
group->planes[i].length = dma_mem->size;
1058+
group->planes[i].data_offset = dma_mem->offset;
1059+
1060+
group->mem[i] = (GstMemory *) _v4l2mem_new (0, GST_ALLOCATOR (allocator),
1061+
NULL, group->planes[i].length, 0, group->planes[i].data_offset,
1062+
group->planes[i].length - group->planes[i].data_offset, i, NULL,
1063+
downstream_fd, group);
1064+
} else {
1065+
/* Take back the allocator reference */
1066+
gst_object_ref (allocator);
1067+
}
1068+
1069+
group->mems_allocated++;
1070+
1071+
g_assert (gst_is_v4l2_memory (group->mem[i]));
1072+
mem = (GstV4l2Memory *) group->mem[i];
1073+
1074+
dma_mem = gst_fd_allocator_alloc (dmabuf_allocator, mem->dmafd,
1075+
group->planes[i].length, GST_FD_MEMORY_FLAG_DONT_CLOSE);
1076+
gst_memory_resize (dma_mem, group->planes[i].data_offset,
1077+
group->planes[i].length - group->planes[i].data_offset);
1078+
1079+
gst_mini_object_set_qdata (GST_MINI_OBJECT (dma_mem),
1080+
GST_V4L2_MEMORY_QUARK, mem, (GDestroyNotify) gst_memory_unref);
1081+
1082+
group->mem[i] = dma_mem;
1083+
}
1084+
1085+
if (!V4L2_TYPE_IS_MULTIPLANAR (obj->type)) {
1086+
group->buffer.bytesused = group->planes[0].bytesused;
1087+
group->buffer.length = group->planes[0].length;
1088+
group->buffer.m.fd = group->planes[0].m.fd;
1089+
1090+
/* FIXME Check if data_offset > 0 and fail for non-multi-planar */
1091+
g_assert (group->planes[0].data_offset == 0);
1092+
} else {
1093+
group->buffer.length = group->n_mem;
1094+
}
1095+
1096+
gst_v4l2_allocator_reset_size (allocator, group);
1097+
1098+
return group;
1099+
1100+
expbuf_failed:
1101+
{
1102+
GST_ERROR_OBJECT (allocator, "Failed to export DMABUF: %s",
1103+
g_strerror (errno));
1104+
goto cleanup;
1105+
}
1106+
cleanup:
1107+
{
1108+
_cleanup_failed_alloc (allocator, group);
1109+
return NULL;
1110+
}
1111+
}
1112+
10241113
static void
10251114
gst_v4l2_allocator_clear_userptr (GstV4l2Allocator * allocator,
10261115
GstV4l2MemoryGroup * group)
@@ -1453,7 +1542,12 @@ gst_v4l2_allocator_reset_group (GstV4l2Allocator * allocator,
14531542
gst_v4l2_allocator_clear_userptr (allocator, group);
14541543
break;
14551544
case V4L2_MEMORY_DMABUF:
1456-
gst_v4l2_allocator_clear_dmabufin (allocator, group);
1545+
if (V4L2_TYPE_IS_CAPTURE(allocator->obj->type) && (allocator->obj->mode == GST_V4L2_IO_DMABUF_IMPORT)) {
1546+
break;
1547+
}
1548+
else {
1549+
gst_v4l2_allocator_clear_dmabufin (allocator, group);
1550+
}
14571551
break;
14581552
case V4L2_MEMORY_MMAP:
14591553
break;

subprojects/gst-plugins-good/sys/v4l2/gstv4l2allocator.h

+3
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,9 @@ GstV4l2MemoryGroup* gst_v4l2_allocator_alloc_dmabuf (GstV4l2Allocator * alloc
137137

138138
GstV4l2MemoryGroup * gst_v4l2_allocator_alloc_dmabufin (GstV4l2Allocator * allocator);
139139

140+
GstV4l2MemoryGroup * gst_v4l2_allocator_alloc_dmabufin_capture (GstV4l2Allocator * allocator,
141+
GstAllocator * dmabuf_allocator, GstBuffer* downstream_buffer);
142+
140143
GstV4l2MemoryGroup * gst_v4l2_allocator_alloc_userptr (GstV4l2Allocator * allocator);
141144

142145
gboolean gst_v4l2_allocator_import_dmabuf (GstV4l2Allocator * allocator,

subprojects/gst-plugins-good/sys/v4l2/gstv4l2bufferpool.c

+40-13
Original file line numberDiff line numberDiff line change
@@ -456,6 +456,7 @@ gst_v4l2_buffer_pool_alloc_buffer (GstBufferPool * bpool, GstBuffer ** buffer,
456456
GstBuffer *newbuf = NULL;
457457
GstV4l2Object *obj;
458458
GstVideoInfo *info;
459+
GstBuffer *downstream_buffer = NULL;
459460

460461
obj = pool->obj;
461462
info = &obj->info;
@@ -476,7 +477,23 @@ gst_v4l2_buffer_pool_alloc_buffer (GstBufferPool * bpool, GstBuffer ** buffer,
476477
group = gst_v4l2_allocator_alloc_userptr (pool->vallocator);
477478
break;
478479
case GST_V4L2_IO_DMABUF_IMPORT:
479-
group = gst_v4l2_allocator_alloc_dmabufin (pool->vallocator);
480+
if (V4L2_TYPE_IS_OUTPUT(obj->type))
481+
group = gst_v4l2_allocator_alloc_dmabufin (pool->vallocator);
482+
else {
483+
GstFlowReturn ret = gst_buffer_pool_acquire_buffer (pool->other_pool, &downstream_buffer, NULL);
484+
if (ret == GST_FLOW_OK)
485+
{
486+
group = gst_v4l2_allocator_alloc_dmabufin_capture (pool->vallocator, pool->allocator, downstream_buffer);
487+
if (group == NULL) {
488+
gst_buffer_unref (downstream_buffer);
489+
GST_DEBUG_OBJECT (pool, "failed to create buffer while dmabuf importing");
490+
}
491+
}
492+
else
493+
{
494+
GST_DEBUG_OBJECT (pool->other_pool, "failed to acquire buffer");
495+
}
496+
}
480497
break;
481498
default:
482499
newbuf = NULL;
@@ -512,6 +529,11 @@ gst_v4l2_buffer_pool_alloc_buffer (GstBufferPool * bpool, GstBuffer ** buffer,
512529

513530
*buffer = newbuf;
514531

532+
if (downstream_buffer) {
533+
gst_mini_object_set_qdata (GST_MINI_OBJECT (newbuf), GST_V4L2_IMPORT_QUARK,
534+
downstream_buffer, (GDestroyNotify) gst_buffer_unref);
535+
}
536+
515537
return GST_FLOW_OK;
516538

517539
/* ERRORS */
@@ -566,6 +588,7 @@ gst_v4l2_buffer_pool_set_config (GstBufferPool * bpool, GstStructure * config)
566588
GST_V4L2_ALLOCATOR_CAN_ALLOCATE (pool->vallocator, USERPTR);
567589
break;
568590
case GST_V4L2_IO_DMABUF_IMPORT:
591+
pool->allocator = gst_dmabuf_allocator_new ();
569592
can_allocate = GST_V4L2_ALLOCATOR_CAN_ALLOCATE (pool->vallocator, DMABUF);
570593
break;
571594
case GST_V4L2_IO_RW:
@@ -1741,7 +1764,6 @@ gst_v4l2_buffer_pool_complete_release_buffer (GstBufferPool * bpool,
17411764
case GST_V4L2_IO_DMABUF:
17421765
case GST_V4L2_IO_MMAP:
17431766
case GST_V4L2_IO_USERPTR:
1744-
case GST_V4L2_IO_DMABUF_IMPORT:
17451767
{
17461768
GstV4l2MemoryGroup *group;
17471769
if (gst_v4l2_is_buffer_valid (buffer, &group)) {
@@ -1773,6 +1795,22 @@ gst_v4l2_buffer_pool_complete_release_buffer (GstBufferPool * bpool,
17731795
}
17741796
break;
17751797
}
1798+
case GST_V4L2_IO_DMABUF_IMPORT:
1799+
{
1800+
GstV4l2MemoryGroup *group;
1801+
if (gst_v4l2_is_buffer_valid (buffer, &group)) {
1802+
GstFlowReturn ret = GST_FLOW_OK;
1803+
if (ret != GST_FLOW_OK ||
1804+
gst_v4l2_buffer_pool_qbuf (pool, buffer, group, NULL) != GST_FLOW_OK)
1805+
pclass->release_buffer (bpool, buffer);
1806+
} else {
1807+
/* Simply release invalid/modified buffer, the allocator will
1808+
* give it back later */
1809+
GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_TAG_MEMORY);
1810+
pclass->release_buffer (bpool, buffer);
1811+
}
1812+
break;
1813+
}
17761814
default:
17771815
g_assert_not_reached ();
17781816
break;
@@ -2221,17 +2259,6 @@ gst_v4l2_buffer_pool_process (GstV4l2BufferPool * pool, GstBuffer ** buf,
22212259

22222260
case GST_V4L2_IO_DMABUF_IMPORT:
22232261
{
2224-
GstBuffer *tmp;
2225-
2226-
/* Replace our buffer with downstream allocated buffer */
2227-
tmp = gst_mini_object_steal_qdata (GST_MINI_OBJECT (*buf),
2228-
GST_V4L2_IMPORT_QUARK);
2229-
2230-
gst_buffer_copy_into (tmp, *buf,
2231-
GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_TIMESTAMPS, 0, -1);
2232-
2233-
gst_buffer_replace (buf, tmp);
2234-
gst_buffer_unref (tmp);
22352262
break;
22362263
}
22372264

subprojects/gst-plugins-good/sys/v4l2/gstv4l2object.c

+5-1
Original file line numberDiff line numberDiff line change
@@ -5214,7 +5214,11 @@ gst_v4l2_object_decide_allocation (GstV4l2Object * obj, GstQuery * query)
52145214
gst_v4l2_buffer_pool_copy_at_threshold (GST_V4L2_BUFFER_POOL (pool),
52155215
FALSE);
52165216
}
5217-
5217+
} else if (V4L2_TYPE_IS_CAPTURE(obj->type) && (obj->mode == GST_V4L2_IO_DMABUF_IMPORT)) {
5218+
// since we reuse right index, so let's keep buffer number of downstream pool same with v4l2buffer pool
5219+
GST_DEBUG_OBJECT (pool, "got min: %d own_min: %d max: %d min_buffers:%d", min, own_min, max, obj->min_buffers);
5220+
own_min = (obj->min_buffers) + min + 1;
5221+
min = own_min;
52185222
} else {
52195223
/* In this case we'll have to configure two buffer pool. For our buffer
52205224
* pool, we'll need what the driver one, and one more, so we can dequeu */

0 commit comments

Comments
 (0)