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 "libavcodec/internal.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 reinit, 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  reinit = v4l2_resolution_changed(&s->capture, &cap_fmt);
204  if (reinit) {
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  if (reinit)
214  s->reinit = 1;
215 
216  if (reinit) {
217  if (s->avctx)
218  ret = ff_set_dimensions(s->avctx, s->capture.width, s->capture.height);
219  if (ret < 0)
220  av_log(logger(ctx), AV_LOG_WARNING, "update avcodec height and width\n");
221 
223  if (ret) {
224  av_log(logger(ctx), AV_LOG_ERROR, "v4l2_m2m_codec_reinit\n");
225  return AVERROR(EINVAL);
226  }
227  goto reinit_run;
228  }
229 
230  /* dummy event received */
231  return 0;
232 
233  /* reinit executed */
234 reinit_run:
235  return 1;
236 }
237 
239 {
240  struct v4l2_decoder_cmd cmd = {
241  .cmd = V4L2_DEC_CMD_STOP,
242  .flags = 0,
243  };
244  int ret;
245 
246  ret = ioctl(ctx_to_m2mctx(ctx)->fd, VIDIOC_DECODER_CMD, &cmd);
247  if (ret) {
248  /* DECODER_CMD is optional */
249  if (errno == ENOTTY)
250  return ff_v4l2_context_set_status(ctx, VIDIOC_STREAMOFF);
251  else
252  return AVERROR(errno);
253  }
254 
255  return 0;
256 }
257 
259 {
260  struct v4l2_encoder_cmd cmd = {
261  .cmd = V4L2_ENC_CMD_STOP,
262  .flags = 0,
263  };
264  int ret;
265 
266  ret = ioctl(ctx_to_m2mctx(ctx)->fd, VIDIOC_ENCODER_CMD, &cmd);
267  if (ret) {
268  /* ENCODER_CMD is optional */
269  if (errno == ENOTTY)
270  return ff_v4l2_context_set_status(ctx, VIDIOC_STREAMOFF);
271  else
272  return AVERROR(errno);
273  }
274 
275  return 0;
276 }
277 
279 {
280  struct v4l2_plane planes[VIDEO_MAX_PLANES];
281  struct v4l2_buffer buf = { 0 };
282  V4L2Buffer *avbuf;
283  struct pollfd pfd = {
284  .events = POLLIN | POLLRDNORM | POLLPRI | POLLOUT | POLLWRNORM, /* default blocking capture */
285  .fd = ctx_to_m2mctx(ctx)->fd,
286  };
287  int i, ret;
288 
289  if (!V4L2_TYPE_IS_OUTPUT(ctx->type) && ctx->buffers) {
290  for (i = 0; i < ctx->num_buffers; i++) {
291  if (ctx->buffers[i].status == V4L2BUF_IN_DRIVER)
292  break;
293  }
294  if (i == ctx->num_buffers)
295  av_log(logger(ctx), AV_LOG_WARNING, "All capture buffers returned to "
296  "userspace. Increase num_capture_buffers "
297  "to prevent device deadlock or dropped "
298  "packets/frames.\n");
299  }
300 
301  /* if we are draining and there are no more capture buffers queued in the driver we are done */
302  if (!V4L2_TYPE_IS_OUTPUT(ctx->type) && ctx_to_m2mctx(ctx)->draining) {
303  for (i = 0; i < ctx->num_buffers; i++) {
304  /* capture buffer initialization happens during decode hence
305  * detection happens at runtime
306  */
307  if (!ctx->buffers)
308  break;
309 
310  if (ctx->buffers[i].status == V4L2BUF_IN_DRIVER)
311  goto start;
312  }
313  ctx->done = 1;
314  return NULL;
315  }
316 
317 start:
318  if (V4L2_TYPE_IS_OUTPUT(ctx->type))
319  pfd.events = POLLOUT | POLLWRNORM;
320  else {
321  /* no need to listen to requests for more input while draining */
322  if (ctx_to_m2mctx(ctx)->draining)
323  pfd.events = POLLIN | POLLRDNORM | POLLPRI;
324  }
325 
326  for (;;) {
327  ret = poll(&pfd, 1, timeout);
328  if (ret > 0)
329  break;
330  if (errno == EINTR)
331  continue;
332  return NULL;
333  }
334 
335  /* 0. handle errors */
336  if (pfd.revents & POLLERR) {
337  /* if we are trying to get free buffers but none have been queued yet
338  no need to raise a warning */
339  if (timeout == 0) {
340  for (i = 0; i < ctx->num_buffers; i++) {
341  if (ctx->buffers[i].status != V4L2BUF_AVAILABLE)
342  av_log(logger(ctx), AV_LOG_WARNING, "%s POLLERR\n", ctx->name);
343  }
344  }
345  else
346  av_log(logger(ctx), AV_LOG_WARNING, "%s POLLERR\n", ctx->name);
347 
348  return NULL;
349  }
350 
351  /* 1. handle resolution changes */
352  if (pfd.revents & POLLPRI) {
354  if (ret < 0) {
355  /* if re-init failed, abort */
356  ctx->done = 1;
357  return NULL;
358  }
359  if (ret) {
360  /* if re-init was successful drop the buffer (if there was one)
361  * since we had to reconfigure capture (unmap all buffers)
362  */
363  return NULL;
364  }
365  }
366 
367  /* 2. dequeue the buffer */
368  if (pfd.revents & (POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM)) {
369 
370  if (!V4L2_TYPE_IS_OUTPUT(ctx->type)) {
371  /* there is a capture buffer ready */
372  if (pfd.revents & (POLLIN | POLLRDNORM))
373  goto dequeue;
374 
375  /* the driver is ready to accept more input; instead of waiting for the capture
376  * buffer to complete we return NULL so input can proceed (we are single threaded)
377  */
378  if (pfd.revents & (POLLOUT | POLLWRNORM))
379  return NULL;
380  }
381 
382 dequeue:
383  memset(&buf, 0, sizeof(buf));
384  buf.memory = V4L2_MEMORY_MMAP;
385  buf.type = ctx->type;
386  if (V4L2_TYPE_IS_MULTIPLANAR(ctx->type)) {
387  memset(planes, 0, sizeof(planes));
388  buf.length = VIDEO_MAX_PLANES;
389  buf.m.planes = planes;
390  }
391 
392  ret = ioctl(ctx_to_m2mctx(ctx)->fd, VIDIOC_DQBUF, &buf);
393  if (ret) {
394  if (errno != EAGAIN) {
395  ctx->done = 1;
396  if (errno != EPIPE)
397  av_log(logger(ctx), AV_LOG_DEBUG, "%s VIDIOC_DQBUF, errno (%s)\n",
398  ctx->name, av_err2str(AVERROR(errno)));
399  }
400  return NULL;
401  }
402 
403  if (ctx_to_m2mctx(ctx)->draining && !V4L2_TYPE_IS_OUTPUT(ctx->type)) {
404  int bytesused = V4L2_TYPE_IS_MULTIPLANAR(buf.type) ?
405  buf.m.planes[0].bytesused : buf.bytesused;
406  if (bytesused == 0) {
407  ctx->done = 1;
408  return NULL;
409  }
410 #ifdef V4L2_BUF_FLAG_LAST
411  if (buf.flags & V4L2_BUF_FLAG_LAST)
412  ctx->done = 1;
413 #endif
414  }
415 
416  avbuf = &ctx->buffers[buf.index];
417  avbuf->status = V4L2BUF_AVAILABLE;
418  avbuf->buf = buf;
419  if (V4L2_TYPE_IS_MULTIPLANAR(ctx->type)) {
420  memcpy(avbuf->planes, planes, sizeof(planes));
421  avbuf->buf.m.planes = avbuf->planes;
422  }
423  return avbuf;
424  }
425 
426  return NULL;
427 }
428 
430 {
431  int timeout = 0; /* return when no more buffers to dequeue */
432  int i;
433 
434  /* get back as many output buffers as possible */
435  if (V4L2_TYPE_IS_OUTPUT(ctx->type)) {
436  do {
437  } while (v4l2_dequeue_v4l2buf(ctx, timeout));
438  }
439 
440  for (i = 0; i < ctx->num_buffers; i++) {
441  if (ctx->buffers[i].status == V4L2BUF_AVAILABLE)
442  return &ctx->buffers[i];
443  }
444 
445  return NULL;
446 }
447 
449 {
450  struct v4l2_requestbuffers req = {
451  .memory = V4L2_MEMORY_MMAP,
452  .type = ctx->type,
453  .count = 0, /* 0 -> unmaps buffers from the driver */
454  };
455  int i, j;
456 
457  for (i = 0; i < ctx->num_buffers; i++) {
458  V4L2Buffer *buffer = &ctx->buffers[i];
459 
460  for (j = 0; j < buffer->num_planes; j++) {
461  struct V4L2Plane_info *p = &buffer->plane_info[j];
462  if (p->mm_addr && p->length)
463  if (munmap(p->mm_addr, p->length) < 0)
464  av_log(logger(ctx), AV_LOG_ERROR, "%s unmap plane (%s))\n", ctx->name, av_err2str(AVERROR(errno)));
465  }
466  }
467 
468  return ioctl(ctx_to_m2mctx(ctx)->fd, VIDIOC_REQBUFS, &req);
469 }
470 
472 {
473  struct v4l2_format *fmt = &ctx->format;
474  uint32_t v4l2_fmt;
475  int ret;
476 
478  if (!v4l2_fmt)
479  return AVERROR(EINVAL);
480 
481  if (V4L2_TYPE_IS_MULTIPLANAR(ctx->type))
482  fmt->fmt.pix_mp.pixelformat = v4l2_fmt;
483  else
484  fmt->fmt.pix.pixelformat = v4l2_fmt;
485 
486  fmt->type = ctx->type;
487 
488  ret = ioctl(ctx_to_m2mctx(ctx)->fd, VIDIOC_TRY_FMT, fmt);
489  if (ret)
490  return AVERROR(EINVAL);
491 
492  return 0;
493 }
494 
496 {
497  enum AVPixelFormat pixfmt = ctx->av_pix_fmt;
498  struct v4l2_fmtdesc fdesc;
499  int ret;
500 
501  memset(&fdesc, 0, sizeof(fdesc));
502  fdesc.type = ctx->type;
503 
504  if (pixfmt != AV_PIX_FMT_NONE) {
506  if (!ret)
507  return 0;
508  }
509 
510  for (;;) {
511  ret = ioctl(ctx_to_m2mctx(ctx)->fd, VIDIOC_ENUM_FMT, &fdesc);
512  if (ret)
513  return AVERROR(EINVAL);
514 
517  if (ret){
518  fdesc.index++;
519  continue;
520  }
521 
522  *p = pixfmt;
523 
524  return 0;
525  }
526 
527  return AVERROR(EINVAL);
528 }
529 
530 static int v4l2_get_coded_format(V4L2Context* ctx, uint32_t *p)
531 {
532  struct v4l2_fmtdesc fdesc;
533  uint32_t v4l2_fmt;
534  int ret;
535 
536  /* translate to a valid v4l2 format */
537  v4l2_fmt = ff_v4l2_format_avcodec_to_v4l2(ctx->av_codec_id);
538  if (!v4l2_fmt)
539  return AVERROR(EINVAL);
540 
541  /* check if the driver supports this format */
542  memset(&fdesc, 0, sizeof(fdesc));
543  fdesc.type = ctx->type;
544 
545  for (;;) {
546  ret = ioctl(ctx_to_m2mctx(ctx)->fd, VIDIOC_ENUM_FMT, &fdesc);
547  if (ret)
548  return AVERROR(EINVAL);
549 
550  if (fdesc.pixelformat == v4l2_fmt)
551  break;
552 
553  fdesc.index++;
554  }
555 
556  *p = v4l2_fmt;
557 
558  return 0;
559 }
560 
561  /*****************************************************************************
562  *
563  * V4L2 Context Interface
564  *
565  *****************************************************************************/
566 
568 {
569  int type = ctx->type;
570  int ret;
571 
572  ret = ioctl(ctx_to_m2mctx(ctx)->fd, cmd, &type);
573  if (ret < 0)
574  return AVERROR(errno);
575 
576  ctx->streamon = (cmd == VIDIOC_STREAMON);
577 
578  return 0;
579 }
580 
582 {
584  V4L2Buffer* avbuf;
585  int ret;
586 
587  if (!frame) {
589  if (ret)
590  av_log(logger(ctx), AV_LOG_ERROR, "%s stop_encode\n", ctx->name);
591  s->draining= 1;
592  return 0;
593  }
594 
595  avbuf = v4l2_getfree_v4l2buf(ctx);
596  if (!avbuf)
597  return AVERROR(EAGAIN);
598 
600  if (ret)
601  return ret;
602 
603  return ff_v4l2_buffer_enqueue(avbuf);
604 }
605 
607 {
609  V4L2Buffer* avbuf;
610  int ret;
611 
612  if (!pkt->size) {
614  if (ret)
615  av_log(logger(ctx), AV_LOG_ERROR, "%s stop_decode\n", ctx->name);
616  s->draining = 1;
617  return 0;
618  }
619 
620  avbuf = v4l2_getfree_v4l2buf(ctx);
621  if (!avbuf)
622  return AVERROR(EAGAIN);
623 
625  if (ret)
626  return ret;
627 
628  return ff_v4l2_buffer_enqueue(avbuf);
629 }
630 
632 {
633  V4L2Buffer *avbuf;
634 
635  /*
636  * timeout=-1 blocks until:
637  * 1. decoded frame available
638  * 2. an input buffer is ready to be dequeued
639  */
640  avbuf = v4l2_dequeue_v4l2buf(ctx, timeout);
641  if (!avbuf) {
642  if (ctx->done)
643  return AVERROR_EOF;
644 
645  return AVERROR(EAGAIN);
646  }
647 
648  return ff_v4l2_buffer_buf_to_avframe(frame, avbuf);
649 }
650 
652 {
653  V4L2Buffer *avbuf;
654 
655  /*
656  * blocks until:
657  * 1. encoded packet available
658  * 2. an input buffer ready to be dequeued
659  */
660  avbuf = v4l2_dequeue_v4l2buf(ctx, -1);
661  if (!avbuf) {
662  if (ctx->done)
663  return AVERROR_EOF;
664 
665  return AVERROR(EAGAIN);
666  }
667 
668  return ff_v4l2_buffer_buf_to_avpkt(pkt, avbuf);
669 }
670 
672 {
673  struct v4l2_format_update fmt = { 0 };
674  int ret;
675 
676  if (ctx->av_codec_id == AV_CODEC_ID_RAWVIDEO) {
678  if (ret)
679  return ret;
680 
681  fmt.update_avfmt = !probe;
682  v4l2_save_to_context(ctx, &fmt);
683 
684  /* format has been tried already */
685  return ret;
686  }
687 
689  if (ret)
690  return ret;
691 
692  fmt.update_v4l2 = 1;
693  v4l2_save_to_context(ctx, &fmt);
694 
695  return ioctl(ctx_to_m2mctx(ctx)->fd, VIDIOC_TRY_FMT, &ctx->format);
696 }
697 
699 {
700  return ioctl(ctx_to_m2mctx(ctx)->fd, VIDIOC_S_FMT, &ctx->format);
701 }
702 
704 {
705  int ret;
706 
707  if (!ctx->buffers)
708  return;
709 
711  if (ret)
712  av_log(logger(ctx), AV_LOG_WARNING, "V4L2 failed to unmap the %s buffers\n", ctx->name);
713 
714  av_freep(&ctx->buffers);
715 }
716 
718 {
720  struct v4l2_requestbuffers req;
721  int ret, i;
722 
723  if (!v4l2_type_supported(ctx)) {
724  av_log(logger(ctx), AV_LOG_ERROR, "type %i not supported\n", ctx->type);
725  return AVERROR_PATCHWELCOME;
726  }
727 
728  ret = ioctl(s->fd, VIDIOC_G_FMT, &ctx->format);
729  if (ret)
730  av_log(logger(ctx), AV_LOG_ERROR, "%s VIDIOC_G_FMT failed\n", ctx->name);
731 
732  memset(&req, 0, sizeof(req));
733  req.count = ctx->num_buffers;
734  req.memory = V4L2_MEMORY_MMAP;
735  req.type = ctx->type;
736  ret = ioctl(s->fd, VIDIOC_REQBUFS, &req);
737  if (ret < 0) {
738  av_log(logger(ctx), AV_LOG_ERROR, "%s VIDIOC_REQBUFS failed: %s\n", ctx->name, strerror(errno));
739  return AVERROR(errno);
740  }
741 
742  ctx->num_buffers = req.count;
743  ctx->buffers = av_mallocz(ctx->num_buffers * sizeof(V4L2Buffer));
744  if (!ctx->buffers) {
745  av_log(logger(ctx), AV_LOG_ERROR, "%s malloc enomem\n", ctx->name);
746  return AVERROR(ENOMEM);
747  }
748 
749  for (i = 0; i < req.count; i++) {
750  ctx->buffers[i].context = ctx;
751  ret = ff_v4l2_buffer_initialize(&ctx->buffers[i], i);
752  if (ret < 0) {
753  av_log(logger(ctx), AV_LOG_ERROR, "%s buffer[%d] initialization (%s)\n", ctx->name, i, av_err2str(ret));
754  goto error;
755  }
756  }
757 
758  av_log(logger(ctx), AV_LOG_DEBUG, "%s: %s %02d buffers initialized: %04ux%04u, sizeimage %08u, bytesperline %08u\n", ctx->name,
759  V4L2_TYPE_IS_MULTIPLANAR(ctx->type) ? av_fourcc2str(ctx->format.fmt.pix_mp.pixelformat) : av_fourcc2str(ctx->format.fmt.pix.pixelformat),
760  req.count,
761  v4l2_get_width(&ctx->format),
762  v4l2_get_height(&ctx->format),
763  V4L2_TYPE_IS_MULTIPLANAR(ctx->type) ? ctx->format.fmt.pix_mp.plane_fmt[0].sizeimage : ctx->format.fmt.pix.sizeimage,
764  V4L2_TYPE_IS_MULTIPLANAR(ctx->type) ? ctx->format.fmt.pix_mp.plane_fmt[0].bytesperline : ctx->format.fmt.pix.bytesperline);
765 
766  return 0;
767 
768 error:
770 
771  av_freep(&ctx->buffers);
772 
773  return ret;
774 }
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:717
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
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:205
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:453
V4L2m2mContext
Definition: v4l2_m2m.h:43
AV_CODEC_ID_RAWVIDEO
@ AV_CODEC_ID_RAWVIDEO
Definition: codec_id.h:63
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:317
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:651
internal.h
ff_v4l2_context_release
void ff_v4l2_context_release(V4L2Context *ctx)
Releases a V4L2Context.
Definition: v4l2_context.c:703
v4l2_stop_encode
static int v4l2_stop_encode(V4L2Context *ctx)
Definition: v4l2_context.c:258
v4l2_format_update::v4l2_fmt
uint32_t v4l2_fmt
Definition: v4l2_context.c:37
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:419
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:448
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:412
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:698
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:671
v4l2_getfree_v4l2buf
static V4L2Buffer * v4l2_getfree_v4l2buf(V4L2Context *ctx)
Definition: v4l2_context.c:429
v4l2_fmt.h
width
#define width
s
#define s(width, name)
Definition: cbs_vp9.c:257
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
planes
static const struct @321 planes[]
ff_v4l2_buffer_enqueue
int ff_v4l2_buffer_enqueue(V4L2Buffer *avbuf)
Enqueues a V4L2Buffer.
Definition: v4l2_buffers.c:561
v4l2_stop_decode
static int v4l2_stop_decode(V4L2Context *ctx)
Definition: v4l2_context.c:238
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:606
v4l2_dequeue_v4l2buf
static V4L2Buffer * v4l2_dequeue_v4l2buf(V4L2Context *ctx, int timeout)
Definition: v4l2_context.c:278
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:478
V4L2BUF_AVAILABLE
@ V4L2BUF_AVAILABLE
Definition: v4l2_buffers.h:36
av_codec_is_decoder
int av_codec_is_decoder(const AVCodec *codec)
Definition: utils.c:81
AVPacket::size
int size
Definition: packet.h:374
v4l2_get_raw_format
static int v4l2_get_raw_format(V4L2Context *ctx, enum AVPixelFormat *p)
Definition: v4l2_context.c:495
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:631
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:567
reinit
static void reinit(Jpeg2000EncoderContext *s)
Definition: j2kenc.c:1514
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:471
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:271
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:263
v4l2_get_coded_format
static int v4l2_get_coded_format(V4L2Context *ctx, uint32_t *p)
Definition: v4l2_context.c:530
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:581
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:383
probe
static int probe(const AVProbeData *p)
Definition: act.c:37
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_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:86
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:350
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
v4l2_m2m.h
ff_v4l2_buffer_initialize
int ff_v4l2_buffer_initialize(V4L2Buffer *avbuf, int index)
Initializes a V4L2Buffer.
Definition: v4l2_buffers.c:494
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:28
av_fourcc2str
#define av_fourcc2str(fourcc)
Definition: avutil.h:348
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