FFmpeg
v4l2_context.c
Go to the documentation of this file.
1 /*
2  * V4L2 context helper functions.
3  *
4  * Copyright (C) 2017 Alexis Ballier <aballier@gentoo.org>
5  * Copyright (C) 2017 Jorge Ramirez <jorge.ramirez-ortiz@linaro.org>
6  *
7  * This file is part of FFmpeg.
8  *
9  * FFmpeg is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  * FFmpeg 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  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with FFmpeg; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22  */
23 
24 #include <linux/videodev2.h>
25 #include <sys/ioctl.h>
26 #include <sys/mman.h>
27 #include <unistd.h>
28 #include <fcntl.h>
29 #include <poll.h>
30 #include "libavcodec/avcodec.h"
31 #include "decode.h"
32 #include "v4l2_buffers.h"
33 #include "v4l2_fmt.h"
34 #include "v4l2_m2m.h"
35 
37  uint32_t v4l2_fmt;
39 
42 };
43 
45 {
46  return V4L2_TYPE_IS_OUTPUT(ctx->type) ?
48  container_of(ctx, V4L2m2mContext, capture);
49 }
50 
52 {
53  return ctx_to_m2mctx(ctx)->avctx;
54 }
55 
56 static inline unsigned int v4l2_get_width(struct v4l2_format *fmt)
57 {
58  return V4L2_TYPE_IS_MULTIPLANAR(fmt->type) ? fmt->fmt.pix_mp.width : fmt->fmt.pix.width;
59 }
60 
61 static inline unsigned int v4l2_get_height(struct v4l2_format *fmt)
62 {
63  return V4L2_TYPE_IS_MULTIPLANAR(fmt->type) ? fmt->fmt.pix_mp.height : fmt->fmt.pix.height;
64 }
65 
67 {
68  struct AVRational sar = { 0, 1 };
69  struct v4l2_cropcap cropcap;
70  int ret;
71 
72  memset(&cropcap, 0, sizeof(cropcap));
73  cropcap.type = ctx->type;
74 
75  ret = ioctl(ctx_to_m2mctx(ctx)->fd, VIDIOC_CROPCAP, &cropcap);
76  if (ret)
77  return sar;
78 
79  sar.num = cropcap.pixelaspect.numerator;
80  sar.den = cropcap.pixelaspect.denominator;
81  return sar;
82 }
83 
84 static inline unsigned int v4l2_resolution_changed(V4L2Context *ctx, struct v4l2_format *fmt2)
85 {
86  struct v4l2_format *fmt1 = &ctx->format;
87  int ret = V4L2_TYPE_IS_MULTIPLANAR(ctx->type) ?
88  fmt1->fmt.pix_mp.width != fmt2->fmt.pix_mp.width ||
89  fmt1->fmt.pix_mp.height != fmt2->fmt.pix_mp.height
90  :
91  fmt1->fmt.pix.width != fmt2->fmt.pix.width ||
92  fmt1->fmt.pix.height != fmt2->fmt.pix.height;
93 
94  if (ret)
95  av_log(logger(ctx), AV_LOG_DEBUG, "%s changed (%dx%d) -> (%dx%d)\n",
96  ctx->name,
97  v4l2_get_width(fmt1), v4l2_get_height(fmt1),
98  v4l2_get_width(fmt2), v4l2_get_height(fmt2));
99 
100  return ret;
101 }
102 
104 {
105  return ctx->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
106  ctx->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ||
107  ctx->type == V4L2_BUF_TYPE_VIDEO_CAPTURE ||
108  ctx->type == V4L2_BUF_TYPE_VIDEO_OUTPUT;
109 }
110 
112 {
114  const int SZ_4K = 0x1000;
115  int size;
116 
117  if (s->avctx && av_codec_is_decoder(s->avctx->codec))
118  return ((width * height * 3 / 2) / 2) + 128;
119 
120  /* encoder */
121  size = FFALIGN(height, 32) * FFALIGN(width, 32) * 3 / 2 / 2;
122  return FFALIGN(size, SZ_4K);
123 }
124 
125 static inline void v4l2_save_to_context(V4L2Context* ctx, struct v4l2_format_update *fmt)
126 {
127  ctx->format.type = ctx->type;
128 
129  if (fmt->update_avfmt)
130  ctx->av_pix_fmt = fmt->av_fmt;
131 
132  if (V4L2_TYPE_IS_MULTIPLANAR(ctx->type)) {
133  /* update the sizes to handle the reconfiguration of the capture stream at runtime */
134  ctx->format.fmt.pix_mp.height = ctx->height;
135  ctx->format.fmt.pix_mp.width = ctx->width;
136  if (fmt->update_v4l2) {
137  ctx->format.fmt.pix_mp.pixelformat = fmt->v4l2_fmt;
138 
139  /* s5p-mfc requires the user to specify a buffer size */
140  ctx->format.fmt.pix_mp.plane_fmt[0].sizeimage =
141  v4l2_get_framesize_compressed(ctx, ctx->width, ctx->height);
142  }
143  } else {
144  ctx->format.fmt.pix.height = ctx->height;
145  ctx->format.fmt.pix.width = ctx->width;
146  if (fmt->update_v4l2) {
147  ctx->format.fmt.pix.pixelformat = fmt->v4l2_fmt;
148 
149  /* s5p-mfc requires the user to specify a buffer size */
150  ctx->format.fmt.pix.sizeimage =
151  v4l2_get_framesize_compressed(ctx, ctx->width, ctx->height);
152  }
153  }
154 }
155 
157 {
158  struct v4l2_decoder_cmd cmd = {
159  .cmd = V4L2_DEC_CMD_START,
160  .flags = 0,
161  };
162  int ret;
163 
164  ret = ioctl(ctx_to_m2mctx(ctx)->fd, VIDIOC_DECODER_CMD, &cmd);
165  if (ret)
166  return AVERROR(errno);
167 
168  return 0;
169 }
170 
171 /**
172  * handle resolution change event and end of stream event
173  * returns 1 if reinit was successful, negative if it failed
174  * returns 0 if reinit was not executed
175  */
177 {
179  struct v4l2_format cap_fmt = s->capture.format;
180  struct v4l2_event evt = { 0 };
181  int ret;
182 
183  ret = ioctl(s->fd, VIDIOC_DQEVENT, &evt);
184  if (ret < 0) {
185  av_log(logger(ctx), AV_LOG_ERROR, "%s VIDIOC_DQEVENT\n", ctx->name);
186  return 0;
187  }
188 
189  if (evt.type == V4L2_EVENT_EOS) {
190  ctx->done = 1;
191  return 0;
192  }
193 
194  if (evt.type != V4L2_EVENT_SOURCE_CHANGE)
195  return 0;
196 
197  ret = ioctl(s->fd, VIDIOC_G_FMT, &cap_fmt);
198  if (ret) {
199  av_log(logger(ctx), AV_LOG_ERROR, "%s VIDIOC_G_FMT\n", s->capture.name);
200  return 0;
201  }
202 
203  if (v4l2_resolution_changed(&s->capture, &cap_fmt)) {
204  s->capture.height = v4l2_get_height(&cap_fmt);
205  s->capture.width = v4l2_get_width(&cap_fmt);
206  s->capture.sample_aspect_ratio = v4l2_get_sar(&s->capture);
207  } else {
209  return 0;
210  }
211 
212  s->reinit = 1;
213 
214  if (s->avctx)
215  ret = ff_set_dimensions(s->avctx, s->capture.width, s->capture.height);
216  if (ret < 0)
217  av_log(logger(ctx), AV_LOG_WARNING, "update avcodec height and width\n");
218 
220  if (ret) {
221  av_log(logger(ctx), AV_LOG_ERROR, "v4l2_m2m_codec_reinit\n");
222  return AVERROR(EINVAL);
223  }
224 
225  /* reinit executed */
226  return 1;
227 }
228 
230 {
231  struct v4l2_decoder_cmd cmd = {
232  .cmd = V4L2_DEC_CMD_STOP,
233  .flags = 0,
234  };
235  int ret;
236 
237  ret = ioctl(ctx_to_m2mctx(ctx)->fd, VIDIOC_DECODER_CMD, &cmd);
238  if (ret) {
239  /* DECODER_CMD is optional */
240  if (errno == ENOTTY)
241  return ff_v4l2_context_set_status(ctx, VIDIOC_STREAMOFF);
242  else
243  return AVERROR(errno);
244  }
245 
246  return 0;
247 }
248 
250 {
251  struct v4l2_encoder_cmd cmd = {
252  .cmd = V4L2_ENC_CMD_STOP,
253  .flags = 0,
254  };
255  int ret;
256 
257  ret = ioctl(ctx_to_m2mctx(ctx)->fd, VIDIOC_ENCODER_CMD, &cmd);
258  if (ret) {
259  /* ENCODER_CMD is optional */
260  if (errno == ENOTTY)
261  return ff_v4l2_context_set_status(ctx, VIDIOC_STREAMOFF);
262  else
263  return AVERROR(errno);
264  }
265 
266  return 0;
267 }
268 
270 {
271  struct v4l2_plane planes[VIDEO_MAX_PLANES];
272  struct v4l2_buffer buf = { 0 };
273  V4L2Buffer *avbuf;
274  struct pollfd pfd = {
275  .events = POLLIN | POLLRDNORM | POLLPRI | POLLOUT | POLLWRNORM, /* default blocking capture */
276  .fd = ctx_to_m2mctx(ctx)->fd,
277  };
278  int i, ret;
279 
280  if (!V4L2_TYPE_IS_OUTPUT(ctx->type) && ctx->buffers) {
281  for (i = 0; i < ctx->num_buffers; i++) {
282  if (ctx->buffers[i].status == V4L2BUF_IN_DRIVER)
283  break;
284  }
285  if (i == ctx->num_buffers)
286  av_log(logger(ctx), AV_LOG_WARNING, "All capture buffers returned to "
287  "userspace. Increase num_capture_buffers "
288  "to prevent device deadlock or dropped "
289  "packets/frames.\n");
290  }
291 
292  /* if we are draining and there are no more capture buffers queued in the driver we are done */
293  if (!V4L2_TYPE_IS_OUTPUT(ctx->type) && ctx_to_m2mctx(ctx)->draining) {
294  for (i = 0; i < ctx->num_buffers; i++) {
295  /* capture buffer initialization happens during decode hence
296  * detection happens at runtime
297  */
298  if (!ctx->buffers)
299  break;
300 
301  if (ctx->buffers[i].status == V4L2BUF_IN_DRIVER)
302  goto start;
303  }
304  ctx->done = 1;
305  return NULL;
306  }
307 
308 start:
309  if (V4L2_TYPE_IS_OUTPUT(ctx->type))
310  pfd.events = POLLOUT | POLLWRNORM;
311  else {
312  /* no need to listen to requests for more input while draining */
313  if (ctx_to_m2mctx(ctx)->draining)
314  pfd.events = POLLIN | POLLRDNORM | POLLPRI;
315  }
316 
317  for (;;) {
318  ret = poll(&pfd, 1, timeout);
319  if (ret > 0)
320  break;
321  if (errno == EINTR)
322  continue;
323  return NULL;
324  }
325 
326  /* 0. handle errors */
327  if (pfd.revents & POLLERR) {
328  /* if we are trying to get free buffers but none have been queued yet
329  no need to raise a warning */
330  if (timeout == 0) {
331  for (i = 0; i < ctx->num_buffers; i++) {
332  if (ctx->buffers[i].status != V4L2BUF_AVAILABLE)
333  av_log(logger(ctx), AV_LOG_WARNING, "%s POLLERR\n", ctx->name);
334  }
335  }
336  else
337  av_log(logger(ctx), AV_LOG_WARNING, "%s POLLERR\n", ctx->name);
338 
339  return NULL;
340  }
341 
342  /* 1. handle resolution changes */
343  if (pfd.revents & POLLPRI) {
345  if (ret < 0) {
346  /* if re-init failed, abort */
347  ctx->done = 1;
348  return NULL;
349  }
350  if (ret) {
351  /* if re-init was successful drop the buffer (if there was one)
352  * since we had to reconfigure capture (unmap all buffers)
353  */
354  return NULL;
355  }
356  }
357 
358  /* 2. dequeue the buffer */
359  if (pfd.revents & (POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM)) {
360 
361  if (!V4L2_TYPE_IS_OUTPUT(ctx->type)) {
362  /* there is a capture buffer ready */
363  if (pfd.revents & (POLLIN | POLLRDNORM))
364  goto dequeue;
365 
366  /* the driver is ready to accept more input; instead of waiting for the capture
367  * buffer to complete we return NULL so input can proceed (we are single threaded)
368  */
369  if (pfd.revents & (POLLOUT | POLLWRNORM))
370  return NULL;
371  }
372 
373 dequeue:
374  memset(&buf, 0, sizeof(buf));
375  buf.memory = V4L2_MEMORY_MMAP;
376  buf.type = ctx->type;
377  if (V4L2_TYPE_IS_MULTIPLANAR(ctx->type)) {
378  memset(planes, 0, sizeof(planes));
379  buf.length = VIDEO_MAX_PLANES;
380  buf.m.planes = planes;
381  }
382 
383  ret = ioctl(ctx_to_m2mctx(ctx)->fd, VIDIOC_DQBUF, &buf);
384  if (ret) {
385  if (errno != EAGAIN) {
386  ctx->done = 1;
387  if (errno != EPIPE)
388  av_log(logger(ctx), AV_LOG_DEBUG, "%s VIDIOC_DQBUF, errno (%s)\n",
389  ctx->name, av_err2str(AVERROR(errno)));
390  }
391  return NULL;
392  }
393 
394  if (ctx_to_m2mctx(ctx)->draining && !V4L2_TYPE_IS_OUTPUT(ctx->type)) {
395  int bytesused = V4L2_TYPE_IS_MULTIPLANAR(buf.type) ?
396  buf.m.planes[0].bytesused : buf.bytesused;
397  if (bytesused == 0) {
398  ctx->done = 1;
399  return NULL;
400  }
401 #ifdef V4L2_BUF_FLAG_LAST
402  if (buf.flags & V4L2_BUF_FLAG_LAST)
403  ctx->done = 1;
404 #endif
405  }
406 
407  avbuf = &ctx->buffers[buf.index];
408  avbuf->status = V4L2BUF_AVAILABLE;
409  avbuf->buf = buf;
410  if (V4L2_TYPE_IS_MULTIPLANAR(ctx->type)) {
411  memcpy(avbuf->planes, planes, sizeof(planes));
412  avbuf->buf.m.planes = avbuf->planes;
413  }
414  return avbuf;
415  }
416 
417  return NULL;
418 }
419 
421 {
422  int timeout = 0; /* return when no more buffers to dequeue */
423  int i;
424 
425  /* get back as many output buffers as possible */
426  if (V4L2_TYPE_IS_OUTPUT(ctx->type)) {
427  do {
428  } while (v4l2_dequeue_v4l2buf(ctx, timeout));
429  }
430 
431  for (i = 0; i < ctx->num_buffers; i++) {
432  if (ctx->buffers[i].status == V4L2BUF_AVAILABLE)
433  return &ctx->buffers[i];
434  }
435 
436  return NULL;
437 }
438 
440 {
441  struct v4l2_requestbuffers req = {
442  .memory = V4L2_MEMORY_MMAP,
443  .type = ctx->type,
444  .count = 0, /* 0 -> unmaps buffers from the driver */
445  };
446  int i, j;
447 
448  for (i = 0; i < ctx->num_buffers; i++) {
449  V4L2Buffer *buffer = &ctx->buffers[i];
450 
451  for (j = 0; j < buffer->num_planes; j++) {
452  struct V4L2Plane_info *p = &buffer->plane_info[j];
453  if (p->mm_addr && p->length)
454  if (munmap(p->mm_addr, p->length) < 0)
455  av_log(logger(ctx), AV_LOG_ERROR, "%s unmap plane (%s))\n", ctx->name, av_err2str(AVERROR(errno)));
456  }
457  }
458 
459  return ioctl(ctx_to_m2mctx(ctx)->fd, VIDIOC_REQBUFS, &req);
460 }
461 
463 {
464  struct v4l2_format *fmt = &ctx->format;
465  uint32_t v4l2_fmt;
466  int ret;
467 
469  if (!v4l2_fmt)
470  return AVERROR(EINVAL);
471 
472  if (V4L2_TYPE_IS_MULTIPLANAR(ctx->type))
473  fmt->fmt.pix_mp.pixelformat = v4l2_fmt;
474  else
475  fmt->fmt.pix.pixelformat = v4l2_fmt;
476 
477  fmt->type = ctx->type;
478 
479  ret = ioctl(ctx_to_m2mctx(ctx)->fd, VIDIOC_TRY_FMT, fmt);
480  if (ret)
481  return AVERROR(EINVAL);
482 
483  return 0;
484 }
485 
487 {
488  enum AVPixelFormat pixfmt = ctx->av_pix_fmt;
489  struct v4l2_fmtdesc fdesc;
490  int ret;
491 
492  memset(&fdesc, 0, sizeof(fdesc));
493  fdesc.type = ctx->type;
494 
495  if (pixfmt != AV_PIX_FMT_NONE) {
497  if (!ret)
498  return 0;
499  }
500 
501  for (;;) {
502  ret = ioctl(ctx_to_m2mctx(ctx)->fd, VIDIOC_ENUM_FMT, &fdesc);
503  if (ret)
504  return AVERROR(EINVAL);
505 
508  if (ret){
509  fdesc.index++;
510  continue;
511  }
512 
513  *p = pixfmt;
514 
515  return 0;
516  }
517 
518  return AVERROR(EINVAL);
519 }
520 
521 static int v4l2_get_coded_format(V4L2Context* ctx, uint32_t *p)
522 {
523  struct v4l2_fmtdesc fdesc;
524  uint32_t v4l2_fmt;
525  int ret;
526 
527  /* translate to a valid v4l2 format */
528  v4l2_fmt = ff_v4l2_format_avcodec_to_v4l2(ctx->av_codec_id);
529  if (!v4l2_fmt)
530  return AVERROR(EINVAL);
531 
532  /* check if the driver supports this format */
533  memset(&fdesc, 0, sizeof(fdesc));
534  fdesc.type = ctx->type;
535 
536  for (;;) {
537  ret = ioctl(ctx_to_m2mctx(ctx)->fd, VIDIOC_ENUM_FMT, &fdesc);
538  if (ret)
539  return AVERROR(EINVAL);
540 
541  if (fdesc.pixelformat == v4l2_fmt)
542  break;
543 
544  fdesc.index++;
545  }
546 
547  *p = v4l2_fmt;
548 
549  return 0;
550 }
551 
552  /*****************************************************************************
553  *
554  * V4L2 Context Interface
555  *
556  *****************************************************************************/
557 
559 {
560  int type = ctx->type;
561  int ret;
562 
563  ret = ioctl(ctx_to_m2mctx(ctx)->fd, cmd, &type);
564  if (ret < 0)
565  return AVERROR(errno);
566 
567  ctx->streamon = (cmd == VIDIOC_STREAMON);
568 
569  return 0;
570 }
571 
573 {
575  V4L2Buffer* avbuf;
576  int ret;
577 
578  if (!frame) {
580  if (ret)
581  av_log(logger(ctx), AV_LOG_ERROR, "%s stop_encode\n", ctx->name);
582  s->draining= 1;
583  return 0;
584  }
585 
586  avbuf = v4l2_getfree_v4l2buf(ctx);
587  if (!avbuf)
588  return AVERROR(EAGAIN);
589 
591  if (ret)
592  return ret;
593 
594  return ff_v4l2_buffer_enqueue(avbuf);
595 }
596 
598 {
600  V4L2Buffer* avbuf;
601  int ret;
602 
603  if (!pkt->size) {
605  if (ret)
606  av_log(logger(ctx), AV_LOG_ERROR, "%s stop_decode\n", ctx->name);
607  s->draining = 1;
608  return 0;
609  }
610 
611  avbuf = v4l2_getfree_v4l2buf(ctx);
612  if (!avbuf)
613  return AVERROR(EAGAIN);
614 
616  if (ret)
617  return ret;
618 
619  return ff_v4l2_buffer_enqueue(avbuf);
620 }
621 
623 {
624  V4L2Buffer *avbuf;
625 
626  /*
627  * timeout=-1 blocks until:
628  * 1. decoded frame available
629  * 2. an input buffer is ready to be dequeued
630  */
631  avbuf = v4l2_dequeue_v4l2buf(ctx, timeout);
632  if (!avbuf) {
633  if (ctx->done)
634  return AVERROR_EOF;
635 
636  return AVERROR(EAGAIN);
637  }
638 
639  return ff_v4l2_buffer_buf_to_avframe(frame, avbuf);
640 }
641 
643 {
644  V4L2Buffer *avbuf;
645 
646  /*
647  * blocks until:
648  * 1. encoded packet available
649  * 2. an input buffer ready to be dequeued
650  */
651  avbuf = v4l2_dequeue_v4l2buf(ctx, -1);
652  if (!avbuf) {
653  if (ctx->done)
654  return AVERROR_EOF;
655 
656  return AVERROR(EAGAIN);
657  }
658 
659  return ff_v4l2_buffer_buf_to_avpkt(pkt, avbuf);
660 }
661 
663 {
664  struct v4l2_format_update fmt = { 0 };
665  int ret;
666 
667  if (ctx->av_codec_id == AV_CODEC_ID_RAWVIDEO) {
669  if (ret)
670  return ret;
671 
672  fmt.update_avfmt = !probe;
673  v4l2_save_to_context(ctx, &fmt);
674 
675  /* format has been tried already */
676  return ret;
677  }
678 
680  if (ret)
681  return ret;
682 
683  fmt.update_v4l2 = 1;
684  v4l2_save_to_context(ctx, &fmt);
685 
686  return ioctl(ctx_to_m2mctx(ctx)->fd, VIDIOC_TRY_FMT, &ctx->format);
687 }
688 
690 {
691  return ioctl(ctx_to_m2mctx(ctx)->fd, VIDIOC_S_FMT, &ctx->format);
692 }
693 
695 {
696  int ret;
697 
698  if (!ctx->buffers)
699  return;
700 
702  if (ret)
703  av_log(logger(ctx), AV_LOG_WARNING, "V4L2 failed to unmap the %s buffers\n", ctx->name);
704 
705  av_freep(&ctx->buffers);
706 }
707 
709 {
711  struct v4l2_requestbuffers req;
712  int ret, i;
713 
714  if (!v4l2_type_supported(ctx)) {
715  av_log(logger(ctx), AV_LOG_ERROR, "type %i not supported\n", ctx->type);
716  return AVERROR_PATCHWELCOME;
717  }
718 
719  ret = ioctl(s->fd, VIDIOC_G_FMT, &ctx->format);
720  if (ret)
721  av_log(logger(ctx), AV_LOG_ERROR, "%s VIDIOC_G_FMT failed\n", ctx->name);
722 
723  memset(&req, 0, sizeof(req));
724  req.count = ctx->num_buffers;
725  req.memory = V4L2_MEMORY_MMAP;
726  req.type = ctx->type;
727  ret = ioctl(s->fd, VIDIOC_REQBUFS, &req);
728  if (ret < 0) {
729  av_log(logger(ctx), AV_LOG_ERROR, "%s VIDIOC_REQBUFS failed: %s\n", ctx->name, strerror(errno));
730  return AVERROR(errno);
731  }
732 
733  ctx->num_buffers = req.count;
734  ctx->buffers = av_mallocz(ctx->num_buffers * sizeof(V4L2Buffer));
735  if (!ctx->buffers) {
736  av_log(logger(ctx), AV_LOG_ERROR, "%s malloc enomem\n", ctx->name);
737  return AVERROR(ENOMEM);
738  }
739 
740  for (i = 0; i < req.count; i++) {
741  ctx->buffers[i].context = ctx;
742  ret = ff_v4l2_buffer_initialize(&ctx->buffers[i], i);
743  if (ret < 0) {
744  av_log(logger(ctx), AV_LOG_ERROR, "%s buffer[%d] initialization (%s)\n", ctx->name, i, av_err2str(ret));
745  goto error;
746  }
747  }
748 
749  av_log(logger(ctx), AV_LOG_DEBUG, "%s: %s %02d buffers initialized: %04ux%04u, sizeimage %08u, bytesperline %08u\n", ctx->name,
750  V4L2_TYPE_IS_MULTIPLANAR(ctx->type) ? av_fourcc2str(ctx->format.fmt.pix_mp.pixelformat) : av_fourcc2str(ctx->format.fmt.pix.pixelformat),
751  req.count,
752  v4l2_get_width(&ctx->format),
753  v4l2_get_height(&ctx->format),
754  V4L2_TYPE_IS_MULTIPLANAR(ctx->type) ? ctx->format.fmt.pix_mp.plane_fmt[0].sizeimage : ctx->format.fmt.pix.sizeimage,
755  V4L2_TYPE_IS_MULTIPLANAR(ctx->type) ? ctx->format.fmt.pix_mp.plane_fmt[0].bytesperline : ctx->format.fmt.pix.bytesperline);
756 
757  return 0;
758 
759 error:
761 
762  av_freep(&ctx->buffers);
763 
764  return ret;
765 }
error
static void error(const char *err)
Definition: target_bsf_fuzzer.c:31
ff_v4l2_context_init
int ff_v4l2_context_init(V4L2Context *ctx)
Initializes a V4L2Context.
Definition: v4l2_context.c:708
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:186
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:64
planes
static const struct @346 planes[]
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
v4l2_get_width
static unsigned int v4l2_get_width(struct v4l2_format *fmt)
Definition: v4l2_context.c:56
v4l2_buffers.h
AVERROR_EOF
#define AVERROR_EOF
End of file.
Definition: error.h:57
ff_v4l2_m2m_codec_reinit
int ff_v4l2_m2m_codec_reinit(V4L2m2mContext *s)
Reinitializes the V4L2m2mContext when the driver cannot continue processing with the capture paramete...
Definition: v4l2_m2m.c:206
output
filter_frame For filters that do not use the this method is called when a frame is pushed to the filter s input It can be called at any time except in a reentrant way If the input frame is enough to produce output
Definition: filter_design.txt:225
ff_v4l2_buffer_buf_to_avpkt
int ff_v4l2_buffer_buf_to_avpkt(AVPacket *pkt, V4L2Buffer *avbuf)
Extracts the data from a V4L2Buffer to an AVPacket.
Definition: v4l2_buffers.c:452
V4L2m2mContext
Definition: v4l2_m2m.h:43
AV_CODEC_ID_RAWVIDEO
@ AV_CODEC_ID_RAWVIDEO
Definition: codec_id.h:65
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:330
ff_v4l2_context_dequeue_packet
int ff_v4l2_context_dequeue_packet(V4L2Context *ctx, AVPacket *pkt)
Dequeues a buffer from a V4L2Context to an AVPacket.
Definition: v4l2_context.c:642
ff_v4l2_context_release
void ff_v4l2_context_release(V4L2Context *ctx)
Releases a V4L2Context.
Definition: v4l2_context.c:694
v4l2_stop_encode
static int v4l2_stop_encode(V4L2Context *ctx)
Definition: v4l2_context.c:249
v4l2_format_update::v4l2_fmt
uint32_t v4l2_fmt
Definition: v4l2_context.c:37
ff_set_dimensions
int ff_set_dimensions(AVCodecContext *s, int width, int height)
Check that the provided frame dimensions are valid and set them on the codec context.
Definition: utils.c:91
ctx_to_m2mctx
static V4L2m2mContext * ctx_to_m2mctx(V4L2Context *ctx)
Definition: v4l2_context.c:44
v4l2_handle_event
static int v4l2_handle_event(V4L2Context *ctx)
handle resolution change event and end of stream event returns 1 if reinit was successful,...
Definition: v4l2_context.c:176
v4l2_start_decode
static int v4l2_start_decode(V4L2Context *ctx)
Definition: v4l2_context.c:156
v4l2_get_framesize_compressed
static int v4l2_get_framesize_compressed(V4L2Context *ctx, int width, int height)
Definition: v4l2_context.c:111
V4L2Buffer::buf
struct v4l2_buffer buf
Definition: v4l2_buffers.h:63
ff_v4l2_buffer_buf_to_avframe
int ff_v4l2_buffer_buf_to_avframe(AVFrame *frame, V4L2Buffer *avbuf)
Extracts the data from a V4L2Buffer to an AVFrame.
Definition: v4l2_buffers.c:418
type
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf type
Definition: writing_filters.txt:86
AVRational::num
int num
Numerator.
Definition: rational.h:59
v4l2_save_to_context
static void v4l2_save_to_context(V4L2Context *ctx, struct v4l2_format_update *fmt)
Definition: v4l2_context.c:125
v4l2_release_buffers
static int v4l2_release_buffers(V4L2Context *ctx)
Definition: v4l2_context.c:439
pkt
AVPacket * pkt
Definition: movenc.c:59
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
ff_v4l2_buffer_avframe_to_buf
int ff_v4l2_buffer_avframe_to_buf(const AVFrame *frame, V4L2Buffer *out)
Extracts the data from an AVFrame to a V4L2Buffer.
Definition: v4l2_buffers.c:411
ff_v4l2_context_set_format
int ff_v4l2_context_set_format(V4L2Context *ctx)
Sets the V4L2Context format in the v4l2 driver.
Definition: v4l2_context.c:689
V4L2Buffer
V4L2Buffer (wrapper for v4l2_buffer management)
Definition: v4l2_buffers.h:44
ff_v4l2_context_get_format
int ff_v4l2_context_get_format(V4L2Context *ctx, int probe)
Queries the driver for a valid v4l2 format and copies it to the context.
Definition: v4l2_context.c:662
v4l2_getfree_v4l2buf
static V4L2Buffer * v4l2_getfree_v4l2buf(V4L2Context *ctx)
Definition: v4l2_context.c:420
v4l2_fmt.h
width
#define width
s
#define s(width, name)
Definition: cbs_vp9.c:256
ff_v4l2_format_v4l2_to_avfmt
enum AVPixelFormat ff_v4l2_format_v4l2_to_avfmt(uint32_t v4l2_fmt, enum AVCodecID avcodec)
Definition: v4l2_fmt.c:132
logger
static AVCodecContext * logger(V4L2Context *ctx)
Definition: v4l2_context.c:51
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:201
ctx
AVFormatContext * ctx
Definition: movenc.c:48
decode.h
ff_v4l2_buffer_enqueue
int ff_v4l2_buffer_enqueue(V4L2Buffer *avbuf)
Enqueues a V4L2Buffer.
Definition: v4l2_buffers.c:560
v4l2_stop_decode
static int v4l2_stop_decode(V4L2Context *ctx)
Definition: v4l2_context.c:229
V4L2Context
Definition: v4l2_context.h:37
NULL
#define NULL
Definition: coverity.c:32
AVERROR_PATCHWELCOME
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
Definition: error.h:64
container_of
#define container_of(ptr, type, member)
Definition: v4l2_m2m.h:35
AVRational
Rational number (pair of numerator and denominator).
Definition: rational.h:58
ff_v4l2_context_enqueue_packet
int ff_v4l2_context_enqueue_packet(V4L2Context *ctx, const AVPacket *pkt)
Enqueues a buffer to a V4L2Context from an AVPacket.
Definition: v4l2_context.c:597
v4l2_dequeue_v4l2buf
static V4L2Buffer * v4l2_dequeue_v4l2buf(V4L2Context *ctx, int timeout)
Definition: v4l2_context.c:269
ff_v4l2_buffer_avpkt_to_buf
int ff_v4l2_buffer_avpkt_to_buf(const AVPacket *pkt, V4L2Buffer *out)
Extracts the data from an AVPacket to a V4L2Buffer.
Definition: v4l2_buffers.c:477
V4L2BUF_AVAILABLE
@ V4L2BUF_AVAILABLE
Definition: v4l2_buffers.h:36
av_codec_is_decoder
int av_codec_is_decoder(const AVCodec *codec)
Definition: utils.c:83
AVPacket::size
int size
Definition: packet.h:375
v4l2_get_raw_format
static int v4l2_get_raw_format(V4L2Context *ctx, enum AVPixelFormat *p)
Definition: v4l2_context.c:486
av_err2str
#define av_err2str(errnum)
Convenience macro, the return value should be used only directly in function arguments but never stan...
Definition: error.h:121
V4L2BUF_IN_DRIVER
@ V4L2BUF_IN_DRIVER
Definition: v4l2_buffers.h:37
size
int size
Definition: twinvq_data.h:10344
v4l2_get_sar
static AVRational v4l2_get_sar(V4L2Context *ctx)
Definition: v4l2_context.c:66
height
#define height
ff_v4l2_context_dequeue_frame
int ff_v4l2_context_dequeue_frame(V4L2Context *ctx, AVFrame *frame, int timeout)
Dequeues a buffer from a V4L2Context to an AVFrame.
Definition: v4l2_context.c:622
ff_v4l2_context_set_status
int ff_v4l2_context_set_status(V4L2Context *ctx, uint32_t cmd)
Sets the status of a V4L2Context.
Definition: v4l2_context.c:558
ff_v4l2_format_avcodec_to_v4l2
uint32_t ff_v4l2_format_avcodec_to_v4l2(enum AVCodecID avcodec)
Definition: v4l2_fmt.c:112
V4L2m2mContext::avctx
AVCodecContext * avctx
Definition: v4l2_m2m.h:52
v4l2_try_raw_format
static int v4l2_try_raw_format(V4L2Context *ctx, enum AVPixelFormat pixfmt)
Definition: v4l2_context.c:462
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:269
V4L2Buffer::planes
struct v4l2_plane planes[VIDEO_MAX_PLANES]
Definition: v4l2_buffers.h:64
v4l2_format_update::update_avfmt
int update_avfmt
Definition: v4l2_context.c:41
av_mallocz
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:254
v4l2_get_coded_format
static int v4l2_get_coded_format(V4L2Context *ctx, uint32_t *p)
Definition: v4l2_context.c:521
ff_v4l2_context_enqueue_frame
int ff_v4l2_context_enqueue_frame(V4L2Context *ctx, const AVFrame *frame)
Enqueues a buffer to a V4L2Context from an AVFrame.
Definition: v4l2_context.c:572
avcodec.h
ret
ret
Definition: filter_design.txt:187
pixfmt
enum AVPixelFormat pixfmt
Definition: kmsgrab.c:365
frame
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several the filter must be ready for frames arriving randomly on any input any filter with several inputs will most likely require some kind of queuing mechanism It is perfectly acceptable to have a limited queue and to drop frames when the inputs are too unbalanced request_frame For filters that do not use the this method is called when a frame is wanted on an output For a it should directly call filter_frame on the corresponding output For a if there are queued frames already one of these frames should be pushed If the filter should request a frame on one of its repeatedly until at least one frame has been pushed Return or at least make progress towards producing a frame
Definition: filter_design.txt:264
v4l2_format_update::av_fmt
enum AVPixelFormat av_fmt
Definition: v4l2_context.c:40
v4l2_format_update::update_v4l2
int update_v4l2
Definition: v4l2_context.c:38
AVCodecContext
main external API structure.
Definition: avcodec.h:426
probe
static int probe(const AVProbeData *p)
Definition: act.c:38
v4l2_get_height
static unsigned int v4l2_get_height(struct v4l2_format *fmt)
Definition: v4l2_context.c:61
buffer
the frame and frame reference mechanism is intended to as much as expensive copies of that data while still allowing the filters to produce correct results The data is stored in buffers represented by AVFrame structures Several references can point to the same frame buffer
Definition: filter_design.txt:49
AVRational::den
int den
Denominator.
Definition: rational.h:60
AV_PIX_FMT_NONE
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:65
V4L2m2mContext::fd
int fd
Definition: v4l2_m2m.h:45
v4l2_format_update
Definition: v4l2_context.c:36
v4l2_resolution_changed
static unsigned int v4l2_resolution_changed(V4L2Context *ctx, struct v4l2_format *fmt2)
Definition: v4l2_context.c:84
ff_v4l2_format_avfmt_to_v4l2
uint32_t ff_v4l2_format_avfmt_to_v4l2(enum AVPixelFormat avfmt)
Definition: v4l2_fmt.c:122
FFALIGN
#define FFALIGN(x, a)
Definition: macros.h:78
AVPacket
This structure stores compressed data.
Definition: packet.h:351
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
v4l2_m2m.h
ff_v4l2_buffer_initialize
int ff_v4l2_buffer_initialize(V4L2Buffer *avbuf, int index)
Initializes a V4L2Buffer.
Definition: v4l2_buffers.c:493
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
av_fourcc2str
#define av_fourcc2str(fourcc)
Definition: avutil.h:354
v4l2_type_supported
static int v4l2_type_supported(V4L2Context *ctx)
Definition: v4l2_context.c:103
V4L2Buffer::status
enum V4L2Buffer_status status
Definition: v4l2_buffers.h:67