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;
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
73 fmt1->fmt.pix.width != fmt2->fmt.pix.width ||
74 fmt1->fmt.pix.height != fmt2->fmt.pix.height;
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;
96 const int SZ_4K = 0x1000;
100 return ((width * height * 3 / 2) / 2) + 128;
114 if (V4L2_TYPE_IS_MULTIPLANAR(ctx->
type)) {
122 ctx->
format.fmt.pix_mp.plane_fmt[0].sizeimage =
132 ctx->
format.fmt.pix.sizeimage =
147 struct v4l2_event evt = { 0 };
148 int full_reinit,
reinit, ret;
150 ret = ioctl(s->
fd, VIDIOC_DQEVENT, &evt);
156 if (evt.type != V4L2_EVENT_SOURCE_CHANGE)
159 ret = ioctl(s->
fd, VIDIOC_G_FMT, &out_fmt);
165 ret = ioctl(s->
fd, VIDIOC_G_FMT, &cap_fmt);
183 if (full_reinit || reinit)
218 struct v4l2_decoder_cmd cmd = {
219 .cmd = V4L2_DEC_CMD_STOP,
224 ret = ioctl(
ctx_to_m2mctx(ctx)->fd, VIDIOC_DECODER_CMD, &cmd);
236 struct v4l2_encoder_cmd cmd = {
237 .cmd = V4L2_ENC_CMD_STOP,
242 ret = ioctl(
ctx_to_m2mctx(ctx)->fd, VIDIOC_ENCODER_CMD, &cmd);
254 struct v4l2_plane planes[VIDEO_MAX_PLANES];
255 struct v4l2_buffer buf = { 0 };
257 struct pollfd pfd = {
258 .events = POLLIN | POLLRDNORM | POLLPRI | POLLOUT | POLLWRNORM,
274 if (V4L2_TYPE_IS_OUTPUT(ctx->
type))
275 pfd.events = POLLOUT | POLLWRNORM;
279 pfd.events = POLLIN | POLLRDNORM | POLLPRI;
283 ret = poll(&pfd, 1, timeout);
292 if (pfd.revents & POLLERR) {
308 if (pfd.revents & POLLPRI) {
324 if (pfd.revents & (POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM)) {
326 if (!V4L2_TYPE_IS_OUTPUT(ctx->
type)) {
328 if (pfd.revents & (POLLIN | POLLRDNORM))
334 if (pfd.revents & (POLLOUT | POLLWRNORM))
339 memset(&buf, 0,
sizeof(buf));
340 buf.memory = V4L2_MEMORY_MMAP;
341 buf.type = ctx->
type;
342 if (V4L2_TYPE_IS_MULTIPLANAR(ctx->
type)) {
343 memset(planes, 0,
sizeof(planes));
344 buf.length = VIDEO_MAX_PLANES;
350 if (errno != EAGAIN) {
359 avbuf = &ctx->
buffers[buf.index];
362 if (V4L2_TYPE_IS_MULTIPLANAR(ctx->
type)) {
363 memcpy(avbuf->
planes, planes,
sizeof(planes));
378 if (V4L2_TYPE_IS_OUTPUT(ctx->
type)) {
393 struct v4l2_requestbuffers req = {
394 .memory = V4L2_MEMORY_MMAP,
404 struct V4L2Plane_info *p = &buffer->
plane_info[j];
405 if (p->mm_addr && p->length)
406 if (munmap(p->mm_addr, p->length) < 0)
424 if (V4L2_TYPE_IS_MULTIPLANAR(ctx->
type))
425 fmt->fmt.pix_mp.pixelformat = v4l2_fmt;
427 fmt->fmt.pix.pixelformat = v4l2_fmt;
429 fmt->type = ctx->
type;
441 struct v4l2_fmtdesc fdesc;
444 memset(&fdesc, 0,
sizeof(fdesc));
445 fdesc.type = ctx->
type;
454 ret = ioctl(
ctx_to_m2mctx(ctx)->fd, VIDIOC_ENUM_FMT, &fdesc);
475 struct v4l2_fmtdesc fdesc;
485 memset(&fdesc, 0,
sizeof(fdesc));
486 fdesc.type = ctx->
type;
489 ret = ioctl(
ctx_to_m2mctx(ctx)->fd, VIDIOC_ENUM_FMT, &fdesc);
493 if (fdesc.pixelformat == v4l2_fmt)
519 ctx->
streamon = (cmd == VIDIOC_STREAMON);
664 struct v4l2_requestbuffers req;
672 ret = ioctl(s->
fd, VIDIOC_G_FMT, &ctx->
format);
676 memset(&req, 0,
sizeof(req));
678 req.memory = V4L2_MEMORY_MMAP;
679 req.type = ctx->
type;
680 ret = ioctl(s->
fd, VIDIOC_REQBUFS, &req);
691 for (i = 0; i < req.count; i++) {
706 V4L2_TYPE_IS_MULTIPLANAR(ctx->
type) ? ctx->
format.fmt.pix_mp.plane_fmt[0].sizeimage : ctx->
format.fmt.pix.sizeimage,
707 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)
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 ff_v4l2_context_dequeue_frame(V4L2Context *ctx, AVFrame *frame)
Dequeues a buffer from a V4L2Context to an AVFrame.
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...
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.
static V4L2Buffer * v4l2_getfree_v4l2buf(V4L2Context *ctx)
int av_codec_is_decoder(const AVCodec *codec)
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)
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 cant continue processing with the capture parameters...
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]
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.
static V4L2Buffer * v4l2_dequeue_v4l2buf(V4L2Context *ctx, int timeout)
Libavcodec external API header.
main external API structure.
V4L2Buffer (wrapper for v4l2_buffer management)
int ff_v4l2_buffer_avpkt_to_buf(const AVPacket *pkt, V4L2Buffer *out)
Extracts the data from an AVPacket to a V4L2Buffer.
int ff_v4l2_m2m_codec_full_reinit(V4L2m2mContext *s)
Reinitializes the V4L2m2mContext when the driver cant continue processing with the any of the current...
#define container_of(ptr, type, member)
static int v4l2_get_coded_format(V4L2Context *ctx, uint32_t *p)
static void reinit(Jpeg2000EncoderContext *s)
int ff_v4l2_context_enqueue_frame(V4L2Context *ctx, const AVFrame *frame)
Enqueues a buffer to a V4L2Context from an AVFrame.
common internal api header.
static const struct @272 planes[]
uint32_t ff_v4l2_format_avcodec_to_v4l2(enum AVCodecID avcodec)
int ff_v4l2_context_get_format(V4L2Context *ctx)
Queries the driver for a valid v4l2 format and copies it to the context.
enum AVPixelFormat pixfmt
int num_buffers
Readonly after init.
static unsigned int v4l2_resolution_changed(V4L2Context *ctx, struct v4l2_format *fmt2)
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.