Merging gst-build
[platform/upstream/gstreamer.git] / subprojects / gst-plugins-bad / sys / v4l2codecs / gstv4l2decoder.c
1 /* GStreamer
2  * Copyright (C) 2020 Nicolas Dufresne <nicolas.dufresne@collabora.com>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
17  * Boston, MA 02110-1301, USA.
18  */
19
20 #ifdef HAVE_CONFIG_H
21 #include <config.h>
22 #endif
23
24 #include "gstv4l2codecallocator.h"
25 #include "gstv4l2codecpool.h"
26 #include "gstv4l2decoder.h"
27 #include "gstv4l2format.h"
28 #include "linux/media.h"
29 #include "linux/videodev2.h"
30
31 #include <fcntl.h>
32 #include <sys/ioctl.h>
33 #include <sys/stat.h>
34 #include <sys/types.h>
35 #include <unistd.h>
36
37 #include <gst/base/base.h>
38
39 GST_DEBUG_CATEGORY (v4l2_decoder_debug);
40 #define GST_CAT_DEFAULT v4l2_decoder_debug
41
42 enum
43 {
44   PROP_0,
45   PROP_MEDIA_DEVICE,
46   PROP_VIDEO_DEVICE,
47 };
48
49 struct _GstV4l2Request
50 {
51   /* non-thread safe */
52   gint ref_count;
53
54   GstV4l2Decoder *decoder;
55   gint fd;
56   guint32 frame_num;
57   GstMemory *bitstream;
58   GstBuffer *pic_buf;
59   GstPoll *poll;
60   GstPollFD pollfd;
61
62   /* request state */
63   gboolean pending;
64   gboolean failed;
65   gboolean hold_pic_buf;
66   gboolean sub_request;
67 };
68
69 struct _GstV4l2Decoder
70 {
71   GstObject parent;
72
73   gboolean opened;
74   gint media_fd;
75   gint video_fd;
76   GstQueueArray *request_pool;
77   GstQueueArray *pending_requests;
78   guint version;
79
80   enum v4l2_buf_type src_buf_type;
81   enum v4l2_buf_type sink_buf_type;
82   gboolean mplane;
83
84   /* properties */
85   gchar *media_device;
86   gchar *video_device;
87   guint render_delay;
88 };
89
90 G_DEFINE_TYPE_WITH_CODE (GstV4l2Decoder, gst_v4l2_decoder, GST_TYPE_OBJECT,
91     GST_DEBUG_CATEGORY_INIT (v4l2_decoder_debug, "v4l2codecs-decoder", 0,
92         "V4L2 stateless decoder helper"));
93
94 static void gst_v4l2_request_free (GstV4l2Request * request);
95
96 static guint32
97 direction_to_buffer_type (GstV4l2Decoder * self, GstPadDirection direction)
98 {
99   if (direction == GST_PAD_SRC)
100     return self->src_buf_type;
101   else
102     return self->sink_buf_type;
103 }
104
105 static void
106 gst_v4l2_decoder_finalize (GObject * obj)
107 {
108   GstV4l2Decoder *self = GST_V4L2_DECODER (obj);
109
110   gst_v4l2_decoder_close (self);
111
112   g_free (self->media_device);
113   g_free (self->video_device);
114   gst_queue_array_free (self->request_pool);
115
116   G_OBJECT_CLASS (gst_v4l2_decoder_parent_class)->finalize (obj);
117 }
118
119 static void
120 gst_v4l2_decoder_init (GstV4l2Decoder * self)
121 {
122   self->request_pool = gst_queue_array_new (16);
123   self->pending_requests = gst_queue_array_new (16);
124 }
125
126 static void
127 gst_v4l2_decoder_class_init (GstV4l2DecoderClass * klass)
128 {
129   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
130
131   gobject_class->finalize = gst_v4l2_decoder_finalize;
132   gobject_class->get_property = gst_v4l2_decoder_get_property;
133   gobject_class->set_property = gst_v4l2_decoder_set_property;
134
135   gst_v4l2_decoder_install_properties (gobject_class, 0, NULL);
136 }
137
138 GstV4l2Decoder *
139 gst_v4l2_decoder_new (GstV4l2CodecDevice * device)
140 {
141   GstV4l2Decoder *decoder;
142
143   g_return_val_if_fail (device->function == MEDIA_ENT_F_PROC_VIDEO_DECODER,
144       NULL);
145
146   decoder = g_object_new (GST_TYPE_V4L2_DECODER,
147       "media-device", device->media_device_path,
148       "video-device", device->video_device_path, NULL);
149
150   return gst_object_ref_sink (decoder);
151 }
152
153 guint
154 gst_v4l2_decoder_get_version (GstV4l2Decoder * self)
155 {
156   return self->version;
157 }
158
159 gboolean
160 gst_v4l2_decoder_open (GstV4l2Decoder * self)
161 {
162   gint ret;
163   struct v4l2_capability querycap;
164   guint32 capabilities;
165
166   self->media_fd = open (self->media_device, 0);
167   if (self->media_fd < 0) {
168     GST_ERROR_OBJECT (self, "Failed to open '%s': %s",
169         self->media_device, g_strerror (errno));
170     return FALSE;
171   }
172
173   self->video_fd = open (self->video_device, O_NONBLOCK);
174   if (self->video_fd < 0) {
175     GST_ERROR_OBJECT (self, "Failed to open '%s': %s",
176         self->video_device, g_strerror (errno));
177     return FALSE;
178   }
179
180   ret = ioctl (self->video_fd, VIDIOC_QUERYCAP, &querycap);
181   if (ret < 0) {
182     GST_ERROR_OBJECT (self, "VIDIOC_QUERYCAP failed: %s", g_strerror (errno));
183     gst_v4l2_decoder_close (self);
184     return FALSE;
185   }
186
187   self->version = querycap.version;
188
189   if (querycap.capabilities & V4L2_CAP_DEVICE_CAPS)
190     capabilities = querycap.device_caps;
191   else
192     capabilities = querycap.capabilities;
193
194   if (capabilities & V4L2_CAP_VIDEO_M2M_MPLANE) {
195     self->sink_buf_type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
196     self->src_buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
197     self->mplane = TRUE;
198   } else if (capabilities & V4L2_CAP_VIDEO_M2M) {
199     self->sink_buf_type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
200     self->src_buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
201     self->mplane = FALSE;
202   } else {
203     GST_ERROR_OBJECT (self, "Unsupported memory-2-memory device.");
204     gst_v4l2_decoder_close (self);
205     return FALSE;
206   }
207
208   self->opened = TRUE;
209
210   return TRUE;
211 }
212
213 gboolean
214 gst_v4l2_decoder_close (GstV4l2Decoder * self)
215 {
216   GstV4l2Request *request;
217
218   while ((request = gst_queue_array_pop_head (self->pending_requests)))
219     gst_v4l2_request_unref (request);
220
221   while ((request = gst_queue_array_pop_head (self->request_pool)))
222     gst_v4l2_request_free (request);
223
224   if (self->media_fd)
225     close (self->media_fd);
226   if (self->video_fd)
227     close (self->video_fd);
228
229   self->media_fd = 0;
230   self->video_fd = 0;
231   self->opened = FALSE;
232
233   return TRUE;
234 }
235
236 gboolean
237 gst_v4l2_decoder_streamon (GstV4l2Decoder * self, GstPadDirection direction)
238 {
239   gint ret;
240   guint32 type = direction_to_buffer_type (self, direction);
241
242   ret = ioctl (self->video_fd, VIDIOC_STREAMON, &type);
243   if (ret < 0) {
244     GST_ERROR_OBJECT (self, "VIDIOC_STREAMON failed: %s", g_strerror (errno));
245     return FALSE;
246   }
247
248   return TRUE;
249 }
250
251 gboolean
252 gst_v4l2_decoder_streamoff (GstV4l2Decoder * self, GstPadDirection direction)
253 {
254   guint32 type = direction_to_buffer_type (self, direction);
255   gint ret;
256
257   if (direction == GST_PAD_SRC) {
258     GstV4l2Request *pending_req;
259
260     /* STREAMOFF have the effect of cancelling all requests and unqueuing all
261      * buffers, so clear the pending request list */
262     while ((pending_req = gst_queue_array_pop_head (self->pending_requests))) {
263       g_clear_pointer (&pending_req->bitstream, gst_memory_unref);
264       pending_req->pending = FALSE;
265       gst_v4l2_request_unref (pending_req);
266     }
267   }
268
269   ret = ioctl (self->video_fd, VIDIOC_STREAMOFF, &type);
270   if (ret < 0) {
271     GST_ERROR_OBJECT (self, "VIDIOC_STREAMOFF failed: %s", g_strerror (errno));
272     return FALSE;
273   }
274
275   return TRUE;
276 }
277
278 gboolean
279 gst_v4l2_decoder_flush (GstV4l2Decoder * self)
280 {
281   /* We ignore streamoff failure as it's not relevant, if we manage to
282    * streamon again, we are good. */
283   gst_v4l2_decoder_streamoff (self, GST_PAD_SINK);
284   gst_v4l2_decoder_streamoff (self, GST_PAD_SRC);
285
286   return gst_v4l2_decoder_streamon (self, GST_PAD_SINK) &&
287       gst_v4l2_decoder_streamon (self, GST_PAD_SRC);
288 }
289
290 gboolean
291 gst_v4l2_decoder_enum_sink_fmt (GstV4l2Decoder * self, gint i,
292     guint32 * out_fmt)
293 {
294   struct v4l2_fmtdesc fmtdesc = { i, self->sink_buf_type, };
295   gint ret;
296
297   g_return_val_if_fail (self->opened, FALSE);
298
299   ret = ioctl (self->video_fd, VIDIOC_ENUM_FMT, &fmtdesc);
300   if (ret < 0) {
301     if (errno != EINVAL)
302       GST_ERROR_OBJECT (self, "VIDIOC_ENUM_FMT failed: %s", g_strerror (errno));
303     return FALSE;
304   }
305
306   GST_DEBUG_OBJECT (self, "Found format %" GST_FOURCC_FORMAT " (%s)",
307       GST_FOURCC_ARGS (fmtdesc.pixelformat), fmtdesc.description);
308   *out_fmt = fmtdesc.pixelformat;
309
310   return TRUE;
311 }
312
313 gboolean
314 gst_v4l2_decoder_set_sink_fmt (GstV4l2Decoder * self, guint32 pix_fmt,
315     gint width, gint height, gint pixel_bitdepth)
316 {
317   struct v4l2_format format = (struct v4l2_format) {
318     .type = self->sink_buf_type,
319     /* Compatible with .fmt.pix for these field */
320     .fmt.pix_mp = (struct v4l2_pix_format_mplane) {
321           .pixelformat = pix_fmt,
322           .width = width,
323           .height = height,
324         },
325   };
326   gint ret;
327   /* Using raw image size for now, it is guarantied to be large enough */
328   gsize sizeimage = (width * height * pixel_bitdepth) / 8;
329
330   if (self->mplane)
331     format.fmt.pix_mp.plane_fmt[0].sizeimage = sizeimage;
332   else
333     format.fmt.pix.sizeimage = sizeimage;
334
335   ret = ioctl (self->video_fd, VIDIOC_S_FMT, &format);
336   if (ret < 0) {
337     GST_ERROR_OBJECT (self, "VIDIOC_S_FMT failed: %s", g_strerror (errno));
338     return FALSE;
339   }
340
341   if (format.fmt.pix_mp.pixelformat != pix_fmt
342       || format.fmt.pix_mp.width < width || format.fmt.pix_mp.height < height) {
343     GST_WARNING_OBJECT (self, "Failed to set sink format to %"
344         GST_FOURCC_FORMAT " %ix%i", GST_FOURCC_ARGS (pix_fmt), width, height);
345     errno = EINVAL;
346     return FALSE;
347   }
348
349   return TRUE;
350 }
351
352 GstCaps *
353 gst_v4l2_decoder_enum_src_formats (GstV4l2Decoder * self)
354 {
355   gint ret;
356   struct v4l2_format fmt = {
357     .type = self->src_buf_type,
358   };
359   GstVideoFormat format;
360   GstCaps *caps;
361   GValue list = G_VALUE_INIT;
362   GValue value = G_VALUE_INIT;
363   gint i;
364
365   g_return_val_if_fail (self->opened, FALSE);
366
367   ret = ioctl (self->video_fd, VIDIOC_G_FMT, &fmt);
368   if (ret < 0) {
369     GST_ERROR_OBJECT (self, "VIDIOC_G_FMT failed: %s", g_strerror (errno));
370     return FALSE;
371   }
372
373   /* We first place a structure with the default pixel format */
374   if (gst_v4l2_format_to_video_format (fmt.fmt.pix_mp.pixelformat, &format))
375     caps = gst_caps_new_simple ("video/x-raw", "format", G_TYPE_STRING,
376         gst_video_format_to_string (format), NULL);
377   else
378     caps = gst_caps_new_empty ();
379
380   /* And then enumerate other possible formats and place that as a second
381    * structure in the caps */
382   g_value_init (&list, GST_TYPE_LIST);
383   g_value_init (&value, G_TYPE_STRING);
384
385   for (i = 0; ret >= 0; i++) {
386     struct v4l2_fmtdesc fmtdesc = { i, self->src_buf_type, };
387
388     ret = ioctl (self->video_fd, VIDIOC_ENUM_FMT, &fmtdesc);
389     if (ret < 0) {
390       if (errno != EINVAL)
391         GST_ERROR_OBJECT (self, "VIDIOC_ENUM_FMT failed: %s",
392             g_strerror (errno));
393       continue;
394     }
395
396     if (gst_v4l2_format_to_video_format (fmtdesc.pixelformat, &format)) {
397       g_value_set_static_string (&value, gst_video_format_to_string (format));
398       gst_value_list_append_value (&list, &value);
399     }
400   }
401   g_value_reset (&value);
402
403   if (gst_value_list_get_size (&list) > 0) {
404     GstStructure *str = gst_structure_new_empty ("video/x-raw");
405     gst_structure_take_value (str, "format", &list);
406     gst_caps_append_structure (caps, str);
407   } else {
408     g_value_reset (&list);
409   }
410
411   return caps;
412 }
413
414 gboolean
415 gst_v4l2_decoder_select_src_format (GstV4l2Decoder * self, GstCaps * caps,
416     GstVideoInfo * info)
417 {
418   gint ret;
419   struct v4l2_format fmt = {
420     .type = self->src_buf_type,
421   };
422   GstStructure *str;
423   const gchar *format_str;
424   GstVideoFormat format;
425   guint32 pix_fmt;
426
427   if (gst_caps_is_empty (caps))
428     return FALSE;
429
430   ret = ioctl (self->video_fd, VIDIOC_G_FMT, &fmt);
431   if (ret < 0) {
432     GST_ERROR_OBJECT (self, "VIDIOC_G_FMT failed: %s", g_strerror (errno));
433     return FALSE;
434   }
435
436   caps = gst_caps_make_writable (caps);
437   str = gst_caps_get_structure (caps, 0);
438   gst_structure_fixate_field (str, "format");
439
440   format_str = gst_structure_get_string (str, "format");
441   format = gst_video_format_from_string (format_str);
442
443   if (gst_v4l2_format_from_video_format (format, &pix_fmt) &&
444       pix_fmt != fmt.fmt.pix_mp.pixelformat) {
445     GST_DEBUG_OBJECT (self, "Trying to use peer format: %s ", format_str);
446     fmt.fmt.pix_mp.pixelformat = pix_fmt;
447
448     ret = ioctl (self->video_fd, VIDIOC_S_FMT, &fmt);
449     if (ret < 0) {
450       GST_ERROR_OBJECT (self, "VIDIOC_S_FMT failed: %s", g_strerror (errno));
451       return FALSE;
452     }
453   }
454
455   if (!gst_v4l2_format_to_video_info (&fmt, info)) {
456     GST_ERROR_OBJECT (self, "Unsupported V4L2 pixelformat %" GST_FOURCC_FORMAT,
457         GST_FOURCC_ARGS (fmt.fmt.pix_mp.pixelformat));
458     return FALSE;
459   }
460
461   GST_INFO_OBJECT (self, "Selected format %s %ix%i",
462       gst_video_format_to_string (info->finfo->format),
463       info->width, info->height);
464
465   return TRUE;
466 }
467
468 gint
469 gst_v4l2_decoder_request_buffers (GstV4l2Decoder * self,
470     GstPadDirection direction, guint num_buffers)
471 {
472   gint ret;
473   struct v4l2_requestbuffers reqbufs = {
474     .count = num_buffers,
475     .memory = V4L2_MEMORY_MMAP,
476     .type = direction_to_buffer_type (self, direction),
477   };
478
479   GST_DEBUG_OBJECT (self, "Requesting %u buffers", num_buffers);
480
481   ret = ioctl (self->video_fd, VIDIOC_REQBUFS, &reqbufs);
482   if (ret < 0) {
483     GST_ERROR_OBJECT (self, "VIDIOC_REQBUFS failed: %s", g_strerror (errno));
484     return ret;
485   }
486
487   return reqbufs.count;
488 }
489
490 gboolean
491 gst_v4l2_decoder_export_buffer (GstV4l2Decoder * self,
492     GstPadDirection direction, gint index, gint * fds, gsize * sizes,
493     gsize * offsets, guint * num_fds)
494 {
495   gint i, ret;
496   struct v4l2_plane planes[GST_VIDEO_MAX_PLANES] = { {0} };
497   struct v4l2_buffer v4l2_buf = {
498     .index = 0,
499     .type = direction_to_buffer_type (self, direction),
500   };
501
502   if (self->mplane) {
503     v4l2_buf.length = GST_VIDEO_MAX_PLANES;
504     v4l2_buf.m.planes = planes;
505   }
506
507   ret = ioctl (self->video_fd, VIDIOC_QUERYBUF, &v4l2_buf);
508   if (ret < 0) {
509     GST_ERROR_OBJECT (self, "VIDIOC_QUERYBUF failed: %s", g_strerror (errno));
510     return FALSE;
511   }
512
513   if (self->mplane) {
514     for (i = 0; i < v4l2_buf.length; i++) {
515       struct v4l2_plane *plane = v4l2_buf.m.planes + i;
516       struct v4l2_exportbuffer expbuf = {
517         .type = direction_to_buffer_type (self, direction),
518         .index = index,
519         .plane = i,
520         .flags = O_CLOEXEC | O_RDWR,
521       };
522
523       ret = ioctl (self->video_fd, VIDIOC_EXPBUF, &expbuf);
524       if (ret < 0) {
525         gint j;
526         GST_ERROR_OBJECT (self, "VIDIOC_EXPBUF failed: %s", g_strerror (errno));
527
528         for (j = i - 1; j >= 0; j--)
529           close (fds[j]);
530
531         return FALSE;
532       }
533
534       *num_fds = v4l2_buf.length;
535       fds[i] = expbuf.fd;
536       sizes[i] = plane->length;
537       offsets[i] = plane->data_offset;
538     }
539   } else {
540     struct v4l2_exportbuffer expbuf = {
541       .type = direction_to_buffer_type (self, direction),
542       .index = index,
543       .flags = O_CLOEXEC | O_RDWR,
544     };
545
546     ret = ioctl (self->video_fd, VIDIOC_EXPBUF, &expbuf);
547     if (ret < 0) {
548       GST_ERROR_OBJECT (self, "VIDIOC_EXPBUF failed: %s", g_strerror (errno));
549       return FALSE;
550     }
551
552     *num_fds = 1;
553     fds[0] = expbuf.fd;
554     sizes[0] = v4l2_buf.length;
555     offsets[0] = 0;
556   }
557
558   return TRUE;
559 }
560
561 static gboolean
562 gst_v4l2_decoder_queue_sink_mem (GstV4l2Decoder * self,
563     GstV4l2Request * request, GstMemory * mem, guint32 frame_num, guint flags)
564 {
565   gint ret;
566   gsize bytesused = gst_memory_get_sizes (mem, NULL, NULL);
567   struct v4l2_plane plane = {
568     .bytesused = bytesused,
569   };
570   struct v4l2_buffer buf = {
571     .type = self->sink_buf_type,
572     .memory = V4L2_MEMORY_MMAP,
573     .index = gst_v4l2_codec_memory_get_index (mem),
574     .timestamp.tv_usec = frame_num,
575     .request_fd = request->fd,
576     .flags = V4L2_BUF_FLAG_REQUEST_FD | flags,
577   };
578
579   GST_TRACE_OBJECT (self, "Queueing bitstream buffer %i", buf.index);
580
581   if (self->mplane) {
582     buf.length = 1;
583     buf.m.planes = &plane;
584   } else {
585     buf.bytesused = bytesused;
586   }
587
588   ret = ioctl (self->video_fd, VIDIOC_QBUF, &buf);
589   if (ret < 0) {
590     GST_ERROR_OBJECT (self, "VIDIOC_QBUF failed: %s", g_strerror (errno));
591     return FALSE;
592   }
593
594   return TRUE;
595 }
596
597 static gboolean
598 gst_v4l2_decoder_queue_src_buffer (GstV4l2Decoder * self, GstBuffer * buffer)
599 {
600   gint i, ret;
601   struct v4l2_plane planes[GST_VIDEO_MAX_PLANES];
602   struct v4l2_buffer buf = {
603     .type = self->src_buf_type,
604     .memory = V4L2_MEMORY_MMAP,
605     .index = gst_v4l2_codec_buffer_get_index (buffer),
606   };
607
608   GST_TRACE_OBJECT (self, "Queuing picture buffer %i", buf.index);
609
610   if (self->mplane) {
611     buf.length = gst_buffer_n_memory (buffer);
612     buf.m.planes = planes;
613     for (i = 0; i < buf.length; i++) {
614       GstMemory *mem = gst_buffer_peek_memory (buffer, i);
615       /* *INDENT-OFF* */
616       planes[i] = (struct v4l2_plane) {
617         .bytesused = gst_memory_get_sizes (mem, NULL, NULL),
618       };
619       /* *INDENT-ON* */
620     }
621   } else {
622     buf.bytesused = gst_buffer_get_size (buffer);
623   }
624
625   ret = ioctl (self->video_fd, VIDIOC_QBUF, &buf);
626   if (ret < 0) {
627     GST_ERROR_OBJECT (self, "VIDIOC_QBUF failed: %s", g_strerror (errno));
628     return FALSE;
629   }
630
631   return TRUE;
632 }
633
634 static gboolean
635 gst_v4l2_decoder_dequeue_sink (GstV4l2Decoder * self)
636 {
637   gint ret;
638   struct v4l2_plane planes[GST_VIDEO_MAX_PLANES] = { {0} };
639   struct v4l2_buffer buf = {
640     .type = self->sink_buf_type,
641     .memory = V4L2_MEMORY_MMAP,
642   };
643
644   if (self->mplane) {
645     buf.length = GST_VIDEO_MAX_PLANES;
646     buf.m.planes = planes;
647   }
648
649   ret = ioctl (self->video_fd, VIDIOC_DQBUF, &buf);
650   if (ret < 0) {
651     GST_ERROR_OBJECT (self, "VIDIOC_DQBUF failed: %s", g_strerror (errno));
652     return FALSE;
653   }
654
655   GST_TRACE_OBJECT (self, "Dequeued bitstream buffer %i", buf.index);
656
657   return TRUE;
658 }
659
660 static gboolean
661 gst_v4l2_decoder_dequeue_src (GstV4l2Decoder * self, guint32 * out_frame_num)
662 {
663   gint ret;
664   struct v4l2_plane planes[GST_VIDEO_MAX_PLANES] = { {0} };
665   struct v4l2_buffer buf = {
666     .type = self->src_buf_type,
667     .memory = V4L2_MEMORY_MMAP,
668   };
669
670   if (self->mplane) {
671     buf.length = GST_VIDEO_MAX_PLANES;
672     buf.m.planes = planes;
673   }
674
675   ret = ioctl (self->video_fd, VIDIOC_DQBUF, &buf);
676   if (ret < 0) {
677     GST_ERROR_OBJECT (self, "VIDIOC_DQBUF failed: %s", g_strerror (errno));
678     return FALSE;
679   }
680
681   *out_frame_num = buf.timestamp.tv_usec;
682
683   GST_TRACE_OBJECT (self, "Dequeued picture buffer %i", buf.index);
684
685   return TRUE;
686 }
687
688 gboolean
689 gst_v4l2_decoder_set_controls (GstV4l2Decoder * self, GstV4l2Request * request,
690     struct v4l2_ext_control * control, guint count)
691 {
692   gint ret;
693   struct v4l2_ext_controls controls = {
694     .controls = control,
695     .count = count,
696     .request_fd = request ? request->fd : 0,
697     .which = request ? V4L2_CTRL_WHICH_REQUEST_VAL : 0,
698   };
699
700   ret = ioctl (self->video_fd, VIDIOC_S_EXT_CTRLS, &controls);
701   if (ret < 0) {
702     GST_ERROR_OBJECT (self, "VIDIOC_S_EXT_CTRLS failed: %s",
703         g_strerror (errno));
704     return FALSE;
705   }
706
707   return TRUE;
708 }
709
710 gboolean
711 gst_v4l2_decoder_get_controls (GstV4l2Decoder * self,
712     struct v4l2_ext_control * control, guint count)
713 {
714   gint ret;
715   struct v4l2_ext_controls controls = {
716     .controls = control,
717     .count = count,
718   };
719
720   ret = ioctl (self->video_fd, VIDIOC_G_EXT_CTRLS, &controls);
721   if (ret < 0) {
722     GST_ERROR_OBJECT (self, "VIDIOC_G_EXT_CTRLS failed: %s",
723         g_strerror (errno));
724     return FALSE;
725   }
726
727   return TRUE;
728 }
729
730 gboolean
731 gst_v4l2_decoder_query_control_size (GstV4l2Decoder * self,
732     unsigned int control_id, unsigned int *control_size)
733 {
734   gint ret;
735   struct v4l2_query_ext_ctrl control = {
736     .id = control_id,
737   };
738
739   *control_size = 0;
740
741   ret = ioctl (self->video_fd, VIDIOC_QUERY_EXT_CTRL, &control);
742   if (ret < 0)
743     /*
744      * It's not an error if a control is not supported by this driver.
745      * Return false but don't print any error.
746      */
747     return FALSE;
748
749   *control_size = control.elem_size;
750   return TRUE;
751 }
752
753 void
754 gst_v4l2_decoder_install_properties (GObjectClass * gobject_class,
755     gint prop_offset, GstV4l2CodecDevice * device)
756 {
757   const gchar *media_device_path = NULL;
758   const gchar *video_device_path = NULL;
759
760   if (device) {
761     media_device_path = device->media_device_path;
762     video_device_path = device->video_device_path;
763   }
764
765   g_object_class_install_property (gobject_class, PROP_MEDIA_DEVICE,
766       g_param_spec_string ("media-device", "Media Device Path",
767           "Path to the media device node", media_device_path,
768           G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
769
770   g_object_class_install_property (gobject_class, PROP_VIDEO_DEVICE,
771       g_param_spec_string ("video-device", "Video Device Path",
772           "Path to the video device node", video_device_path,
773           G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
774 }
775
776 void
777 gst_v4l2_decoder_set_property (GObject * object, guint prop_id,
778     const GValue * value, GParamSpec * pspec)
779 {
780   GstV4l2Decoder *self = GST_V4L2_DECODER (object);
781
782   switch (prop_id) {
783     case PROP_MEDIA_DEVICE:
784       g_free (self->media_device);
785       self->media_device = g_value_dup_string (value);
786       break;
787     case PROP_VIDEO_DEVICE:
788       g_free (self->video_device);
789       self->video_device = g_value_dup_string (value);
790       break;
791     default:
792       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
793       break;
794   }
795 }
796
797 void
798 gst_v4l2_decoder_get_property (GObject * object, guint prop_id,
799     GValue * value, GParamSpec * pspec)
800 {
801   GstV4l2Decoder *self = GST_V4L2_DECODER (object);
802
803   switch (prop_id) {
804     case PROP_MEDIA_DEVICE:
805       g_value_set_string (value, self->media_device);
806       break;
807     case PROP_VIDEO_DEVICE:
808       g_value_set_string (value, self->video_device);
809       break;
810     default:
811       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
812       break;
813   }
814 }
815
816 /**
817  * gst_v4l2_decoder_register:
818  * @plugin: a #GstPlugin
819  * @dec_type: A #GType for the codec
820  * @class_init: The #GClassInitFunc for #dec_type
821  * @instance_init: The #GInstanceInitFunc for #dec_type
822  * @element_name_tmpl: A string to use for the first codec found and as a template for the next ones.
823  * @device: (transfer full) A #GstV4l2CodecDevice
824  * @rank: The rank to use for the element
825  * @class_data: (nullable) (transfer full) A #gpointer to pass as class_data, set to @device if null
826  * @element_name (nullable) (out) Sets the pointer to the new element name
827  *
828  * Registers a decoder element as a subtype of @dec_type for @plugin.
829  * Will create a different sub_types for each subsequent @decoder of the
830  * same type.
831  */
832 void
833 gst_v4l2_decoder_register (GstPlugin * plugin,
834     GType dec_type, GClassInitFunc class_init, gconstpointer class_data,
835     GInstanceInitFunc instance_init, const gchar * element_name_tmpl,
836     GstV4l2CodecDevice * device, guint rank, gchar ** element_name)
837 {
838   GTypeQuery type_query;
839   GTypeInfo type_info = { 0, };
840   GType subtype;
841   gchar *type_name;
842
843   g_type_query (dec_type, &type_query);
844   memset (&type_info, 0, sizeof (type_info));
845   type_info.class_size = type_query.class_size;
846   type_info.instance_size = type_query.instance_size;
847   type_info.class_init = class_init;
848   type_info.class_data = class_data;
849   type_info.instance_init = instance_init;
850
851   if (class_data == device)
852     GST_MINI_OBJECT_FLAG_SET (device, GST_MINI_OBJECT_FLAG_MAY_BE_LEAKED);
853
854   /* The first decoder to be registered should use a constant name, like
855    * v4l2slvp8dec, for any additional decoders, we create unique names. Decoder
856    * names may change between boots, so this should help gain stable names for
857    * the most common use cases. SL stands for state-less, we differentiate
858    * with v4l2vp8dec as this element may not have the same properties */
859   type_name = g_strdup_printf (element_name_tmpl, "");
860
861   if (g_type_from_name (type_name) != 0) {
862     gchar *basename = g_path_get_basename (device->video_device_path);
863     g_free (type_name);
864     type_name = g_strdup_printf (element_name_tmpl, basename);
865     g_free (basename);
866   }
867
868   subtype = g_type_register_static (dec_type, type_name, &type_info, 0);
869
870   if (!gst_element_register (plugin, type_name, rank, subtype)) {
871     GST_WARNING ("Failed to register plugin '%s'", type_name);
872     g_free (type_name);
873     type_name = NULL;
874   }
875
876   if (element_name)
877     *element_name = type_name;
878   else
879     g_free (type_name);
880 }
881
882 /*
883  * gst_v4l2_decoder_alloc_request:
884  * @self a #GstV4l2Decoder pointer
885  * @frame_num: Used as a timestamp to identify references
886  * @bitstream the #GstMemory that holds the bitstream data
887  * @pic_buf the #GstBuffer holding the decoded picture
888  *
889  * Allocate a Linux media request file descriptor. This request wrapper will
890  * hold a reference to the requested bitstream memory to decoded and the
891  * picture buffer this request will decode to. This will be used for
892  * transparent management of the V4L2 queues.
893  *
894  * Returns: a new #GstV4l2Request
895  */
896 GstV4l2Request *
897 gst_v4l2_decoder_alloc_request (GstV4l2Decoder * self, guint32 frame_num,
898     GstMemory * bitstream, GstBuffer * pic_buf)
899 {
900   GstV4l2Request *request = gst_queue_array_pop_head (self->request_pool);
901   gint ret;
902
903   if (!request) {
904     request = g_new0 (GstV4l2Request, 1);
905
906     ret = ioctl (self->media_fd, MEDIA_IOC_REQUEST_ALLOC, &request->fd);
907     if (ret < 0) {
908       GST_ERROR_OBJECT (self, "MEDIA_IOC_REQUEST_ALLOC failed: %s",
909           g_strerror (errno));
910       return NULL;
911     }
912
913     request->poll = gst_poll_new (FALSE);
914     gst_poll_fd_init (&request->pollfd);
915     request->pollfd.fd = request->fd;
916     gst_poll_add_fd (request->poll, &request->pollfd);
917     gst_poll_fd_ctl_pri (request->poll, &request->pollfd, TRUE);
918   }
919
920   request->decoder = g_object_ref (self);
921   request->bitstream = gst_memory_ref (bitstream);
922   request->pic_buf = gst_buffer_ref (pic_buf);
923   request->frame_num = frame_num;
924   request->ref_count = 1;
925
926   return request;
927 }
928
929 /*
930  * gst_v4l2_decoder_alloc_sub_request:
931  * @self a #GstV4l2Decoder pointer
932  * @prev_request the #GstV4l2Request this request continue
933  * @bitstream the #GstMemory that holds the bitstream data
934  *
935  * Allocate a Linux media request file descriptor. Similar to
936  * gst_v4l2_decoder_alloc_request(), but used when a request is the
937  * continuation of the decoding of the same picture. This is notably the case
938  * for subsequent slices or for second field of a frame.
939  *
940  * Returns: a new #GstV4l2Request
941  */
942 GstV4l2Request *
943 gst_v4l2_decoder_alloc_sub_request (GstV4l2Decoder * self,
944     GstV4l2Request * prev_request, GstMemory * bitstream)
945 {
946   GstV4l2Request *request = gst_queue_array_pop_head (self->request_pool);
947   gint ret;
948
949   if (!request) {
950     request = g_new0 (GstV4l2Request, 1);
951
952     ret = ioctl (self->media_fd, MEDIA_IOC_REQUEST_ALLOC, &request->fd);
953     if (ret < 0) {
954       GST_ERROR_OBJECT (self, "MEDIA_IOC_REQUEST_ALLOC failed: %s",
955           g_strerror (errno));
956       return NULL;
957     }
958
959     request->poll = gst_poll_new (FALSE);
960     gst_poll_fd_init (&request->pollfd);
961     request->pollfd.fd = request->fd;
962     gst_poll_add_fd (request->poll, &request->pollfd);
963     gst_poll_fd_ctl_pri (request->poll, &request->pollfd, TRUE);
964   }
965
966   request->decoder = g_object_ref (self);
967   request->bitstream = gst_memory_ref (bitstream);
968   request->pic_buf = gst_buffer_ref (prev_request->pic_buf);
969   request->frame_num = prev_request->frame_num;
970   request->sub_request = TRUE;
971   request->ref_count = 1;
972
973   return request;
974 }
975
976 /**
977  * gst_v4l2_decoder_set_render_delay:
978  * @self: a #GstV4l2Decoder pointer
979  * @delay: The expected render delay
980  *
981  * The decoder will adjust the number of allowed concurrent request in order
982  * to allow this delay. The same number of concurrent bitstream buffer will be
983  * used, so make sure to adjust the number of bitstream buffer.
984  *
985  * For per-slice decoder, this is the maximum number of pending slice, so the
986  * render backlog in frame may be less then the render delay.
987  */
988 void
989 gst_v4l2_decoder_set_render_delay (GstV4l2Decoder * self, guint delay)
990 {
991   self->render_delay = delay;
992 }
993
994 /**
995  * gst_v4l2_decoder_get_render_delay:
996  * @self: a #GstV4l2Decoder pointer
997  *
998  * This function is used to avoid storing the render delay in multiple places.
999  *
1000  * Returns: The currently configured render delay.
1001  */
1002 guint
1003 gst_v4l2_decoder_get_render_delay (GstV4l2Decoder * self)
1004 {
1005   return self->render_delay;
1006 }
1007
1008 GstV4l2Request *
1009 gst_v4l2_request_ref (GstV4l2Request * request)
1010 {
1011   request->ref_count++;
1012   return request;
1013 }
1014
1015 static void
1016 gst_v4l2_request_free (GstV4l2Request * request)
1017 {
1018   GstV4l2Decoder *decoder = request->decoder;
1019
1020   request->decoder = NULL;
1021   close (request->fd);
1022   gst_poll_free (request->poll);
1023   g_free (request);
1024
1025   if (decoder)
1026     g_object_unref (decoder);
1027 }
1028
1029 void
1030 gst_v4l2_request_unref (GstV4l2Request * request)
1031 {
1032   GstV4l2Decoder *decoder = request->decoder;
1033   gint ret;
1034
1035   g_return_if_fail (request->ref_count > 0);
1036
1037   if (--request->ref_count > 0)
1038     return;
1039
1040   g_clear_pointer (&request->bitstream, gst_memory_unref);
1041   g_clear_pointer (&request->pic_buf, gst_buffer_unref);
1042   request->frame_num = G_MAXUINT32;
1043   request->failed = FALSE;
1044   request->hold_pic_buf = FALSE;
1045   request->sub_request = FALSE;
1046
1047   if (request->pending) {
1048     gint idx;
1049
1050     GST_DEBUG_OBJECT (decoder, "Freeing pending request %p.", request);
1051
1052     idx = gst_queue_array_find (decoder->pending_requests, NULL, request);
1053     if (idx >= 0)
1054       gst_queue_array_drop_element (decoder->pending_requests, idx);
1055
1056     gst_v4l2_request_free (request);
1057     return;
1058   }
1059
1060   GST_TRACE_OBJECT (decoder, "Recycling request %p.", request);
1061
1062   ret = ioctl (request->fd, MEDIA_REQUEST_IOC_REINIT, NULL);
1063   if (ret < 0) {
1064     GST_ERROR_OBJECT (request->decoder, "MEDIA_REQUEST_IOC_REINIT failed: %s",
1065         g_strerror (errno));
1066     gst_v4l2_request_free (request);
1067     return;
1068   }
1069
1070   gst_queue_array_push_tail (decoder->request_pool, request);
1071   g_clear_object (&request->decoder);
1072 }
1073
1074 gboolean
1075 gst_v4l2_request_queue (GstV4l2Request * request, guint flags)
1076 {
1077   GstV4l2Decoder *decoder = request->decoder;
1078   gint ret;
1079   guint max_pending;
1080
1081   GST_TRACE_OBJECT (decoder, "Queuing request %p.", request);
1082
1083   if (!gst_v4l2_decoder_queue_sink_mem (decoder, request,
1084           request->bitstream, request->frame_num, flags)) {
1085     GST_ERROR_OBJECT (decoder, "Driver did not accept the bitstream data.");
1086     return FALSE;
1087   }
1088
1089   if (!request->sub_request &&
1090       !gst_v4l2_decoder_queue_src_buffer (decoder, request->pic_buf)) {
1091     GST_ERROR_OBJECT (decoder, "Driver did not accept the picture buffer.");
1092     return FALSE;
1093   }
1094
1095   ret = ioctl (request->fd, MEDIA_REQUEST_IOC_QUEUE, NULL);
1096   if (ret < 0) {
1097     GST_ERROR_OBJECT (decoder, "MEDIA_REQUEST_IOC_QUEUE, failed: %s",
1098         g_strerror (errno));
1099     return FALSE;
1100   }
1101
1102   if (flags & V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF)
1103     request->hold_pic_buf = TRUE;
1104
1105   request->pending = TRUE;
1106   gst_queue_array_push_tail (decoder->pending_requests,
1107       gst_v4l2_request_ref (request));
1108
1109   max_pending = MAX (1, decoder->render_delay);
1110
1111   if (gst_queue_array_get_length (decoder->pending_requests) > max_pending) {
1112     GstV4l2Request *pending_req;
1113
1114     pending_req = gst_queue_array_peek_head (decoder->pending_requests);
1115     gst_v4l2_request_set_done (pending_req);
1116   }
1117
1118   return TRUE;
1119 }
1120
1121 gint
1122 gst_v4l2_request_set_done (GstV4l2Request * request)
1123 {
1124   GstV4l2Decoder *decoder = request->decoder;
1125   GstV4l2Request *pending_req = NULL;
1126   gint ret;
1127
1128   if (!request->pending)
1129     return 1;
1130
1131   ret = gst_poll_wait (request->poll, GST_SECOND);
1132   if (ret <= 0)
1133     return ret;
1134
1135   while ((pending_req = gst_queue_array_pop_head (decoder->pending_requests))) {
1136     gst_v4l2_decoder_dequeue_sink (decoder);
1137     g_clear_pointer (&pending_req->bitstream, gst_memory_unref);
1138
1139     if (!pending_req->hold_pic_buf) {
1140       guint32 frame_num = G_MAXUINT32;
1141
1142       if (!gst_v4l2_decoder_dequeue_src (decoder, &frame_num)) {
1143         pending_req->failed = TRUE;
1144       } else if (frame_num != pending_req->frame_num) {
1145         GST_WARNING_OBJECT (decoder,
1146             "Requested frame %u, but driver returned frame %u.",
1147             pending_req->frame_num, frame_num);
1148         pending_req->failed = TRUE;
1149       }
1150     }
1151
1152     pending_req->pending = FALSE;
1153     gst_v4l2_request_unref (pending_req);
1154
1155     if (pending_req == request)
1156       break;
1157   }
1158
1159   /* Pending request must be in the pending request list */
1160   g_assert (pending_req == request);
1161
1162   return ret;
1163 }
1164
1165 gboolean
1166 gst_v4l2_request_failed (GstV4l2Request * request)
1167 {
1168   return request->failed;
1169 }