v4l2src: fix support for bayer format
[platform/upstream/gstreamer.git] / subprojects / gst-plugins-good / sys / v4l2 / gstv4l2bufferpool.c
1 /* GStreamer
2  *
3  * Copyright (C) 2001-2002 Ronald Bultje <rbultje@ronald.bitfreak.net>
4  *               2006 Edgard Lima <edgard.lima@gmail.com>
5  *               2009 Texas Instruments, Inc - http://www.ti.com/
6  *
7  * gstv4l2bufferpool.c V4L2 buffer pool class
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Library General Public
11  * License as published by the Free Software Foundation; either
12  * version 2 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Library General Public License for more details.
18  *
19  * You should have received a copy of the GNU Library General Public
20  * License along with this library; if not, write to the
21  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
22  * Boston, MA 02110-1301, USA.
23  */
24
25 #ifdef HAVE_CONFIG_H
26 #  include <config.h>
27 #endif
28
29 #ifndef _GNU_SOURCE
30 # define _GNU_SOURCE            /* O_CLOEXEC */
31 #endif
32 #include <fcntl.h>
33
34 #include <sys/mman.h>
35 #include <string.h>
36 #include <unistd.h>
37
38 #include "gst/video/video.h"
39 #include "gst/video/gstvideometa.h"
40 #include "gst/video/gstvideopool.h"
41 #include "gst/allocators/gstdmabuf.h"
42
43 #include <gstv4l2bufferpool.h>
44
45 #include "gstv4l2object.h"
46 #include <glib/gi18n-lib.h>
47 #include <gst/glib-compat-private.h>
48
49 GST_DEBUG_CATEGORY_STATIC (v4l2bufferpool_debug);
50 GST_DEBUG_CATEGORY_STATIC (CAT_PERFORMANCE);
51 #define GST_CAT_DEFAULT v4l2bufferpool_debug
52
53 #define GST_V4L2_IMPORT_QUARK gst_v4l2_buffer_pool_import_quark ()
54
55
56 /*
57  * GstV4l2BufferPool:
58  */
59 #define gst_v4l2_buffer_pool_parent_class parent_class
60 G_DEFINE_TYPE (GstV4l2BufferPool, gst_v4l2_buffer_pool, GST_TYPE_BUFFER_POOL);
61
62 enum _GstV4l2BufferPoolAcquireFlags
63 {
64   GST_V4L2_BUFFER_POOL_ACQUIRE_FLAG_RESURRECT =
65       GST_BUFFER_POOL_ACQUIRE_FLAG_LAST,
66   GST_V4L2_BUFFER_POOL_ACQUIRE_FLAG_LAST
67 };
68
69 /* Buffer state flags */
70 enum _GstV4l2BufferState
71 {
72   /* Buffer is free (either on the GstBufferPool free queue, or no GstBuffer has
73    * been allocated yet) */
74   BUFFER_STATE_FREE = 0,
75
76   /* Buffer had outstanding external users */
77   BUFFER_STATE_OUTSTANDING = 1,
78
79   /* Buffer is on one of the kernel queues */
80   BUFFER_STATE_QUEUED = 2,
81 };
82
83 static void gst_v4l2_buffer_pool_complete_release_buffer (GstBufferPool * bpool,
84     GstBuffer * buffer, gboolean queued);
85
86 static gboolean
87 gst_v4l2_is_buffer_valid (GstBuffer * buffer, GstV4l2MemoryGroup ** out_group)
88 {
89   GstMemory *mem = gst_buffer_peek_memory (buffer, 0);
90   gboolean valid = FALSE;
91
92   if (GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_TAG_MEMORY))
93     goto done;
94
95   if (gst_is_dmabuf_memory (mem))
96     mem = gst_mini_object_get_qdata (GST_MINI_OBJECT (mem),
97         GST_V4L2_MEMORY_QUARK);
98
99   if (mem && gst_is_v4l2_memory (mem)) {
100     GstV4l2Memory *vmem = (GstV4l2Memory *) mem;
101     GstV4l2MemoryGroup *group = vmem->group;
102     gint i;
103
104     if (group->n_mem != gst_buffer_n_memory (buffer))
105       goto done;
106
107     for (i = 0; i < group->n_mem; i++) {
108       if (group->mem[i] != gst_buffer_peek_memory (buffer, i))
109         goto done;
110
111       if (!gst_memory_is_writable (group->mem[i]))
112         goto done;
113     }
114
115     valid = TRUE;
116     if (out_group)
117       *out_group = group;
118   }
119
120 done:
121   return valid;
122 }
123
124 static void
125 gst_v4l2_buffer_pool_resize_buffer (GstBufferPool * bpool, GstBuffer * buffer)
126 {
127   GstV4l2BufferPool *pool = GST_V4L2_BUFFER_POOL (bpool);
128   GstV4l2MemoryGroup *group;
129
130   if (gst_v4l2_is_buffer_valid (buffer, &group)) {
131     gst_v4l2_allocator_reset_group (pool->vallocator, group);
132   } else {
133     GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_TAG_MEMORY);
134   }
135 }
136
137 static GstFlowReturn
138 gst_v4l2_buffer_pool_copy_buffer (GstV4l2BufferPool * pool, GstBuffer * dest,
139     GstBuffer * src)
140 {
141   const GstVideoFormatInfo *finfo = pool->caps_info.finfo;
142
143   GST_LOG_OBJECT (pool, "copying buffer");
144
145   if (finfo && (finfo->format != GST_VIDEO_FORMAT_UNKNOWN &&
146           finfo->format != GST_VIDEO_FORMAT_ENCODED)) {
147     GstVideoFrame src_frame, dest_frame;
148
149     GST_DEBUG_OBJECT (pool, "copy video frame");
150
151     /* we have raw video, use videoframe copy to get strides right */
152     if (!gst_video_frame_map (&src_frame, &pool->caps_info, src, GST_MAP_READ))
153       goto invalid_buffer;
154
155     if (!gst_video_frame_map (&dest_frame, &pool->caps_info, dest,
156             GST_MAP_WRITE)) {
157       gst_video_frame_unmap (&src_frame);
158       goto invalid_buffer;
159     }
160
161     gst_video_frame_copy (&dest_frame, &src_frame);
162
163     gst_video_frame_unmap (&src_frame);
164     gst_video_frame_unmap (&dest_frame);
165   } else {
166     GstMapInfo map;
167
168     GST_DEBUG_OBJECT (pool, "copy raw bytes");
169
170     if (!gst_buffer_map (src, &map, GST_MAP_READ))
171       goto invalid_buffer;
172
173     gst_buffer_fill (dest, 0, map.data, gst_buffer_get_size (src));
174
175     gst_buffer_unmap (src, &map);
176     gst_buffer_resize (dest, 0, gst_buffer_get_size (src));
177   }
178
179   gst_buffer_copy_into (dest, src,
180       GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_TIMESTAMPS, 0, -1);
181
182   GST_CAT_LOG_OBJECT (CAT_PERFORMANCE, pool, "slow copy into buffer %p", dest);
183
184   return GST_FLOW_OK;
185
186 invalid_buffer:
187   {
188     GST_ERROR_OBJECT (pool, "could not map buffer");
189     return GST_FLOW_ERROR;
190   }
191 }
192
193 struct UserPtrData
194 {
195   GstBuffer *buffer;
196   gboolean is_frame;
197   GstVideoFrame frame;
198   GstMapInfo map;
199 };
200
201 static GQuark
202 gst_v4l2_buffer_pool_import_quark (void)
203 {
204   static GQuark quark = 0;
205
206   if (quark == 0)
207     quark = g_quark_from_string ("GstV4l2BufferPoolUsePtrData");
208
209   return quark;
210 }
211
212 static void
213 _unmap_userptr_frame (struct UserPtrData *data)
214 {
215   if (data->is_frame)
216     gst_video_frame_unmap (&data->frame);
217   else
218     gst_buffer_unmap (data->buffer, &data->map);
219
220   if (data->buffer)
221     gst_buffer_unref (data->buffer);
222
223   g_slice_free (struct UserPtrData, data);
224 }
225
226 static GstFlowReturn
227 gst_v4l2_buffer_pool_import_userptr (GstV4l2BufferPool * pool,
228     GstBuffer * dest, GstBuffer * src)
229 {
230   GstFlowReturn ret = GST_FLOW_OK;
231   GstV4l2MemoryGroup *group = NULL;
232   GstMapFlags flags;
233   const GstVideoFormatInfo *finfo = pool->caps_info.finfo;
234   struct UserPtrData *data = NULL;
235
236   GST_LOG_OBJECT (pool, "importing userptr");
237
238   /* get the group */
239   if (!gst_v4l2_is_buffer_valid (dest, &group))
240     goto not_our_buffer;
241
242   if (V4L2_TYPE_IS_OUTPUT (pool->obj->type))
243     flags = GST_MAP_READ;
244   else
245     flags = GST_MAP_WRITE;
246
247   data = g_slice_new0 (struct UserPtrData);
248
249   if (finfo && (finfo->format != GST_VIDEO_FORMAT_UNKNOWN &&
250           finfo->format != GST_VIDEO_FORMAT_ENCODED)) {
251     gsize size[GST_VIDEO_MAX_PLANES] = { 0, };
252     gint i;
253
254     data->is_frame = TRUE;
255
256     if (!gst_video_frame_map (&data->frame, &pool->caps_info, src, flags))
257       goto invalid_buffer;
258
259     for (i = 0; i < GST_VIDEO_FORMAT_INFO_N_PLANES (finfo); i++) {
260       if (GST_VIDEO_FORMAT_INFO_IS_TILED (finfo)) {
261         gint tinfo = GST_VIDEO_FRAME_PLANE_STRIDE (&data->frame, i);
262         size[i] = GST_VIDEO_TILE_X_TILES (tinfo) *
263             GST_VIDEO_TILE_Y_TILES (tinfo) *
264             GST_VIDEO_FORMAT_INFO_TILE_SIZE (finfo, i);
265       } else {
266         size[i] = GST_VIDEO_FRAME_PLANE_STRIDE (&data->frame, i) *
267             GST_VIDEO_FRAME_COMP_HEIGHT (&data->frame, i);
268       }
269     }
270
271     /* In the single planar API, planes must be contiguous in memory and
272      * therefore they must have expected size. ie: no padding.
273      * To check these conditions, we check that plane 'i' start address
274      * + plane 'i' size equals to plane 'i+1' start address */
275     if (!V4L2_TYPE_IS_MULTIPLANAR (pool->obj->type)) {
276       for (i = 0; i < (GST_VIDEO_FORMAT_INFO_N_PLANES (finfo) - 1); i++) {
277         const struct v4l2_pix_format *pix_fmt = &pool->obj->format.fmt.pix;
278         gpointer tmp;
279         gint estride = gst_video_format_info_extrapolate_stride (finfo, i,
280             pix_fmt->bytesperline);
281         guint eheight = GST_VIDEO_FORMAT_INFO_SCALE_HEIGHT (finfo, i,
282             pix_fmt->height);
283
284         tmp = ((guint8 *) data->frame.data[i]) + estride * eheight;
285         if (tmp != data->frame.data[i + 1])
286           goto non_contiguous_mem;
287       }
288     }
289
290     if (!gst_v4l2_allocator_import_userptr (pool->vallocator, group,
291             data->frame.info.size, finfo->n_planes, data->frame.data, size))
292       goto import_failed;
293   } else {
294     gpointer ptr[1];
295     gsize size[1];
296
297     data->is_frame = FALSE;
298
299     if (!gst_buffer_map (src, &data->map, flags))
300       goto invalid_buffer;
301
302     ptr[0] = data->map.data;
303     size[0] = data->map.size;
304
305     if (!gst_v4l2_allocator_import_userptr (pool->vallocator, group,
306             data->map.size, 1, ptr, size))
307       goto import_failed;
308   }
309
310   data->buffer = gst_buffer_ref (src);
311
312   gst_mini_object_set_qdata (GST_MINI_OBJECT (dest), GST_V4L2_IMPORT_QUARK,
313       data, (GDestroyNotify) _unmap_userptr_frame);
314
315   gst_buffer_copy_into (dest, src,
316       GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_TIMESTAMPS, 0, -1);
317
318   return ret;
319
320 not_our_buffer:
321   {
322     GST_ERROR_OBJECT (pool, "destination buffer invalid or not from our pool");
323     return GST_FLOW_ERROR;
324   }
325 invalid_buffer:
326   {
327     GST_ERROR_OBJECT (pool, "could not map buffer");
328     g_slice_free (struct UserPtrData, data);
329     return GST_FLOW_ERROR;
330   }
331 non_contiguous_mem:
332   {
333     GST_ERROR_OBJECT (pool, "memory is not contiguous or plane size mismatch");
334     _unmap_userptr_frame (data);
335     return GST_FLOW_ERROR;
336   }
337 import_failed:
338   {
339     GST_ERROR_OBJECT (pool, "failed to import data");
340     _unmap_userptr_frame (data);
341     return GST_FLOW_ERROR;
342   }
343 }
344
345 static GstFlowReturn
346 gst_v4l2_buffer_pool_import_dmabuf (GstV4l2BufferPool * pool,
347     GstBuffer * dest, GstBuffer * src)
348 {
349   GstV4l2MemoryGroup *group = NULL;
350   GstMemory *dma_mem[GST_VIDEO_MAX_PLANES] = { 0 };
351   guint n_mem = gst_buffer_n_memory (src);
352   gint i;
353
354   GST_LOG_OBJECT (pool, "importing dmabuf");
355
356   if (!gst_v4l2_is_buffer_valid (dest, &group))
357     goto not_our_buffer;
358
359   if (n_mem > GST_VIDEO_MAX_PLANES)
360     goto too_many_mems;
361
362   for (i = 0; i < n_mem; i++)
363     dma_mem[i] = gst_buffer_peek_memory (src, i);
364
365   if (!gst_v4l2_allocator_import_dmabuf (pool->vallocator, group, n_mem,
366           dma_mem))
367     goto import_failed;
368
369   gst_mini_object_set_qdata (GST_MINI_OBJECT (dest), GST_V4L2_IMPORT_QUARK,
370       gst_buffer_ref (src), (GDestroyNotify) gst_buffer_unref);
371
372   gst_buffer_copy_into (dest, src,
373       GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_TIMESTAMPS, 0, -1);
374
375   return GST_FLOW_OK;
376
377 not_our_buffer:
378   {
379     GST_ERROR_OBJECT (pool, "destination buffer invalid or not from our pool");
380     return GST_FLOW_ERROR;
381   }
382 too_many_mems:
383   {
384     GST_ERROR_OBJECT (pool, "could not map buffer");
385     return GST_FLOW_ERROR;
386   }
387 import_failed:
388   {
389     GST_ERROR_OBJECT (pool, "failed to import dmabuf");
390     return GST_FLOW_ERROR;
391   }
392 }
393
394 static GstFlowReturn
395 gst_v4l2_buffer_pool_prepare_buffer (GstV4l2BufferPool * pool,
396     GstBuffer * dest, GstBuffer * src)
397 {
398   GstFlowReturn ret = GST_FLOW_OK;
399   gboolean own_src = FALSE;
400
401   if (src == NULL) {
402     if (pool->other_pool == NULL) {
403       GST_ERROR_OBJECT (pool, "can't prepare buffer, source buffer missing");
404       return GST_FLOW_ERROR;
405     }
406
407     ret = gst_buffer_pool_acquire_buffer (pool->other_pool, &src, NULL);
408     if (ret != GST_FLOW_OK) {
409       GST_ERROR_OBJECT (pool, "failed to acquire buffer from downstream pool");
410       goto done;
411     }
412
413     own_src = TRUE;
414   }
415
416   switch (pool->obj->mode) {
417     case GST_V4L2_IO_MMAP:
418     case GST_V4L2_IO_DMABUF:
419       ret = gst_v4l2_buffer_pool_copy_buffer (pool, dest, src);
420       break;
421     case GST_V4L2_IO_USERPTR:
422       ret = gst_v4l2_buffer_pool_import_userptr (pool, dest, src);
423       break;
424     case GST_V4L2_IO_DMABUF_IMPORT:
425       ret = gst_v4l2_buffer_pool_import_dmabuf (pool, dest, src);
426       break;
427     default:
428       break;
429   }
430
431   if (own_src)
432     gst_buffer_unref (src);
433
434 done:
435   return ret;
436 }
437
438 static GstFlowReturn
439 gst_v4l2_buffer_pool_alloc_buffer (GstBufferPool * bpool, GstBuffer ** buffer,
440     GstBufferPoolAcquireParams * params)
441 {
442   GstV4l2BufferPool *pool = GST_V4L2_BUFFER_POOL (bpool);
443   GstV4l2MemoryGroup *group = NULL;
444   GstBuffer *newbuf = NULL;
445   GstV4l2Object *obj;
446   GstVideoInfo *info;
447
448   obj = pool->obj;
449   info = &obj->info;
450
451   switch (obj->mode) {
452     case GST_V4L2_IO_RW:
453       newbuf =
454           gst_buffer_new_allocate (pool->allocator, pool->size, &pool->params);
455       break;
456     case GST_V4L2_IO_MMAP:
457       group = gst_v4l2_allocator_alloc_mmap (pool->vallocator);
458       break;
459     case GST_V4L2_IO_DMABUF:
460       group = gst_v4l2_allocator_alloc_dmabuf (pool->vallocator,
461           pool->allocator);
462       break;
463     case GST_V4L2_IO_USERPTR:
464       group = gst_v4l2_allocator_alloc_userptr (pool->vallocator);
465       break;
466     case GST_V4L2_IO_DMABUF_IMPORT:
467       group = gst_v4l2_allocator_alloc_dmabufin (pool->vallocator);
468       break;
469     default:
470       newbuf = NULL;
471       g_assert_not_reached ();
472       break;
473   }
474
475   if (group != NULL) {
476     gint i;
477     newbuf = gst_buffer_new ();
478
479     for (i = 0; i < group->n_mem; i++)
480       gst_buffer_append_memory (newbuf, group->mem[i]);
481
482     if (g_atomic_int_get (&pool->buffer_state[group->buffer.index])) {
483       GST_WARNING_OBJECT (pool, "newly allocated buffer %u is not free",
484           group->buffer.index);
485     }
486   } else if (newbuf == NULL) {
487     goto allocation_failed;
488   }
489
490   /* add metadata to raw video buffers */
491   if (pool->add_videometa) {
492     GstVideoMeta *videometa =
493         gst_buffer_add_video_meta_full (newbuf, GST_VIDEO_FRAME_FLAG_NONE,
494         GST_VIDEO_INFO_FORMAT (info), GST_VIDEO_INFO_WIDTH (info),
495         GST_VIDEO_INFO_HEIGHT (info), GST_VIDEO_INFO_N_PLANES (info),
496         info->offset, info->stride);
497     if (videometa)
498       gst_video_meta_set_alignment (videometa, obj->align);
499   }
500
501   *buffer = newbuf;
502
503   return GST_FLOW_OK;
504
505   /* ERRORS */
506 allocation_failed:
507   {
508     GST_ERROR_OBJECT (pool, "failed to allocate buffer");
509     return GST_FLOW_ERROR;
510   }
511 }
512
513 static gboolean
514 gst_v4l2_buffer_pool_set_config (GstBufferPool * bpool, GstStructure * config)
515 {
516   GstV4l2BufferPool *pool = GST_V4L2_BUFFER_POOL (bpool);
517   GstV4l2Object *obj = pool->obj;
518   GstCaps *caps;
519   guint size, min_buffers, max_buffers;
520   GstAllocator *allocator;
521   GstAllocationParams params;
522   gboolean can_allocate = FALSE;
523   gboolean updated = FALSE;
524   gboolean ret;
525
526   pool->add_videometa =
527       gst_buffer_pool_config_has_option (config,
528       GST_BUFFER_POOL_OPTION_VIDEO_META);
529
530   /* parse the config and keep around */
531   if (!gst_buffer_pool_config_get_params (config, &caps, &size, &min_buffers,
532           &max_buffers))
533     goto wrong_config;
534
535   if (!gst_buffer_pool_config_get_allocator (config, &allocator, &params))
536     goto wrong_config;
537
538   GST_DEBUG_OBJECT (pool, "config %" GST_PTR_FORMAT, config);
539
540   if (pool->allocator)
541     gst_object_unref (pool->allocator);
542   pool->allocator = NULL;
543
544   switch (obj->mode) {
545     case GST_V4L2_IO_DMABUF:
546       pool->allocator = gst_dmabuf_allocator_new ();
547       can_allocate = GST_V4L2_ALLOCATOR_CAN_ALLOCATE (pool->vallocator, MMAP);
548       break;
549     case GST_V4L2_IO_MMAP:
550       can_allocate = GST_V4L2_ALLOCATOR_CAN_ALLOCATE (pool->vallocator, MMAP);
551       break;
552     case GST_V4L2_IO_USERPTR:
553       can_allocate =
554           GST_V4L2_ALLOCATOR_CAN_ALLOCATE (pool->vallocator, USERPTR);
555       break;
556     case GST_V4L2_IO_DMABUF_IMPORT:
557       can_allocate = GST_V4L2_ALLOCATOR_CAN_ALLOCATE (pool->vallocator, DMABUF);
558       break;
559     case GST_V4L2_IO_RW:
560       if (allocator)
561         pool->allocator = g_object_ref (allocator);
562       pool->params = params;
563       /* No need to change the configuration */
564       goto done;
565       break;
566     default:
567       g_assert_not_reached ();
568       break;
569   }
570
571   /* libv4l2 conversion code does not handle CREATE_BUFS, and may lead to
572    * instability and crash, disable it for now */
573   if (can_allocate && obj->fmtdesc->flags & V4L2_FMT_FLAG_EMULATED) {
574     GST_WARNING_OBJECT (pool,
575         "libv4l2 converter detected, disabling CREATE_BUFS");
576     can_allocate = FALSE;
577     GST_OBJECT_FLAG_UNSET (pool->vallocator,
578         GST_V4L2_ALLOCATOR_FLAG_MMAP_CREATE_BUFS
579         | GST_V4L2_ALLOCATOR_FLAG_USERPTR_CREATE_BUFS
580         | GST_V4L2_ALLOCATOR_FLAG_DMABUF_CREATE_BUFS);
581   }
582
583   if (min_buffers < GST_V4L2_MIN_BUFFERS (obj)) {
584     updated = TRUE;
585     min_buffers = GST_V4L2_MIN_BUFFERS (obj);
586     GST_INFO_OBJECT (pool, "increasing minimum buffers to %u", min_buffers);
587   }
588
589   /* respect driver requirements */
590   if (min_buffers < obj->min_buffers) {
591     updated = TRUE;
592     min_buffers = obj->min_buffers;
593     GST_INFO_OBJECT (pool, "increasing minimum buffers to %u", min_buffers);
594   }
595
596   if (max_buffers > VIDEO_MAX_FRAME || max_buffers == 0) {
597     updated = TRUE;
598     max_buffers = VIDEO_MAX_FRAME;
599     GST_INFO_OBJECT (pool, "reducing maximum buffers to %u", max_buffers);
600   }
601
602   if (min_buffers > max_buffers) {
603     updated = TRUE;
604     min_buffers = max_buffers;
605     GST_INFO_OBJECT (pool, "reducing minimum buffers to %u", min_buffers);
606   } else if (min_buffers != max_buffers) {
607     if (!can_allocate) {
608       updated = TRUE;
609       max_buffers = min_buffers;
610       GST_INFO_OBJECT (pool, "can't allocate, setting maximum to minimum");
611     }
612   }
613
614   if (!pool->add_videometa && obj->need_video_meta) {
615     GST_INFO_OBJECT (pool, "adding needed video meta");
616     updated = TRUE;
617     gst_buffer_pool_config_add_option (config,
618         GST_BUFFER_POOL_OPTION_VIDEO_META);
619   }
620
621   /* Always update the config to ensure the configured size matches */
622   gst_buffer_pool_config_set_params (config, caps, obj->info.size, min_buffers,
623       max_buffers);
624
625   /* keep a GstVideoInfo with defaults for the when we need to copy */
626   gst_video_info_from_caps (&pool->caps_info, caps);
627
628 done:
629   ret = GST_BUFFER_POOL_CLASS (parent_class)->set_config (bpool, config);
630
631   /* If anything was changed documentation recommend to return FALSE */
632   return !updated && ret;
633
634   /* ERRORS */
635 wrong_config:
636   {
637     GST_ERROR_OBJECT (pool, "invalid config %" GST_PTR_FORMAT, config);
638     return FALSE;
639   }
640 }
641
642 static GstFlowReturn
643 gst_v4l2_buffer_pool_resurrect_buffer (GstV4l2BufferPool * pool)
644 {
645   GstBufferPoolAcquireParams params = { 0 };
646   GstBuffer *buffer = NULL;
647   GstFlowReturn ret;
648
649   GST_DEBUG_OBJECT (pool, "A buffer was lost, reallocating it");
650
651   /* block recursive calls to this function */
652   g_signal_handler_block (pool->vallocator, pool->group_released_handler);
653
654   params.flags =
655       (GstBufferPoolAcquireFlags) GST_V4L2_BUFFER_POOL_ACQUIRE_FLAG_RESURRECT |
656       GST_BUFFER_POOL_ACQUIRE_FLAG_DONTWAIT;
657   ret =
658       gst_buffer_pool_acquire_buffer (GST_BUFFER_POOL (pool), &buffer, &params);
659
660   if (ret == GST_FLOW_OK)
661     gst_buffer_unref (buffer);
662
663   g_signal_handler_unblock (pool->vallocator, pool->group_released_handler);
664
665   return ret;
666 }
667
668 static gboolean
669 gst_v4l2_buffer_pool_streamon (GstV4l2BufferPool * pool)
670 {
671   GstV4l2Object *obj = pool->obj;
672
673   if (pool->streaming)
674     return TRUE;
675
676   switch (obj->mode) {
677     case GST_V4L2_IO_MMAP:
678     case GST_V4L2_IO_USERPTR:
679     case GST_V4L2_IO_DMABUF:
680     case GST_V4L2_IO_DMABUF_IMPORT:
681       if (!V4L2_TYPE_IS_OUTPUT (pool->obj->type)) {
682         guint num_queued;
683         guint i, n = 0;
684
685         num_queued = g_atomic_int_get (&pool->num_queued);
686         if (num_queued < pool->num_allocated)
687           n = pool->num_allocated - num_queued;
688
689         /* For captures, we need to enqueue buffers before we start streaming,
690          * so the driver don't underflow immediately. As we have put then back
691          * into the base class queue, resurrect them, then releasing will queue
692          * them back. */
693         for (i = 0; i < n; i++)
694           gst_v4l2_buffer_pool_resurrect_buffer (pool);
695       }
696
697       if (obj->ioctl (pool->video_fd, VIDIOC_STREAMON, &obj->type) < 0)
698         goto streamon_failed;
699
700       pool->streaming = TRUE;
701
702       GST_DEBUG_OBJECT (pool, "Started streaming");
703       break;
704     default:
705       break;
706   }
707
708   return TRUE;
709
710 streamon_failed:
711   {
712     GST_ERROR_OBJECT (pool, "error with STREAMON %d (%s)", errno,
713         g_strerror (errno));
714     return FALSE;
715   }
716 }
717
718 /* Call with streamlock held, or when streaming threads are down */
719 static void
720 gst_v4l2_buffer_pool_streamoff (GstV4l2BufferPool * pool)
721 {
722   GstBufferPoolClass *pclass = GST_BUFFER_POOL_CLASS (parent_class);
723   GstV4l2Object *obj = pool->obj;
724   gint i;
725
726   if (!pool->streaming)
727     return;
728
729   switch (obj->mode) {
730     case GST_V4L2_IO_MMAP:
731     case GST_V4L2_IO_USERPTR:
732     case GST_V4L2_IO_DMABUF:
733     case GST_V4L2_IO_DMABUF_IMPORT:
734
735       if (obj->ioctl (pool->video_fd, VIDIOC_STREAMOFF, &obj->type) < 0)
736         GST_WARNING_OBJECT (pool, "STREAMOFF failed with errno %d (%s)",
737             errno, g_strerror (errno));
738
739       pool->streaming = FALSE;
740
741       GST_DEBUG_OBJECT (pool, "Stopped streaming");
742
743       if (pool->vallocator)
744         gst_v4l2_allocator_flush (pool->vallocator);
745       break;
746     default:
747       break;
748   }
749
750   for (i = 0; i < VIDEO_MAX_FRAME; i++) {
751     gint old_buffer_state =
752         g_atomic_int_and (&pool->buffer_state[i], ~BUFFER_STATE_QUEUED);
753     if ((old_buffer_state & BUFFER_STATE_QUEUED) && pool->buffers[i]) {
754       GstBuffer *buffer = pool->buffers[i];
755       GstBufferPool *bpool = GST_BUFFER_POOL (pool);
756
757       pool->buffers[i] = NULL;
758
759       if (!(old_buffer_state & BUFFER_STATE_OUTSTANDING)) {
760         if (V4L2_TYPE_IS_OUTPUT (pool->obj->type))
761           gst_v4l2_buffer_pool_complete_release_buffer (bpool, buffer, FALSE);
762
763         else                    /* Don't re-enqueue capture buffer on stop */
764           pclass->release_buffer (bpool, buffer);
765       }
766
767       g_atomic_int_add (&pool->num_queued, -1);
768     }
769   }
770 }
771
772 static gboolean
773 gst_v4l2_buffer_pool_start (GstBufferPool * bpool)
774 {
775   GstV4l2BufferPool *pool = GST_V4L2_BUFFER_POOL (bpool);
776   GstBufferPoolClass *pclass = GST_BUFFER_POOL_CLASS (parent_class);
777   GstV4l2Object *obj = pool->obj;
778   GstStructure *config;
779   GstCaps *caps;
780   guint size, min_buffers, max_buffers;
781   guint max_latency, min_latency, copy_threshold = 0;
782   gboolean can_allocate = FALSE, ret = TRUE;
783
784   GST_DEBUG_OBJECT (pool, "activating pool");
785
786   if (pool->other_pool) {
787     GstBuffer *buffer;
788
789     if (!gst_buffer_pool_set_active (pool->other_pool, TRUE))
790       goto other_pool_failed;
791
792     if (gst_buffer_pool_acquire_buffer (pool->other_pool, &buffer, NULL) !=
793         GST_FLOW_OK)
794       goto other_pool_failed;
795
796     if (!gst_v4l2_object_try_import (obj, buffer)) {
797       gst_buffer_unref (buffer);
798       goto cannot_import;
799     }
800     gst_buffer_unref (buffer);
801   }
802
803   config = gst_buffer_pool_get_config (bpool);
804   if (!gst_buffer_pool_config_get_params (config, &caps, &size, &min_buffers,
805           &max_buffers))
806     goto wrong_config;
807
808   min_latency = MAX (GST_V4L2_MIN_BUFFERS (obj), obj->min_buffers);
809
810   switch (obj->mode) {
811     case GST_V4L2_IO_RW:
812       can_allocate = TRUE;
813 #ifdef HAVE_LIBV4L2
814       /* This workaround a unfixable bug in libv4l2 when RW is emulated on top
815        * of MMAP. In this case, the first read initialize the queues, but the
816        * poll before that will always fail. Doing an empty read, forces the
817        * queue to be initialized now. We only do this if we have a streaming
818        * driver. */
819       if (obj->device_caps & V4L2_CAP_STREAMING)
820         obj->read (obj->video_fd, NULL, 0);
821 #endif
822       break;
823     case GST_V4L2_IO_DMABUF:
824     case GST_V4L2_IO_MMAP:
825     {
826       guint count;
827
828       can_allocate = GST_V4L2_ALLOCATOR_CAN_ALLOCATE (pool->vallocator, MMAP);
829
830       /* first, lets request buffers, and see how many we can get: */
831       GST_DEBUG_OBJECT (pool, "requesting %d MMAP buffers", min_buffers);
832
833       count = gst_v4l2_allocator_start (pool->vallocator, min_buffers,
834           V4L2_MEMORY_MMAP);
835       pool->num_allocated = count;
836
837       if (count < GST_V4L2_MIN_BUFFERS (obj)) {
838         min_buffers = count;
839         goto no_buffers;
840       }
841
842       /* V4L2 buffer pool are often very limited in the amount of buffers it
843        * can offer. The copy_threshold will workaround this limitation by
844        * falling back to copy if the pipeline needed more buffers. This also
845        * prevent having to do REQBUFS(N)/REQBUFS(0) every time configure is
846        * called. */
847       if (count != min_buffers || pool->enable_copy_threshold) {
848         GST_WARNING_OBJECT (pool,
849             "Uncertain or not enough buffers, enabling copy threshold");
850         min_buffers = count;
851         copy_threshold = min_latency;
852       }
853
854       break;
855     }
856     case GST_V4L2_IO_USERPTR:
857     {
858       guint count;
859
860       can_allocate =
861           GST_V4L2_ALLOCATOR_CAN_ALLOCATE (pool->vallocator, USERPTR);
862
863       GST_DEBUG_OBJECT (pool, "requesting %d USERPTR buffers", min_buffers);
864
865       count = gst_v4l2_allocator_start (pool->vallocator, min_buffers,
866           V4L2_MEMORY_USERPTR);
867       pool->num_allocated = count;
868
869       /* There is no rational to not get what we asked */
870       if (count < min_buffers) {
871         min_buffers = count;
872         goto no_buffers;
873       }
874
875       min_buffers = count;
876       break;
877     }
878     case GST_V4L2_IO_DMABUF_IMPORT:
879     {
880       guint count;
881
882       can_allocate = GST_V4L2_ALLOCATOR_CAN_ALLOCATE (pool->vallocator, DMABUF);
883
884       GST_DEBUG_OBJECT (pool, "requesting %d DMABUF buffers", min_buffers);
885
886       count = gst_v4l2_allocator_start (pool->vallocator, min_buffers,
887           V4L2_MEMORY_DMABUF);
888       pool->num_allocated = count;
889
890       /* There is no rational to not get what we asked */
891       if (count < min_buffers) {
892         min_buffers = count;
893         goto no_buffers;
894       }
895
896       min_buffers = count;
897       break;
898     }
899     default:
900       min_buffers = 0;
901       copy_threshold = 0;
902       g_assert_not_reached ();
903       break;
904   }
905
906   if (can_allocate)
907     max_latency = max_buffers;
908   else
909     max_latency = min_buffers;
910
911   pool->size = size;
912   pool->copy_threshold = copy_threshold;
913   pool->max_latency = max_latency;
914   pool->min_latency = min_latency;
915   pool->num_queued = 0;
916
917   if (max_buffers != 0 && max_buffers < min_buffers)
918     max_buffers = min_buffers;
919
920   gst_buffer_pool_config_set_params (config, caps, size, min_buffers,
921       max_buffers);
922   pclass->set_config (bpool, config);
923   gst_structure_free (config);
924
925   /* now, allocate the buffers: */
926   if (!pclass->start (bpool))
927     goto start_failed;
928
929   if (!V4L2_TYPE_IS_OUTPUT (obj->type)) {
930     if (g_atomic_int_get (&pool->num_queued) < pool->num_allocated)
931       goto queue_failed;
932
933     pool->group_released_handler =
934         g_signal_connect_swapped (pool->vallocator, "group-released",
935         G_CALLBACK (gst_v4l2_buffer_pool_resurrect_buffer), pool);
936     ret = gst_v4l2_buffer_pool_streamon (pool);
937   }
938
939   return ret;
940
941   /* ERRORS */
942 wrong_config:
943   {
944     GST_ERROR_OBJECT (pool, "invalid config %" GST_PTR_FORMAT, config);
945     gst_structure_free (config);
946     return FALSE;
947   }
948 no_buffers:
949   {
950     GST_ERROR_OBJECT (pool,
951         "we received %d buffer from device '%s', we want at least %d",
952         min_buffers, obj->videodev, GST_V4L2_MIN_BUFFERS (obj));
953     gst_structure_free (config);
954     return FALSE;
955   }
956 start_failed:
957   {
958     GST_ERROR_OBJECT (pool, "allocate failed");
959     return FALSE;
960   }
961 other_pool_failed:
962   {
963     GST_ERROR_OBJECT (pool, "failed to activate the other pool %"
964         GST_PTR_FORMAT, pool->other_pool);
965     return FALSE;
966   }
967 queue_failed:
968   {
969     GST_ERROR_OBJECT (pool, "failed to queue buffers into the capture queue");
970     return FALSE;
971   }
972 cannot_import:
973   {
974     GST_ERROR_OBJECT (pool, "cannot import buffers from downstream pool");
975     return FALSE;
976   }
977 }
978
979 static gboolean
980 gst_v4l2_buffer_pool_vallocator_stop (GstV4l2BufferPool * pool)
981 {
982   GstV4l2Return vret;
983
984   if (!pool->vallocator)
985     return TRUE;
986
987   vret = gst_v4l2_allocator_stop (pool->vallocator);
988
989   if (vret == GST_V4L2_BUSY)
990     GST_WARNING_OBJECT (pool, "some buffers are still outstanding");
991
992   return (vret == GST_V4L2_OK);
993 }
994
995 static gboolean
996 gst_v4l2_buffer_pool_stop (GstBufferPool * bpool)
997 {
998   GstV4l2BufferPool *pool = GST_V4L2_BUFFER_POOL (bpool);
999   gboolean ret;
1000
1001   GST_DEBUG_OBJECT (pool, "stopping pool");
1002
1003   if (pool->group_released_handler > 0) {
1004     g_signal_handler_disconnect (pool->vallocator,
1005         pool->group_released_handler);
1006     pool->group_released_handler = 0;
1007   }
1008
1009   if (pool->other_pool) {
1010     gst_buffer_pool_set_active (pool->other_pool, FALSE);
1011     gst_object_unref (pool->other_pool);
1012     pool->other_pool = NULL;
1013   }
1014
1015   if (!pool->orphaned)
1016     gst_v4l2_buffer_pool_streamoff (pool);
1017
1018   ret = GST_BUFFER_POOL_CLASS (parent_class)->stop (bpool);
1019
1020   if (ret)
1021     ret = gst_v4l2_buffer_pool_vallocator_stop (pool);
1022
1023   return ret;
1024 }
1025
1026 gboolean
1027 gst_v4l2_buffer_pool_orphan (GstV4l2Object * v4l2object)
1028 {
1029   GstBufferPool *bpool = gst_v4l2_object_get_buffer_pool (v4l2object);
1030   GstV4l2BufferPool *pool;
1031   gboolean ret;
1032
1033   /* Nothing to do if there is no pool */
1034   if (!bpool)
1035     return TRUE;
1036
1037   pool = GST_V4L2_BUFFER_POOL (bpool);
1038
1039   if (pool->orphaned != FALSE
1040       || !GST_V4L2_ALLOCATOR_CAN_ORPHAN_BUFS (pool->vallocator)
1041       || g_getenv ("GST_V4L2_FORCE_DRAIN")) {
1042     gst_object_unref (bpool);
1043     return FALSE;
1044   }
1045
1046   GST_DEBUG_OBJECT (pool, "orphaning pool");
1047   gst_buffer_pool_set_active (bpool, FALSE);
1048
1049   /* We lock to prevent racing with a return buffer in QBuf, and has a
1050    * workaround of not being able to use the pool hidden activation lock. */
1051   GST_OBJECT_LOCK (pool);
1052
1053   gst_v4l2_buffer_pool_streamoff (pool);
1054   ret = gst_v4l2_allocator_orphan (pool->vallocator);
1055   if (ret)
1056     pool->orphaned = TRUE;
1057
1058   GST_OBJECT_UNLOCK (pool);
1059
1060   if (ret) {
1061     GstBufferPool *old_pool;
1062     GST_OBJECT_LOCK (v4l2object->element);
1063     old_pool = v4l2object->pool;
1064     v4l2object->pool = NULL;
1065     GST_OBJECT_UNLOCK (v4l2object->element);
1066     if (old_pool)
1067       gst_object_unref (old_pool);
1068   }
1069
1070   gst_object_unref (bpool);
1071
1072   return ret;
1073 }
1074
1075 static void
1076 gst_v4l2_buffer_pool_flush_start (GstBufferPool * bpool)
1077 {
1078   GstV4l2BufferPool *pool = GST_V4L2_BUFFER_POOL (bpool);
1079
1080   GST_DEBUG_OBJECT (pool, "start flushing");
1081
1082   gst_poll_set_flushing (pool->obj->poll, TRUE);
1083
1084   GST_OBJECT_LOCK (pool);
1085   pool->empty = FALSE;
1086   g_cond_broadcast (&pool->empty_cond);
1087   GST_OBJECT_UNLOCK (pool);
1088
1089   if (pool->other_pool && gst_buffer_pool_is_active (pool->other_pool))
1090     gst_buffer_pool_set_flushing (pool->other_pool, TRUE);
1091 }
1092
1093 static void
1094 gst_v4l2_buffer_pool_flush_stop (GstBufferPool * bpool)
1095 {
1096   GstV4l2BufferPool *pool = GST_V4L2_BUFFER_POOL (bpool);
1097
1098   GST_DEBUG_OBJECT (pool, "stop flushing");
1099
1100   if (pool->other_pool && gst_buffer_pool_is_active (pool->other_pool))
1101     gst_buffer_pool_set_flushing (pool->other_pool, FALSE);
1102
1103   gst_poll_set_flushing (pool->obj->poll, FALSE);
1104 }
1105
1106 static GstFlowReturn
1107 gst_v4l2_buffer_pool_poll (GstV4l2BufferPool * pool, gboolean wait)
1108 {
1109   GstClockTime timeout;
1110
1111   if (wait)
1112     timeout = GST_CLOCK_TIME_NONE;
1113   else
1114     timeout = 0;
1115
1116   /* In RW mode there is no queue, hence no need to wait while the queue is
1117    * empty */
1118   if (pool->obj->mode != GST_V4L2_IO_RW) {
1119     GST_OBJECT_LOCK (pool);
1120
1121     if (!wait && pool->empty) {
1122       GST_OBJECT_UNLOCK (pool);
1123       return GST_V4L2_FLOW_LAST_BUFFER;
1124     }
1125
1126     while (pool->empty)
1127       g_cond_wait (&pool->empty_cond, GST_OBJECT_GET_LOCK (pool));
1128
1129     GST_OBJECT_UNLOCK (pool);
1130   }
1131
1132   if (!pool->obj->can_poll_device) {
1133     if (wait)
1134       return GST_FLOW_OK;
1135     else
1136       return GST_V4L2_FLOW_LAST_BUFFER;
1137   }
1138
1139   return gst_v4l2_object_poll (pool->obj, timeout);
1140 }
1141
1142 static GstFlowReturn
1143 gst_v4l2_buffer_pool_qbuf (GstV4l2BufferPool * pool, GstBuffer * buf,
1144     GstV4l2MemoryGroup * group, guint32 * frame_number)
1145 {
1146   const GstV4l2Object *obj = pool->obj;
1147   gint old_buffer_state;
1148   gint index;
1149
1150   index = group->buffer.index;
1151
1152   old_buffer_state =
1153       g_atomic_int_or (&pool->buffer_state[index], BUFFER_STATE_QUEUED);
1154   if (old_buffer_state & BUFFER_STATE_QUEUED)
1155     goto already_queued;
1156
1157   GST_LOG_OBJECT (pool, "queuing buffer %i, previous-state = %i", index,
1158       old_buffer_state);
1159
1160   if (V4L2_TYPE_IS_OUTPUT (obj->type)) {
1161     enum v4l2_field field;
1162
1163     /* Buffer field is the same as the one defined in format */
1164     if (V4L2_TYPE_IS_MULTIPLANAR (obj->type))
1165       field = obj->format.fmt.pix_mp.field;
1166     else
1167       field = obj->format.fmt.pix.field;
1168
1169     group->buffer.field = field;
1170   }
1171
1172   if (frame_number) {
1173     group->buffer.timestamp.tv_sec = *frame_number;
1174     group->buffer.timestamp.tv_usec = 0;
1175   } else {
1176     if (GST_BUFFER_TIMESTAMP_IS_VALID (buf)) {
1177       GstClockTime timestamp = GST_BUFFER_TIMESTAMP (buf);
1178       GST_TIME_TO_TIMEVAL (timestamp, group->buffer.timestamp);
1179     } else {
1180       group->buffer.timestamp.tv_sec = -1;
1181       group->buffer.timestamp.tv_usec = -1;
1182     }
1183   }
1184
1185   GST_OBJECT_LOCK (pool);
1186
1187   /* If the pool was orphaned, don't try to queue any returned buffers.
1188    * This is done with the objet lock in order to synchronize with
1189    * orphaning. */
1190   if (pool->orphaned)
1191     goto was_orphaned;
1192
1193   g_atomic_int_inc (&pool->num_queued);
1194   pool->buffers[index] = buf;
1195
1196   if (!gst_v4l2_allocator_qbuf (pool->vallocator, group))
1197     goto queue_failed;
1198
1199   pool->empty = FALSE;
1200   g_cond_signal (&pool->empty_cond);
1201   GST_OBJECT_UNLOCK (pool);
1202
1203   return GST_FLOW_OK;
1204
1205 already_queued:
1206   {
1207     GST_ERROR_OBJECT (pool, "the buffer %i was already queued", index);
1208     return GST_FLOW_ERROR;
1209   }
1210 was_orphaned:
1211   {
1212     GST_DEBUG_OBJECT (pool, "pool was orphaned, not queuing back buffer.");
1213     GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_TAG_MEMORY);
1214     g_atomic_int_and (&pool->buffer_state[index], ~BUFFER_STATE_QUEUED);
1215     GST_OBJECT_UNLOCK (pool);
1216     return GST_FLOW_FLUSHING;
1217   }
1218 queue_failed:
1219   {
1220     GST_ERROR_OBJECT (pool, "could not queue a buffer %i", index);
1221     /* Mark broken buffer to the allocator */
1222     GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_TAG_MEMORY);
1223     g_atomic_int_add (&pool->num_queued, -1);
1224     pool->buffers[index] = NULL;
1225     g_atomic_int_and (&pool->buffer_state[index], ~BUFFER_STATE_QUEUED);
1226     GST_OBJECT_UNLOCK (pool);
1227     return GST_FLOW_ERROR;
1228   }
1229 }
1230
1231 static GstFlowReturn
1232 gst_v4l2_buffer_pool_dqbuf (GstV4l2BufferPool * pool, GstBuffer ** buffer,
1233     gboolean * outstanding, gboolean wait)
1234 {
1235   GstFlowReturn res;
1236   GstBuffer *outbuf = NULL;
1237   GstV4l2Object *obj = pool->obj;
1238   GstClockTime timestamp;
1239   GstV4l2MemoryGroup *group;
1240   GstVideoMeta *vmeta;
1241   gsize size;
1242   gint i;
1243   gint old_buffer_state;
1244
1245   if ((res = gst_v4l2_buffer_pool_poll (pool, wait)) < GST_FLOW_OK)
1246     goto poll_failed;
1247
1248   if (res == GST_V4L2_FLOW_LAST_BUFFER) {
1249     GST_LOG_OBJECT (pool, "nothing to dequeue");
1250     goto done;
1251   }
1252
1253   if (res == GST_V4L2_FLOW_RESOLUTION_CHANGE) {
1254     GST_INFO_OBJECT (pool, "Resolution change detected.");
1255     goto done;
1256   }
1257
1258   GST_LOG_OBJECT (pool, "dequeueing a buffer");
1259
1260   res = gst_v4l2_allocator_dqbuf (pool->vallocator, &group);
1261   if (res == GST_V4L2_FLOW_LAST_BUFFER)
1262     goto eos;
1263   if (res != GST_FLOW_OK)
1264     goto dqbuf_failed;
1265
1266   old_buffer_state =
1267       g_atomic_int_and (&pool->buffer_state[group->buffer.index],
1268       ~BUFFER_STATE_QUEUED);
1269   if (!(old_buffer_state & BUFFER_STATE_QUEUED))
1270     goto no_buffer;
1271
1272   if (outstanding) {
1273     *outstanding = (old_buffer_state & BUFFER_STATE_OUTSTANDING) != 0;
1274   } else if (old_buffer_state & BUFFER_STATE_OUTSTANDING) {
1275     GST_WARNING_OBJECT (pool, "unexpected outstanding buffer %u",
1276         group->buffer.index);
1277   }
1278
1279   outbuf = pool->buffers[group->buffer.index];
1280   if (outbuf == NULL)
1281     goto no_buffer;
1282
1283   pool->buffers[group->buffer.index] = NULL;
1284   if (g_atomic_int_dec_and_test (&pool->num_queued)) {
1285     GST_OBJECT_LOCK (pool);
1286     pool->empty = TRUE;
1287     GST_OBJECT_UNLOCK (pool);
1288   }
1289
1290   timestamp = GST_TIMEVAL_TO_TIME (group->buffer.timestamp);
1291
1292   size = 0;
1293   vmeta = gst_buffer_get_video_meta (outbuf);
1294   for (i = 0; i < group->n_mem; i++) {
1295     GST_LOG_OBJECT (pool,
1296         "dequeued buffer %p seq:%d (ix=%d), mem %p used %d, plane=%d, flags %08x, ts %"
1297         GST_TIME_FORMAT ", pool-queued=%d, buffer=%p, previous-state=%i",
1298         outbuf, group->buffer.sequence, group->buffer.index, group->mem[i],
1299         group->planes[i].bytesused, i, group->buffer.flags,
1300         GST_TIME_ARGS (timestamp), pool->num_queued, outbuf, old_buffer_state);
1301
1302     if (vmeta) {
1303       vmeta->offset[i] = size;
1304       size += gst_memory_get_sizes (group->mem[i], NULL, NULL);
1305     }
1306   }
1307
1308   /* Ignore timestamp and field for OUTPUT device */
1309   if (V4L2_TYPE_IS_OUTPUT (obj->type))
1310     goto done;
1311
1312   /* Check for driver bug in reporting feild */
1313   if (group->buffer.field == V4L2_FIELD_ANY) {
1314     /* Only warn once to avoid the spamming */
1315 #ifndef GST_DISABLE_GST_DEBUG
1316     if (!pool->has_warned_on_buggy_field) {
1317       pool->has_warned_on_buggy_field = TRUE;
1318       GST_WARNING_OBJECT (pool,
1319           "Driver should never set v4l2_buffer.field to ANY");
1320     }
1321 #endif
1322
1323     /* Use the value from the format (works for UVC bug) */
1324     group->buffer.field = obj->format.fmt.pix.field;
1325
1326     /* If driver also has buggy S_FMT, assume progressive */
1327     if (group->buffer.field == V4L2_FIELD_ANY) {
1328 #ifndef GST_DISABLE_GST_DEBUG
1329       if (!pool->has_warned_on_buggy_field) {
1330         pool->has_warned_on_buggy_field = TRUE;
1331         GST_WARNING_OBJECT (pool,
1332             "Driver should never set v4l2_format.pix.field to ANY");
1333       }
1334 #endif
1335
1336       group->buffer.field = V4L2_FIELD_NONE;
1337     }
1338   }
1339
1340   /* set top/bottom field first if v4l2_buffer has the information */
1341   switch (group->buffer.field) {
1342     case V4L2_FIELD_NONE:
1343       GST_BUFFER_FLAG_UNSET (outbuf, GST_VIDEO_BUFFER_FLAG_INTERLACED);
1344       GST_BUFFER_FLAG_UNSET (outbuf, GST_VIDEO_BUFFER_FLAG_TFF);
1345       break;
1346     case V4L2_FIELD_TOP:
1347       GST_BUFFER_FLAG_SET (outbuf, GST_VIDEO_BUFFER_FLAG_INTERLACED);
1348       GST_BUFFER_FLAG_SET (outbuf, GST_VIDEO_BUFFER_FLAG_TOP_FIELD);
1349       break;
1350     case V4L2_FIELD_BOTTOM:
1351       GST_BUFFER_FLAG_SET (outbuf, GST_VIDEO_BUFFER_FLAG_INTERLACED);
1352       GST_BUFFER_FLAG_SET (outbuf, GST_VIDEO_BUFFER_FLAG_BOTTOM_FIELD);
1353       break;
1354     case V4L2_FIELD_INTERLACED_TB:
1355       GST_BUFFER_FLAG_SET (outbuf, GST_VIDEO_BUFFER_FLAG_INTERLACED);
1356       GST_BUFFER_FLAG_SET (outbuf, GST_VIDEO_BUFFER_FLAG_TFF);
1357       break;
1358     case V4L2_FIELD_INTERLACED_BT:
1359       GST_BUFFER_FLAG_SET (outbuf, GST_VIDEO_BUFFER_FLAG_INTERLACED);
1360       GST_BUFFER_FLAG_UNSET (outbuf, GST_VIDEO_BUFFER_FLAG_TFF);
1361       break;
1362     case V4L2_FIELD_INTERLACED:
1363       GST_BUFFER_FLAG_SET (outbuf, GST_VIDEO_BUFFER_FLAG_INTERLACED);
1364       if (obj->tv_norm == V4L2_STD_NTSC_M ||
1365           obj->tv_norm == V4L2_STD_NTSC_M_JP ||
1366           obj->tv_norm == V4L2_STD_NTSC_M_KR) {
1367         GST_BUFFER_FLAG_UNSET (outbuf, GST_VIDEO_BUFFER_FLAG_TFF);
1368       } else {
1369         GST_BUFFER_FLAG_SET (outbuf, GST_VIDEO_BUFFER_FLAG_TFF);
1370       }
1371       break;
1372     default:
1373       GST_BUFFER_FLAG_UNSET (outbuf, GST_VIDEO_BUFFER_FLAG_INTERLACED);
1374       GST_BUFFER_FLAG_UNSET (outbuf, GST_VIDEO_BUFFER_FLAG_TFF);
1375       GST_FIXME_OBJECT (pool,
1376           "Unhandled enum v4l2_field %d - treating as progressive",
1377           group->buffer.field);
1378       break;
1379   }
1380
1381   if (!gst_v4l2_object_is_raw (obj)) {
1382     if ((group->buffer.flags & V4L2_BUF_FLAG_KEYFRAME) ||
1383         GST_V4L2_PIXELFORMAT (obj) == V4L2_PIX_FMT_MJPEG ||
1384         GST_V4L2_PIXELFORMAT (obj) == V4L2_PIX_FMT_JPEG ||
1385         GST_V4L2_PIXELFORMAT (obj) == V4L2_PIX_FMT_PJPG)
1386       GST_BUFFER_FLAG_UNSET (outbuf, GST_BUFFER_FLAG_DELTA_UNIT);
1387     else
1388       GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_DELTA_UNIT);
1389   }
1390
1391   if (group->buffer.flags & V4L2_BUF_FLAG_ERROR)
1392     GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_CORRUPTED);
1393
1394   GST_BUFFER_TIMESTAMP (outbuf) = timestamp;
1395   GST_BUFFER_OFFSET (outbuf) = group->buffer.sequence;
1396   GST_BUFFER_OFFSET_END (outbuf) = group->buffer.sequence + 1;
1397
1398 done:
1399   *buffer = outbuf;
1400
1401   return res;
1402
1403   /* ERRORS */
1404 poll_failed:
1405   {
1406     GST_DEBUG_OBJECT (pool, "poll error %s", gst_flow_get_name (res));
1407     return res;
1408   }
1409 eos:
1410   {
1411     return GST_V4L2_FLOW_LAST_BUFFER;
1412   }
1413 dqbuf_failed:
1414   {
1415     return GST_FLOW_ERROR;
1416   }
1417 no_buffer:
1418   {
1419     GST_ERROR_OBJECT (pool, "No free buffer found in the pool at index %d.",
1420         group->buffer.index);
1421     return GST_FLOW_ERROR;
1422   }
1423 }
1424
1425 static GstFlowReturn
1426 gst_v4l2_buffer_pool_acquire_buffer (GstBufferPool * bpool, GstBuffer ** buffer,
1427     GstBufferPoolAcquireParams * params)
1428 {
1429   GstFlowReturn ret;
1430   GstV4l2BufferPool *pool = GST_V4L2_BUFFER_POOL (bpool);
1431   GstBufferPoolClass *pclass = GST_BUFFER_POOL_CLASS (parent_class);
1432   GstV4l2Object *obj = pool->obj;
1433
1434   GST_DEBUG_OBJECT (pool, "acquire");
1435
1436   /* If this is being called to resurrect a lost buffer */
1437   if (params && params->flags & GST_V4L2_BUFFER_POOL_ACQUIRE_FLAG_RESURRECT) {
1438     ret = pclass->acquire_buffer (bpool, buffer, params);
1439     goto done;
1440   }
1441
1442   switch (obj->type) {
1443     case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1444     case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
1445       /* capture, This function should return a buffer with new captured data */
1446       switch (obj->mode) {
1447         case GST_V4L2_IO_RW:
1448         {
1449           /* take empty buffer from the pool */
1450           ret = pclass->acquire_buffer (bpool, buffer, params);
1451           break;
1452         }
1453         case GST_V4L2_IO_DMABUF:
1454         case GST_V4L2_IO_MMAP:
1455         case GST_V4L2_IO_USERPTR:
1456         case GST_V4L2_IO_DMABUF_IMPORT:
1457         {
1458           /* just dequeue a buffer, we basically use the queue of v4l2 as the
1459            * storage for our buffers. This function does poll first so we can
1460            * interrupt it fine. */
1461           ret = gst_v4l2_buffer_pool_dqbuf (pool, buffer, NULL, TRUE);
1462           break;
1463         }
1464         default:
1465           ret = GST_FLOW_ERROR;
1466           g_assert_not_reached ();
1467           break;
1468       }
1469       break;
1470
1471
1472     case V4L2_BUF_TYPE_VIDEO_OUTPUT:
1473     case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
1474       /* playback, This function should return an empty buffer */
1475       switch (obj->mode) {
1476         case GST_V4L2_IO_RW:
1477           /* get an empty buffer */
1478           ret = pclass->acquire_buffer (bpool, buffer, params);
1479           break;
1480
1481         case GST_V4L2_IO_MMAP:
1482         case GST_V4L2_IO_DMABUF:
1483         case GST_V4L2_IO_USERPTR:
1484         case GST_V4L2_IO_DMABUF_IMPORT:
1485           /* get a free unqueued buffer */
1486           ret = pclass->acquire_buffer (bpool, buffer, params);
1487           break;
1488
1489         default:
1490           ret = GST_FLOW_ERROR;
1491           g_assert_not_reached ();
1492           break;
1493       }
1494       break;
1495
1496     default:
1497       ret = GST_FLOW_ERROR;
1498       g_assert_not_reached ();
1499       break;
1500   }
1501 done:
1502   /* Mark buffer as outstanding */
1503   if (ret == GST_FLOW_OK) {
1504     GstV4l2MemoryGroup *group;
1505     if (gst_v4l2_is_buffer_valid (*buffer, &group)) {
1506       GST_LOG_OBJECT (pool, "mark buffer %u outstanding", group->buffer.index);
1507       g_atomic_int_or (&pool->buffer_state[group->buffer.index],
1508           BUFFER_STATE_OUTSTANDING);
1509     }
1510   }
1511
1512   return ret;
1513 }
1514
1515 /*
1516  * Completes a release buffer operation
1517  *
1518  * Before calling this function:
1519  * - The buffer state (if applicable) must have already been updated.
1520  * - The buffer must not be outstanding.
1521  * - The "queued" argument contains whether the buffer is currently queued.
1522  */
1523 static void
1524 gst_v4l2_buffer_pool_complete_release_buffer (GstBufferPool * bpool,
1525     GstBuffer * buffer, gboolean queued)
1526 {
1527   GstV4l2BufferPool *pool = GST_V4L2_BUFFER_POOL (bpool);
1528   GstBufferPoolClass *pclass = GST_BUFFER_POOL_CLASS (parent_class);
1529   GstV4l2Object *obj = pool->obj;
1530
1531   GST_DEBUG_OBJECT (pool, "complete release buffer %p (queued = %s)", buffer,
1532       queued ? "yes" : "no");
1533
1534   switch (obj->type) {
1535     case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1536     case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
1537       /* capture, put the buffer back in the queue so that we can refill it
1538        * later. */
1539       if (queued) {
1540         GST_WARNING_OBJECT (pool,
1541             "capture buffer %p was release while still queued", buffer);
1542       }
1543
1544       switch (obj->mode) {
1545         case GST_V4L2_IO_RW:
1546           /* release back in the pool */
1547           pclass->release_buffer (bpool, buffer);
1548           break;
1549
1550         case GST_V4L2_IO_DMABUF:
1551         case GST_V4L2_IO_MMAP:
1552         case GST_V4L2_IO_USERPTR:
1553         case GST_V4L2_IO_DMABUF_IMPORT:
1554         {
1555           GstV4l2MemoryGroup *group;
1556           if (gst_v4l2_is_buffer_valid (buffer, &group)) {
1557             GstFlowReturn ret = GST_FLOW_OK;
1558
1559             gst_v4l2_allocator_reset_group (pool->vallocator, group);
1560             /* queue back in the device */
1561             if (pool->other_pool)
1562               ret = gst_v4l2_buffer_pool_prepare_buffer (pool, buffer, NULL);
1563             if (ret != GST_FLOW_OK ||
1564                 gst_v4l2_buffer_pool_qbuf (pool, buffer, group,
1565                     NULL) != GST_FLOW_OK)
1566               pclass->release_buffer (bpool, buffer);
1567           } else {
1568             /* Simply release invalid/modified buffer, the allocator will
1569              * give it back later */
1570             GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_TAG_MEMORY);
1571             pclass->release_buffer (bpool, buffer);
1572           }
1573           break;
1574         }
1575         default:
1576           g_assert_not_reached ();
1577           break;
1578       }
1579       break;
1580
1581     case V4L2_BUF_TYPE_VIDEO_OUTPUT:
1582     case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
1583       switch (obj->mode) {
1584         case GST_V4L2_IO_RW:
1585           /* release back in the pool */
1586           pclass->release_buffer (bpool, buffer);
1587           break;
1588
1589         case GST_V4L2_IO_MMAP:
1590         case GST_V4L2_IO_DMABUF:
1591         case GST_V4L2_IO_USERPTR:
1592         case GST_V4L2_IO_DMABUF_IMPORT:
1593         {
1594           GstV4l2MemoryGroup *group;
1595           guint index;
1596
1597           if (!gst_v4l2_is_buffer_valid (buffer, &group)) {
1598             /* Simply release invalid/modified buffer, the allocator will
1599              * give it back later */
1600             GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_TAG_MEMORY);
1601             pclass->release_buffer (bpool, buffer);
1602             break;
1603           }
1604
1605           index = group->buffer.index;
1606
1607           if (!queued) {
1608             GST_LOG_OBJECT (pool, "buffer %u not queued, putting on free list",
1609                 index);
1610
1611             /* Remove qdata, this will unmap any map data in userptr */
1612             gst_mini_object_set_qdata (GST_MINI_OBJECT (buffer),
1613                 GST_V4L2_IMPORT_QUARK, NULL, NULL);
1614
1615             /* reset to default size */
1616             gst_v4l2_allocator_reset_group (pool->vallocator, group);
1617
1618             /* playback, put the buffer back in the queue to refill later. */
1619             pclass->release_buffer (bpool, buffer);
1620           } else {
1621             /* the buffer is queued in the device but maybe not played yet. We just
1622              * leave it there and not make it available for future calls to acquire
1623              * for now. The buffer will be dequeued and reused later. */
1624             GST_LOG_OBJECT (pool, "buffer %u is queued", index);
1625           }
1626           break;
1627         }
1628
1629         default:
1630           g_assert_not_reached ();
1631           break;
1632       }
1633       break;
1634
1635     default:
1636       g_assert_not_reached ();
1637       break;
1638   }
1639 }
1640
1641 static void
1642 gst_v4l2_buffer_pool_release_buffer (GstBufferPool * bpool, GstBuffer * buffer)
1643 {
1644   GstV4l2BufferPool *pool = GST_V4L2_BUFFER_POOL (bpool);
1645   GstV4l2MemoryGroup *group;
1646   gboolean queued = FALSE;
1647
1648   if (gst_v4l2_is_buffer_valid (buffer, &group)) {
1649     gint old_buffer_state =
1650         g_atomic_int_and (&pool->buffer_state[group->buffer.index],
1651         ~BUFFER_STATE_OUTSTANDING);
1652     queued = (old_buffer_state & BUFFER_STATE_QUEUED) != 0;
1653     GST_LOG_OBJECT (pool, "mark buffer %u not outstanding",
1654         group->buffer.index);
1655   }
1656
1657   gst_v4l2_buffer_pool_complete_release_buffer (bpool, buffer, queued);
1658 }
1659
1660 static void
1661 gst_v4l2_buffer_pool_dispose (GObject * object)
1662 {
1663   GstV4l2BufferPool *pool = GST_V4L2_BUFFER_POOL (object);
1664
1665   if (pool->vallocator)
1666     gst_object_unref (pool->vallocator);
1667   pool->vallocator = NULL;
1668
1669   if (pool->allocator)
1670     gst_object_unref (pool->allocator);
1671   pool->allocator = NULL;
1672
1673   if (pool->other_pool)
1674     gst_object_unref (pool->other_pool);
1675   pool->other_pool = NULL;
1676
1677   G_OBJECT_CLASS (parent_class)->dispose (object);
1678 }
1679
1680 static void
1681 gst_v4l2_buffer_pool_finalize (GObject * object)
1682 {
1683   GstV4l2BufferPool *pool = GST_V4L2_BUFFER_POOL (object);
1684
1685   if (pool->video_fd >= 0)
1686     pool->obj->close (pool->video_fd);
1687
1688   /* This can't be done in dispose method because we must not set pointer
1689    * to NULL as it is part of the v4l2object and dispose could be called
1690    * multiple times */
1691   gst_object_unref (pool->obj->element);
1692
1693   g_cond_clear (&pool->empty_cond);
1694
1695   /* FIXME have we done enough here ? */
1696
1697   G_OBJECT_CLASS (parent_class)->finalize (object);
1698 }
1699
1700 static void
1701 gst_v4l2_buffer_pool_init (GstV4l2BufferPool * pool)
1702 {
1703   g_cond_init (&pool->empty_cond);
1704   pool->empty = TRUE;
1705   pool->orphaned = FALSE;
1706   for (gint i = 0; i < VIDEO_MAX_FRAME; i++)
1707     g_atomic_int_set (&pool->buffer_state[i], BUFFER_STATE_FREE);
1708 }
1709
1710 static void
1711 gst_v4l2_buffer_pool_class_init (GstV4l2BufferPoolClass * klass)
1712 {
1713   GObjectClass *object_class = G_OBJECT_CLASS (klass);
1714   GstBufferPoolClass *bufferpool_class = GST_BUFFER_POOL_CLASS (klass);
1715
1716   object_class->dispose = gst_v4l2_buffer_pool_dispose;
1717   object_class->finalize = gst_v4l2_buffer_pool_finalize;
1718
1719   bufferpool_class->start = gst_v4l2_buffer_pool_start;
1720   bufferpool_class->stop = gst_v4l2_buffer_pool_stop;
1721   bufferpool_class->set_config = gst_v4l2_buffer_pool_set_config;
1722   bufferpool_class->alloc_buffer = gst_v4l2_buffer_pool_alloc_buffer;
1723   bufferpool_class->acquire_buffer = gst_v4l2_buffer_pool_acquire_buffer;
1724   bufferpool_class->release_buffer = gst_v4l2_buffer_pool_release_buffer;
1725   bufferpool_class->flush_start = gst_v4l2_buffer_pool_flush_start;
1726   bufferpool_class->flush_stop = gst_v4l2_buffer_pool_flush_stop;
1727
1728   GST_DEBUG_CATEGORY_INIT (v4l2bufferpool_debug, "v4l2bufferpool", 0,
1729       "V4L2 Buffer Pool");
1730   GST_DEBUG_CATEGORY_GET (CAT_PERFORMANCE, "GST_PERFORMANCE");
1731 }
1732
1733 /**
1734  * gst_v4l2_buffer_pool_new:
1735  * @obj:  the v4l2 object owning the pool
1736  *
1737  * Construct a new buffer pool.
1738  *
1739  * Returns: the new pool, use gst_object_unref() to free resources
1740  */
1741 GstBufferPool *
1742 gst_v4l2_buffer_pool_new (GstV4l2Object * obj, GstCaps * caps)
1743 {
1744   GstV4l2BufferPool *pool;
1745   GstStructure *config;
1746   gchar *name, *parent_name;
1747   gint fd;
1748
1749   fd = obj->dup (obj->video_fd);
1750   if (fd < 0)
1751     goto dup_failed;
1752
1753   /* setting a significant unique name */
1754   parent_name = gst_object_get_name (GST_OBJECT (obj->element));
1755   name = g_strdup_printf ("%s:pool%u:%s",
1756       parent_name, obj->pool_seq++,
1757       V4L2_TYPE_IS_OUTPUT (obj->type) ? "sink" : "src");
1758   g_free (parent_name);
1759
1760   pool = (GstV4l2BufferPool *) g_object_new (GST_TYPE_V4L2_BUFFER_POOL,
1761       "name", name, NULL);
1762   g_object_ref_sink (pool);
1763   g_free (name);
1764
1765   pool->video_fd = fd;
1766   pool->obj = obj;
1767
1768   pool->vallocator = gst_v4l2_allocator_new (GST_OBJECT (pool), obj);
1769   if (pool->vallocator == NULL)
1770     goto allocator_failed;
1771
1772   gst_object_ref (obj->element);
1773
1774   config = gst_buffer_pool_get_config (GST_BUFFER_POOL_CAST (pool));
1775   gst_buffer_pool_config_set_params (config, caps, obj->info.size, 0, 0);
1776   /* This will simply set a default config, but will not configure the pool
1777    * because min and max are not valid */
1778   gst_buffer_pool_set_config (GST_BUFFER_POOL_CAST (pool), config);
1779
1780   return GST_BUFFER_POOL (pool);
1781
1782   /* ERRORS */
1783 dup_failed:
1784   {
1785     GST_ERROR ("failed to dup fd %d (%s)", errno, g_strerror (errno));
1786     return NULL;
1787   }
1788 allocator_failed:
1789   {
1790     GST_ERROR_OBJECT (pool, "Failed to create V4L2 allocator");
1791     gst_object_unref (pool);
1792     return NULL;
1793   }
1794 }
1795
1796 static GstFlowReturn
1797 gst_v4l2_do_read (GstV4l2BufferPool * pool, GstBuffer * buf)
1798 {
1799   GstFlowReturn res;
1800   GstV4l2Object *obj = pool->obj;
1801   gint amount;
1802   GstMapInfo map;
1803   gint toread;
1804
1805   toread = obj->info.size;
1806
1807   GST_LOG_OBJECT (pool, "reading %d bytes into buffer %p", toread, buf);
1808
1809   gst_buffer_map (buf, &map, GST_MAP_WRITE);
1810
1811   do {
1812     if ((res = gst_v4l2_buffer_pool_poll (pool, TRUE)) != GST_FLOW_OK)
1813       goto poll_error;
1814
1815     amount = obj->read (obj->video_fd, map.data, toread);
1816
1817     if (amount == toread) {
1818       break;
1819     } else if (amount == -1) {
1820       if (errno == EAGAIN || errno == EINTR) {
1821         continue;
1822       } else
1823         goto read_error;
1824     } else {
1825       /* short reads can happen if a signal interrupts the read */
1826       continue;
1827     }
1828   } while (TRUE);
1829
1830   GST_LOG_OBJECT (pool, "read %d bytes", amount);
1831   gst_buffer_unmap (buf, &map);
1832   gst_buffer_resize (buf, 0, amount);
1833
1834   return GST_FLOW_OK;
1835
1836   /* ERRORS */
1837 poll_error:
1838   {
1839     GST_DEBUG ("poll error %s", gst_flow_get_name (res));
1840     goto cleanup;
1841   }
1842 read_error:
1843   {
1844     GST_ELEMENT_ERROR (obj->element, RESOURCE, READ,
1845         (_("Error reading %d bytes from device '%s'."),
1846             toread, obj->videodev), GST_ERROR_SYSTEM);
1847     res = GST_FLOW_ERROR;
1848     goto cleanup;
1849   }
1850 cleanup:
1851   {
1852     gst_buffer_unmap (buf, &map);
1853     gst_buffer_resize (buf, 0, 0);
1854     return res;
1855   }
1856 }
1857
1858 /**
1859  * gst_v4l2_buffer_pool_process:
1860  * @bpool: a #GstBufferPool
1861  * @buf: a #GstBuffer, maybe be replaced
1862  * @frame_number: 32 bit frame number or %NULL
1863  *
1864  * Process @buf in @bpool. For capture devices, this functions fills @buf with
1865  * data from the device. For output devices, this functions send the contents of
1866  * @buf to the device for playback.
1867  *
1868  * If non-%NULL and an output device, @frame_number is stored inside the timestamp for output devices and read
1869  * back from the timestamp for capture devices.
1870  *
1871  * Returns: %GST_FLOW_OK on success.
1872  */
1873 GstFlowReturn
1874 gst_v4l2_buffer_pool_process (GstV4l2BufferPool * pool, GstBuffer ** buf,
1875     guint32 * frame_number)
1876 {
1877   GstFlowReturn ret = GST_FLOW_OK;
1878   GstBufferPool *bpool = GST_BUFFER_POOL_CAST (pool);
1879   GstV4l2Object *obj = pool->obj;
1880
1881   GST_DEBUG_OBJECT (pool, "process buffer %p", *buf);
1882
1883   if (GST_BUFFER_POOL_IS_FLUSHING (pool))
1884     return GST_FLOW_FLUSHING;
1885
1886   switch (obj->type) {
1887     case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1888     case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
1889       /* capture */
1890       switch (obj->mode) {
1891         case GST_V4L2_IO_RW:
1892           /* capture into the buffer */
1893           ret = gst_v4l2_do_read (pool, *buf);
1894           break;
1895
1896         case GST_V4L2_IO_MMAP:
1897         case GST_V4L2_IO_DMABUF:
1898         {
1899           GstBuffer *tmp;
1900
1901           if ((*buf)->pool == bpool) {
1902             guint num_queued;
1903             gsize size = gst_buffer_get_size (*buf);
1904
1905             /* Legacy M2M devices return empty buffer when drained */
1906             if (size == 0 && GST_V4L2_IS_M2M (obj->device_caps)) {
1907               gst_v4l2_buffer_pool_resize_buffer (bpool, *buf);
1908               goto eos;
1909             }
1910
1911             if (GST_VIDEO_INFO_FORMAT (&pool->caps_info) !=
1912                 GST_VIDEO_FORMAT_ENCODED && size < pool->size)
1913               goto buffer_truncated;
1914
1915             num_queued = g_atomic_int_get (&pool->num_queued);
1916             GST_TRACE_OBJECT (pool, "Only %i buffer left in the capture queue.",
1917                 num_queued);
1918
1919             /* If we have no more buffer, and can allocate it time to do so */
1920             if (num_queued == 0) {
1921               if (GST_V4L2_ALLOCATOR_CAN_ALLOCATE (pool->vallocator, MMAP)) {
1922                 GST_DEBUG_OBJECT (pool, "Resurrect for empty queue");
1923                 ret = gst_v4l2_buffer_pool_resurrect_buffer (pool);
1924                 if (ret == GST_FLOW_OK || ret == GST_FLOW_FLUSHING)
1925                   goto done;
1926               }
1927             }
1928
1929             /* start copying buffers when we are running low on buffers */
1930             if (num_queued < pool->copy_threshold) {
1931               GstBuffer *copy;
1932
1933               if (GST_V4L2_ALLOCATOR_CAN_ALLOCATE (pool->vallocator, MMAP)) {
1934                 GST_DEBUG_OBJECT (pool, "Resurrect for threshold");
1935                 ret = gst_v4l2_buffer_pool_resurrect_buffer (pool);
1936                 if (ret == GST_FLOW_OK || ret == GST_FLOW_FLUSHING)
1937                   goto done;
1938               }
1939
1940               /* copy the buffer */
1941               copy = gst_buffer_copy_region (*buf,
1942                   GST_BUFFER_COPY_ALL | GST_BUFFER_COPY_DEEP, 0, -1);
1943               GST_LOG_OBJECT (pool, "copy buffer %p->%p", *buf, copy);
1944
1945               /* and requeue so that we can continue capturing */
1946               gst_buffer_unref (*buf);
1947               *buf = copy;
1948             }
1949
1950             ret = GST_FLOW_OK;
1951             /* nothing, data was inside the buffer when we did _acquire() */
1952             goto done;
1953           }
1954
1955           /* buffer not from our pool, grab a frame and copy it into the target */
1956           if ((ret = gst_v4l2_buffer_pool_dqbuf (pool, &tmp, NULL, TRUE))
1957               != GST_FLOW_OK)
1958             goto done;
1959
1960           /* An empty buffer on capture indicates the end of stream */
1961           if (gst_buffer_get_size (tmp) == 0) {
1962             gst_v4l2_buffer_pool_complete_release_buffer (bpool, tmp, FALSE);
1963
1964             /* Legacy M2M devices return empty buffer when drained */
1965             if (GST_V4L2_IS_M2M (obj->device_caps)) {
1966               gst_v4l2_buffer_pool_resize_buffer (bpool, *buf);
1967               goto eos;
1968             }
1969           }
1970
1971           ret = gst_v4l2_buffer_pool_copy_buffer (pool, *buf, tmp);
1972
1973           /* an queue the buffer again after the copy */
1974           gst_v4l2_buffer_pool_complete_release_buffer (bpool, tmp, FALSE);
1975
1976           if (ret != GST_FLOW_OK)
1977             goto copy_failed;
1978           break;
1979         }
1980
1981         case GST_V4L2_IO_USERPTR:
1982         {
1983           struct UserPtrData *data;
1984           GstBuffer *tmp;
1985
1986           /* Replace our buffer with downstream allocated buffer */
1987           data = gst_mini_object_steal_qdata (GST_MINI_OBJECT (*buf),
1988               GST_V4L2_IMPORT_QUARK);
1989           tmp = gst_buffer_ref (data->buffer);
1990           _unmap_userptr_frame (data);
1991
1992           /* Now tmp is writable, copy the flags and timestamp */
1993           gst_buffer_copy_into (tmp, *buf,
1994               GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_TIMESTAMPS, 0, -1);
1995
1996           gst_buffer_replace (buf, tmp);
1997           gst_buffer_unref (tmp);
1998           break;
1999         }
2000
2001         case GST_V4L2_IO_DMABUF_IMPORT:
2002         {
2003           GstBuffer *tmp;
2004
2005           /* Replace our buffer with downstream allocated buffer */
2006           tmp = gst_mini_object_steal_qdata (GST_MINI_OBJECT (*buf),
2007               GST_V4L2_IMPORT_QUARK);
2008
2009           gst_buffer_copy_into (tmp, *buf,
2010               GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_TIMESTAMPS, 0, -1);
2011
2012           gst_buffer_replace (buf, tmp);
2013           gst_buffer_unref (tmp);
2014           break;
2015         }
2016
2017         default:
2018           g_assert_not_reached ();
2019           break;
2020       }
2021       break;
2022
2023     case V4L2_BUF_TYPE_VIDEO_OUTPUT:
2024     case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
2025       /* playback */
2026       switch (obj->mode) {
2027         case GST_V4L2_IO_RW:
2028           /* FIXME, do write() */
2029           GST_WARNING_OBJECT (pool, "implement write()");
2030           break;
2031
2032         case GST_V4L2_IO_USERPTR:
2033         case GST_V4L2_IO_DMABUF_IMPORT:
2034         case GST_V4L2_IO_DMABUF:
2035         case GST_V4L2_IO_MMAP:
2036         {
2037           GstBuffer *to_queue = NULL;
2038           GstBuffer *buffer;
2039           GstV4l2MemoryGroup *group;
2040           gint index;
2041           gboolean outstanding;
2042
2043           if ((*buf)->pool != bpool)
2044             goto copying;
2045
2046           if (!gst_v4l2_is_buffer_valid (*buf, &group))
2047             goto copying;
2048
2049           index = group->buffer.index;
2050
2051           GST_LOG_OBJECT (pool, "processing buffer %i from our pool", index);
2052
2053           if (g_atomic_int_get (&pool->buffer_state[index]) &
2054               BUFFER_STATE_QUEUED) {
2055             GST_LOG_OBJECT (pool, "buffer %i already queued, copying", index);
2056             goto copying;
2057           }
2058
2059           /* we can queue directly */
2060           to_queue = gst_buffer_ref (*buf);
2061
2062         copying:
2063           if (to_queue == NULL) {
2064             GstBufferPoolAcquireParams params = { 0 };
2065
2066             GST_LOG_OBJECT (pool, "alloc buffer from our pool");
2067
2068             /* this can return EOS if all buffers are outstanding which would
2069              * be strange because we would expect the upstream element to have
2070              * allocated them and returned to us.. */
2071             params.flags = GST_BUFFER_POOL_ACQUIRE_FLAG_DONTWAIT;
2072             ret = gst_buffer_pool_acquire_buffer (bpool, &to_queue, &params);
2073             if (ret != GST_FLOW_OK)
2074               goto acquire_failed;
2075
2076             ret = gst_v4l2_buffer_pool_prepare_buffer (pool, to_queue, *buf);
2077             if (ret != GST_FLOW_OK) {
2078               gst_buffer_unref (to_queue);
2079               goto prepare_failed;
2080             }
2081
2082             /* retrieve the group */
2083             gst_v4l2_is_buffer_valid (to_queue, &group);
2084           }
2085
2086           if ((ret =
2087                   gst_v4l2_buffer_pool_qbuf (pool, to_queue, group,
2088                       frame_number))
2089               != GST_FLOW_OK)
2090             goto queue_failed;
2091
2092           /* if we are not streaming yet (this is the first buffer, start
2093            * streaming now */
2094           if (!gst_v4l2_buffer_pool_streamon (pool)) {
2095             /* don't check return value because qbuf would have failed */
2096             gst_v4l2_is_buffer_valid (to_queue, &group);
2097
2098             /* qbuf has stored to_queue buffer but we are not in
2099              * streaming state, so the flush logic won't be performed.
2100              * To avoid leaks, flush the allocator and restore the queued
2101              * buffer as non-queued */
2102             gst_v4l2_allocator_flush (pool->vallocator);
2103
2104             pool->buffers[group->buffer.index] = NULL;
2105             g_atomic_int_and (&pool->buffer_state[group->buffer.index],
2106                 ~BUFFER_STATE_QUEUED);
2107
2108             gst_mini_object_set_qdata (GST_MINI_OBJECT (to_queue),
2109                 GST_V4L2_IMPORT_QUARK, NULL, NULL);
2110             gst_buffer_unref (to_queue);
2111             g_atomic_int_add (&pool->num_queued, -1);
2112             goto start_failed;
2113           }
2114
2115           /* Remove our ref, we will still hold this buffer in acquire as needed,
2116            * otherwise the pool will think it is outstanding and will refuse to stop. */
2117           gst_buffer_unref (to_queue);
2118
2119           /* release as many buffer as possible */
2120           while (gst_v4l2_buffer_pool_dqbuf (pool, &buffer, &outstanding,
2121                   FALSE) == GST_FLOW_OK) {
2122             if (!outstanding)
2123               gst_v4l2_buffer_pool_complete_release_buffer (bpool, buffer,
2124                   FALSE);
2125           }
2126
2127           if (g_atomic_int_get (&pool->num_queued) >= pool->min_latency) {
2128             /* all buffers are queued, try to dequeue one and release it back
2129              * into the pool so that _acquire can get to it again. */
2130             ret =
2131                 gst_v4l2_buffer_pool_dqbuf (pool, &buffer, &outstanding, TRUE);
2132             if (ret == GST_FLOW_OK && !outstanding)
2133               /* release the rendered buffer back into the pool. This wakes up any
2134                * thread waiting for a buffer in _acquire(). */
2135               gst_v4l2_buffer_pool_complete_release_buffer (bpool, buffer,
2136                   FALSE);
2137           }
2138           break;
2139         }
2140         default:
2141           g_assert_not_reached ();
2142           break;
2143       }
2144       break;
2145     default:
2146       g_assert_not_reached ();
2147       break;
2148   }
2149 done:
2150   return ret;
2151
2152   /* ERRORS */
2153 copy_failed:
2154   {
2155     GST_ERROR_OBJECT (pool, "failed to copy buffer");
2156     return ret;
2157   }
2158 buffer_truncated:
2159   {
2160     GST_WARNING_OBJECT (pool,
2161         "Dropping truncated buffer, this is likely a driver bug.");
2162     gst_buffer_unref (*buf);
2163     *buf = NULL;
2164     return GST_V4L2_FLOW_CORRUPTED_BUFFER;
2165   }
2166 eos:
2167   {
2168     GST_DEBUG_OBJECT (pool, "end of sequence reached");
2169     gst_buffer_unref (*buf);
2170     *buf = NULL;
2171     return GST_V4L2_FLOW_LAST_BUFFER;
2172   }
2173 acquire_failed:
2174   {
2175     if (ret == GST_FLOW_FLUSHING)
2176       GST_DEBUG_OBJECT (pool, "flushing");
2177     else
2178       GST_WARNING_OBJECT (pool, "failed to acquire a buffer: %s",
2179           gst_flow_get_name (ret));
2180     return ret;
2181   }
2182 prepare_failed:
2183   {
2184     GST_ERROR_OBJECT (pool, "failed to prepare data");
2185     return ret;
2186   }
2187 queue_failed:
2188   {
2189     GST_ERROR_OBJECT (pool, "failed to queue buffer");
2190     return ret;
2191   }
2192 start_failed:
2193   {
2194     GST_ERROR_OBJECT (pool, "failed to start streaming");
2195     return GST_FLOW_ERROR;
2196   }
2197 }
2198
2199 void
2200 gst_v4l2_buffer_pool_set_other_pool (GstV4l2BufferPool * pool,
2201     GstBufferPool * other_pool)
2202 {
2203   g_return_if_fail (!gst_buffer_pool_is_active (GST_BUFFER_POOL (pool)));
2204
2205   if (pool->other_pool)
2206     gst_object_unref (pool->other_pool);
2207   pool->other_pool = gst_object_ref (other_pool);
2208 }
2209
2210 void
2211 gst_v4l2_buffer_pool_copy_at_threshold (GstV4l2BufferPool * pool, gboolean copy)
2212 {
2213   GST_OBJECT_LOCK (pool);
2214   pool->enable_copy_threshold = copy;
2215   GST_OBJECT_UNLOCK (pool);
2216 }
2217
2218 static GstFlowReturn
2219 gst_v4l2_buffer_pool_flush_events (GstV4l2Object * v4l2object)
2220 {
2221   GstFlowReturn ret = GST_FLOW_OK;
2222   gboolean event_found;
2223
2224   /* FIXME simplify this when we drop legacy support for driver without poll()
2225    * support. When we do, we can switch the video_fd to non blocking, and just
2226    * pop the events directly. */
2227
2228   do {
2229     struct v4l2_event event = { 0, };
2230     gint poll_ret;
2231
2232     event_found = FALSE;
2233
2234     gst_poll_set_flushing (v4l2object->poll, FALSE);
2235
2236     do {
2237       /* GstPoll don't have 0ns timeout, but 1 will do */
2238       poll_ret = gst_poll_wait (v4l2object->poll, 1);
2239     } while (poll_ret == EAGAIN || poll_ret == EINTR);
2240
2241     if (gst_poll_fd_has_pri (v4l2object->poll, &v4l2object->pollfd)) {
2242       if (!gst_v4l2_dequeue_event (v4l2object, &event))
2243         return GST_FLOW_ERROR;
2244
2245       event_found = TRUE;
2246
2247       if (event.type == V4L2_EVENT_SOURCE_CHANGE &&
2248           (event.u.src_change.changes & V4L2_EVENT_SRC_CH_RESOLUTION)) {
2249         GST_DEBUG_OBJECT (v4l2object->dbg_obj,
2250             "Can't streamon capture as the resolution have changed.");
2251         ret = GST_V4L2_FLOW_RESOLUTION_CHANGE;
2252       }
2253     }
2254   } while (event_found);
2255
2256   return ret;
2257 }
2258
2259 GstFlowReturn
2260 gst_v4l2_buffer_pool_flush (GstV4l2Object * v4l2object)
2261 {
2262   GstBufferPool *bpool = gst_v4l2_object_get_buffer_pool (v4l2object);
2263   GstV4l2BufferPool *pool;
2264   GstFlowReturn ret = GST_FLOW_OK;
2265
2266   if (!bpool)
2267     return GST_FLOW_ERROR;
2268
2269   pool = GST_V4L2_BUFFER_POOL (bpool);
2270
2271   gst_v4l2_buffer_pool_streamoff (pool);
2272
2273   if (!V4L2_TYPE_IS_OUTPUT (pool->obj->type)) {
2274     ret = gst_v4l2_buffer_pool_flush_events (v4l2object);
2275
2276     /* If the format haven't change, avoid reallocation to go back to
2277      * streaming */
2278     if (ret == GST_FLOW_OK)
2279       ret = gst_v4l2_buffer_pool_streamon (pool);
2280   }
2281
2282   gst_object_unref (bpool);
2283   return ret;
2284 }
2285
2286 /**
2287  * gst_v4l2_buffer_pool_enable_resolution_change:
2288  * @pool: a #GstBufferPool
2289  *
2290  * When this is called, the pool will subscribe to the
2291  * %V4L2_EVENT_SOURCE_CHANGE. Upon receiving this event, it will notify
2292  * the element acquiring buffer with the special flow return
2293  * %GST_V4L2_FLOW_RESOLUTION_CHANGE.
2294  */
2295 void
2296 gst_v4l2_buffer_pool_enable_resolution_change (GstV4l2BufferPool * pool)
2297 {
2298   gst_v4l2_object_subscribe_event (pool->obj, V4L2_EVENT_SOURCE_CHANGE);
2299 }