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 "libavutil/mem.h"
31 #include "libavcodec/avcodec.h"
32 #include "decode.h"
33 #include "v4l2_buffers.h"
34 #include "v4l2_fmt.h"
35 #include "v4l2_m2m.h"
36 
38  uint32_t v4l2_fmt;
40 
43 };
44 
46 {
47  return V4L2_TYPE_IS_OUTPUT(ctx->type) ?
49  container_of(ctx, V4L2m2mContext, capture);
50 }
51 
53 {
54  return ctx_to_m2mctx(ctx)->avctx;
55 }
56 
57 static inline unsigned int v4l2_get_width(struct v4l2_format *fmt)
58 {
59  return V4L2_TYPE_IS_MULTIPLANAR(fmt->type) ? fmt->fmt.pix_mp.width : fmt->fmt.pix.width;
60 }
61 
62 static inline unsigned int v4l2_get_height(struct v4l2_format *fmt)
63 {
64  return V4L2_TYPE_IS_MULTIPLANAR(fmt->type) ? fmt->fmt.pix_mp.height : fmt->fmt.pix.height;
65 }
66 
68 {
69  struct AVRational sar = { 0, 1 };
70  struct v4l2_cropcap cropcap;
71  int ret;
72 
73  memset(&cropcap, 0, sizeof(cropcap));
74  cropcap.type = ctx->type;
75 
76  ret = ioctl(ctx_to_m2mctx(ctx)->fd, VIDIOC_CROPCAP, &cropcap);
77  if (ret)
78  return sar;
79 
80  sar.num = cropcap.pixelaspect.numerator;
81  sar.den = cropcap.pixelaspect.denominator;
82  return sar;
83 }
84 
85 static inline unsigned int v4l2_resolution_changed(V4L2Context *ctx, struct v4l2_format *fmt2)
86 {
87  struct v4l2_format *fmt1 = &ctx->format;
88  int ret = V4L2_TYPE_IS_MULTIPLANAR(ctx->type) ?
89  fmt1->fmt.pix_mp.width != fmt2->fmt.pix_mp.width ||
90  fmt1->fmt.pix_mp.height != fmt2->fmt.pix_mp.height
91  :
92  fmt1->fmt.pix.width != fmt2->fmt.pix.width ||
93  fmt1->fmt.pix.height != fmt2->fmt.pix.height;
94 
95  if (ret)
96  av_log(logger(ctx), AV_LOG_DEBUG, "%s changed (%dx%d) -> (%dx%d)\n",
97  ctx->name,
98  v4l2_get_width(fmt1), v4l2_get_height(fmt1),
99  v4l2_get_width(fmt2), v4l2_get_height(fmt2));
100 
101  return ret;
102 }
103 
105 {
106  return ctx->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
107  ctx->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ||
108  ctx->type == V4L2_BUF_TYPE_VIDEO_CAPTURE ||
109  ctx->type == V4L2_BUF_TYPE_VIDEO_OUTPUT;
110 }
111 
113 {
115  const int SZ_4K = 0x1000;
116  int size;
117 
118  if (s->avctx && av_codec_is_decoder(s->avctx->codec))
119  return ((width * height * 3 / 2) / 2) + 128;
120 
121  /* encoder */
122  size = FFALIGN(height, 32) * FFALIGN(width, 32) * 3 / 2 / 2;
123  return FFALIGN(size, SZ_4K);
124 }
125 
126 static inline void v4l2_save_to_context(V4L2Context* ctx, struct v4l2_format_update *fmt)
127 {
128  ctx->format.type = ctx->type;
129 
130  if (fmt->update_avfmt)
131  ctx->av_pix_fmt = fmt->av_fmt;
132 
133  if (V4L2_TYPE_IS_MULTIPLANAR(ctx->type)) {
134  /* update the sizes to handle the reconfiguration of the capture stream at runtime */
135  ctx->format.fmt.pix_mp.height = ctx->height;
136  ctx->format.fmt.pix_mp.width = ctx->width;
137  if (fmt->update_v4l2) {
138  ctx->format.fmt.pix_mp.pixelformat = fmt->v4l2_fmt;
139 
140  /* s5p-mfc requires the user to specify a buffer size */
141  ctx->format.fmt.pix_mp.plane_fmt[0].sizeimage =
142  v4l2_get_framesize_compressed(ctx, ctx->width, ctx->height);
143  }
144  } else {
145  ctx->format.fmt.pix.height = ctx->height;
146  ctx->format.fmt.pix.width = ctx->width;
147  if (fmt->update_v4l2) {
148  ctx->format.fmt.pix.pixelformat = fmt->v4l2_fmt;
149 
150  /* s5p-mfc requires the user to specify a buffer size */
151  ctx->format.fmt.pix.sizeimage =
152  v4l2_get_framesize_compressed(ctx, ctx->width, ctx->height);
153  }
154  }
155 }
156 
158 {
159  struct v4l2_decoder_cmd cmd = {
160  .cmd = V4L2_DEC_CMD_START,
161  .flags = 0,
162  };
163  int ret;
164 
165  ret = ioctl(ctx_to_m2mctx(ctx)->fd, VIDIOC_DECODER_CMD, &cmd);
166  if (ret)
167  return AVERROR(errno);
168 
169  return 0;
170 }
171 
172 /**
173  * handle resolution change event and end of stream event
174  * returns 1 if reinit was successful, negative if it failed
175  * returns 0 if reinit was not executed
176  */
178 {
180  struct v4l2_format cap_fmt = s->capture.format;
181  struct v4l2_event evt = { 0 };
182  int ret;
183 
184  ret = ioctl(s->fd, VIDIOC_DQEVENT, &evt);
185  if (ret < 0) {
186  av_log(logger(ctx), AV_LOG_ERROR, "%s VIDIOC_DQEVENT\n", ctx->name);
187  return 0;
188  }
189 
190  if (evt.type == V4L2_EVENT_EOS) {
191  ctx->done = 1;
192  return 0;
193  }
194 
195  if (evt.type != V4L2_EVENT_SOURCE_CHANGE)
196  return 0;
197 
198  ret = ioctl(s->fd, VIDIOC_G_FMT, &cap_fmt);
199  if (ret) {
200  av_log(logger(ctx), AV_LOG_ERROR, "%s VIDIOC_G_FMT\n", s->capture.name);
201  return 0;
202  }
203 
204  if (v4l2_resolution_changed(&s->capture, &cap_fmt)) {
205  s->capture.height = v4l2_get_height(&cap_fmt);
206  s->capture.width = v4l2_get_width(&cap_fmt);
207  s->capture.sample_aspect_ratio = v4l2_get_sar(&s->capture);
208  } else {
210  return 0;
211  }
212 
213  s->reinit = 1;
214 
215  if (s->avctx)
216  ret = ff_set_dimensions(s->avctx, s->capture.width, s->capture.height);
217  if (ret < 0)
218  av_log(logger(ctx), AV_LOG_WARNING, "update avcodec height and width\n");
219 
221  if (ret) {
222  av_log(logger(ctx), AV_LOG_ERROR, "v4l2_m2m_codec_reinit\n");
223  return AVERROR(EINVAL);
224  }
225 
226  /* reinit executed */
227  return 1;
228 }
229 
231 {
232  struct v4l2_decoder_cmd cmd = {
233  .cmd = V4L2_DEC_CMD_STOP,
234  .flags = 0,
235  };
236  int ret;
237 
238  ret = ioctl(ctx_to_m2mctx(ctx)->fd, VIDIOC_DECODER_CMD, &cmd);
239  if (ret) {
240  /* DECODER_CMD is optional */
241  if (errno == ENOTTY)
242  return ff_v4l2_context_set_status(ctx, VIDIOC_STREAMOFF);
243  else
244  return AVERROR(errno);
245  }
246 
247  return 0;
248 }
249 
251 {
252  struct v4l2_encoder_cmd cmd = {
253  .cmd = V4L2_ENC_CMD_STOP,
254  .flags = 0,
255  };
256  int ret;
257 
258  ret = ioctl(ctx_to_m2mctx(ctx)->fd, VIDIOC_ENCODER_CMD, &cmd);
259  if (ret) {
260  /* ENCODER_CMD is optional */
261  if (errno == ENOTTY)
262  return ff_v4l2_context_set_status(ctx, VIDIOC_STREAMOFF);
263  else
264  return AVERROR(errno);
265  }
266 
267  return 0;
268 }
269 
271 {
272  struct v4l2_plane planes[VIDEO_MAX_PLANES];
273  struct v4l2_buffer buf = { 0 };
274  V4L2Buffer *avbuf;
275  struct pollfd pfd = {
276  .events = POLLIN | POLLRDNORM | POLLPRI | POLLOUT | POLLWRNORM, /* default blocking capture */
277  .fd = ctx_to_m2mctx(ctx)->fd,
278  };
279  int i, ret;
280 
281  if (!V4L2_TYPE_IS_OUTPUT(ctx->type) && ctx->buffers) {
282  for (i = 0; i < ctx->num_buffers; i++) {
283  if (ctx->buffers[i].status == V4L2BUF_IN_DRIVER)
284  break;
285  }
286  if (i == ctx->num_buffers)
287  av_log(logger(ctx), AV_LOG_WARNING, "All capture buffers returned to "
288  "userspace. Increase num_capture_buffers "
289  "to prevent device deadlock or dropped "
290  "packets/frames.\n");
291  }
292 
293  /* if we are draining and there are no more capture buffers queued in the driver we are done */
294  if (!V4L2_TYPE_IS_OUTPUT(ctx->type) && ctx_to_m2mctx(ctx)->draining) {
295  for (i = 0; i < ctx->num_buffers; i++) {
296  /* capture buffer initialization happens during decode hence
297  * detection happens at runtime
298  */
299  if (!ctx->buffers)
300  break;
301 
302  if (ctx->buffers[i].status == V4L2BUF_IN_DRIVER)
303  goto start;
304  }
305  ctx->done = 1;
306  return NULL;
307  }
308 
309 start:
310  if (V4L2_TYPE_IS_OUTPUT(ctx->type))
311  pfd.events = POLLOUT | POLLWRNORM;
312  else {
313  /* no need to listen to requests for more input while draining */
314  if (ctx_to_m2mctx(ctx)->draining)
315  pfd.events = POLLIN | POLLRDNORM | POLLPRI;
316  }
317 
318  for (;;) {
319  ret = poll(&pfd, 1, timeout);
320  if (ret > 0)
321  break;
322  if (errno == EINTR)
323  continue;
324  return NULL;
325  }
326 
327  /* 0. handle errors */
328  if (pfd.revents & POLLERR) {
329  /* if we are trying to get free buffers but none have been queued yet,
330  * or if no buffers have been allocated yet, no need to raise a warning
331  */
332  if (timeout == 0) {
333  if (!ctx->buffers)
334  return NULL;
335 
336  for (i = 0; i < ctx->num_buffers; i++) {
337  if (ctx->buffers[i].status != V4L2BUF_AVAILABLE)
338  av_log(logger(ctx), AV_LOG_WARNING, "%s POLLERR\n", ctx->name);
339  }
340  }
341  else
342  av_log(logger(ctx), AV_LOG_WARNING, "%s POLLERR\n", ctx->name);
343 
344  return NULL;
345  }
346 
347  /* 1. handle resolution changes */
348  if (pfd.revents & POLLPRI) {
350  if (ret < 0) {
351  /* if re-init failed, abort */
352  ctx->done = 1;
353  return NULL;
354  }
355  if (ret) {
356  /* if re-init was successful drop the buffer (if there was one)
357  * since we had to reconfigure capture (unmap all buffers)
358  */
359  return NULL;
360  }
361  }
362 
363  /* 2. dequeue the buffer */
364  if (pfd.revents & (POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM)) {
365 
366  if (!V4L2_TYPE_IS_OUTPUT(ctx->type)) {
367  /* there is a capture buffer ready */
368  if (pfd.revents & (POLLIN | POLLRDNORM))
369  goto dequeue;
370 
371  /* the driver is ready to accept more input; instead of waiting for the capture
372  * buffer to complete we return NULL so input can proceed (we are single threaded)
373  */
374  if (pfd.revents & (POLLOUT | POLLWRNORM))
375  return NULL;
376  }
377 
378 dequeue:
379  memset(&buf, 0, sizeof(buf));
380  buf.memory = V4L2_MEMORY_MMAP;
381  buf.type = ctx->type;
382  if (V4L2_TYPE_IS_MULTIPLANAR(ctx->type)) {
383  memset(planes, 0, sizeof(planes));
384  buf.length = VIDEO_MAX_PLANES;
385  buf.m.planes = planes;
386  }
387 
388  ret = ioctl(ctx_to_m2mctx(ctx)->fd, VIDIOC_DQBUF, &buf);
389  if (ret) {
390  if (errno != EAGAIN) {
391  ctx->done = 1;
392  if (errno != EPIPE)
393  av_log(logger(ctx), AV_LOG_DEBUG, "%s VIDIOC_DQBUF, errno (%s)\n",
394  ctx->name, av_err2str(AVERROR(errno)));
395  }
396  return NULL;
397  }
398 
399  if (ctx_to_m2mctx(ctx)->draining && !V4L2_TYPE_IS_OUTPUT(ctx->type)) {
400  int bytesused = V4L2_TYPE_IS_MULTIPLANAR(buf.type) ?
401  buf.m.planes[0].bytesused : buf.bytesused;
402  if (bytesused == 0) {
403  ctx->done = 1;
404  return NULL;
405  }
406 #ifdef V4L2_BUF_FLAG_LAST
407  if (buf.flags & V4L2_BUF_FLAG_LAST)
408  ctx->done = 1;
409 #endif
410  }
411 
412  avbuf = &ctx->buffers[buf.index];
413  avbuf->status = V4L2BUF_AVAILABLE;
414  avbuf->buf = buf;
415  if (V4L2_TYPE_IS_MULTIPLANAR(ctx->type)) {
416  memcpy(avbuf->planes, planes, sizeof(planes));
417  avbuf->buf.m.planes = avbuf->planes;
418  }
419  return avbuf;
420  }
421 
422  return NULL;
423 }
424 
426 {
427  int timeout = 0; /* return when no more buffers to dequeue */
428  int i;
429 
430  /* get back as many output buffers as possible */
431  if (V4L2_TYPE_IS_OUTPUT(ctx->type)) {
432  do {
433  } while (v4l2_dequeue_v4l2buf(ctx, timeout));
434  }
435 
436  for (i = 0; i < ctx->num_buffers; i++) {
437  if (ctx->buffers[i].status == V4L2BUF_AVAILABLE)
438  return &ctx->buffers[i];
439  }
440 
441  return NULL;
442 }
443 
445 {
446  struct v4l2_requestbuffers req = {
447  .memory = V4L2_MEMORY_MMAP,
448  .type = ctx->type,
449  .count = 0, /* 0 -> unmaps buffers from the driver */
450  };
451  int i, j;
452 
453  for (i = 0; i < ctx->num_buffers; i++) {
454  V4L2Buffer *buffer = &ctx->buffers[i];
455 
456  for (j = 0; j < buffer->num_planes; j++) {
457  struct V4L2Plane_info *p = &buffer->plane_info[j];
458  if (p->mm_addr && p->length)
459  if (munmap(p->mm_addr, p->length) < 0)
460  av_log(logger(ctx), AV_LOG_ERROR, "%s unmap plane (%s))\n", ctx->name, av_err2str(AVERROR(errno)));
461  }
462  }
463 
464  return ioctl(ctx_to_m2mctx(ctx)->fd, VIDIOC_REQBUFS, &req);
465 }
466 
468 {
469  struct v4l2_format *fmt = &ctx->format;
470  uint32_t v4l2_fmt;
471  int ret;
472 
474  if (!v4l2_fmt)
475  return AVERROR(EINVAL);
476 
477  if (V4L2_TYPE_IS_MULTIPLANAR(ctx->type))
478  fmt->fmt.pix_mp.pixelformat = v4l2_fmt;
479  else
480  fmt->fmt.pix.pixelformat = v4l2_fmt;
481 
482  fmt->type = ctx->type;
483 
484  ret = ioctl(ctx_to_m2mctx(ctx)->fd, VIDIOC_TRY_FMT, fmt);
485  if (ret)
486  return AVERROR(EINVAL);
487 
488  return 0;
489 }
490 
492 {
493  enum AVPixelFormat pixfmt = ctx->av_pix_fmt;
494  struct v4l2_fmtdesc fdesc;
495  int ret;
496 
497  memset(&fdesc, 0, sizeof(fdesc));
498  fdesc.type = ctx->type;
499 
500  if (pixfmt != AV_PIX_FMT_NONE) {
502  if (!ret)
503  return 0;
504  }
505 
506  for (;;) {
507  ret = ioctl(ctx_to_m2mctx(ctx)->fd, VIDIOC_ENUM_FMT, &fdesc);
508  if (ret)
509  return AVERROR(EINVAL);
510 
513  if (ret){
514  fdesc.index++;
515  continue;
516  }
517 
518  *p = pixfmt;
519 
520  return 0;
521  }
522 
523  return AVERROR(EINVAL);
524 }
525 
526 static int v4l2_get_coded_format(V4L2Context* ctx, uint32_t *p)
527 {
528  struct v4l2_fmtdesc fdesc;
529  uint32_t v4l2_fmt;
530  int ret;
531 
532  /* translate to a valid v4l2 format */
533  v4l2_fmt = ff_v4l2_format_avcodec_to_v4l2(ctx->av_codec_id);
534  if (!v4l2_fmt)
535  return AVERROR(EINVAL);
536 
537  /* check if the driver supports this format */
538  memset(&fdesc, 0, sizeof(fdesc));
539  fdesc.type = ctx->type;
540 
541  for (;;) {
542  ret = ioctl(ctx_to_m2mctx(ctx)->fd, VIDIOC_ENUM_FMT, &fdesc);
543  if (ret)
544  return AVERROR(EINVAL);
545 
546  if (fdesc.pixelformat == v4l2_fmt)
547  break;
548 
549  fdesc.index++;
550  }
551 
552  *p = v4l2_fmt;
553 
554  return 0;
555 }
556 
557  /*****************************************************************************
558  *
559  * V4L2 Context Interface
560  *
561  *****************************************************************************/
562 
564 {
565  int type = ctx->type;
566  int ret;
567 
568  ret = ioctl(ctx_to_m2mctx(ctx)->fd, cmd, &type);
569  if (ret < 0)
570  return AVERROR(errno);
571 
572  ctx->streamon = (cmd == VIDIOC_STREAMON);
573 
574  return 0;
575 }
576 
578 {
580  V4L2Buffer* avbuf;
581  int ret;
582 
583  if (!frame) {
585  if (ret)
586  av_log(logger(ctx), AV_LOG_ERROR, "%s stop_encode\n", ctx->name);
587  s->draining= 1;
588  return 0;
589  }
590 
591  avbuf = v4l2_getfree_v4l2buf(ctx);
592  if (!avbuf)
593  return AVERROR(EAGAIN);
594 
596  if (ret)
597  return ret;
598 
599  return ff_v4l2_buffer_enqueue(avbuf);
600 }
601 
603 {
605  V4L2Buffer* avbuf;
606  int ret;
607 
608  if (!pkt->size) {
610  if (ret)
611  av_log(logger(ctx), AV_LOG_ERROR, "%s stop_decode\n", ctx->name);
612  s->draining = 1;
613  return 0;
614  }
615 
616  avbuf = v4l2_getfree_v4l2buf(ctx);
617  if (!avbuf)
618  return AVERROR(EAGAIN);
619 
621  if (ret)
622  return ret;
623 
624  return ff_v4l2_buffer_enqueue(avbuf);
625 }
626 
628 {
629  V4L2Buffer *avbuf;
630 
631  /*
632  * timeout=-1 blocks until:
633  * 1. decoded frame available
634  * 2. an input buffer is ready to be dequeued
635  */
636  avbuf = v4l2_dequeue_v4l2buf(ctx, timeout);
637  if (!avbuf) {
638  if (ctx->done)
639  return AVERROR_EOF;
640 
641  return AVERROR(EAGAIN);
642  }
643 
644  return ff_v4l2_buffer_buf_to_avframe(frame, avbuf);
645 }
646 
648 {
649  V4L2Buffer *avbuf;
650 
651  /*
652  * blocks until:
653  * 1. encoded packet available
654  * 2. an input buffer ready to be dequeued
655  */
656  avbuf = v4l2_dequeue_v4l2buf(ctx, -1);
657  if (!avbuf) {
658  if (ctx->done)
659  return AVERROR_EOF;
660 
661  return AVERROR(EAGAIN);
662  }
663 
664  return ff_v4l2_buffer_buf_to_avpkt(pkt, avbuf);
665 }
666 
668 {
669  struct v4l2_format_update fmt = { 0 };
670  int ret;
671 
672  if (ctx->av_codec_id == AV_CODEC_ID_RAWVIDEO) {
674  if (ret)
675  return ret;
676 
677  fmt.update_avfmt = !probe;
678  v4l2_save_to_context(ctx, &fmt);
679 
680  /* format has been tried already */
681  return ret;
682  }
683 
685  if (ret)
686  return ret;
687 
688  fmt.update_v4l2 = 1;
689  v4l2_save_to_context(ctx, &fmt);
690 
691  return ioctl(ctx_to_m2mctx(ctx)->fd, VIDIOC_TRY_FMT, &ctx->format);
692 }
693 
695 {
696  return ioctl(ctx_to_m2mctx(ctx)->fd, VIDIOC_S_FMT, &ctx->format);
697 }
698 
700 {
701  int ret;
702 
703  if (!ctx->buffers)
704  return;
705 
707  if (ret)
708  av_log(logger(ctx), AV_LOG_WARNING, "V4L2 failed to unmap the %s buffers\n", ctx->name);
709 
710  av_freep(&ctx->buffers);
711 }
712 
714 {
716  struct v4l2_requestbuffers req;
717  int ret, i;
718 
719  if (!v4l2_type_supported(ctx)) {
720  av_log(logger(ctx), AV_LOG_ERROR, "type %i not supported\n", ctx->type);
721  return AVERROR_PATCHWELCOME;
722  }
723 
724  ret = ioctl(s->fd, VIDIOC_G_FMT, &ctx->format);
725  if (ret)
726  av_log(logger(ctx), AV_LOG_ERROR, "%s VIDIOC_G_FMT failed\n", ctx->name);
727 
728  memset(&req, 0, sizeof(req));
729  req.count = ctx->num_buffers;
730  req.memory = V4L2_MEMORY_MMAP;
731  req.type = ctx->type;
732  ret = ioctl(s->fd, VIDIOC_REQBUFS, &req);
733  if (ret < 0) {
734  av_log(logger(ctx), AV_LOG_ERROR, "%s VIDIOC_REQBUFS failed: %s\n", ctx->name, strerror(errno));
735  return AVERROR(errno);
736  }
737 
738  ctx->num_buffers = req.count;
739  ctx->buffers = av_mallocz(ctx->num_buffers * sizeof(V4L2Buffer));
740  if (!ctx->buffers) {
741  av_log(logger(ctx), AV_LOG_ERROR, "%s malloc enomem\n", ctx->name);
742  return AVERROR(ENOMEM);
743  }
744 
745  for (i = 0; i < req.count; i++) {
746  ctx->buffers[i].context = ctx;
747  ret = ff_v4l2_buffer_initialize(&ctx->buffers[i], i);
748  if (ret < 0) {
749  av_log(logger(ctx), AV_LOG_ERROR, "%s buffer[%d] initialization (%s)\n", ctx->name, i, av_err2str(ret));
750  goto error;
751  }
752  }
753 
754  av_log(logger(ctx), AV_LOG_DEBUG, "%s: %s %02d buffers initialized: %04ux%04u, sizeimage %08u, bytesperline %08u\n", ctx->name,
755  V4L2_TYPE_IS_MULTIPLANAR(ctx->type) ? av_fourcc2str(ctx->format.fmt.pix_mp.pixelformat) : av_fourcc2str(ctx->format.fmt.pix.pixelformat),
756  req.count,
757  v4l2_get_width(&ctx->format),
758  v4l2_get_height(&ctx->format),
759  V4L2_TYPE_IS_MULTIPLANAR(ctx->type) ? ctx->format.fmt.pix_mp.plane_fmt[0].sizeimage : ctx->format.fmt.pix.sizeimage,
760  V4L2_TYPE_IS_MULTIPLANAR(ctx->type) ? ctx->format.fmt.pix_mp.plane_fmt[0].bytesperline : ctx->format.fmt.pix.bytesperline);
761 
762  return 0;
763 
764 error:
766 
767  av_freep(&ctx->buffers);
768 
769  return ret;
770 }
error
static void error(const char *err)
Definition: target_bsf_fuzzer.c:32
ff_v4l2_context_init
int ff_v4l2_context_init(V4L2Context *ctx)
Initializes a V4L2Context.
Definition: v4l2_context.c:713
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:186
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:71
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:57
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:208
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:374
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:647
ff_v4l2_context_release
void ff_v4l2_context_release(V4L2Context *ctx)
Releases a V4L2Context.
Definition: v4l2_context.c:699
v4l2_stop_encode
static int v4l2_stop_encode(V4L2Context *ctx)
Definition: v4l2_context.c:250
v4l2_format_update::v4l2_fmt
uint32_t v4l2_fmt
Definition: v4l2_context.c:38
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:94
ctx_to_m2mctx
static V4L2m2mContext * ctx_to_m2mctx(V4L2Context *ctx)
Definition: v4l2_context.c:45
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:177
v4l2_start_decode
static int v4l2_start_decode(V4L2Context *ctx)
Definition: v4l2_context.c:157
v4l2_get_framesize_compressed
static int v4l2_get_framesize_compressed(V4L2Context *ctx, int width, int height)
Definition: v4l2_context.c:112
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:417
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:126
v4l2_release_buffers
static int v4l2_release_buffers(V4L2Context *ctx)
Definition: v4l2_context.c:444
pkt
AVPacket * pkt
Definition: movenc.c:60
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:410
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:694
V4L2Buffer
V4L2Buffer (wrapper for v4l2_buffer management)
Definition: v4l2_buffers.h:43
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:667
v4l2_getfree_v4l2buf
static V4L2Buffer * v4l2_getfree_v4l2buf(V4L2Context *ctx)
Definition: v4l2_context.c:425
v4l2_fmt.h
width
#define width
s
#define s(width, name)
Definition: cbs_vp9.c:198
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:52
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:49
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:230
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:602
v4l2_dequeue_v4l2buf
static V4L2Buffer * v4l2_dequeue_v4l2buf(V4L2Context *ctx, int timeout)
Definition: v4l2_context.c:270
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:35
av_codec_is_decoder
int av_codec_is_decoder(const AVCodec *codec)
Definition: utils.c:86
AVPacket::size
int size
Definition: packet.h:525
v4l2_get_raw_format
static int v4l2_get_raw_format(V4L2Context *ctx, enum AVPixelFormat *p)
Definition: v4l2_context.c:491
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:36
size
int size
Definition: twinvq_data.h:10344
v4l2_get_sar
static AVRational v4l2_get_sar(V4L2Context *ctx)
Definition: v4l2_context.c:67
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:627
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:563
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:467
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
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:42
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:256
v4l2_get_coded_format
static int v4l2_get_coded_format(V4L2Context *ctx, uint32_t *p)
Definition: v4l2_context.c:526
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:577
avcodec.h
ret
ret
Definition: filter_design.txt:187
pixfmt
enum AVPixelFormat pixfmt
Definition: kmsgrab.c:367
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:41
v4l2_format_update::update_v4l2
int update_v4l2
Definition: v4l2_context.c:39
AVCodecContext
main external API structure.
Definition: avcodec.h:445
probe
static int probe(const AVProbeData *p)
Definition: act.c:39
v4l2_get_height
static unsigned int v4l2_get_height(struct v4l2_format *fmt)
Definition: v4l2_context.c:62
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:72
V4L2m2mContext::fd
int fd
Definition: v4l2_m2m.h:45
v4l2_format_update
Definition: v4l2_context.c:37
planes
static const struct @400 planes[]
v4l2_resolution_changed
static unsigned int v4l2_resolution_changed(V4L2Context *ctx, struct v4l2_format *fmt2)
Definition: v4l2_context.c:85
mem.h
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:501
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:345
v4l2_type_supported
static int v4l2_type_supported(V4L2Context *ctx)
Definition: v4l2_context.c:104
V4L2Buffer::status
enum V4L2Buffer_status status
Definition: v4l2_buffers.h:67