24 #include <linux/videodev2.h> 25 #include <sys/ioctl.h> 46 return V4L2_TYPE_IS_OUTPUT(ctx->
type) ?
58 return V4L2_TYPE_IS_MULTIPLANAR(fmt->type) ? fmt->fmt.pix_mp.width : fmt->fmt.pix.width;
63 return V4L2_TYPE_IS_MULTIPLANAR(fmt->type) ? fmt->fmt.pix_mp.height : fmt->fmt.pix.height;
69 struct v4l2_cropcap cropcap;
72 memset(&cropcap, 0,
sizeof(cropcap));
73 cropcap.type = ctx->
type;
75 ret = ioctl(
ctx_to_m2mctx(ctx)->fd, VIDIOC_CROPCAP, &cropcap);
79 sar.
num = cropcap.pixelaspect.numerator;
80 sar.
den = cropcap.pixelaspect.denominator;
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
91 fmt1->fmt.pix.width != fmt2->fmt.pix.width ||
92 fmt1->fmt.pix.height != fmt2->fmt.pix.height;
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;
114 const int SZ_4K = 0x1000;
118 return ((width * height * 3 / 2) / 2) + 128;
132 if (V4L2_TYPE_IS_MULTIPLANAR(ctx->
type)) {
140 ctx->
format.fmt.pix_mp.plane_fmt[0].sizeimage =
150 ctx->
format.fmt.pix.sizeimage =
166 struct v4l2_event evt = { 0 };
169 ret = ioctl(s->
fd, VIDIOC_DQEVENT, &evt);
175 if (evt.type == V4L2_EVENT_EOS) {
180 if (evt.type != V4L2_EVENT_SOURCE_CHANGE)
183 ret = ioctl(s->
fd, VIDIOC_G_FMT, &out_fmt);
189 ret = ioctl(s->
fd, VIDIOC_G_FMT, &cap_fmt);
209 if (full_reinit || reinit)
245 struct v4l2_decoder_cmd cmd = {
246 .cmd = V4L2_DEC_CMD_STOP,
251 ret = ioctl(
ctx_to_m2mctx(ctx)->fd, VIDIOC_DECODER_CMD, &cmd);
265 struct v4l2_encoder_cmd cmd = {
266 .cmd = V4L2_ENC_CMD_STOP,
271 ret = ioctl(
ctx_to_m2mctx(ctx)->fd, VIDIOC_ENCODER_CMD, &cmd);
285 struct v4l2_plane planes[VIDEO_MAX_PLANES];
286 struct v4l2_buffer buf = { 0 };
288 struct pollfd pfd = {
289 .events = POLLIN | POLLRDNORM | POLLPRI | POLLOUT | POLLWRNORM,
294 if (!V4L2_TYPE_IS_OUTPUT(ctx->
type) && ctx->
buffers) {
301 "userspace. Increase num_capture_buffers " 302 "to prevent device deadlock or dropped " 303 "packets/frames.\n");
323 if (V4L2_TYPE_IS_OUTPUT(ctx->
type))
324 pfd.events = POLLOUT | POLLWRNORM;
328 pfd.events = POLLIN | POLLRDNORM | POLLPRI;
332 ret = poll(&pfd, 1, timeout);
341 if (pfd.revents & POLLERR) {
357 if (pfd.revents & POLLPRI) {
373 if (pfd.revents & (POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM)) {
375 if (!V4L2_TYPE_IS_OUTPUT(ctx->
type)) {
377 if (pfd.revents & (POLLIN | POLLRDNORM))
383 if (pfd.revents & (POLLOUT | POLLWRNORM))
388 memset(&buf, 0,
sizeof(buf));
389 buf.memory = V4L2_MEMORY_MMAP;
390 buf.type = ctx->
type;
391 if (V4L2_TYPE_IS_MULTIPLANAR(ctx->
type)) {
392 memset(planes, 0,
sizeof(planes));
393 buf.length = VIDEO_MAX_PLANES;
399 if (errno != EAGAIN) {
409 int bytesused = V4L2_TYPE_IS_MULTIPLANAR(buf.type) ?
410 buf.m.planes[0].bytesused : buf.bytesused;
411 if (bytesused == 0) {
415 #ifdef V4L2_BUF_FLAG_LAST 416 if (buf.flags & V4L2_BUF_FLAG_LAST)
421 avbuf = &ctx->
buffers[buf.index];
424 if (V4L2_TYPE_IS_MULTIPLANAR(ctx->
type)) {
425 memcpy(avbuf->
planes, planes,
sizeof(planes));
440 if (V4L2_TYPE_IS_OUTPUT(ctx->
type)) {
455 struct v4l2_requestbuffers req = {
456 .memory = V4L2_MEMORY_MMAP,
466 struct V4L2Plane_info *p = &buffer->
plane_info[j];
467 if (p->mm_addr && p->length)
468 if (munmap(p->mm_addr, p->length) < 0)
478 struct v4l2_format *fmt = &ctx->
format;
486 if (V4L2_TYPE_IS_MULTIPLANAR(ctx->
type))
487 fmt->fmt.pix_mp.pixelformat =
v4l2_fmt;
489 fmt->fmt.pix.pixelformat =
v4l2_fmt;
491 fmt->type = ctx->
type;
503 struct v4l2_fmtdesc fdesc;
506 memset(&fdesc, 0,
sizeof(fdesc));
507 fdesc.type = ctx->
type;
516 ret = ioctl(
ctx_to_m2mctx(ctx)->fd, VIDIOC_ENUM_FMT, &fdesc);
537 struct v4l2_fmtdesc fdesc;
547 memset(&fdesc, 0,
sizeof(fdesc));
548 fdesc.type = ctx->
type;
551 ret = ioctl(
ctx_to_m2mctx(ctx)->fd, VIDIOC_ENUM_FMT, &fdesc);
555 if (fdesc.pixelformat == v4l2_fmt)
581 ctx->
streamon = (cmd == VIDIOC_STREAMON);
725 struct v4l2_requestbuffers req;
733 ret = ioctl(s->
fd, VIDIOC_G_FMT, &ctx->
format);
737 memset(&req, 0,
sizeof(req));
739 req.memory = V4L2_MEMORY_MMAP;
740 req.type = ctx->
type;
741 ret = ioctl(s->
fd, VIDIOC_REQBUFS, &req);
754 for (i = 0; i < req.count; i++) {
768 V4L2_TYPE_IS_MULTIPLANAR(ctx->
type) ? ctx->
format.fmt.pix_mp.plane_fmt[0].sizeimage : ctx->
format.fmt.pix.sizeimage,
769 V4L2_TYPE_IS_MULTIPLANAR(ctx->
type) ? ctx->
format.fmt.pix_mp.plane_fmt[0].bytesperline : ctx->
format.fmt.pix.bytesperline);
enum AVPixelFormat ff_v4l2_format_v4l2_to_avfmt(uint32_t v4l2_fmt, enum AVCodecID avcodec)
static int v4l2_stop_encode(V4L2Context *ctx)
const struct AVCodec * codec
This structure describes decoded (raw) audio or video data.
const char * name
context name.
int ff_v4l2_buffer_buf_to_avpkt(AVPacket *pkt, V4L2Buffer *avbuf)
Extracts the data from a V4L2Buffer to an AVPacket.
static int v4l2_handle_event(V4L2Context *ctx)
handle resolution change event and end of stream event returns 1 if reinit was successful, negative if it failed returns 0 if reinit was not executed
#define AV_LOG_WARNING
Something somehow does not look correct.
int ff_v4l2_context_init(V4L2Context *ctx)
Initializes a V4L2Context.
int ff_v4l2_buffer_initialize(V4L2Buffer *avbuf, int index)
Initializes a V4L2Buffer.
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.
uint32_t ff_v4l2_format_avfmt_to_v4l2(enum AVPixelFormat avfmt)
int av_codec_is_decoder(const AVCodec *codec)
int width
Width and height of the frames it produces (in case of a capture context, e.g.
int ff_v4l2_buffer_avframe_to_buf(const AVFrame *frame, V4L2Buffer *out)
Extracts the data from an AVFrame to a V4L2Buffer.
static int v4l2_type_supported(V4L2Context *ctx)
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
static void error(const char *err)
int ff_v4l2_context_dequeue_packet(V4L2Context *ctx, AVPacket *pkt)
Dequeues a buffer from a V4L2Context to an AVPacket.
enum V4L2Buffer_status status
void ff_v4l2_context_release(V4L2Context *ctx)
Releases a V4L2Context.
int ff_v4l2_context_set_format(V4L2Context *ctx)
Sets the V4L2Context format in the v4l2 driver.
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 V4L2Buffer * v4l2_getfree_v4l2buf(V4L2Context *ctx)
enum AVCodecID av_codec_id
AVCodecID corresponding to this buffer context.
static unsigned int v4l2_get_width(struct v4l2_format *fmt)
static V4L2m2mContext * ctx_to_m2mctx(V4L2Context *ctx)
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
struct V4L2Buffer::V4L2Plane_info plane_info[VIDEO_MAX_PLANES]
int ff_v4l2_buffer_enqueue(V4L2Buffer *avbuf)
Enqueues a V4L2Buffer.
#define AVERROR_EOF
End of file.
static AVCodecContext * logger(V4L2Context *ctx)
int ff_v4l2_m2m_codec_reinit(V4L2m2mContext *s)
Reinitializes the V4L2m2mContext when the driver cannot continue processing with the capture paramete...
struct V4L2Context * context
int done
Either no more buffers available or an unrecoverable error was notified by the V4L2 kernel driver: on...
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
static int v4l2_get_framesize_compressed(V4L2Context *ctx, int width, int height)
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
#define av_fourcc2str(fourcc)
int ff_v4l2_buffer_buf_to_avframe(AVFrame *frame, V4L2Buffer *avbuf)
Extracts the data from a V4L2Buffer to an AVFrame.
enum AVPixelFormat av_pix_fmt
AVPixelFormat corresponding to this buffer context.
static void v4l2_save_to_context(V4L2Context *ctx, struct v4l2_format_update *fmt)
static int v4l2_release_buffers(V4L2Context *ctx)
V4L2Buffer * buffers
Indexed array of V4L2Buffers.
int streamon
Whether the stream has been started (VIDIOC_STREAMON has been sent).
static int v4l2_get_raw_format(V4L2Context *ctx, enum AVPixelFormat *p)
#define av_err2str(errnum)
Convenience macro, the return value should be used only directly in function arguments but never stan...
int ff_v4l2_context_enqueue_packet(V4L2Context *ctx, const AVPacket *pkt)
Enqueues a buffer to a V4L2Context from an AVPacket.
static int v4l2_try_raw_format(V4L2Context *ctx, enum AVPixelFormat pixfmt)
struct v4l2_plane planes[VIDEO_MAX_PLANES]
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
static int v4l2_stop_decode(V4L2Context *ctx)
struct v4l2_format format
Format returned by the driver after initializing the buffer context.
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
int ff_v4l2_context_set_status(V4L2Context *ctx, uint32_t cmd)
Sets the status of a V4L2Context.
AVRational sample_aspect_ratio
static V4L2Buffer * v4l2_dequeue_v4l2buf(V4L2Context *ctx, int timeout)
Libavcodec external API header.
main external API structure.
V4L2Buffer (wrapper for v4l2_buffer management)
static const struct @324 planes[]
int ff_v4l2_buffer_avpkt_to_buf(const AVPacket *pkt, V4L2Buffer *out)
Extracts the data from an AVPacket to a V4L2Buffer.
int ff_v4l2_context_dequeue_frame(V4L2Context *ctx, AVFrame *frame, int timeout)
Dequeues a buffer from a V4L2Context to an AVFrame.
int ff_v4l2_m2m_codec_full_reinit(V4L2m2mContext *s)
Reinitializes the V4L2m2mContext when the driver cannot continue processing with the any of the curre...
#define container_of(ptr, type, member)
Rational number (pair of numerator and denominator).
static AVRational v4l2_get_sar(V4L2Context *ctx)
static int v4l2_get_coded_format(V4L2Context *ctx, uint32_t *p)
static void reinit(Jpeg2000EncoderContext *s)
static int probe(const AVProbeData *p)
int ff_v4l2_context_enqueue_frame(V4L2Context *ctx, const AVFrame *frame)
Enqueues a buffer to a V4L2Context from an AVFrame.
common internal api header.
uint32_t ff_v4l2_format_avcodec_to_v4l2(enum AVCodecID avcodec)
enum AVPixelFormat pixfmt
int num_buffers
Readonly after init.
static unsigned int v4l2_resolution_changed(V4L2Context *ctx, struct v4l2_format *fmt2)
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
AVPixelFormat
Pixel format.
This structure stores compressed data.
static unsigned int v4l2_get_height(struct v4l2_format *fmt)
enum v4l2_buf_type type
Type of this buffer context.