FFmpeg
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
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) ?
47  container_of(ctx, V4L2m2mContext, output) :
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 
66 static inline unsigned int v4l2_resolution_changed(V4L2Context *ctx, struct v4l2_format *fmt2)
67 {
68  struct v4l2_format *fmt1 = &ctx->format;
69  int ret = V4L2_TYPE_IS_MULTIPLANAR(ctx->type) ?
70  fmt1->fmt.pix_mp.width != fmt2->fmt.pix_mp.width ||
71  fmt1->fmt.pix_mp.height != fmt2->fmt.pix_mp.height
72  :
73  fmt1->fmt.pix.width != fmt2->fmt.pix.width ||
74  fmt1->fmt.pix.height != fmt2->fmt.pix.height;
75 
76  if (ret)
77  av_log(logger(ctx), AV_LOG_DEBUG, "%s changed (%dx%d) -> (%dx%d)\n",
78  ctx->name,
79  v4l2_get_width(fmt1), v4l2_get_height(fmt1),
80  v4l2_get_width(fmt2), v4l2_get_height(fmt2));
81 
82  return ret;
83 }
84 
85 static inline int v4l2_type_supported(V4L2Context *ctx)
86 {
87  return ctx->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
88  ctx->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ||
89  ctx->type == V4L2_BUF_TYPE_VIDEO_CAPTURE ||
90  ctx->type == V4L2_BUF_TYPE_VIDEO_OUTPUT;
91 }
92 
94 {
96  const int SZ_4K = 0x1000;
97  int size;
98 
100  return ((width * height * 3 / 2) / 2) + 128;
101 
102  /* encoder */
103  size = FFALIGN(height, 32) * FFALIGN(width, 32) * 3 / 2 / 2;
104  return FFALIGN(size, SZ_4K);
105 }
106 
108 {
109  ctx->format.type = ctx->type;
110 
111  if (fmt->update_avfmt)
112  ctx->av_pix_fmt = fmt->av_fmt;
113 
114  if (V4L2_TYPE_IS_MULTIPLANAR(ctx->type)) {
115  /* update the sizes to handle the reconfiguration of the capture stream at runtime */
116  ctx->format.fmt.pix_mp.height = ctx->height;
117  ctx->format.fmt.pix_mp.width = ctx->width;
118  if (fmt->update_v4l2) {
119  ctx->format.fmt.pix_mp.pixelformat = fmt->v4l2_fmt;
120 
121  /* s5p-mfc requires the user to specify a buffer size */
122  ctx->format.fmt.pix_mp.plane_fmt[0].sizeimage =
123  v4l2_get_framesize_compressed(ctx, ctx->width, ctx->height);
124  }
125  } else {
126  ctx->format.fmt.pix.height = ctx->height;
127  ctx->format.fmt.pix.width = ctx->width;
128  if (fmt->update_v4l2) {
129  ctx->format.fmt.pix.pixelformat = fmt->v4l2_fmt;
130 
131  /* s5p-mfc requires the user to specify a buffer size */
132  ctx->format.fmt.pix.sizeimage =
133  v4l2_get_framesize_compressed(ctx, ctx->width, ctx->height);
134  }
135  }
136 }
137 
138 /**
139  * returns 1 if reinit was successful, negative if it failed
140  * returns 0 if reinit was not executed
141  */
143 {
145  struct v4l2_format cap_fmt = s->capture.format;
146  struct v4l2_format out_fmt = s->output.format;
147  struct v4l2_event evt = { 0 };
148  int full_reinit, reinit, ret;
149 
150  ret = ioctl(s->fd, VIDIOC_DQEVENT, &evt);
151  if (ret < 0) {
152  av_log(logger(ctx), AV_LOG_ERROR, "%s VIDIOC_DQEVENT\n", ctx->name);
153  return 0;
154  }
155 
156  if (evt.type != V4L2_EVENT_SOURCE_CHANGE)
157  return 0;
158 
159  ret = ioctl(s->fd, VIDIOC_G_FMT, &out_fmt);
160  if (ret) {
161  av_log(logger(ctx), AV_LOG_ERROR, "%s VIDIOC_G_FMT\n", s->output.name);
162  return 0;
163  }
164 
165  ret = ioctl(s->fd, VIDIOC_G_FMT, &cap_fmt);
166  if (ret) {
167  av_log(logger(ctx), AV_LOG_ERROR, "%s VIDIOC_G_FMT\n", s->capture.name);
168  return 0;
169  }
170 
171  full_reinit = v4l2_resolution_changed(&s->output, &out_fmt);
172  if (full_reinit) {
173  s->output.height = v4l2_get_height(&out_fmt);
174  s->output.width = v4l2_get_width(&out_fmt);
175  }
176 
177  reinit = v4l2_resolution_changed(&s->capture, &cap_fmt);
178  if (reinit) {
179  s->capture.height = v4l2_get_height(&cap_fmt);
180  s->capture.width = v4l2_get_width(&cap_fmt);
181  }
182 
183  if (full_reinit || reinit)
184  s->reinit = 1;
185 
186  if (full_reinit) {
188  if (ret) {
189  av_log(logger(ctx), AV_LOG_ERROR, "v4l2_m2m_codec_full_reinit\n");
190  return -EINVAL;
191  }
192  goto reinit_run;
193  }
194 
195  if (reinit) {
197  if (ret < 0)
198  av_log(logger(ctx), AV_LOG_WARNING, "update avcodec height and width\n");
199 
200  ret = ff_v4l2_m2m_codec_reinit(s);
201  if (ret) {
202  av_log(logger(ctx), AV_LOG_ERROR, "v4l2_m2m_codec_reinit\n");
203  return -EINVAL;
204  }
205  goto reinit_run;
206  }
207 
208  /* dummy event received */
209  return 0;
210 
211  /* reinit executed */
212 reinit_run:
213  return 1;
214 }
215 
217 {
218  struct v4l2_decoder_cmd cmd = {
219  .cmd = V4L2_DEC_CMD_STOP,
220  };
221  int ret;
222 
223  ret = ioctl(ctx_to_m2mctx(ctx)->fd, VIDIOC_DECODER_CMD, &cmd);
224  if (ret) {
225  /* DECODER_CMD is optional */
226  if (errno == ENOTTY)
227  return ff_v4l2_context_set_status(ctx, VIDIOC_STREAMOFF);
228  }
229 
230  return 0;
231 }
232 
234 {
235  struct v4l2_encoder_cmd cmd = {
236  .cmd = V4L2_ENC_CMD_STOP,
237  };
238  int ret;
239 
240  ret = ioctl(ctx_to_m2mctx(ctx)->fd, VIDIOC_ENCODER_CMD, &cmd);
241  if (ret) {
242  /* ENCODER_CMD is optional */
243  if (errno == ENOTTY)
244  return ff_v4l2_context_set_status(ctx, VIDIOC_STREAMOFF);
245  }
246 
247  return 0;
248 }
249 
251 {
252  struct v4l2_plane planes[VIDEO_MAX_PLANES];
253  struct v4l2_buffer buf = { 0 };
254  V4L2Buffer* avbuf = NULL;
255  struct pollfd pfd = {
256  .events = POLLIN | POLLRDNORM | POLLPRI | POLLOUT | POLLWRNORM, /* default blocking capture */
257  .fd = ctx_to_m2mctx(ctx)->fd,
258  };
259  int ret;
260 
261  if (V4L2_TYPE_IS_OUTPUT(ctx->type))
262  pfd.events = POLLOUT | POLLWRNORM;
263 
264  for (;;) {
265  ret = poll(&pfd, 1, timeout);
266  if (ret > 0)
267  break;
268  if (errno == EINTR)
269  continue;
270 
271  /* timeout is being used to indicate last valid bufer when draining */
272  if (ctx_to_m2mctx(ctx)->draining)
273  ctx->done = 1;
274 
275  return NULL;
276  }
277 
278  /* 0. handle errors */
279  if (pfd.revents & POLLERR) {
280  av_log(logger(ctx), AV_LOG_WARNING, "%s POLLERR\n", ctx->name);
281  return NULL;
282  }
283 
284  /* 1. handle resolution changes */
285  if (pfd.revents & POLLPRI) {
286  ret = v4l2_handle_event(ctx);
287  if (ret < 0) {
288  /* if re-init failed, abort */
289  ctx->done = EINVAL;
290  return NULL;
291  }
292  if (ret) {
293  /* if re-init was successful drop the buffer (if there was one)
294  * since we had to reconfigure capture (unmap all buffers)
295  */
296  return NULL;
297  }
298  }
299 
300  /* 2. dequeue the buffer */
301  if (pfd.revents & (POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM)) {
302 
303  if (!V4L2_TYPE_IS_OUTPUT(ctx->type)) {
304  /* there is a capture buffer ready */
305  if (pfd.revents & (POLLIN | POLLRDNORM))
306  goto dequeue;
307 
308  /* the driver is ready to accept more input; instead of waiting for the capture
309  * buffer to complete we return NULL so input can proceed (we are single threaded)
310  */
311  if (pfd.revents & (POLLOUT | POLLWRNORM))
312  return NULL;
313  }
314 
315 dequeue:
316  memset(&buf, 0, sizeof(buf));
317  buf.memory = V4L2_MEMORY_MMAP;
318  buf.type = ctx->type;
319  if (V4L2_TYPE_IS_MULTIPLANAR(ctx->type)) {
320  memset(planes, 0, sizeof(planes));
321  buf.length = VIDEO_MAX_PLANES;
322  buf.m.planes = planes;
323  }
324 
325  ret = ioctl(ctx_to_m2mctx(ctx)->fd, VIDIOC_DQBUF, &buf);
326  if (ret) {
327  if (errno != EAGAIN) {
328  ctx->done = errno;
329  if (errno != EPIPE)
330  av_log(logger(ctx), AV_LOG_DEBUG, "%s VIDIOC_DQBUF, errno (%s)\n",
331  ctx->name, av_err2str(AVERROR(errno)));
332  }
333  } else {
334  avbuf = &ctx->buffers[buf.index];
335  avbuf->status = V4L2BUF_AVAILABLE;
336  avbuf->buf = buf;
337  if (V4L2_TYPE_IS_MULTIPLANAR(ctx->type)) {
338  memcpy(avbuf->planes, planes, sizeof(planes));
339  avbuf->buf.m.planes = avbuf->planes;
340  }
341  }
342  }
343 
344  return avbuf;
345 }
346 
348 {
349  int timeout = 0; /* return when no more buffers to dequeue */
350  int i;
351 
352  /* get back as many output buffers as possible */
353  if (V4L2_TYPE_IS_OUTPUT(ctx->type)) {
354  do {
355  } while (v4l2_dequeue_v4l2buf(ctx, timeout));
356  }
357 
358  for (i = 0; i < ctx->num_buffers; i++) {
359  if (ctx->buffers[i].status == V4L2BUF_AVAILABLE)
360  return &ctx->buffers[i];
361  }
362 
363  return NULL;
364 }
365 
367 {
368  struct v4l2_requestbuffers req = {
369  .memory = V4L2_MEMORY_MMAP,
370  .type = ctx->type,
371  .count = 0, /* 0 -> unmaps buffers from the driver */
372  };
373  int i, j;
374 
375  for (i = 0; i < ctx->num_buffers; i++) {
376  V4L2Buffer *buffer = &ctx->buffers[i];
377 
378  for (j = 0; j < buffer->num_planes; j++) {
379  struct V4L2Plane_info *p = &buffer->plane_info[j];
380  if (p->mm_addr && p->length)
381  if (munmap(p->mm_addr, p->length) < 0)
382  av_log(logger(ctx), AV_LOG_ERROR, "%s unmap plane (%s))\n", ctx->name, av_err2str(AVERROR(errno)));
383  }
384  }
385 
386  return ioctl(ctx_to_m2mctx(ctx)->fd, VIDIOC_REQBUFS, &req);
387 }
388 
390 {
391  struct v4l2_format *fmt = &ctx->format;
392  uint32_t v4l2_fmt;
393  int ret;
394 
395  v4l2_fmt = ff_v4l2_format_avfmt_to_v4l2(pixfmt);
396  if (!v4l2_fmt)
397  return AVERROR(EINVAL);
398 
399  if (V4L2_TYPE_IS_MULTIPLANAR(ctx->type))
400  fmt->fmt.pix_mp.pixelformat = v4l2_fmt;
401  else
402  fmt->fmt.pix.pixelformat = v4l2_fmt;
403 
404  fmt->type = ctx->type;
405 
406  ret = ioctl(ctx_to_m2mctx(ctx)->fd, VIDIOC_TRY_FMT, fmt);
407  if (ret)
408  return AVERROR(EINVAL);
409 
410  return 0;
411 }
412 
414 {
415  enum AVPixelFormat pixfmt = ctx->av_pix_fmt;
416  struct v4l2_fmtdesc fdesc;
417  int ret;
418 
419  memset(&fdesc, 0, sizeof(fdesc));
420  fdesc.type = ctx->type;
421 
422  if (pixfmt != AV_PIX_FMT_NONE) {
423  ret = v4l2_try_raw_format(ctx, pixfmt);
424  if (ret)
425  pixfmt = AV_PIX_FMT_NONE;
426  else
427  return 0;
428  }
429 
430  for (;;) {
431  ret = ioctl(ctx_to_m2mctx(ctx)->fd, VIDIOC_ENUM_FMT, &fdesc);
432  if (ret)
433  return AVERROR(EINVAL);
434 
435  pixfmt = ff_v4l2_format_v4l2_to_avfmt(fdesc.pixelformat, AV_CODEC_ID_RAWVIDEO);
436  ret = v4l2_try_raw_format(ctx, pixfmt);
437  if (ret){
438  fdesc.index++;
439  continue;
440  }
441 
442  *p = pixfmt;
443 
444  return 0;
445  }
446 
447  return AVERROR(EINVAL);
448 }
449 
450 static int v4l2_get_coded_format(V4L2Context* ctx, uint32_t *p)
451 {
452  struct v4l2_fmtdesc fdesc;
453  uint32_t v4l2_fmt;
454  int ret;
455 
456  /* translate to a valid v4l2 format */
458  if (!v4l2_fmt)
459  return AVERROR(EINVAL);
460 
461  /* check if the driver supports this format */
462  memset(&fdesc, 0, sizeof(fdesc));
463  fdesc.type = ctx->type;
464 
465  for (;;) {
466  ret = ioctl(ctx_to_m2mctx(ctx)->fd, VIDIOC_ENUM_FMT, &fdesc);
467  if (ret)
468  return AVERROR(EINVAL);
469 
470  if (fdesc.pixelformat == v4l2_fmt)
471  break;
472 
473  fdesc.index++;
474  }
475 
476  *p = v4l2_fmt;
477 
478  return 0;
479 }
480 
481  /*****************************************************************************
482  *
483  * V4L2 Context Interface
484  *
485  *****************************************************************************/
486 
488 {
489  int type = ctx->type;
490  int ret;
491 
492  ret = ioctl(ctx_to_m2mctx(ctx)->fd, cmd, &type);
493  if (ret < 0)
494  return AVERROR(errno);
495 
496  ctx->streamon = (cmd == VIDIOC_STREAMON);
497 
498  return 0;
499 }
500 
502 {
504  V4L2Buffer* avbuf;
505  int ret;
506 
507  if (!frame) {
508  ret = v4l2_stop_encode(ctx);
509  if (ret)
510  av_log(logger(ctx), AV_LOG_ERROR, "%s stop_encode\n", ctx->name);
511  s->draining= 1;
512  return 0;
513  }
514 
515  avbuf = v4l2_getfree_v4l2buf(ctx);
516  if (!avbuf)
517  return AVERROR(ENOMEM);
518 
519  ret = ff_v4l2_buffer_avframe_to_buf(frame, avbuf);
520  if (ret)
521  return ret;
522 
523  return ff_v4l2_buffer_enqueue(avbuf);
524 }
525 
527 {
529  V4L2Buffer* avbuf;
530  int ret;
531 
532  if (!pkt->size) {
533  ret = v4l2_stop_decode(ctx);
534  if (ret)
535  av_log(logger(ctx), AV_LOG_ERROR, "%s stop_decode\n", ctx->name);
536  s->draining = 1;
537  return 0;
538  }
539 
540  avbuf = v4l2_getfree_v4l2buf(ctx);
541  if (!avbuf)
542  return AVERROR(ENOMEM);
543 
544  ret = ff_v4l2_buffer_avpkt_to_buf(pkt, avbuf);
545  if (ret)
546  return ret;
547 
548  return ff_v4l2_buffer_enqueue(avbuf);
549 }
550 
552 {
553  V4L2Buffer* avbuf = NULL;
554 
555  /* if we are draining, we are no longer inputing data, therefore enable a
556  * timeout so we can dequeue and flag the last valid buffer.
557  *
558  * blocks until:
559  * 1. decoded frame available
560  * 2. an input buffer is ready to be dequeued
561  */
562  avbuf = v4l2_dequeue_v4l2buf(ctx, ctx_to_m2mctx(ctx)->draining ? 200 : -1);
563  if (!avbuf) {
564  if (ctx->done)
565  return AVERROR_EOF;
566 
567  return AVERROR(EAGAIN);
568  }
569 
570  return ff_v4l2_buffer_buf_to_avframe(frame, avbuf);
571 }
572 
574 {
575  V4L2Buffer* avbuf = NULL;
576 
577  /* if we are draining, we are no longer inputing data, therefore enable a
578  * timeout so we can dequeue and flag the last valid buffer.
579  *
580  * blocks until:
581  * 1. encoded packet available
582  * 2. an input buffer ready to be dequeued
583  */
584  avbuf = v4l2_dequeue_v4l2buf(ctx, ctx_to_m2mctx(ctx)->draining ? 200 : -1);
585  if (!avbuf) {
586  if (ctx->done)
587  return AVERROR_EOF;
588 
589  return AVERROR(EAGAIN);
590  }
591 
592  return ff_v4l2_buffer_buf_to_avpkt(pkt, avbuf);
593 }
594 
596 {
597  struct v4l2_format_update fmt = { 0 };
598  int ret;
599 
600  if (ctx->av_codec_id == AV_CODEC_ID_RAWVIDEO) {
601  ret = v4l2_get_raw_format(ctx, &fmt.av_fmt);
602  if (ret)
603  return ret;
604 
605  fmt.update_avfmt = 1;
606  v4l2_save_to_context(ctx, &fmt);
607 
608  /* format has been tried already */
609  return ret;
610  }
611 
612  ret = v4l2_get_coded_format(ctx, &fmt.v4l2_fmt);
613  if (ret)
614  return ret;
615 
616  fmt.update_v4l2 = 1;
617  v4l2_save_to_context(ctx, &fmt);
618 
619  return ioctl(ctx_to_m2mctx(ctx)->fd, VIDIOC_TRY_FMT, &ctx->format);
620 }
621 
623 {
624  return ioctl(ctx_to_m2mctx(ctx)->fd, VIDIOC_S_FMT, &ctx->format);
625 }
626 
628 {
629  int ret;
630 
631  if (!ctx->buffers)
632  return;
633 
634  ret = v4l2_release_buffers(ctx);
635  if (ret)
636  av_log(logger(ctx), AV_LOG_WARNING, "V4L2 failed to unmap the %s buffers\n", ctx->name);
637 
638  av_free(ctx->buffers);
639  ctx->buffers = NULL;
640 }
641 
643 {
645  struct v4l2_requestbuffers req;
646  int ret, i;
647 
648  if (!v4l2_type_supported(ctx)) {
649  av_log(logger(ctx), AV_LOG_ERROR, "type %i not supported\n", ctx->type);
650  return AVERROR_PATCHWELCOME;
651  }
652 
653  ret = ioctl(s->fd, VIDIOC_G_FMT, &ctx->format);
654  if (ret)
655  av_log(logger(ctx), AV_LOG_ERROR, "%s VIDIOC_G_FMT failed\n", ctx->name);
656 
657  memset(&req, 0, sizeof(req));
658  req.count = ctx->num_buffers;
659  req.memory = V4L2_MEMORY_MMAP;
660  req.type = ctx->type;
661  ret = ioctl(s->fd, VIDIOC_REQBUFS, &req);
662  if (ret < 0)
663  return AVERROR(errno);
664 
665  ctx->num_buffers = req.count;
666  ctx->buffers = av_mallocz(ctx->num_buffers * sizeof(V4L2Buffer));
667  if (!ctx->buffers) {
668  av_log(logger(ctx), AV_LOG_ERROR, "%s malloc enomem\n", ctx->name);
669  return AVERROR(ENOMEM);
670  }
671 
672  for (i = 0; i < req.count; i++) {
673  ctx->buffers[i].context = ctx;
674  ret = ff_v4l2_buffer_initialize(&ctx->buffers[i], i);
675  if (ret < 0) {
676  av_log(logger(ctx), AV_LOG_ERROR, "%s buffer initialization (%s)\n", ctx->name, av_err2str(ret));
677  av_free(ctx->buffers);
678  return ret;
679  }
680  }
681 
682  av_log(logger(ctx), AV_LOG_DEBUG, "%s: %s %02d buffers initialized: %04ux%04u, sizeimage %08u, bytesperline %08u\n", ctx->name,
683  V4L2_TYPE_IS_MULTIPLANAR(ctx->type) ? av_fourcc2str(ctx->format.fmt.pix_mp.pixelformat) : av_fourcc2str(ctx->format.fmt.pix.pixelformat),
684  req.count,
685  v4l2_get_width(&ctx->format),
686  v4l2_get_height(&ctx->format),
687  V4L2_TYPE_IS_MULTIPLANAR(ctx->type) ? ctx->format.fmt.pix_mp.plane_fmt[0].sizeimage : ctx->format.fmt.pix.sizeimage,
688  V4L2_TYPE_IS_MULTIPLANAR(ctx->type) ? ctx->format.fmt.pix_mp.plane_fmt[0].bytesperline : ctx->format.fmt.pix.bytesperline);
689 
690  return 0;
691 }
enum AVPixelFormat ff_v4l2_format_v4l2_to_avfmt(uint32_t v4l2_fmt, enum AVCodecID avcodec)
Definition: v4l2_fmt.c:132
static int v4l2_stop_encode(V4L2Context *ctx)
Definition: v4l2_context.c:233
#define NULL
Definition: coverity.c:32
const struct AVCodec * codec
Definition: avcodec.h:1770
const char * s
Definition: avisynth_c.h:768
This structure describes decoded (raw) audio or video data.
Definition: frame.h:201
const char * name
context name.
Definition: v4l2_context.h:40
AVCodecContext * avctx
Definition: v4l2_m2m.h:57
const char * fmt
Definition: avisynth_c.h:769
int ff_v4l2_buffer_buf_to_avpkt(AVPacket *pkt, V4L2Buffer *avbuf)
Extracts the data from a V4L2Buffer to an AVPacket.
Definition: v4l2_buffers.c:340
static int v4l2_handle_event(V4L2Context *ctx)
returns 1 if reinit was successful, negative if it failed returns 0 if reinit was not executed ...
Definition: v4l2_context.c:142
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:182
int ff_v4l2_context_init(V4L2Context *ctx)
Initializes a V4L2Context.
Definition: v4l2_context.c:642
int ff_v4l2_buffer_initialize(V4L2Buffer *avbuf, int index)
Initializes a V4L2Buffer.
Definition: v4l2_buffers.c:381
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:211
uint32_t ff_v4l2_format_avfmt_to_v4l2(enum AVPixelFormat avfmt)
Definition: v4l2_fmt.c:122
int size
Definition: avcodec.h:1680
int ff_v4l2_context_dequeue_frame(V4L2Context *ctx, AVFrame *frame)
Dequeues a buffer from a V4L2Context to an AVFrame.
Definition: v4l2_context.c:551
int width
Width and height of the frames it produces (in case of a capture context, e.g.
Definition: v4l2_context.h:71
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:274
static int v4l2_type_supported(V4L2Context *ctx)
Definition: v4l2_context.c:85
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:222
static AVPacket pkt
int ff_v4l2_context_dequeue_packet(V4L2Context *ctx, AVPacket *pkt)
Dequeues a buffer from a V4L2Context to an AVPacket.
Definition: v4l2_context.c:573
enum V4L2Buffer_status status
Definition: v4l2_buffers.h:58
void ff_v4l2_context_release(V4L2Context *ctx)
Releases a V4L2Context.
Definition: v4l2_context.c:627
int ff_v4l2_context_set_format(V4L2Context *ctx)
Sets the V4L2Context format in the v4l2 driver.
Definition: v4l2_context.c:622
static V4L2Buffer * v4l2_getfree_v4l2buf(V4L2Context *ctx)
Definition: v4l2_context.c:347
int av_codec_is_decoder(const AVCodec *codec)
Definition: utils.c:174
enum AVCodecID av_codec_id
AVCodecID corresponding to this buffer context.
Definition: v4l2_context.h:59
static unsigned int v4l2_get_width(struct v4l2_format *fmt)
Definition: v4l2_context.c:56
static V4L2m2mContext * ctx_to_m2mctx(V4L2Context *ctx)
Definition: v4l2_context.c:44
struct V4L2Buffer::V4L2Plane_info plane_info[VIDEO_MAX_PLANES]
static AVFrame * frame
int ff_v4l2_buffer_enqueue(V4L2Buffer *avbuf)
Enqueues a V4L2Buffer.
Definition: v4l2_buffers.c:450
#define height
#define AVERROR_EOF
End of file.
Definition: error.h:55
ptrdiff_t size
Definition: opengl_enc.c:101
#define FFALIGN(x, a)
Definition: macros.h:48
static AVCodecContext * logger(V4L2Context *ctx)
Definition: v4l2_context.c:51
int ff_v4l2_m2m_codec_reinit(V4L2m2mContext *s)
Reinitializes the V4L2m2mContext when the driver cant continue processing with the capture parameters...
Definition: v4l2_m2m.c:189
#define av_log(a,...)
struct V4L2Context * context
Definition: v4l2_buffers.h:42
int done
Either no more buffers available or an unrecoverable error was notified by the V4L2 kernel driver: on...
Definition: v4l2_context.h:92
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
#define AVERROR(e)
Definition: error.h:43
struct v4l2_buffer buf
Definition: v4l2_buffers.h:54
static int v4l2_get_framesize_compressed(V4L2Context *ctx, int width, int height)
Definition: v4l2_context.c:93
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:197
#define av_fourcc2str(fourcc)
Definition: avutil.h:348
int ff_v4l2_buffer_buf_to_avframe(AVFrame *frame, V4L2Buffer *avbuf)
Extracts the data from a V4L2Buffer to an AVFrame.
Definition: v4l2_buffers.c:289
uint16_t width
Definition: gdv.c:47
int ff_v4l2_context_set_status(V4L2Context *ctx, int cmd)
Sets the status of a V4L2Context.
Definition: v4l2_context.c:487
enum AVPixelFormat av_pix_fmt
AVPixelFormat corresponding to this buffer context.
Definition: v4l2_context.h:53
static void v4l2_save_to_context(V4L2Context *ctx, struct v4l2_format_update *fmt)
Definition: v4l2_context.c:107
static int v4l2_release_buffers(V4L2Context *ctx)
Definition: v4l2_context.c:366
V4L2Buffer * buffers
Indexed array of V4L2Buffers.
Definition: v4l2_context.h:76
int streamon
Whether the stream has been started (VIDIOC_STREAMON has been sent).
Definition: v4l2_context.h:86
static int v4l2_get_raw_format(V4L2Context *ctx, enum AVPixelFormat *p)
Definition: v4l2_context.c:413
#define av_err2str(errnum)
Convenience macro, the return value should be used only directly in function arguments but never stan...
Definition: error.h:119
AVFormatContext * ctx
Definition: movenc.c:48
int ff_v4l2_context_enqueue_packet(V4L2Context *ctx, const AVPacket *pkt)
Enqueues a buffer to a V4L2Context from an AVPacket.
Definition: v4l2_context.c:526
static int v4l2_try_raw_format(V4L2Context *ctx, enum AVPixelFormat pixfmt)
Definition: v4l2_context.c:389
struct v4l2_plane planes[VIDEO_MAX_PLANES]
Definition: v4l2_buffers.h:55
static int v4l2_stop_decode(V4L2Context *ctx)
Definition: v4l2_context.c:216
enum AVPixelFormat av_fmt
Definition: v4l2_context.c:40
struct v4l2_format format
Format returned by the driver after initializing the buffer context.
Definition: v4l2_context.h:65
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
Definition: error.h:62
static V4L2Buffer * v4l2_dequeue_v4l2buf(V4L2Context *ctx, int timeout)
Definition: v4l2_context.c:250
V4L2Context capture
Definition: v4l2_m2m.h:50
Libavcodec external API header.
main external API structure.
Definition: avcodec.h:1761
V4L2Buffer (wrapper for v4l2_buffer management)
Definition: v4l2_buffers.h:40
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:365
void * buf
Definition: avisynth_c.h:690
GLint GLenum type
Definition: opengl_enc.c:105
int ff_v4l2_m2m_codec_full_reinit(V4L2m2mContext *s)
Reinitializes the V4L2m2mContext when the driver cant continue processing with the any of the current...
Definition: v4l2_m2m.c:233
#define container_of(ptr, type, member)
Definition: v4l2_m2m.h:35
V4L2Context output
Definition: v4l2_m2m.h:51
static int v4l2_get_coded_format(V4L2Context *ctx, uint32_t *p)
Definition: v4l2_context.c:450
static void reinit(Jpeg2000EncoderContext *s)
Definition: j2kenc.c:976
int ff_v4l2_context_enqueue_frame(V4L2Context *ctx, const AVFrame *frame)
Enqueues a buffer to a V4L2Context from an AVFrame.
Definition: v4l2_context.c:501
common internal api header.
uint32_t ff_v4l2_format_avcodec_to_v4l2(enum AVCodecID avcodec)
Definition: v4l2_fmt.c:112
#define av_free(p)
int num_planes
Definition: v4l2_buffers.h:51
int ff_v4l2_context_get_format(V4L2Context *ctx)
Queries the driver for a valid v4l2 format and copies it to the context.
Definition: v4l2_context.c:595
enum AVPixelFormat pixfmt
Definition: kmsgrab.c:202
int num_buffers
Readonly after init.
Definition: v4l2_context.h:81
static unsigned int v4l2_resolution_changed(V4L2Context *ctx, struct v4l2_format *fmt2)
Definition: v4l2_context.c:66
AVPixelFormat
Pixel format.
Definition: pixfmt.h:60
This structure stores compressed data.
Definition: avcodec.h:1656
static unsigned int v4l2_get_height(struct v4l2_format *fmt)
Definition: v4l2_context.c:61
GLuint buffer
Definition: opengl_enc.c:102
enum v4l2_buf_type type
Type of this buffer context.
Definition: v4l2_context.h:47