24#include <linux/videodev2.h>
47 return V4L2_TYPE_IS_OUTPUT(
ctx->type) ?
59 return V4L2_TYPE_IS_MULTIPLANAR(fmt->type) ? fmt->fmt.pix_mp.
width : fmt->fmt.pix.width;
64 return V4L2_TYPE_IS_MULTIPLANAR(fmt->type) ? fmt->fmt.pix_mp.height : fmt->fmt.pix.height;
70 struct v4l2_cropcap cropcap;
73 memset(&cropcap, 0,
sizeof(cropcap));
74 cropcap.type =
ctx->type;
80 sar.
num = cropcap.pixelaspect.numerator;
81 sar.
den = cropcap.pixelaspect.denominator;
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
92 fmt1->fmt.pix.width != fmt2->fmt.pix.width ||
93 fmt1->fmt.pix.height != fmt2->fmt.pix.height;
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;
115 const int SZ_4K = 0x1000;
128 ctx->format.type =
ctx->type;
133 if (V4L2_TYPE_IS_MULTIPLANAR(
ctx->type)) {
135 ctx->format.fmt.pix_mp.height =
ctx->height;
136 ctx->format.fmt.pix_mp.width =
ctx->width;
138 ctx->format.fmt.pix_mp.pixelformat = fmt->
v4l2_fmt;
141 ctx->format.fmt.pix_mp.plane_fmt[0].sizeimage =
145 ctx->format.fmt.pix.height =
ctx->height;
146 ctx->format.fmt.pix.width =
ctx->width;
151 ctx->format.fmt.pix.sizeimage =
159 struct v4l2_decoder_cmd cmd = {
160 .cmd = V4L2_DEC_CMD_START,
180 struct v4l2_format cap_fmt =
s->capture.format;
181 struct v4l2_event evt = { 0 };
184 ret = ioctl(
s->fd, VIDIOC_DQEVENT, &evt);
190 if (evt.type == V4L2_EVENT_EOS) {
195 if (evt.type != V4L2_EVENT_SOURCE_CHANGE)
198 ret = ioctl(
s->fd, VIDIOC_G_FMT, &cap_fmt);
232 struct v4l2_decoder_cmd cmd = {
233 .cmd = V4L2_DEC_CMD_STOP,
252 struct v4l2_encoder_cmd cmd = {
253 .cmd = V4L2_ENC_CMD_STOP,
272 struct v4l2_plane
planes[VIDEO_MAX_PLANES];
273 struct v4l2_buffer buf = { 0 };
275 struct pollfd pfd = {
276 .events = POLLIN | POLLRDNORM | POLLPRI | POLLOUT | POLLWRNORM,
281 if (!V4L2_TYPE_IS_OUTPUT(
ctx->type) &&
ctx->buffers) {
282 for (
i = 0;
i <
ctx->num_buffers;
i++) {
286 if (
i ==
ctx->num_buffers)
288 "userspace. Increase num_capture_buffers "
289 "to prevent device deadlock or dropped "
290 "packets/frames.\n");
295 for (
i = 0;
i <
ctx->num_buffers;
i++) {
310 if (V4L2_TYPE_IS_OUTPUT(
ctx->type))
311 pfd.events = POLLOUT | POLLWRNORM;
315 pfd.events = POLLIN | POLLRDNORM | POLLPRI;
319 ret = poll(&pfd, 1, timeout);
328 if (pfd.revents & POLLERR) {
336 for (
i = 0;
i <
ctx->num_buffers;
i++) {
348 if (pfd.revents & POLLPRI) {
364 if (pfd.revents & (POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM)) {
366 if (!V4L2_TYPE_IS_OUTPUT(
ctx->type)) {
368 if (pfd.revents & (POLLIN | POLLRDNORM))
374 if (pfd.revents & (POLLOUT | POLLWRNORM))
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)) {
384 buf.length = VIDEO_MAX_PLANES;
390 if (errno != EAGAIN) {
400 int bytesused = V4L2_TYPE_IS_MULTIPLANAR(buf.type) ?
401 buf.m.planes[0].bytesused : buf.bytesused;
402 if (bytesused == 0) {
406#ifdef V4L2_BUF_FLAG_LAST
407 if (buf.flags & V4L2_BUF_FLAG_LAST)
412 avbuf = &
ctx->buffers[buf.index];
415 if (V4L2_TYPE_IS_MULTIPLANAR(
ctx->type)) {
431 if (V4L2_TYPE_IS_OUTPUT(
ctx->type)) {
436 for (
i = 0;
i <
ctx->num_buffers;
i++) {
438 return &
ctx->buffers[
i];
446 struct v4l2_requestbuffers req = {
447 .memory = V4L2_MEMORY_MMAP,
453 for (
i = 0;
i <
ctx->num_buffers;
i++) {
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)
469 struct v4l2_format *fmt = &
ctx->format;
477 if (V4L2_TYPE_IS_MULTIPLANAR(
ctx->type))
478 fmt->fmt.pix_mp.pixelformat = v4l2_fmt;
480 fmt->fmt.pix.pixelformat = v4l2_fmt;
482 fmt->type =
ctx->type;
494 struct v4l2_fmtdesc fdesc;
497 memset(&fdesc, 0,
sizeof(fdesc));
498 fdesc.type =
ctx->type;
528 struct v4l2_fmtdesc fdesc;
538 memset(&fdesc, 0,
sizeof(fdesc));
539 fdesc.type =
ctx->type;
546 if (fdesc.pixelformat == v4l2_fmt)
572 ctx->streamon = (cmd == VIDIOC_STREAMON);
716 struct v4l2_requestbuffers req;
724 ret = ioctl(
s->fd, VIDIOC_G_FMT, &
ctx->format);
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);
738 ctx->num_buffers = req.count;
745 for (
i = 0;
i < req.count;
i++) {
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);
static int probe(const AVProbeData *p)
Libavcodec external API header.
#define i(width, name, range_min, range_max)
int ff_set_dimensions(AVCodecContext *s, int width, int height)
int av_codec_is_decoder(const AVCodec *codec)
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
#define AVERROR_EOF
End of file.
#define av_err2str(errnum)
Convenience macro, the return value should be used only directly in function arguments but never stan...
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
#define AV_LOG_WARNING
Something somehow does not look correct.
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
#define av_fourcc2str(fourcc)
enum AVPixelFormat pixfmt
static const struct @257111027162314367033347246032313251342043035002 planes[]
Memory handling functions.
AVPixelFormat
Pixel format.
main external API structure.
int width
picture width / height.
This structure describes decoded (raw) audio or video data.
This structure stores compressed data.
Rational number (pair of numerator and denominator).
V4L2Buffer (wrapper for v4l2_buffer management)
enum V4L2Buffer_status status
struct v4l2_plane planes[VIDEO_MAX_PLANES]
static void error(const char *err)
static AVFormatContext * ctx
int ff_v4l2_buffer_avframe_to_buf(const AVFrame *frame, V4L2Buffer *out)
Extracts the data from an AVFrame to a V4L2Buffer.
int ff_v4l2_buffer_avpkt_to_buf(const AVPacket *pkt, V4L2Buffer *out)
Extracts the data from an AVPacket to a V4L2Buffer.
int ff_v4l2_buffer_buf_to_avframe(AVFrame *frame, V4L2Buffer *avbuf)
Extracts the data from a V4L2Buffer to an AVFrame.
int ff_v4l2_buffer_enqueue(V4L2Buffer *avbuf)
Enqueues a V4L2Buffer.
int ff_v4l2_buffer_initialize(V4L2Buffer *avbuf, int index)
Initializes a V4L2Buffer.
int ff_v4l2_buffer_buf_to_avpkt(AVPacket *pkt, V4L2Buffer *avbuf)
Extracts the data from a V4L2Buffer to an AVPacket.
void ff_v4l2_context_release(V4L2Context *ctx)
Releases a V4L2Context.
static void v4l2_save_to_context(V4L2Context *ctx, struct v4l2_format_update *fmt)
static int v4l2_release_buffers(V4L2Context *ctx)
int ff_v4l2_context_get_format(V4L2Context *ctx, int probe)
Queries the driver for a valid v4l2 format and copies it to the context.
static int v4l2_get_framesize_compressed(V4L2Context *ctx, int width, int height)
static unsigned int v4l2_get_height(struct v4l2_format *fmt)
static AVRational v4l2_get_sar(V4L2Context *ctx)
static AVCodecContext * logger(V4L2Context *ctx)
int ff_v4l2_context_dequeue_frame(V4L2Context *ctx, AVFrame *frame, int timeout)
Dequeues a buffer from a V4L2Context to an AVFrame.
static unsigned int v4l2_get_width(struct v4l2_format *fmt)
int ff_v4l2_context_set_status(V4L2Context *ctx, uint32_t cmd)
Sets the status of a V4L2Context.
int ff_v4l2_context_enqueue_frame(V4L2Context *ctx, const AVFrame *frame)
Enqueues a buffer to a V4L2Context from an AVFrame.
int ff_v4l2_context_enqueue_packet(V4L2Context *ctx, const AVPacket *pkt)
Enqueues a buffer to a V4L2Context from an AVPacket.
static int v4l2_stop_encode(V4L2Context *ctx)
static int v4l2_handle_event(V4L2Context *ctx)
handle resolution change event and end of stream event returns 1 if reinit was successful,...
static int v4l2_get_coded_format(V4L2Context *ctx, uint32_t *p)
static int v4l2_stop_decode(V4L2Context *ctx)
int ff_v4l2_context_dequeue_packet(V4L2Context *ctx, AVPacket *pkt)
Dequeues a buffer from a V4L2Context to an AVPacket.
int ff_v4l2_context_set_format(V4L2Context *ctx)
Sets the V4L2Context format in the v4l2 driver.
static int v4l2_type_supported(V4L2Context *ctx)
static V4L2m2mContext * ctx_to_m2mctx(V4L2Context *ctx)
static V4L2Buffer * v4l2_getfree_v4l2buf(V4L2Context *ctx)
static int v4l2_start_decode(V4L2Context *ctx)
static V4L2Buffer * v4l2_dequeue_v4l2buf(V4L2Context *ctx, int timeout)
static int v4l2_try_raw_format(V4L2Context *ctx, enum AVPixelFormat pixfmt)
static int v4l2_get_raw_format(V4L2Context *ctx, enum AVPixelFormat *p)
static unsigned int v4l2_resolution_changed(V4L2Context *ctx, struct v4l2_format *fmt2)
int ff_v4l2_context_init(V4L2Context *ctx)
Initializes a V4L2Context.
enum AVPixelFormat ff_v4l2_format_v4l2_to_avfmt(uint32_t v4l2_fmt, enum AVCodecID avcodec)
uint32_t ff_v4l2_format_avcodec_to_v4l2(enum AVCodecID avcodec)
uint32_t ff_v4l2_format_avfmt_to_v4l2(enum AVPixelFormat avfmt)
int ff_v4l2_m2m_codec_reinit(V4L2m2mContext *s)
Reinitializes the V4L2m2mContext when the driver cannot continue processing with the capture paramete...
#define container_of(ptr, type, member)