68bab75e600a7056f2b8e62b72dd1711b84be2cd
[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   const GstVideoInfo *info = &obj->info;
1241   gint i;
1242   gint old_buffer_state;
1243
1244   if ((res = gst_v4l2_buffer_pool_poll (pool, wait)) < GST_FLOW_OK)
1245     goto poll_failed;
1246
1247   if (res == GST_V4L2_FLOW_LAST_BUFFER) {
1248     GST_LOG_OBJECT (pool, "nothing to dequeue");
1249     goto done;
1250   }
1251
1252   if (res == GST_V4L2_FLOW_RESOLUTION_CHANGE) {
1253     GST_INFO_OBJECT (pool, "Resolution change detected.");
1254     goto done;
1255   }
1256
1257   GST_LOG_OBJECT (pool, "dequeueing a buffer");
1258
1259   res = gst_v4l2_allocator_dqbuf (pool->vallocator, &group);
1260   if (res == GST_V4L2_FLOW_LAST_BUFFER)
1261     goto eos;
1262   if (res != GST_FLOW_OK)
1263     goto dqbuf_failed;
1264
1265   old_buffer_state =
1266       g_atomic_int_and (&pool->buffer_state[group->buffer.index],
1267       ~BUFFER_STATE_QUEUED);
1268   if (!(old_buffer_state & BUFFER_STATE_QUEUED))
1269     goto no_buffer;
1270
1271   if (outstanding) {
1272     *outstanding = (old_buffer_state & BUFFER_STATE_OUTSTANDING) != 0;
1273   } else if (old_buffer_state & BUFFER_STATE_OUTSTANDING) {
1274     GST_WARNING_OBJECT (pool, "unexpected outstanding buffer %u",
1275         group->buffer.index);
1276   }
1277
1278   outbuf = pool->buffers[group->buffer.index];
1279   if (outbuf == NULL)
1280     goto no_buffer;
1281
1282   pool->buffers[group->buffer.index] = NULL;
1283   if (g_atomic_int_dec_and_test (&pool->num_queued)) {
1284     GST_OBJECT_LOCK (pool);
1285     pool->empty = TRUE;
1286     GST_OBJECT_UNLOCK (pool);
1287   }
1288
1289   timestamp = GST_TIMEVAL_TO_TIME (group->buffer.timestamp);
1290
1291   for (i = 0; i < group->n_mem; i++) {
1292     const GstVideoFormatInfo *finfo = info->finfo;
1293
1294     GST_LOG_OBJECT (pool,
1295         "dequeued buffer %p seq:%d (ix=%d), mem %p used %d, plane=%d, flags %08x, ts %"
1296         GST_TIME_FORMAT ", pool-queued=%d, buffer=%p, previous-state=%i",
1297         outbuf, group->buffer.sequence, group->buffer.index, group->mem[i],
1298         group->planes[i].bytesused, i, group->buffer.flags,
1299         GST_TIME_ARGS (timestamp), pool->num_queued, outbuf, old_buffer_state);
1300
1301     if (GST_VIDEO_INFO_FORMAT (&pool->caps_info) == GST_VIDEO_FORMAT_ENCODED)
1302       break;
1303
1304     /* Ensure our offset matches the expected plane size, or image size if
1305      * there is only one memory */
1306     if (group->n_mem == 1) {
1307       gst_memory_resize (group->mem[0], 0, info->size + info->offset[0]);
1308       break;
1309     }
1310
1311     if (!GST_VIDEO_FORMAT_INFO_IS_TILED (finfo))
1312       gst_memory_resize (group->mem[i], 0, obj->plane_size[i]);
1313   }
1314
1315   /* Ignore timestamp and field for OUTPUT device */
1316   if (V4L2_TYPE_IS_OUTPUT (obj->type))
1317     goto done;
1318
1319   /* Check for driver bug in reporting feild */
1320   if (group->buffer.field == V4L2_FIELD_ANY) {
1321     /* Only warn once to avoid the spamming */
1322 #ifndef GST_DISABLE_GST_DEBUG
1323     if (!pool->has_warned_on_buggy_field) {
1324       pool->has_warned_on_buggy_field = TRUE;
1325       GST_WARNING_OBJECT (pool,
1326           "Driver should never set v4l2_buffer.field to ANY");
1327     }
1328 #endif
1329
1330     /* Use the value from the format (works for UVC bug) */
1331     group->buffer.field = obj->format.fmt.pix.field;
1332
1333     /* If driver also has buggy S_FMT, assume progressive */
1334     if (group->buffer.field == V4L2_FIELD_ANY) {
1335 #ifndef GST_DISABLE_GST_DEBUG
1336       if (!pool->has_warned_on_buggy_field) {
1337         pool->has_warned_on_buggy_field = TRUE;
1338         GST_WARNING_OBJECT (pool,
1339             "Driver should never set v4l2_format.pix.field to ANY");
1340       }
1341 #endif
1342
1343       group->buffer.field = V4L2_FIELD_NONE;
1344     }
1345   }
1346
1347   /* set top/bottom field first if v4l2_buffer has the information */
1348   switch (group->buffer.field) {
1349     case V4L2_FIELD_NONE:
1350       GST_BUFFER_FLAG_UNSET (outbuf, GST_VIDEO_BUFFER_FLAG_INTERLACED);
1351       GST_BUFFER_FLAG_UNSET (outbuf, GST_VIDEO_BUFFER_FLAG_TFF);
1352       break;
1353     case V4L2_FIELD_TOP:
1354       GST_BUFFER_FLAG_SET (outbuf, GST_VIDEO_BUFFER_FLAG_INTERLACED);
1355       GST_BUFFER_FLAG_SET (outbuf, GST_VIDEO_BUFFER_FLAG_TOP_FIELD);
1356       break;
1357     case V4L2_FIELD_BOTTOM:
1358       GST_BUFFER_FLAG_SET (outbuf, GST_VIDEO_BUFFER_FLAG_INTERLACED);
1359       GST_BUFFER_FLAG_SET (outbuf, GST_VIDEO_BUFFER_FLAG_BOTTOM_FIELD);
1360       break;
1361     case V4L2_FIELD_INTERLACED_TB:
1362       GST_BUFFER_FLAG_SET (outbuf, GST_VIDEO_BUFFER_FLAG_INTERLACED);
1363       GST_BUFFER_FLAG_SET (outbuf, GST_VIDEO_BUFFER_FLAG_TFF);
1364       break;
1365     case V4L2_FIELD_INTERLACED_BT:
1366       GST_BUFFER_FLAG_SET (outbuf, GST_VIDEO_BUFFER_FLAG_INTERLACED);
1367       GST_BUFFER_FLAG_UNSET (outbuf, GST_VIDEO_BUFFER_FLAG_TFF);
1368       break;
1369     case V4L2_FIELD_INTERLACED:
1370       GST_BUFFER_FLAG_SET (outbuf, GST_VIDEO_BUFFER_FLAG_INTERLACED);
1371       if (obj->tv_norm == V4L2_STD_NTSC_M ||
1372           obj->tv_norm == V4L2_STD_NTSC_M_JP ||
1373           obj->tv_norm == V4L2_STD_NTSC_M_KR) {
1374         GST_BUFFER_FLAG_UNSET (outbuf, GST_VIDEO_BUFFER_FLAG_TFF);
1375       } else {
1376         GST_BUFFER_FLAG_SET (outbuf, GST_VIDEO_BUFFER_FLAG_TFF);
1377       }
1378       break;
1379     default:
1380       GST_BUFFER_FLAG_UNSET (outbuf, GST_VIDEO_BUFFER_FLAG_INTERLACED);
1381       GST_BUFFER_FLAG_UNSET (outbuf, GST_VIDEO_BUFFER_FLAG_TFF);
1382       GST_FIXME_OBJECT (pool,
1383           "Unhandled enum v4l2_field %d - treating as progressive",
1384           group->buffer.field);
1385       break;
1386   }
1387
1388   if (!gst_v4l2_object_is_raw (obj)) {
1389     if ((group->buffer.flags & V4L2_BUF_FLAG_KEYFRAME) ||
1390         GST_V4L2_PIXELFORMAT (obj) == V4L2_PIX_FMT_MJPEG ||
1391         GST_V4L2_PIXELFORMAT (obj) == V4L2_PIX_FMT_JPEG ||
1392         GST_V4L2_PIXELFORMAT (obj) == V4L2_PIX_FMT_PJPG)
1393       GST_BUFFER_FLAG_UNSET (outbuf, GST_BUFFER_FLAG_DELTA_UNIT);
1394     else
1395       GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_DELTA_UNIT);
1396   }
1397
1398   if (group->buffer.flags & V4L2_BUF_FLAG_ERROR)
1399     GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_CORRUPTED);
1400
1401   GST_BUFFER_TIMESTAMP (outbuf) = timestamp;
1402   GST_BUFFER_OFFSET (outbuf) = group->buffer.sequence;
1403   GST_BUFFER_OFFSET_END (outbuf) = group->buffer.sequence + 1;
1404
1405 done:
1406   *buffer = outbuf;
1407
1408   return res;
1409
1410   /* ERRORS */
1411 poll_failed:
1412   {
1413     GST_DEBUG_OBJECT (pool, "poll error %s", gst_flow_get_name (res));
1414     return res;
1415   }
1416 eos:
1417   {
1418     return GST_V4L2_FLOW_LAST_BUFFER;
1419   }
1420 dqbuf_failed:
1421   {
1422     return GST_FLOW_ERROR;
1423   }
1424 no_buffer:
1425   {
1426     GST_ERROR_OBJECT (pool, "No free buffer found in the pool at index %d.",
1427         group->buffer.index);
1428     return GST_FLOW_ERROR;
1429   }
1430 }
1431
1432 static GstFlowReturn
1433 gst_v4l2_buffer_pool_acquire_buffer (GstBufferPool * bpool, GstBuffer ** buffer,
1434     GstBufferPoolAcquireParams * params)
1435 {
1436   GstFlowReturn ret;
1437   GstV4l2BufferPool *pool = GST_V4L2_BUFFER_POOL (bpool);
1438   GstBufferPoolClass *pclass = GST_BUFFER_POOL_CLASS (parent_class);
1439   GstV4l2Object *obj = pool->obj;
1440
1441   GST_DEBUG_OBJECT (pool, "acquire");
1442
1443   /* If this is being called to resurrect a lost buffer */
1444   if (params && params->flags & GST_V4L2_BUFFER_POOL_ACQUIRE_FLAG_RESURRECT) {
1445     ret = pclass->acquire_buffer (bpool, buffer, params);
1446     goto done;
1447   }
1448
1449   switch (obj->type) {
1450     case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1451     case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
1452       /* capture, This function should return a buffer with new captured data */
1453       switch (obj->mode) {
1454         case GST_V4L2_IO_RW:
1455         {
1456           /* take empty buffer from the pool */
1457           ret = pclass->acquire_buffer (bpool, buffer, params);
1458           break;
1459         }
1460         case GST_V4L2_IO_DMABUF:
1461         case GST_V4L2_IO_MMAP:
1462         case GST_V4L2_IO_USERPTR:
1463         case GST_V4L2_IO_DMABUF_IMPORT:
1464         {
1465           /* just dequeue a buffer, we basically use the queue of v4l2 as the
1466            * storage for our buffers. This function does poll first so we can
1467            * interrupt it fine. */
1468           ret = gst_v4l2_buffer_pool_dqbuf (pool, buffer, NULL, TRUE);
1469           break;
1470         }
1471         default:
1472           ret = GST_FLOW_ERROR;
1473           g_assert_not_reached ();
1474           break;
1475       }
1476       break;
1477
1478
1479     case V4L2_BUF_TYPE_VIDEO_OUTPUT:
1480     case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
1481       /* playback, This function should return an empty buffer */
1482       switch (obj->mode) {
1483         case GST_V4L2_IO_RW:
1484           /* get an empty buffer */
1485           ret = pclass->acquire_buffer (bpool, buffer, params);
1486           break;
1487
1488         case GST_V4L2_IO_MMAP:
1489         case GST_V4L2_IO_DMABUF:
1490         case GST_V4L2_IO_USERPTR:
1491         case GST_V4L2_IO_DMABUF_IMPORT:
1492           /* get a free unqueued buffer */
1493           ret = pclass->acquire_buffer (bpool, buffer, params);
1494           break;
1495
1496         default:
1497           ret = GST_FLOW_ERROR;
1498           g_assert_not_reached ();
1499           break;
1500       }
1501       break;
1502
1503     default:
1504       ret = GST_FLOW_ERROR;
1505       g_assert_not_reached ();
1506       break;
1507   }
1508 done:
1509   /* Mark buffer as outstanding */
1510   if (ret == GST_FLOW_OK) {
1511     GstV4l2MemoryGroup *group;
1512     if (gst_v4l2_is_buffer_valid (*buffer, &group)) {
1513       GST_LOG_OBJECT (pool, "mark buffer %u outstanding", group->buffer.index);
1514       g_atomic_int_or (&pool->buffer_state[group->buffer.index],
1515           BUFFER_STATE_OUTSTANDING);
1516     }
1517   }
1518
1519   return ret;
1520 }
1521
1522 /*
1523  * Completes a release buffer operation
1524  *
1525  * Before calling this function:
1526  * - The buffer state (if applicable) must have already been updated.
1527  * - The buffer must not be outstanding.
1528  * - The "queued" argument contains whether the buffer is currently queued.
1529  */
1530 static void
1531 gst_v4l2_buffer_pool_complete_release_buffer (GstBufferPool * bpool,
1532     GstBuffer * buffer, gboolean queued)
1533 {
1534   GstV4l2BufferPool *pool = GST_V4L2_BUFFER_POOL (bpool);
1535   GstBufferPoolClass *pclass = GST_BUFFER_POOL_CLASS (parent_class);
1536   GstV4l2Object *obj = pool->obj;
1537
1538   GST_DEBUG_OBJECT (pool, "complete release buffer %p (queued = %s)", buffer,
1539       queued ? "yes" : "no");
1540
1541   switch (obj->type) {
1542     case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1543     case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
1544       /* capture, put the buffer back in the queue so that we can refill it
1545        * later. */
1546       if (queued) {
1547         GST_WARNING_OBJECT (pool,
1548             "capture buffer %p was release while still queued", buffer);
1549       }
1550
1551       switch (obj->mode) {
1552         case GST_V4L2_IO_RW:
1553           /* release back in the pool */
1554           pclass->release_buffer (bpool, buffer);
1555           break;
1556
1557         case GST_V4L2_IO_DMABUF:
1558         case GST_V4L2_IO_MMAP:
1559         case GST_V4L2_IO_USERPTR:
1560         case GST_V4L2_IO_DMABUF_IMPORT:
1561         {
1562           GstV4l2MemoryGroup *group;
1563           if (gst_v4l2_is_buffer_valid (buffer, &group)) {
1564             GstFlowReturn ret = GST_FLOW_OK;
1565
1566             gst_v4l2_allocator_reset_group (pool->vallocator, group);
1567             /* queue back in the device */
1568             if (pool->other_pool)
1569               ret = gst_v4l2_buffer_pool_prepare_buffer (pool, buffer, NULL);
1570             if (ret != GST_FLOW_OK ||
1571                 gst_v4l2_buffer_pool_qbuf (pool, buffer, group,
1572                     NULL) != GST_FLOW_OK)
1573               pclass->release_buffer (bpool, buffer);
1574           } else {
1575             /* Simply release invalid/modified buffer, the allocator will
1576              * give it back later */
1577             GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_TAG_MEMORY);
1578             pclass->release_buffer (bpool, buffer);
1579           }
1580           break;
1581         }
1582         default:
1583           g_assert_not_reached ();
1584           break;
1585       }
1586       break;
1587
1588     case V4L2_BUF_TYPE_VIDEO_OUTPUT:
1589     case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
1590       switch (obj->mode) {
1591         case GST_V4L2_IO_RW:
1592           /* release back in the pool */
1593           pclass->release_buffer (bpool, buffer);
1594           break;
1595
1596         case GST_V4L2_IO_MMAP:
1597         case GST_V4L2_IO_DMABUF:
1598         case GST_V4L2_IO_USERPTR:
1599         case GST_V4L2_IO_DMABUF_IMPORT:
1600         {
1601           GstV4l2MemoryGroup *group;
1602           guint index;
1603
1604           if (!gst_v4l2_is_buffer_valid (buffer, &group)) {
1605             /* Simply release invalid/modified buffer, the allocator will
1606              * give it back later */
1607             GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_TAG_MEMORY);
1608             pclass->release_buffer (bpool, buffer);
1609             break;
1610           }
1611
1612           index = group->buffer.index;
1613
1614           if (!queued) {
1615             GST_LOG_OBJECT (pool, "buffer %u not queued, putting on free list",
1616                 index);
1617
1618             /* Remove qdata, this will unmap any map data in userptr */
1619             gst_mini_object_set_qdata (GST_MINI_OBJECT (buffer),
1620                 GST_V4L2_IMPORT_QUARK, NULL, NULL);
1621
1622             /* reset to default size */
1623             gst_v4l2_allocator_reset_group (pool->vallocator, group);
1624
1625             /* playback, put the buffer back in the queue to refill later. */
1626             pclass->release_buffer (bpool, buffer);
1627           } else {
1628             /* the buffer is queued in the device but maybe not played yet. We just
1629              * leave it there and not make it available for future calls to acquire
1630              * for now. The buffer will be dequeued and reused later. */
1631             GST_LOG_OBJECT (pool, "buffer %u is queued", index);
1632           }
1633           break;
1634         }
1635
1636         default:
1637           g_assert_not_reached ();
1638           break;
1639       }
1640       break;
1641
1642     default:
1643       g_assert_not_reached ();
1644       break;
1645   }
1646 }
1647
1648 static void
1649 gst_v4l2_buffer_pool_release_buffer (GstBufferPool * bpool, GstBuffer * buffer)
1650 {
1651   GstV4l2BufferPool *pool = GST_V4L2_BUFFER_POOL (bpool);
1652   GstV4l2MemoryGroup *group;
1653   gboolean queued = FALSE;
1654
1655   if (gst_v4l2_is_buffer_valid (buffer, &group)) {
1656     gint old_buffer_state =
1657         g_atomic_int_and (&pool->buffer_state[group->buffer.index],
1658         ~BUFFER_STATE_OUTSTANDING);
1659     queued = (old_buffer_state & BUFFER_STATE_QUEUED) != 0;
1660     GST_LOG_OBJECT (pool, "mark buffer %u not outstanding",
1661         group->buffer.index);
1662   }
1663
1664   gst_v4l2_buffer_pool_complete_release_buffer (bpool, buffer, queued);
1665 }
1666
1667 static void
1668 gst_v4l2_buffer_pool_dispose (GObject * object)
1669 {
1670   GstV4l2BufferPool *pool = GST_V4L2_BUFFER_POOL (object);
1671
1672   if (pool->vallocator)
1673     gst_object_unref (pool->vallocator);
1674   pool->vallocator = NULL;
1675
1676   if (pool->allocator)
1677     gst_object_unref (pool->allocator);
1678   pool->allocator = NULL;
1679
1680   if (pool->other_pool)
1681     gst_object_unref (pool->other_pool);
1682   pool->other_pool = NULL;
1683
1684   G_OBJECT_CLASS (parent_class)->dispose (object);
1685 }
1686
1687 static void
1688 gst_v4l2_buffer_pool_finalize (GObject * object)
1689 {
1690   GstV4l2BufferPool *pool = GST_V4L2_BUFFER_POOL (object);
1691
1692   if (pool->video_fd >= 0)
1693     pool->obj->close (pool->video_fd);
1694
1695   /* This can't be done in dispose method because we must not set pointer
1696    * to NULL as it is part of the v4l2object and dispose could be called
1697    * multiple times */
1698   gst_object_unref (pool->obj->element);
1699
1700   g_cond_clear (&pool->empty_cond);
1701
1702   /* FIXME have we done enough here ? */
1703
1704   G_OBJECT_CLASS (parent_class)->finalize (object);
1705 }
1706
1707 static void
1708 gst_v4l2_buffer_pool_init (GstV4l2BufferPool * pool)
1709 {
1710   g_cond_init (&pool->empty_cond);
1711   pool->empty = TRUE;
1712   pool->orphaned = FALSE;
1713   for (gint i = 0; i < VIDEO_MAX_FRAME; i++)
1714     g_atomic_int_set (&pool->buffer_state[i], BUFFER_STATE_FREE);
1715 }
1716
1717 static void
1718 gst_v4l2_buffer_pool_class_init (GstV4l2BufferPoolClass * klass)
1719 {
1720   GObjectClass *object_class = G_OBJECT_CLASS (klass);
1721   GstBufferPoolClass *bufferpool_class = GST_BUFFER_POOL_CLASS (klass);
1722
1723   object_class->dispose = gst_v4l2_buffer_pool_dispose;
1724   object_class->finalize = gst_v4l2_buffer_pool_finalize;
1725
1726   bufferpool_class->start = gst_v4l2_buffer_pool_start;
1727   bufferpool_class->stop = gst_v4l2_buffer_pool_stop;
1728   bufferpool_class->set_config = gst_v4l2_buffer_pool_set_config;
1729   bufferpool_class->alloc_buffer = gst_v4l2_buffer_pool_alloc_buffer;
1730   bufferpool_class->acquire_buffer = gst_v4l2_buffer_pool_acquire_buffer;
1731   bufferpool_class->release_buffer = gst_v4l2_buffer_pool_release_buffer;
1732   bufferpool_class->flush_start = gst_v4l2_buffer_pool_flush_start;
1733   bufferpool_class->flush_stop = gst_v4l2_buffer_pool_flush_stop;
1734
1735   GST_DEBUG_CATEGORY_INIT (v4l2bufferpool_debug, "v4l2bufferpool", 0,
1736       "V4L2 Buffer Pool");
1737   GST_DEBUG_CATEGORY_GET (CAT_PERFORMANCE, "GST_PERFORMANCE");
1738 }
1739
1740 /**
1741  * gst_v4l2_buffer_pool_new:
1742  * @obj:  the v4l2 object owning the pool
1743  *
1744  * Construct a new buffer pool.
1745  *
1746  * Returns: the new pool, use gst_object_unref() to free resources
1747  */
1748 GstBufferPool *
1749 gst_v4l2_buffer_pool_new (GstV4l2Object * obj, GstCaps * caps)
1750 {
1751   GstV4l2BufferPool *pool;
1752   GstStructure *config;
1753   gchar *name, *parent_name;
1754   gint fd;
1755
1756   fd = obj->dup (obj->video_fd);
1757   if (fd < 0)
1758     goto dup_failed;
1759
1760   /* setting a significant unique name */
1761   parent_name = gst_object_get_name (GST_OBJECT (obj->element));
1762   name = g_strdup_printf ("%s:pool%u:%s",
1763       parent_name, obj->pool_seq++,
1764       V4L2_TYPE_IS_OUTPUT (obj->type) ? "sink" : "src");
1765   g_free (parent_name);
1766
1767   pool = (GstV4l2BufferPool *) g_object_new (GST_TYPE_V4L2_BUFFER_POOL,
1768       "name", name, NULL);
1769   g_object_ref_sink (pool);
1770   g_free (name);
1771
1772   pool->video_fd = fd;
1773   pool->obj = obj;
1774
1775   pool->vallocator = gst_v4l2_allocator_new (GST_OBJECT (pool), obj);
1776   if (pool->vallocator == NULL)
1777     goto allocator_failed;
1778
1779   gst_object_ref (obj->element);
1780
1781   config = gst_buffer_pool_get_config (GST_BUFFER_POOL_CAST (pool));
1782   gst_buffer_pool_config_set_params (config, caps, obj->info.size, 0, 0);
1783   /* This will simply set a default config, but will not configure the pool
1784    * because min and max are not valid */
1785   gst_buffer_pool_set_config (GST_BUFFER_POOL_CAST (pool), config);
1786
1787   return GST_BUFFER_POOL (pool);
1788
1789   /* ERRORS */
1790 dup_failed:
1791   {
1792     GST_ERROR ("failed to dup fd %d (%s)", errno, g_strerror (errno));
1793     return NULL;
1794   }
1795 allocator_failed:
1796   {
1797     GST_ERROR_OBJECT (pool, "Failed to create V4L2 allocator");
1798     gst_object_unref (pool);
1799     return NULL;
1800   }
1801 }
1802
1803 static GstFlowReturn
1804 gst_v4l2_do_read (GstV4l2BufferPool * pool, GstBuffer * buf)
1805 {
1806   GstFlowReturn res;
1807   GstV4l2Object *obj = pool->obj;
1808   gint amount;
1809   GstMapInfo map;
1810   gint toread;
1811
1812   toread = obj->info.size;
1813
1814   GST_LOG_OBJECT (pool, "reading %d bytes into buffer %p", toread, buf);
1815
1816   gst_buffer_map (buf, &map, GST_MAP_WRITE);
1817
1818   do {
1819     if ((res = gst_v4l2_buffer_pool_poll (pool, TRUE)) != GST_FLOW_OK)
1820       goto poll_error;
1821
1822     amount = obj->read (obj->video_fd, map.data, toread);
1823
1824     if (amount == toread) {
1825       break;
1826     } else if (amount == -1) {
1827       if (errno == EAGAIN || errno == EINTR) {
1828         continue;
1829       } else
1830         goto read_error;
1831     } else {
1832       /* short reads can happen if a signal interrupts the read */
1833       continue;
1834     }
1835   } while (TRUE);
1836
1837   GST_LOG_OBJECT (pool, "read %d bytes", amount);
1838   gst_buffer_unmap (buf, &map);
1839   gst_buffer_resize (buf, 0, amount);
1840
1841   return GST_FLOW_OK;
1842
1843   /* ERRORS */
1844 poll_error:
1845   {
1846     GST_DEBUG ("poll error %s", gst_flow_get_name (res));
1847     goto cleanup;
1848   }
1849 read_error:
1850   {
1851     GST_ELEMENT_ERROR (obj->element, RESOURCE, READ,
1852         (_("Error reading %d bytes from device '%s'."),
1853             toread, obj->videodev), GST_ERROR_SYSTEM);
1854     res = GST_FLOW_ERROR;
1855     goto cleanup;
1856   }
1857 cleanup:
1858   {
1859     gst_buffer_unmap (buf, &map);
1860     gst_buffer_resize (buf, 0, 0);
1861     return res;
1862   }
1863 }
1864
1865 /**
1866  * gst_v4l2_buffer_pool_process:
1867  * @bpool: a #GstBufferPool
1868  * @buf: a #GstBuffer, maybe be replaced
1869  * @frame_number: 32 bit frame number or %NULL
1870  *
1871  * Process @buf in @bpool. For capture devices, this functions fills @buf with
1872  * data from the device. For output devices, this functions send the contents of
1873  * @buf to the device for playback.
1874  *
1875  * If non-%NULL and an output device, @frame_number is stored inside the timestamp for output devices and read
1876  * back from the timestamp for capture devices.
1877  *
1878  * Returns: %GST_FLOW_OK on success.
1879  */
1880 GstFlowReturn
1881 gst_v4l2_buffer_pool_process (GstV4l2BufferPool * pool, GstBuffer ** buf,
1882     guint32 * frame_number)
1883 {
1884   GstFlowReturn ret = GST_FLOW_OK;
1885   GstBufferPool *bpool = GST_BUFFER_POOL_CAST (pool);
1886   GstV4l2Object *obj = pool->obj;
1887
1888   GST_DEBUG_OBJECT (pool, "process buffer %p", *buf);
1889
1890   if (GST_BUFFER_POOL_IS_FLUSHING (pool))
1891     return GST_FLOW_FLUSHING;
1892
1893   switch (obj->type) {
1894     case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1895     case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
1896       /* capture */
1897       switch (obj->mode) {
1898         case GST_V4L2_IO_RW:
1899           /* capture into the buffer */
1900           ret = gst_v4l2_do_read (pool, *buf);
1901           break;
1902
1903         case GST_V4L2_IO_MMAP:
1904         case GST_V4L2_IO_DMABUF:
1905         {
1906           GstBuffer *tmp;
1907
1908           if ((*buf)->pool == bpool) {
1909             guint num_queued;
1910             gsize size = gst_buffer_get_size (*buf);
1911
1912             /* Legacy M2M devices return empty buffer when drained */
1913             if (size == 0 && GST_V4L2_IS_M2M (obj->device_caps)) {
1914               gst_v4l2_buffer_pool_resize_buffer (bpool, *buf);
1915               goto eos;
1916             }
1917
1918             if (GST_VIDEO_INFO_FORMAT (&pool->caps_info) !=
1919                 GST_VIDEO_FORMAT_ENCODED && size < pool->size)
1920               goto buffer_truncated;
1921
1922             num_queued = g_atomic_int_get (&pool->num_queued);
1923             GST_TRACE_OBJECT (pool, "Only %i buffer left in the capture queue.",
1924                 num_queued);
1925
1926             /* If we have no more buffer, and can allocate it time to do so */
1927             if (num_queued == 0) {
1928               if (GST_V4L2_ALLOCATOR_CAN_ALLOCATE (pool->vallocator, MMAP)) {
1929                 GST_DEBUG_OBJECT (pool, "Resurrect for empty queue");
1930                 ret = gst_v4l2_buffer_pool_resurrect_buffer (pool);
1931                 if (ret == GST_FLOW_OK || ret == GST_FLOW_FLUSHING)
1932                   goto done;
1933               }
1934             }
1935
1936             /* start copying buffers when we are running low on buffers */
1937             if (num_queued < pool->copy_threshold) {
1938               GstBuffer *copy;
1939
1940               if (GST_V4L2_ALLOCATOR_CAN_ALLOCATE (pool->vallocator, MMAP)) {
1941                 GST_DEBUG_OBJECT (pool, "Resurrect for threshold");
1942                 ret = gst_v4l2_buffer_pool_resurrect_buffer (pool);
1943                 if (ret == GST_FLOW_OK || ret == GST_FLOW_FLUSHING)
1944                   goto done;
1945               }
1946
1947               /* copy the buffer */
1948               copy = gst_buffer_copy_region (*buf,
1949                   GST_BUFFER_COPY_ALL | GST_BUFFER_COPY_DEEP, 0, -1);
1950               GST_LOG_OBJECT (pool, "copy buffer %p->%p", *buf, copy);
1951
1952               /* and requeue so that we can continue capturing */
1953               gst_buffer_unref (*buf);
1954               *buf = copy;
1955             }
1956
1957             ret = GST_FLOW_OK;
1958             /* nothing, data was inside the buffer when we did _acquire() */
1959             goto done;
1960           }
1961
1962           /* buffer not from our pool, grab a frame and copy it into the target */
1963           if ((ret = gst_v4l2_buffer_pool_dqbuf (pool, &tmp, NULL, TRUE))
1964               != GST_FLOW_OK)
1965             goto done;
1966
1967           /* An empty buffer on capture indicates the end of stream */
1968           if (gst_buffer_get_size (tmp) == 0) {
1969             gst_v4l2_buffer_pool_complete_release_buffer (bpool, tmp, FALSE);
1970
1971             /* Legacy M2M devices return empty buffer when drained */
1972             if (GST_V4L2_IS_M2M (obj->device_caps)) {
1973               gst_v4l2_buffer_pool_resize_buffer (bpool, *buf);
1974               goto eos;
1975             }
1976           }
1977
1978           ret = gst_v4l2_buffer_pool_copy_buffer (pool, *buf, tmp);
1979
1980           /* an queue the buffer again after the copy */
1981           gst_v4l2_buffer_pool_complete_release_buffer (bpool, tmp, FALSE);
1982
1983           if (ret != GST_FLOW_OK)
1984             goto copy_failed;
1985           break;
1986         }
1987
1988         case GST_V4L2_IO_USERPTR:
1989         {
1990           struct UserPtrData *data;
1991           GstBuffer *tmp;
1992
1993           /* Replace our buffer with downstream allocated buffer */
1994           data = gst_mini_object_steal_qdata (GST_MINI_OBJECT (*buf),
1995               GST_V4L2_IMPORT_QUARK);
1996           tmp = gst_buffer_ref (data->buffer);
1997           _unmap_userptr_frame (data);
1998
1999           /* Now tmp is writable, copy the flags and timestamp */
2000           gst_buffer_copy_into (tmp, *buf,
2001               GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_TIMESTAMPS, 0, -1);
2002
2003           gst_buffer_replace (buf, tmp);
2004           gst_buffer_unref (tmp);
2005           break;
2006         }
2007
2008         case GST_V4L2_IO_DMABUF_IMPORT:
2009         {
2010           GstBuffer *tmp;
2011
2012           /* Replace our buffer with downstream allocated buffer */
2013           tmp = gst_mini_object_steal_qdata (GST_MINI_OBJECT (*buf),
2014               GST_V4L2_IMPORT_QUARK);
2015
2016           gst_buffer_copy_into (tmp, *buf,
2017               GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_TIMESTAMPS, 0, -1);
2018
2019           gst_buffer_replace (buf, tmp);
2020           gst_buffer_unref (tmp);
2021           break;
2022         }
2023
2024         default:
2025           g_assert_not_reached ();
2026           break;
2027       }
2028       break;
2029
2030     case V4L2_BUF_TYPE_VIDEO_OUTPUT:
2031     case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
2032       /* playback */
2033       switch (obj->mode) {
2034         case GST_V4L2_IO_RW:
2035           /* FIXME, do write() */
2036           GST_WARNING_OBJECT (pool, "implement write()");
2037           break;
2038
2039         case GST_V4L2_IO_USERPTR:
2040         case GST_V4L2_IO_DMABUF_IMPORT:
2041         case GST_V4L2_IO_DMABUF:
2042         case GST_V4L2_IO_MMAP:
2043         {
2044           GstBuffer *to_queue = NULL;
2045           GstBuffer *buffer;
2046           GstV4l2MemoryGroup *group;
2047           gint index;
2048           gboolean outstanding;
2049
2050           if ((*buf)->pool != bpool)
2051             goto copying;
2052
2053           if (!gst_v4l2_is_buffer_valid (*buf, &group))
2054             goto copying;
2055
2056           index = group->buffer.index;
2057
2058           GST_LOG_OBJECT (pool, "processing buffer %i from our pool", index);
2059
2060           if (g_atomic_int_get (&pool->buffer_state[index]) &
2061               BUFFER_STATE_QUEUED) {
2062             GST_LOG_OBJECT (pool, "buffer %i already queued, copying", index);
2063             goto copying;
2064           }
2065
2066           /* we can queue directly */
2067           to_queue = gst_buffer_ref (*buf);
2068
2069         copying:
2070           if (to_queue == NULL) {
2071             GstBufferPoolAcquireParams params = { 0 };
2072
2073             GST_LOG_OBJECT (pool, "alloc buffer from our pool");
2074
2075             /* this can return EOS if all buffers are outstanding which would
2076              * be strange because we would expect the upstream element to have
2077              * allocated them and returned to us.. */
2078             params.flags = GST_BUFFER_POOL_ACQUIRE_FLAG_DONTWAIT;
2079             ret = gst_buffer_pool_acquire_buffer (bpool, &to_queue, &params);
2080             if (ret != GST_FLOW_OK)
2081               goto acquire_failed;
2082
2083             ret = gst_v4l2_buffer_pool_prepare_buffer (pool, to_queue, *buf);
2084             if (ret != GST_FLOW_OK) {
2085               gst_buffer_unref (to_queue);
2086               goto prepare_failed;
2087             }
2088
2089             /* retrieve the group */
2090             gst_v4l2_is_buffer_valid (to_queue, &group);
2091           }
2092
2093           if ((ret =
2094                   gst_v4l2_buffer_pool_qbuf (pool, to_queue, group,
2095                       frame_number))
2096               != GST_FLOW_OK)
2097             goto queue_failed;
2098
2099           /* if we are not streaming yet (this is the first buffer, start
2100            * streaming now */
2101           if (!gst_v4l2_buffer_pool_streamon (pool)) {
2102             /* don't check return value because qbuf would have failed */
2103             gst_v4l2_is_buffer_valid (to_queue, &group);
2104
2105             /* qbuf has stored to_queue buffer but we are not in
2106              * streaming state, so the flush logic won't be performed.
2107              * To avoid leaks, flush the allocator and restore the queued
2108              * buffer as non-queued */
2109             gst_v4l2_allocator_flush (pool->vallocator);
2110
2111             pool->buffers[group->buffer.index] = NULL;
2112             g_atomic_int_and (&pool->buffer_state[group->buffer.index],
2113                 ~BUFFER_STATE_QUEUED);
2114
2115             gst_mini_object_set_qdata (GST_MINI_OBJECT (to_queue),
2116                 GST_V4L2_IMPORT_QUARK, NULL, NULL);
2117             gst_buffer_unref (to_queue);
2118             g_atomic_int_add (&pool->num_queued, -1);
2119             goto start_failed;
2120           }
2121
2122           /* Remove our ref, we will still hold this buffer in acquire as needed,
2123            * otherwise the pool will think it is outstanding and will refuse to stop. */
2124           gst_buffer_unref (to_queue);
2125
2126           /* release as many buffer as possible */
2127           while (gst_v4l2_buffer_pool_dqbuf (pool, &buffer, &outstanding,
2128                   FALSE) == GST_FLOW_OK) {
2129             if (!outstanding)
2130               gst_v4l2_buffer_pool_complete_release_buffer (bpool, buffer,
2131                   FALSE);
2132           }
2133
2134           if (g_atomic_int_get (&pool->num_queued) >= pool->min_latency) {
2135             /* all buffers are queued, try to dequeue one and release it back
2136              * into the pool so that _acquire can get to it again. */
2137             ret =
2138                 gst_v4l2_buffer_pool_dqbuf (pool, &buffer, &outstanding, TRUE);
2139             if (ret == GST_FLOW_OK && !outstanding)
2140               /* release the rendered buffer back into the pool. This wakes up any
2141                * thread waiting for a buffer in _acquire(). */
2142               gst_v4l2_buffer_pool_complete_release_buffer (bpool, buffer,
2143                   FALSE);
2144           }
2145           break;
2146         }
2147         default:
2148           g_assert_not_reached ();
2149           break;
2150       }
2151       break;
2152     default:
2153       g_assert_not_reached ();
2154       break;
2155   }
2156 done:
2157   return ret;
2158
2159   /* ERRORS */
2160 copy_failed:
2161   {
2162     GST_ERROR_OBJECT (pool, "failed to copy buffer");
2163     return ret;
2164   }
2165 buffer_truncated:
2166   {
2167     GST_WARNING_OBJECT (pool,
2168         "Dropping truncated buffer, this is likely a driver bug.");
2169     gst_buffer_unref (*buf);
2170     *buf = NULL;
2171     return GST_V4L2_FLOW_CORRUPTED_BUFFER;
2172   }
2173 eos:
2174   {
2175     GST_DEBUG_OBJECT (pool, "end of sequence reached");
2176     gst_buffer_unref (*buf);
2177     *buf = NULL;
2178     return GST_V4L2_FLOW_LAST_BUFFER;
2179   }
2180 acquire_failed:
2181   {
2182     if (ret == GST_FLOW_FLUSHING)
2183       GST_DEBUG_OBJECT (pool, "flushing");
2184     else
2185       GST_WARNING_OBJECT (pool, "failed to acquire a buffer: %s",
2186           gst_flow_get_name (ret));
2187     return ret;
2188   }
2189 prepare_failed:
2190   {
2191     GST_ERROR_OBJECT (pool, "failed to prepare data");
2192     return ret;
2193   }
2194 queue_failed:
2195   {
2196     GST_ERROR_OBJECT (pool, "failed to queue buffer");
2197     return ret;
2198   }
2199 start_failed:
2200   {
2201     GST_ERROR_OBJECT (pool, "failed to start streaming");
2202     return GST_FLOW_ERROR;
2203   }
2204 }
2205
2206 void
2207 gst_v4l2_buffer_pool_set_other_pool (GstV4l2BufferPool * pool,
2208     GstBufferPool * other_pool)
2209 {
2210   g_return_if_fail (!gst_buffer_pool_is_active (GST_BUFFER_POOL (pool)));
2211
2212   if (pool->other_pool)
2213     gst_object_unref (pool->other_pool);
2214   pool->other_pool = gst_object_ref (other_pool);
2215 }
2216
2217 void
2218 gst_v4l2_buffer_pool_copy_at_threshold (GstV4l2BufferPool * pool, gboolean copy)
2219 {
2220   GST_OBJECT_LOCK (pool);
2221   pool->enable_copy_threshold = copy;
2222   GST_OBJECT_UNLOCK (pool);
2223 }
2224
2225 static GstFlowReturn
2226 gst_v4l2_buffer_pool_flush_events (GstV4l2Object * v4l2object)
2227 {
2228   GstFlowReturn ret = GST_FLOW_OK;
2229   gboolean event_found;
2230
2231   /* FIXME simplify this when we drop legacy support for driver without poll()
2232    * support. When we do, we can switch the video_fd to non blocking, and just
2233    * pop the events directly. */
2234
2235   do {
2236     struct v4l2_event event = { 0, };
2237     gint poll_ret;
2238
2239     event_found = FALSE;
2240
2241     gst_poll_set_flushing (v4l2object->poll, FALSE);
2242
2243     do {
2244       /* GstPoll don't have 0ns timeout, but 1 will do */
2245       poll_ret = gst_poll_wait (v4l2object->poll, 1);
2246     } while (poll_ret == EAGAIN || poll_ret == EINTR);
2247
2248     if (gst_poll_fd_has_pri (v4l2object->poll, &v4l2object->pollfd)) {
2249       if (!gst_v4l2_dequeue_event (v4l2object, &event))
2250         return GST_FLOW_ERROR;
2251
2252       event_found = TRUE;
2253
2254       if (event.type == V4L2_EVENT_SOURCE_CHANGE &&
2255           (event.u.src_change.changes & V4L2_EVENT_SRC_CH_RESOLUTION)) {
2256         GST_DEBUG_OBJECT (v4l2object->dbg_obj,
2257             "Can't streamon capture as the resolution have changed.");
2258         ret = GST_V4L2_FLOW_RESOLUTION_CHANGE;
2259       }
2260     }
2261   } while (event_found);
2262
2263   return ret;
2264 }
2265
2266 GstFlowReturn
2267 gst_v4l2_buffer_pool_flush (GstV4l2Object * v4l2object)
2268 {
2269   GstBufferPool *bpool = gst_v4l2_object_get_buffer_pool (v4l2object);
2270   GstV4l2BufferPool *pool;
2271   GstFlowReturn ret = GST_FLOW_OK;
2272
2273   if (!bpool)
2274     return GST_FLOW_ERROR;
2275
2276   pool = GST_V4L2_BUFFER_POOL (bpool);
2277
2278   gst_v4l2_buffer_pool_streamoff (pool);
2279
2280   if (!V4L2_TYPE_IS_OUTPUT (pool->obj->type)) {
2281     ret = gst_v4l2_buffer_pool_flush_events (v4l2object);
2282
2283     /* If the format haven't change, avoid reallocation to go back to
2284      * streaming */
2285     if (ret == GST_FLOW_OK)
2286       ret = gst_v4l2_buffer_pool_streamon (pool);
2287   }
2288
2289   gst_object_unref (bpool);
2290   return ret;
2291 }
2292
2293 /**
2294  * gst_v4l2_buffer_pool_enable_resolution_change:
2295  * @pool: a #GstBufferPool
2296  *
2297  * When this is called, the pool will subscribe to the
2298  * %V4L2_EVENT_SOURCE_CHANGE. Upon receiving this event, it will notify
2299  * the element acquiring buffer with the special flow return
2300  * %GST_V4L2_FLOW_RESOLUTION_CHANGE.
2301  */
2302 void
2303 gst_v4l2_buffer_pool_enable_resolution_change (GstV4l2BufferPool * pool)
2304 {
2305   gst_v4l2_object_subscribe_event (pool->obj, V4L2_EVENT_SOURCE_CHANGE);
2306 }