1 // SPDX-License-Identifier: GPL-2.0
4 * A v4l2-mem2mem device that wraps the video codec MMAL component.
6 * Copyright 2018 Raspberry Pi (Trading) Ltd.
7 * Author: Dave Stevenson (dave.stevenson@raspberrypi.org)
9 * Loosely based on the vim2m virtual driver by Pawel Osciak
10 * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
11 * Pawel Osciak, <pawel@osciak.com>
12 * Marek Szyprowski, <m.szyprowski@samsung.com>
14 * Whilst this driver uses the v4l2_mem2mem framework, it does not need the
15 * scheduling aspects, so will always take the buffers, pass them to the VPU,
16 * and then signal the job as complete.
18 * This program is free software; you can redistribute it and/or modify
19 * it under the terms of the GNU General Public License as published by the
20 * Free Software Foundation; either version 2 of the
21 * License, or (at your option) any later version
23 #include <linux/module.h>
24 #include <linux/delay.h>
26 #include <linux/timer.h>
27 #include <linux/sched.h>
28 #include <linux/slab.h>
29 #include <linux/platform_device.h>
30 #include <linux/syscalls.h>
32 #include <media/v4l2-mem2mem.h>
33 #include <media/v4l2-device.h>
34 #include <media/v4l2-ioctl.h>
35 #include <media/v4l2-ctrls.h>
36 #include <media/v4l2-event.h>
37 #include <media/videobuf2-dma-contig.h>
39 #include "vchiq-mmal/mmal-encodings.h"
40 #include "vchiq-mmal/mmal-msg.h"
41 #include "vchiq-mmal/mmal-parameters.h"
42 #include "vchiq-mmal/mmal-vchiq.h"
45 * Default /dev/videoN node numbers for decode and encode.
46 * Deliberately avoid the very low numbers as these are often taken by webcams
47 * etc, and simple apps tend to only go for /dev/video0.
49 static int decode_video_nr = 10;
50 module_param(decode_video_nr, int, 0644);
51 MODULE_PARM_DESC(decode_video_nr, "decoder video device number");
53 static int encode_video_nr = 11;
54 module_param(encode_video_nr, int, 0644);
55 MODULE_PARM_DESC(encode_video_nr, "encoder video device number");
57 static int isp_video_nr = 12;
58 module_param(isp_video_nr, int, 0644);
59 MODULE_PARM_DESC(isp_video_nr, "isp video device number");
62 * Workaround for GStreamer v4l2convert component not considering Bayer formats
63 * as raw, and therefore not considering a V4L2 device that supports them as
64 * as a suitable candidate.
66 static bool disable_bayer;
67 module_param(disable_bayer, bool, 0644);
68 MODULE_PARM_DESC(disable_bayer, "Disable support for Bayer formats");
70 static unsigned int debug;
71 module_param(debug, uint, 0644);
72 MODULE_PARM_DESC(debug, "activates debug info (0-3)");
74 enum bcm2835_codec_role {
80 static const char * const roles[] = {
86 static const char * const components[] = {
97 #define DEFAULT_WIDTH 640
98 #define DEFAULT_HEIGHT 480
100 * The unanswered question - what is the maximum size of a compressed frame?
101 * V4L2 mandates that the encoded frame must fit in a single buffer. Sizing
102 * that buffer is a compromise between wasting memory and risking not fitting.
103 * The 1080P version of Big Buck Bunny has some frames that exceed 512kB.
104 * Adopt a moderately arbitrary split at 720P for switching between 512 and
107 #define DEF_COMP_BUF_SIZE_GREATER_720P (768 << 10)
108 #define DEF_COMP_BUF_SIZE_720P_OR_LESS (512 << 10)
110 /* Flags that indicate a format can be used for capture/output */
111 #define MEM2MEM_CAPTURE BIT(0)
112 #define MEM2MEM_OUTPUT BIT(1)
114 #define MEM2MEM_NAME "bcm2835-codec"
116 struct bcm2835_codec_fmt {
119 int bytesperline_align;
122 int size_multiplier_x2;
126 static const struct bcm2835_codec_fmt supported_formats[] = {
129 .fourcc = V4L2_PIX_FMT_YUV420,
131 .bytesperline_align = 32,
133 .mmal_fmt = MMAL_ENCODING_I420,
134 .size_multiplier_x2 = 3,
136 .fourcc = V4L2_PIX_FMT_YVU420,
138 .bytesperline_align = 32,
140 .mmal_fmt = MMAL_ENCODING_YV12,
141 .size_multiplier_x2 = 3,
143 .fourcc = V4L2_PIX_FMT_NV12,
145 .bytesperline_align = 32,
147 .mmal_fmt = MMAL_ENCODING_NV12,
148 .size_multiplier_x2 = 3,
150 .fourcc = V4L2_PIX_FMT_NV21,
152 .bytesperline_align = 32,
154 .mmal_fmt = MMAL_ENCODING_NV21,
155 .size_multiplier_x2 = 3,
157 .fourcc = V4L2_PIX_FMT_RGB565,
159 .bytesperline_align = 32,
161 .mmal_fmt = MMAL_ENCODING_RGB16,
162 .size_multiplier_x2 = 2,
164 .fourcc = V4L2_PIX_FMT_YUYV,
166 .bytesperline_align = 32,
168 .mmal_fmt = MMAL_ENCODING_YUYV,
169 .size_multiplier_x2 = 2,
171 .fourcc = V4L2_PIX_FMT_UYVY,
173 .bytesperline_align = 32,
175 .mmal_fmt = MMAL_ENCODING_UYVY,
176 .size_multiplier_x2 = 2,
178 .fourcc = V4L2_PIX_FMT_YVYU,
180 .bytesperline_align = 32,
182 .mmal_fmt = MMAL_ENCODING_YVYU,
183 .size_multiplier_x2 = 2,
185 .fourcc = V4L2_PIX_FMT_VYUY,
187 .bytesperline_align = 32,
189 .mmal_fmt = MMAL_ENCODING_VYUY,
190 .size_multiplier_x2 = 2,
193 .fourcc = V4L2_PIX_FMT_RGB24,
195 .bytesperline_align = 32,
197 .mmal_fmt = MMAL_ENCODING_RGB24,
198 .size_multiplier_x2 = 2,
200 .fourcc = V4L2_PIX_FMT_BGR24,
202 .bytesperline_align = 32,
204 .mmal_fmt = MMAL_ENCODING_BGR24,
205 .size_multiplier_x2 = 2,
207 .fourcc = V4L2_PIX_FMT_BGR32,
209 .bytesperline_align = 32,
211 .mmal_fmt = MMAL_ENCODING_BGRA,
212 .size_multiplier_x2 = 2,
216 .fourcc = V4L2_PIX_FMT_SRGGB8,
218 .bytesperline_align = 32,
220 .mmal_fmt = MMAL_ENCODING_BAYER_SRGGB8,
221 .size_multiplier_x2 = 2,
224 .fourcc = V4L2_PIX_FMT_SBGGR8,
226 .bytesperline_align = 32,
228 .mmal_fmt = MMAL_ENCODING_BAYER_SBGGR8,
229 .size_multiplier_x2 = 2,
232 .fourcc = V4L2_PIX_FMT_SGRBG8,
234 .bytesperline_align = 32,
236 .mmal_fmt = MMAL_ENCODING_BAYER_SGRBG8,
237 .size_multiplier_x2 = 2,
240 .fourcc = V4L2_PIX_FMT_SGBRG8,
242 .bytesperline_align = 32,
244 .mmal_fmt = MMAL_ENCODING_BAYER_SGBRG8,
245 .size_multiplier_x2 = 2,
249 .fourcc = V4L2_PIX_FMT_SRGGB10P,
251 .bytesperline_align = 32,
253 .mmal_fmt = MMAL_ENCODING_BAYER_SRGGB10P,
254 .size_multiplier_x2 = 2,
257 .fourcc = V4L2_PIX_FMT_SBGGR10P,
259 .bytesperline_align = 32,
261 .mmal_fmt = MMAL_ENCODING_BAYER_SBGGR10P,
262 .size_multiplier_x2 = 2,
265 .fourcc = V4L2_PIX_FMT_SGRBG10P,
267 .bytesperline_align = 32,
269 .mmal_fmt = MMAL_ENCODING_BAYER_SGRBG10P,
270 .size_multiplier_x2 = 2,
273 .fourcc = V4L2_PIX_FMT_SGBRG10P,
275 .bytesperline_align = 32,
277 .mmal_fmt = MMAL_ENCODING_BAYER_SGBRG10P,
278 .size_multiplier_x2 = 2,
282 .fourcc = V4L2_PIX_FMT_SRGGB12P,
284 .bytesperline_align = 32,
286 .mmal_fmt = MMAL_ENCODING_BAYER_SRGGB12P,
287 .size_multiplier_x2 = 2,
290 .fourcc = V4L2_PIX_FMT_SBGGR12P,
292 .bytesperline_align = 32,
294 .mmal_fmt = MMAL_ENCODING_BAYER_SBGGR12P,
295 .size_multiplier_x2 = 2,
298 .fourcc = V4L2_PIX_FMT_SGRBG12P,
300 .bytesperline_align = 32,
302 .mmal_fmt = MMAL_ENCODING_BAYER_SGRBG12P,
303 .size_multiplier_x2 = 2,
306 .fourcc = V4L2_PIX_FMT_SGBRG12P,
308 .bytesperline_align = 32,
310 .mmal_fmt = MMAL_ENCODING_BAYER_SGBRG12P,
311 .size_multiplier_x2 = 2,
315 .fourcc = V4L2_PIX_FMT_SRGGB14P,
317 .bytesperline_align = 32,
319 .mmal_fmt = MMAL_ENCODING_BAYER_SRGGB14P,
320 .size_multiplier_x2 = 2,
323 .fourcc = V4L2_PIX_FMT_SBGGR14P,
325 .bytesperline_align = 32,
327 .mmal_fmt = MMAL_ENCODING_BAYER_SBGGR14P,
328 .size_multiplier_x2 = 2,
332 .fourcc = V4L2_PIX_FMT_SGRBG14P,
334 .bytesperline_align = 32,
336 .mmal_fmt = MMAL_ENCODING_BAYER_SGRBG14P,
337 .size_multiplier_x2 = 2,
340 .fourcc = V4L2_PIX_FMT_SGBRG14P,
342 .bytesperline_align = 32,
344 .mmal_fmt = MMAL_ENCODING_BAYER_SGBRG14P,
345 .size_multiplier_x2 = 2,
349 .fourcc = V4L2_PIX_FMT_SRGGB16,
351 .bytesperline_align = 32,
353 .mmal_fmt = MMAL_ENCODING_BAYER_SRGGB16,
354 .size_multiplier_x2 = 2,
357 .fourcc = V4L2_PIX_FMT_SBGGR16,
359 .bytesperline_align = 32,
361 .mmal_fmt = MMAL_ENCODING_BAYER_SBGGR16,
362 .size_multiplier_x2 = 2,
365 .fourcc = V4L2_PIX_FMT_SGRBG16,
367 .bytesperline_align = 32,
369 .mmal_fmt = MMAL_ENCODING_BAYER_SGRBG16,
370 .size_multiplier_x2 = 2,
373 .fourcc = V4L2_PIX_FMT_SGBRG16,
375 .bytesperline_align = 32,
377 .mmal_fmt = MMAL_ENCODING_BAYER_SGBRG16,
378 .size_multiplier_x2 = 2,
381 /* Monochrome MIPI formats */
383 .fourcc = V4L2_PIX_FMT_GREY,
385 .bytesperline_align = 32,
387 .mmal_fmt = MMAL_ENCODING_GREY,
388 .size_multiplier_x2 = 2,
391 .fourcc = V4L2_PIX_FMT_Y10P,
393 .bytesperline_align = 32,
395 .mmal_fmt = MMAL_ENCODING_Y10P,
396 .size_multiplier_x2 = 2,
399 .fourcc = V4L2_PIX_FMT_Y12P,
401 .bytesperline_align = 32,
403 .mmal_fmt = MMAL_ENCODING_Y12P,
404 .size_multiplier_x2 = 2,
407 .fourcc = V4L2_PIX_FMT_Y14P,
409 .bytesperline_align = 32,
411 .mmal_fmt = MMAL_ENCODING_Y14P,
412 .size_multiplier_x2 = 2,
415 .fourcc = V4L2_PIX_FMT_Y16,
417 .bytesperline_align = 32,
419 .mmal_fmt = MMAL_ENCODING_Y16,
420 .size_multiplier_x2 = 2,
422 /* Compressed formats */
423 .fourcc = V4L2_PIX_FMT_H264,
425 .flags = V4L2_FMT_FLAG_COMPRESSED,
426 .mmal_fmt = MMAL_ENCODING_H264,
428 .fourcc = V4L2_PIX_FMT_MJPEG,
430 .flags = V4L2_FMT_FLAG_COMPRESSED,
431 .mmal_fmt = MMAL_ENCODING_MJPEG,
433 .fourcc = V4L2_PIX_FMT_MPEG4,
435 .flags = V4L2_FMT_FLAG_COMPRESSED,
436 .mmal_fmt = MMAL_ENCODING_MP4V,
438 .fourcc = V4L2_PIX_FMT_H263,
440 .flags = V4L2_FMT_FLAG_COMPRESSED,
441 .mmal_fmt = MMAL_ENCODING_H263,
443 .fourcc = V4L2_PIX_FMT_MPEG2,
445 .flags = V4L2_FMT_FLAG_COMPRESSED,
446 .mmal_fmt = MMAL_ENCODING_MP2V,
448 .fourcc = V4L2_PIX_FMT_VP8,
450 .flags = V4L2_FMT_FLAG_COMPRESSED,
451 .mmal_fmt = MMAL_ENCODING_VP8,
455 struct bcm2835_codec_fmt_list {
456 struct bcm2835_codec_fmt *list;
457 unsigned int num_entries;
460 struct m2m_mmal_buffer {
461 struct v4l2_m2m_buffer m2m;
462 struct mmal_buffer mmal;
465 /* Per-queue, driver-specific private data */
466 struct bcm2835_codec_q_data {
468 * These parameters should be treated as gospel, with everything else
469 * being determined from them.
471 /* Buffer width/height */
472 unsigned int bytesperline;
474 /* Crop size used for selection handling */
475 unsigned int crop_width;
476 unsigned int crop_height;
479 unsigned int sizeimage;
480 unsigned int sequence;
481 struct bcm2835_codec_fmt *fmt;
483 /* One extra buffer header so we can send an EOS. */
484 struct m2m_mmal_buffer eos_buffer;
485 bool eos_buffer_in_use; /* debug only */
488 struct bcm2835_codec_dev {
489 struct platform_device *pdev;
492 struct v4l2_device v4l2_dev;
493 struct video_device vfd;
494 /* mutex for the v4l2 device */
495 struct mutex dev_mutex;
498 /* allocated mmal instance and components */
499 enum bcm2835_codec_role role;
500 /* The list of formats supported on input and output queues. */
501 struct bcm2835_codec_fmt_list supported_fmts[2];
503 struct vchiq_mmal_instance *instance;
505 struct v4l2_m2m_dev *m2m_dev;
508 struct bcm2835_codec_ctx {
510 struct bcm2835_codec_dev *dev;
512 struct v4l2_ctrl_handler hdl;
514 struct vchiq_mmal_component *component;
515 bool component_enabled;
517 enum v4l2_colorspace colorspace;
518 enum v4l2_ycbcr_encoding ycbcr_enc;
519 enum v4l2_xfer_func xfer_func;
520 enum v4l2_quantization quant;
522 /* Source and destination queue data */
523 struct bcm2835_codec_q_data q_data[2];
525 unsigned int framerate_num;
526 unsigned int framerate_denom;
531 struct completion frame_cmplt;
534 struct bcm2835_codec_driver {
535 struct platform_device *pdev;
536 struct media_device mdev;
538 struct bcm2835_codec_dev *encode;
539 struct bcm2835_codec_dev *decode;
540 struct bcm2835_codec_dev *isp;
548 static const struct bcm2835_codec_fmt *get_fmt(u32 mmal_fmt)
552 for (i = 0; i < ARRAY_SIZE(supported_formats); i++) {
553 if (supported_formats[i].mmal_fmt == mmal_fmt &&
554 (!disable_bayer || !supported_formats[i].is_bayer))
555 return &supported_formats[i];
561 struct bcm2835_codec_fmt_list *get_format_list(struct bcm2835_codec_dev *dev,
564 return &dev->supported_fmts[capture ? 1 : 0];
568 struct bcm2835_codec_fmt *get_default_format(struct bcm2835_codec_dev *dev,
571 return &dev->supported_fmts[capture ? 1 : 0].list[0];
575 struct bcm2835_codec_fmt *find_format_pix_fmt(u32 pix_fmt,
576 struct bcm2835_codec_dev *dev,
579 struct bcm2835_codec_fmt *fmt;
581 struct bcm2835_codec_fmt_list *fmts =
582 &dev->supported_fmts[capture ? 1 : 0];
584 for (k = 0; k < fmts->num_entries; k++) {
585 fmt = &fmts->list[k];
586 if (fmt->fourcc == pix_fmt)
589 if (k == fmts->num_entries)
592 return &fmts->list[k];
596 struct bcm2835_codec_fmt *find_format(struct v4l2_format *f,
597 struct bcm2835_codec_dev *dev,
600 return find_format_pix_fmt(f->fmt.pix_mp.pixelformat, dev, capture);
603 static inline struct bcm2835_codec_ctx *file2ctx(struct file *file)
605 return container_of(file->private_data, struct bcm2835_codec_ctx, fh);
608 static struct bcm2835_codec_q_data *get_q_data(struct bcm2835_codec_ctx *ctx,
609 enum v4l2_buf_type type)
612 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
613 return &ctx->q_data[V4L2_M2M_SRC];
614 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
615 return &ctx->q_data[V4L2_M2M_DST];
617 v4l2_err(&ctx->dev->v4l2_dev, "%s: Invalid queue type %u\n",
624 static struct vchiq_mmal_port *get_port_data(struct bcm2835_codec_ctx *ctx,
625 enum v4l2_buf_type type)
631 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
632 return &ctx->component->input[0];
633 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
634 return &ctx->component->output[0];
636 v4l2_err(&ctx->dev->v4l2_dev, "%s: Invalid queue type %u\n",
648 * job_ready() - check whether an instance is ready to be scheduled to run
650 static int job_ready(void *priv)
652 struct bcm2835_codec_ctx *ctx = priv;
654 if (!v4l2_m2m_num_src_bufs_ready(ctx->fh.m2m_ctx) &&
655 !v4l2_m2m_num_dst_bufs_ready(ctx->fh.m2m_ctx))
661 static void job_abort(void *priv)
663 struct bcm2835_codec_ctx *ctx = priv;
665 v4l2_dbg(1, debug, &ctx->dev->v4l2_dev, "%s\n", __func__);
666 /* Will cancel the transaction in the next interrupt handler */
670 static inline unsigned int get_sizeimage(int bpl, int width, int height,
671 struct bcm2835_codec_fmt *fmt)
673 if (fmt->flags & V4L2_FMT_FLAG_COMPRESSED) {
674 if (width * height > 1280 * 720)
675 return DEF_COMP_BUF_SIZE_GREATER_720P;
677 return DEF_COMP_BUF_SIZE_720P_OR_LESS;
679 return (bpl * height * fmt->size_multiplier_x2) >> 1;
683 static inline unsigned int get_bytesperline(int width,
684 struct bcm2835_codec_fmt *fmt)
686 return ALIGN((width * fmt->depth) >> 3, fmt->bytesperline_align);
689 static void setup_mmal_port_format(struct bcm2835_codec_ctx *ctx,
690 struct bcm2835_codec_q_data *q_data,
691 struct vchiq_mmal_port *port)
693 port->format.encoding = q_data->fmt->mmal_fmt;
695 if (!(q_data->fmt->flags & V4L2_FMT_FLAG_COMPRESSED)) {
696 /* Raw image format - set width/height */
697 port->es.video.width = (q_data->bytesperline << 3) /
699 port->es.video.height = q_data->height;
700 port->es.video.crop.width = q_data->crop_width;
701 port->es.video.crop.height = q_data->crop_height;
702 port->es.video.frame_rate.num = ctx->framerate_num;
703 port->es.video.frame_rate.den = ctx->framerate_denom;
705 /* Compressed format - leave resolution as 0 for decode */
706 if (ctx->dev->role == DECODE) {
707 port->es.video.width = 0;
708 port->es.video.height = 0;
709 port->es.video.crop.width = 0;
710 port->es.video.crop.height = 0;
712 port->es.video.width = q_data->crop_width;
713 port->es.video.height = q_data->height;
714 port->es.video.crop.width = q_data->crop_width;
715 port->es.video.crop.height = q_data->crop_height;
716 port->format.bitrate = ctx->bitrate;
717 port->es.video.frame_rate.num = ctx->framerate_num;
718 port->es.video.frame_rate.den = ctx->framerate_denom;
721 port->es.video.crop.x = 0;
722 port->es.video.crop.y = 0;
724 port->current_buffer.size = q_data->sizeimage;
727 static void ip_buffer_cb(struct vchiq_mmal_instance *instance,
728 struct vchiq_mmal_port *port, int status,
729 struct mmal_buffer *mmal_buf)
731 struct bcm2835_codec_ctx *ctx = port->cb_ctx/*, *curr_ctx*/;
732 struct m2m_mmal_buffer *buf =
733 container_of(mmal_buf, struct m2m_mmal_buffer, mmal);
735 v4l2_dbg(2, debug, &ctx->dev->v4l2_dev, "%s: port %p buf %p length %lu, flags %x\n",
736 __func__, port, mmal_buf, mmal_buf->length,
737 mmal_buf->mmal_flags);
739 if (buf == &ctx->q_data[V4L2_M2M_SRC].eos_buffer) {
740 /* Do we need to add lcoking to prevent multiple submission of
741 * the EOS, and therefore handle mutliple return here?
743 v4l2_dbg(1, debug, &ctx->dev->v4l2_dev, "%s: eos buffer returned.\n",
745 ctx->q_data[V4L2_M2M_SRC].eos_buffer_in_use = false;
750 /* error in transfer */
752 /* there was a buffer with the error so return it */
753 vb2_buffer_done(&buf->m2m.vb.vb2_buf,
754 VB2_BUF_STATE_ERROR);
758 v4l2_err(&ctx->dev->v4l2_dev, "%s: Not expecting cmd msgs on ip callback - %08x\n",
759 __func__, mmal_buf->cmd);
761 * CHECKME: Should we return here. The buffer shouldn't have a
762 * message context or vb2 buf associated.
766 v4l2_dbg(3, debug, &ctx->dev->v4l2_dev, "%s: no error. Return buffer %p\n",
767 __func__, &buf->m2m.vb.vb2_buf);
768 vb2_buffer_done(&buf->m2m.vb.vb2_buf, VB2_BUF_STATE_DONE);
770 ctx->num_ip_buffers++;
771 v4l2_dbg(2, debug, &ctx->dev->v4l2_dev, "%s: done %d input buffers\n",
772 __func__, ctx->num_ip_buffers);
775 complete(&ctx->frame_cmplt);
778 static void queue_res_chg_event(struct bcm2835_codec_ctx *ctx)
780 static const struct v4l2_event ev_src_ch = {
781 .type = V4L2_EVENT_SOURCE_CHANGE,
782 .u.src_change.changes =
783 V4L2_EVENT_SRC_CH_RESOLUTION,
786 v4l2_event_queue_fh(&ctx->fh, &ev_src_ch);
789 static void send_eos_event(struct bcm2835_codec_ctx *ctx)
791 static const struct v4l2_event ev = {
792 .type = V4L2_EVENT_EOS,
795 v4l2_dbg(1, debug, &ctx->dev->v4l2_dev, "Sending EOS event\n");
797 v4l2_event_queue_fh(&ctx->fh, &ev);
800 static void color_mmal2v4l(struct bcm2835_codec_ctx *ctx, u32 mmal_color_space)
802 switch (mmal_color_space) {
803 case MMAL_COLOR_SPACE_ITUR_BT601:
804 ctx->colorspace = V4L2_COLORSPACE_REC709;
805 ctx->xfer_func = V4L2_XFER_FUNC_709;
806 ctx->ycbcr_enc = V4L2_YCBCR_ENC_601;
807 ctx->quant = V4L2_QUANTIZATION_LIM_RANGE;
810 case MMAL_COLOR_SPACE_ITUR_BT709:
811 ctx->colorspace = V4L2_COLORSPACE_REC709;
812 ctx->xfer_func = V4L2_XFER_FUNC_709;
813 ctx->ycbcr_enc = V4L2_YCBCR_ENC_709;
814 ctx->quant = V4L2_QUANTIZATION_LIM_RANGE;
819 static void handle_fmt_changed(struct bcm2835_codec_ctx *ctx,
820 struct mmal_buffer *mmal_buf)
822 struct bcm2835_codec_q_data *q_data;
823 struct mmal_msg_event_format_changed *format =
824 (struct mmal_msg_event_format_changed *)mmal_buf->buffer;
825 v4l2_dbg(1, debug, &ctx->dev->v4l2_dev, "%s: Format changed: buff size min %u, rec %u, buff num min %u, rec %u\n",
827 format->buffer_size_min,
828 format->buffer_size_recommended,
829 format->buffer_num_min,
830 format->buffer_num_recommended
832 if (format->format.type != MMAL_ES_TYPE_VIDEO) {
833 v4l2_dbg(1, debug, &ctx->dev->v4l2_dev, "%s: Format changed but not video %u\n",
834 __func__, format->format.type);
837 v4l2_dbg(1, debug, &ctx->dev->v4l2_dev, "%s: Format changed to %ux%u, crop %ux%u, colourspace %08X\n",
838 __func__, format->es.video.width, format->es.video.height,
839 format->es.video.crop.width, format->es.video.crop.height,
840 format->es.video.color_space);
842 q_data = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
843 v4l2_dbg(1, debug, &ctx->dev->v4l2_dev, "%s: Format was %ux%u, crop %ux%u\n",
844 __func__, q_data->bytesperline, q_data->height,
845 q_data->crop_width, q_data->crop_height);
847 q_data->crop_width = format->es.video.crop.width;
848 q_data->crop_height = format->es.video.crop.height;
849 q_data->bytesperline = get_bytesperline(format->es.video.width,
852 q_data->height = format->es.video.height;
853 q_data->sizeimage = format->buffer_size_min;
854 if (format->es.video.color_space)
855 color_mmal2v4l(ctx, format->es.video.color_space);
857 queue_res_chg_event(ctx);
860 static void op_buffer_cb(struct vchiq_mmal_instance *instance,
861 struct vchiq_mmal_port *port, int status,
862 struct mmal_buffer *mmal_buf)
864 struct bcm2835_codec_ctx *ctx = port->cb_ctx;
865 struct m2m_mmal_buffer *buf;
866 struct vb2_v4l2_buffer *vb2;
868 v4l2_dbg(2, debug, &ctx->dev->v4l2_dev,
869 "%s: status:%d, buf:%p, length:%lu, flags %u, pts %lld\n",
870 __func__, status, mmal_buf, mmal_buf->length,
871 mmal_buf->mmal_flags, mmal_buf->pts);
873 buf = container_of(mmal_buf, struct m2m_mmal_buffer, mmal);
877 /* error in transfer */
879 /* there was a buffer with the error so return it */
880 vb2_buffer_done(&vb2->vb2_buf, VB2_BUF_STATE_ERROR);
886 switch (mmal_buf->cmd) {
887 case MMAL_EVENT_FORMAT_CHANGED:
889 handle_fmt_changed(ctx, mmal_buf);
893 v4l2_err(&ctx->dev->v4l2_dev, "%s: Unexpected event on output callback - %08x\n",
894 __func__, mmal_buf->cmd);
900 v4l2_dbg(3, debug, &ctx->dev->v4l2_dev, "%s: length %lu, flags %x, idx %u\n",
901 __func__, mmal_buf->length, mmal_buf->mmal_flags,
904 if (mmal_buf->length == 0) {
905 /* stream ended, or buffer being returned during disable. */
906 v4l2_dbg(2, debug, &ctx->dev->v4l2_dev, "%s: Empty buffer - flags %04x",
907 __func__, mmal_buf->mmal_flags);
908 if (!mmal_buf->mmal_flags & MMAL_BUFFER_HEADER_FLAG_EOS) {
909 vb2_buffer_done(&vb2->vb2_buf, VB2_BUF_STATE_ERROR);
911 complete(&ctx->frame_cmplt);
915 if (mmal_buf->mmal_flags & MMAL_BUFFER_HEADER_FLAG_EOS) {
916 /* EOS packet from the VPU */
918 vb2->flags |= V4L2_BUF_FLAG_LAST;
921 /* vb2 timestamps in nsecs, mmal in usecs */
922 vb2->vb2_buf.timestamp = mmal_buf->pts * 1000;
924 vb2_set_plane_payload(&vb2->vb2_buf, 0, mmal_buf->length);
925 if (mmal_buf->mmal_flags & MMAL_BUFFER_HEADER_FLAG_KEYFRAME)
926 vb2->flags |= V4L2_BUF_FLAG_KEYFRAME;
928 vb2_buffer_done(&vb2->vb2_buf, VB2_BUF_STATE_DONE);
929 ctx->num_op_buffers++;
931 v4l2_dbg(2, debug, &ctx->dev->v4l2_dev, "%s: done %d output buffers\n",
932 __func__, ctx->num_op_buffers);
935 complete(&ctx->frame_cmplt);
938 /* vb2_to_mmal_buffer() - converts vb2 buffer header to MMAL
940 * Copies all the required fields from a VB2 buffer to the MMAL buffer header,
941 * ready for sending to the VPU.
943 static void vb2_to_mmal_buffer(struct m2m_mmal_buffer *buf,
944 struct vb2_v4l2_buffer *vb2)
947 buf->mmal.mmal_flags = 0;
948 if (vb2->flags & V4L2_BUF_FLAG_KEYFRAME)
949 buf->mmal.mmal_flags |= MMAL_BUFFER_HEADER_FLAG_KEYFRAME;
952 * Adding this means that the data must be framed correctly as one frame
953 * per buffer. The underlying decoder has no such requirement, but it
954 * will reduce latency as the bistream parser will be kicked immediately
955 * to parse the frame, rather than relying on its own heuristics for
958 buf->mmal.mmal_flags |= MMAL_BUFFER_HEADER_FLAG_FRAME_END;
960 buf->mmal.length = vb2->vb2_buf.planes[0].bytesused;
962 * Minor ambiguity in the V4L2 spec as to whether passing in a 0 length
963 * buffer, or one with V4L2_BUF_FLAG_LAST set denotes end of stream.
966 if (!buf->mmal.length || vb2->flags & V4L2_BUF_FLAG_LAST)
967 buf->mmal.mmal_flags |= MMAL_BUFFER_HEADER_FLAG_EOS;
969 /* vb2 timestamps in nsecs, mmal in usecs */
970 pts = vb2->vb2_buf.timestamp;
973 buf->mmal.dts = MMAL_TIME_UNKNOWN;
976 /* device_run() - prepares and starts the device
978 * This simulates all the immediate preparations required before starting
979 * a device. This will be called by the framework when it decides to schedule
980 * a particular instance.
982 static void device_run(void *priv)
984 struct bcm2835_codec_ctx *ctx = priv;
985 struct bcm2835_codec_dev *dev = ctx->dev;
986 struct vb2_v4l2_buffer *src_buf, *dst_buf;
987 struct m2m_mmal_buffer *src_m2m_buf = NULL, *dst_m2m_buf = NULL;
988 struct v4l2_m2m_buffer *m2m;
991 v4l2_dbg(3, debug, &ctx->dev->v4l2_dev, "%s: off we go\n", __func__);
993 src_buf = v4l2_m2m_buf_remove(&ctx->fh.m2m_ctx->out_q_ctx);
995 m2m = container_of(src_buf, struct v4l2_m2m_buffer, vb);
996 src_m2m_buf = container_of(m2m, struct m2m_mmal_buffer, m2m);
997 vb2_to_mmal_buffer(src_m2m_buf, src_buf);
999 ret = vchiq_mmal_submit_buffer(dev->instance,
1000 &ctx->component->input[0],
1001 &src_m2m_buf->mmal);
1002 v4l2_dbg(3, debug, &ctx->dev->v4l2_dev, "%s: Submitted ip buffer len %lu, pts %llu, flags %04x\n",
1003 __func__, src_m2m_buf->mmal.length,
1004 src_m2m_buf->mmal.pts, src_m2m_buf->mmal.mmal_flags);
1006 v4l2_err(&ctx->dev->v4l2_dev, "%s: Failed submitting ip buffer\n",
1010 dst_buf = v4l2_m2m_buf_remove(&ctx->fh.m2m_ctx->cap_q_ctx);
1012 m2m = container_of(dst_buf, struct v4l2_m2m_buffer, vb);
1013 dst_m2m_buf = container_of(m2m, struct m2m_mmal_buffer, m2m);
1014 vb2_to_mmal_buffer(dst_m2m_buf, dst_buf);
1016 ret = vchiq_mmal_submit_buffer(dev->instance,
1017 &ctx->component->output[0],
1018 &dst_m2m_buf->mmal);
1020 v4l2_err(&ctx->dev->v4l2_dev, "%s: Failed submitting op buffer\n",
1024 v4l2_dbg(3, debug, &ctx->dev->v4l2_dev, "%s: Submitted src %p, dst %p\n",
1025 __func__, src_m2m_buf, dst_m2m_buf);
1027 /* Complete the job here. */
1028 v4l2_m2m_job_finish(ctx->dev->m2m_dev, ctx->fh.m2m_ctx);
1034 static int vidioc_querycap(struct file *file, void *priv,
1035 struct v4l2_capability *cap)
1037 struct bcm2835_codec_dev *dev = video_drvdata(file);
1039 strncpy(cap->driver, MEM2MEM_NAME, sizeof(cap->driver) - 1);
1040 strncpy(cap->card, dev->vfd.name, sizeof(cap->card) - 1);
1041 snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s",
1046 static int enum_fmt(struct v4l2_fmtdesc *f, struct bcm2835_codec_ctx *ctx,
1049 struct bcm2835_codec_fmt *fmt;
1050 struct bcm2835_codec_fmt_list *fmts =
1051 get_format_list(ctx->dev, capture);
1053 if (f->index < fmts->num_entries) {
1055 fmt = &fmts->list[f->index];
1056 f->pixelformat = fmt->fourcc;
1057 f->flags = fmt->flags;
1061 /* Format not found */
1065 static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
1066 struct v4l2_fmtdesc *f)
1068 struct bcm2835_codec_ctx *ctx = file2ctx(file);
1070 return enum_fmt(f, ctx, true);
1073 static int vidioc_enum_fmt_vid_out(struct file *file, void *priv,
1074 struct v4l2_fmtdesc *f)
1076 struct bcm2835_codec_ctx *ctx = file2ctx(file);
1078 return enum_fmt(f, ctx, false);
1081 static int vidioc_g_fmt(struct bcm2835_codec_ctx *ctx, struct v4l2_format *f)
1083 struct vb2_queue *vq;
1084 struct bcm2835_codec_q_data *q_data;
1086 vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type);
1090 q_data = get_q_data(ctx, f->type);
1092 f->fmt.pix_mp.width = q_data->crop_width;
1093 f->fmt.pix_mp.height = q_data->height;
1094 f->fmt.pix_mp.pixelformat = q_data->fmt->fourcc;
1095 f->fmt.pix_mp.field = V4L2_FIELD_NONE;
1096 f->fmt.pix_mp.colorspace = ctx->colorspace;
1097 f->fmt.pix_mp.plane_fmt[0].sizeimage = q_data->sizeimage;
1098 f->fmt.pix_mp.plane_fmt[0].bytesperline = q_data->bytesperline;
1099 f->fmt.pix_mp.num_planes = 1;
1100 f->fmt.pix_mp.ycbcr_enc = ctx->ycbcr_enc;
1101 f->fmt.pix_mp.quantization = ctx->quant;
1102 f->fmt.pix_mp.xfer_func = ctx->xfer_func;
1104 memset(f->fmt.pix_mp.plane_fmt[0].reserved, 0,
1105 sizeof(f->fmt.pix_mp.plane_fmt[0].reserved));
1110 static int vidioc_g_fmt_vid_out(struct file *file, void *priv,
1111 struct v4l2_format *f)
1113 return vidioc_g_fmt(file2ctx(file), f);
1116 static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
1117 struct v4l2_format *f)
1119 return vidioc_g_fmt(file2ctx(file), f);
1122 static int vidioc_try_fmt(struct bcm2835_codec_ctx *ctx, struct v4l2_format *f,
1123 struct bcm2835_codec_fmt *fmt)
1126 * The V4L2 specification requires the driver to correct the format
1127 * struct if any of the dimensions is unsupported
1129 if (f->fmt.pix_mp.width > MAX_W)
1130 f->fmt.pix_mp.width = MAX_W;
1131 if (f->fmt.pix_mp.height > MAX_H)
1132 f->fmt.pix_mp.height = MAX_H;
1134 if (!fmt->flags & V4L2_FMT_FLAG_COMPRESSED) {
1135 /* Only clip min w/h on capture. Treat 0x0 as unknown. */
1136 if (f->fmt.pix_mp.width < MIN_W)
1137 f->fmt.pix_mp.width = MIN_W;
1138 if (f->fmt.pix_mp.height < MIN_H)
1139 f->fmt.pix_mp.height = MIN_H;
1142 * For decoders the buffer must have a vertical alignment of 16
1144 * The selection will reflect any cropping rectangle when only
1145 * some of the pixels are active.
1147 if (ctx->dev->role == DECODE)
1148 f->fmt.pix_mp.height = ALIGN(f->fmt.pix_mp.height, 16);
1150 f->fmt.pix_mp.num_planes = 1;
1151 f->fmt.pix_mp.plane_fmt[0].bytesperline =
1152 get_bytesperline(f->fmt.pix_mp.width, fmt);
1153 f->fmt.pix_mp.plane_fmt[0].sizeimage =
1154 get_sizeimage(f->fmt.pix_mp.plane_fmt[0].bytesperline,
1155 f->fmt.pix_mp.width, f->fmt.pix_mp.height, fmt);
1156 memset(f->fmt.pix_mp.plane_fmt[0].reserved, 0,
1157 sizeof(f->fmt.pix_mp.plane_fmt[0].reserved));
1159 f->fmt.pix_mp.field = V4L2_FIELD_NONE;
1164 static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
1165 struct v4l2_format *f)
1167 struct bcm2835_codec_fmt *fmt;
1168 struct bcm2835_codec_ctx *ctx = file2ctx(file);
1170 fmt = find_format(f, ctx->dev, true);
1172 f->fmt.pix_mp.pixelformat = get_default_format(ctx->dev,
1174 fmt = find_format(f, ctx->dev, true);
1177 return vidioc_try_fmt(ctx, f, fmt);
1180 static int vidioc_try_fmt_vid_out(struct file *file, void *priv,
1181 struct v4l2_format *f)
1183 struct bcm2835_codec_fmt *fmt;
1184 struct bcm2835_codec_ctx *ctx = file2ctx(file);
1186 fmt = find_format(f, ctx->dev, false);
1188 f->fmt.pix_mp.pixelformat = get_default_format(ctx->dev,
1190 fmt = find_format(f, ctx->dev, false);
1193 if (!f->fmt.pix_mp.colorspace)
1194 f->fmt.pix_mp.colorspace = ctx->colorspace;
1196 return vidioc_try_fmt(ctx, f, fmt);
1199 static int vidioc_s_fmt(struct bcm2835_codec_ctx *ctx, struct v4l2_format *f,
1200 unsigned int requested_height)
1202 struct bcm2835_codec_q_data *q_data;
1203 struct vb2_queue *vq;
1204 struct vchiq_mmal_port *port;
1205 bool update_capture_port = false;
1208 v4l2_dbg(1, debug, &ctx->dev->v4l2_dev, "Setting format for type %d, wxh: %dx%d, fmt: " V4L2_FOURCC_CONV ", size %u\n",
1209 f->type, f->fmt.pix_mp.width, f->fmt.pix_mp.height,
1210 V4L2_FOURCC_CONV_ARGS(f->fmt.pix_mp.pixelformat),
1211 f->fmt.pix_mp.plane_fmt[0].sizeimage);
1213 vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type);
1217 q_data = get_q_data(ctx, f->type);
1221 if (vb2_is_busy(vq)) {
1222 v4l2_err(&ctx->dev->v4l2_dev, "%s queue busy\n", __func__);
1226 q_data->fmt = find_format(f, ctx->dev,
1227 f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
1228 q_data->crop_width = f->fmt.pix_mp.width;
1229 q_data->height = f->fmt.pix_mp.height;
1230 if (!q_data->selection_set)
1231 q_data->crop_height = requested_height;
1234 * Copying the behaviour of vicodec which retains a single set of
1235 * colorspace parameters for both input and output.
1237 ctx->colorspace = f->fmt.pix_mp.colorspace;
1238 ctx->xfer_func = f->fmt.pix_mp.xfer_func;
1239 ctx->ycbcr_enc = f->fmt.pix_mp.ycbcr_enc;
1240 ctx->quant = f->fmt.pix_mp.quantization;
1242 /* All parameters should have been set correctly by try_fmt */
1243 q_data->bytesperline = f->fmt.pix_mp.plane_fmt[0].bytesperline;
1244 q_data->sizeimage = f->fmt.pix_mp.plane_fmt[0].sizeimage;
1246 v4l2_dbg(1, debug, &ctx->dev->v4l2_dev, "Calulated bpl as %u, size %u\n",
1247 q_data->bytesperline, q_data->sizeimage);
1249 if (ctx->dev->role == DECODE &&
1250 q_data->fmt->flags & V4L2_FMT_FLAG_COMPRESSED &&
1251 q_data->crop_width && q_data->height) {
1253 * On the decoder, if provided with a resolution on the input
1254 * side, then replicate that to the output side.
1255 * GStreamer appears not to support V4L2_EVENT_SOURCE_CHANGE,
1256 * nor set up a resolution on the output side, therefore
1257 * we can't decode anything at a resolution other than the
1260 struct bcm2835_codec_q_data *q_data_dst =
1261 &ctx->q_data[V4L2_M2M_DST];
1263 q_data_dst->crop_width = q_data->crop_width;
1264 q_data_dst->crop_height = q_data->crop_height;
1265 q_data_dst->height = ALIGN(q_data->crop_height, 16);
1267 q_data_dst->bytesperline =
1268 get_bytesperline(f->fmt.pix_mp.width, q_data_dst->fmt);
1269 q_data_dst->sizeimage = get_sizeimage(q_data_dst->bytesperline,
1270 q_data_dst->crop_width,
1273 update_capture_port = true;
1276 /* If we have a component then setup the port as well */
1277 port = get_port_data(ctx, vq->type);
1281 setup_mmal_port_format(ctx, q_data, port);
1282 ret = vchiq_mmal_port_set_format(ctx->dev->instance, port);
1284 v4l2_err(&ctx->dev->v4l2_dev, "%s: Failed vchiq_mmal_port_set_format on port, ret %d\n",
1289 if (q_data->sizeimage < port->minimum_buffer.size) {
1290 v4l2_err(&ctx->dev->v4l2_dev, "%s: Current buffer size of %u < min buf size %u - driver mismatch to MMAL\n",
1291 __func__, q_data->sizeimage,
1292 port->minimum_buffer.size);
1295 v4l2_dbg(1, debug, &ctx->dev->v4l2_dev, "Set format for type %d, wxh: %dx%d, fmt: %08x, size %u\n",
1296 f->type, q_data->crop_width, q_data->height,
1297 q_data->fmt->fourcc, q_data->sizeimage);
1299 if (update_capture_port) {
1300 struct vchiq_mmal_port *port_dst = &ctx->component->output[0];
1301 struct bcm2835_codec_q_data *q_data_dst =
1302 &ctx->q_data[V4L2_M2M_DST];
1304 setup_mmal_port_format(ctx, q_data_dst, port_dst);
1305 ret = vchiq_mmal_port_set_format(ctx->dev->instance, port_dst);
1307 v4l2_err(&ctx->dev->v4l2_dev, "%s: Failed vchiq_mmal_port_set_format on output port, ret %d\n",
1315 static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
1316 struct v4l2_format *f)
1318 unsigned int height = f->fmt.pix_mp.height;
1321 ret = vidioc_try_fmt_vid_cap(file, priv, f);
1325 return vidioc_s_fmt(file2ctx(file), f, height);
1328 static int vidioc_s_fmt_vid_out(struct file *file, void *priv,
1329 struct v4l2_format *f)
1331 unsigned int height = f->fmt.pix_mp.height;
1334 ret = vidioc_try_fmt_vid_out(file, priv, f);
1338 ret = vidioc_s_fmt(file2ctx(file), f, height);
1342 static int vidioc_g_selection(struct file *file, void *priv,
1343 struct v4l2_selection *s)
1345 struct bcm2835_codec_ctx *ctx = file2ctx(file);
1346 struct bcm2835_codec_q_data *q_data;
1349 * The selection API takes V4L2_BUF_TYPE_VIDEO_CAPTURE and
1350 * V4L2_BUF_TYPE_VIDEO_OUTPUT, even if the device implements the MPLANE
1351 * API. The V4L2 core will have converted the MPLANE variants to
1353 * Open code this instead of using get_q_data in this case.
1356 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1357 /* CAPTURE on encoder is not valid. */
1358 if (ctx->dev->role == ENCODE)
1360 q_data = &ctx->q_data[V4L2_M2M_DST];
1362 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
1363 /* OUTPUT on deoder is not valid. */
1364 if (ctx->dev->role == DECODE)
1366 q_data = &ctx->q_data[V4L2_M2M_SRC];
1372 switch (ctx->dev->role) {
1374 switch (s->target) {
1375 case V4L2_SEL_TGT_COMPOSE_DEFAULT:
1376 case V4L2_SEL_TGT_COMPOSE:
1379 s->r.width = q_data->crop_width;
1380 s->r.height = q_data->crop_height;
1382 case V4L2_SEL_TGT_COMPOSE_BOUNDS:
1385 s->r.width = q_data->crop_width;
1386 s->r.height = q_data->crop_height;
1393 switch (s->target) {
1394 case V4L2_SEL_TGT_CROP_DEFAULT:
1395 case V4L2_SEL_TGT_CROP_BOUNDS:
1398 s->r.width = q_data->bytesperline;
1399 s->r.height = q_data->height;
1401 case V4L2_SEL_TGT_CROP:
1404 s->r.width = q_data->crop_width;
1405 s->r.height = q_data->crop_height;
1418 static int vidioc_s_selection(struct file *file, void *priv,
1419 struct v4l2_selection *s)
1421 struct bcm2835_codec_ctx *ctx = file2ctx(file);
1422 struct bcm2835_codec_q_data *q_data = NULL;
1425 * The selection API takes V4L2_BUF_TYPE_VIDEO_CAPTURE and
1426 * V4L2_BUF_TYPE_VIDEO_OUTPUT, even if the device implements the MPLANE
1427 * API. The V4L2 core will have converted the MPLANE variants to
1430 * Open code this instead of using get_q_data in this case.
1433 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1434 /* CAPTURE on encoder is not valid. */
1435 if (ctx->dev->role == ENCODE)
1437 q_data = &ctx->q_data[V4L2_M2M_DST];
1439 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
1440 /* OUTPUT on deoder is not valid. */
1441 if (ctx->dev->role == DECODE)
1443 q_data = &ctx->q_data[V4L2_M2M_SRC];
1449 v4l2_dbg(1, debug, &ctx->dev->v4l2_dev, "%s: ctx %p, type %d, q_data %p, target %d, rect x/y %d/%d, w/h %ux%u\n",
1450 __func__, ctx, s->type, q_data, s->target, s->r.left, s->r.top,
1451 s->r.width, s->r.height);
1453 switch (ctx->dev->role) {
1455 switch (s->target) {
1456 case V4L2_SEL_TGT_COMPOSE:
1457 /* Accept cropped image */
1460 s->r.width = min(s->r.width, q_data->crop_width);
1461 s->r.height = min(s->r.height, q_data->height);
1462 q_data->crop_width = s->r.width;
1463 q_data->crop_height = s->r.height;
1464 q_data->selection_set = true;
1471 switch (s->target) {
1472 case V4L2_SEL_TGT_CROP:
1473 /* Only support crop from (0,0) */
1476 s->r.width = min(s->r.width, q_data->crop_width);
1477 s->r.height = min(s->r.height, q_data->crop_height);
1478 q_data->crop_width = s->r.width;
1479 q_data->crop_height = s->r.height;
1480 q_data->selection_set = true;
1493 static int vidioc_s_parm(struct file *file, void *priv,
1494 struct v4l2_streamparm *parm)
1496 struct bcm2835_codec_ctx *ctx = file2ctx(file);
1498 if (parm->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
1501 if (!parm->parm.output.timeperframe.denominator ||
1502 !parm->parm.output.timeperframe.numerator)
1505 ctx->framerate_num =
1506 parm->parm.output.timeperframe.denominator;
1507 ctx->framerate_denom =
1508 parm->parm.output.timeperframe.numerator;
1510 parm->parm.output.capability = V4L2_CAP_TIMEPERFRAME;
1515 static int vidioc_g_parm(struct file *file, void *priv,
1516 struct v4l2_streamparm *parm)
1518 struct bcm2835_codec_ctx *ctx = file2ctx(file);
1520 if (parm->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
1523 parm->parm.output.capability = V4L2_CAP_TIMEPERFRAME;
1524 parm->parm.output.timeperframe.denominator =
1526 parm->parm.output.timeperframe.numerator =
1527 ctx->framerate_denom;
1532 static int vidioc_subscribe_evt(struct v4l2_fh *fh,
1533 const struct v4l2_event_subscription *sub)
1535 switch (sub->type) {
1536 case V4L2_EVENT_EOS:
1537 return v4l2_event_subscribe(fh, sub, 2, NULL);
1538 case V4L2_EVENT_SOURCE_CHANGE:
1539 return v4l2_src_change_event_subscribe(fh, sub);
1541 return v4l2_ctrl_subscribe_event(fh, sub);
1545 static int bcm2835_codec_set_level_profile(struct bcm2835_codec_ctx *ctx,
1546 struct v4l2_ctrl *ctrl)
1548 struct mmal_parameter_video_profile param;
1549 int param_size = sizeof(param);
1553 * Level and Profile are set via the same MMAL parameter.
1554 * Retrieve the current settings and amend the one that has changed.
1556 ret = vchiq_mmal_port_parameter_get(ctx->dev->instance,
1557 &ctx->component->output[0],
1558 MMAL_PARAMETER_PROFILE,
1565 case V4L2_CID_MPEG_VIDEO_H264_PROFILE:
1566 switch (ctrl->val) {
1567 case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE:
1568 param.profile = MMAL_VIDEO_PROFILE_H264_BASELINE;
1570 case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE:
1572 MMAL_VIDEO_PROFILE_H264_CONSTRAINED_BASELINE;
1574 case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN:
1575 param.profile = MMAL_VIDEO_PROFILE_H264_MAIN;
1577 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH:
1578 param.profile = MMAL_VIDEO_PROFILE_H264_HIGH;
1581 /* Should never get here */
1586 case V4L2_CID_MPEG_VIDEO_H264_LEVEL:
1587 switch (ctrl->val) {
1588 case V4L2_MPEG_VIDEO_H264_LEVEL_1_0:
1589 param.level = MMAL_VIDEO_LEVEL_H264_1;
1591 case V4L2_MPEG_VIDEO_H264_LEVEL_1B:
1592 param.level = MMAL_VIDEO_LEVEL_H264_1b;
1594 case V4L2_MPEG_VIDEO_H264_LEVEL_1_1:
1595 param.level = MMAL_VIDEO_LEVEL_H264_11;
1597 case V4L2_MPEG_VIDEO_H264_LEVEL_1_2:
1598 param.level = MMAL_VIDEO_LEVEL_H264_12;
1600 case V4L2_MPEG_VIDEO_H264_LEVEL_1_3:
1601 param.level = MMAL_VIDEO_LEVEL_H264_13;
1603 case V4L2_MPEG_VIDEO_H264_LEVEL_2_0:
1604 param.level = MMAL_VIDEO_LEVEL_H264_2;
1606 case V4L2_MPEG_VIDEO_H264_LEVEL_2_1:
1607 param.level = MMAL_VIDEO_LEVEL_H264_21;
1609 case V4L2_MPEG_VIDEO_H264_LEVEL_2_2:
1610 param.level = MMAL_VIDEO_LEVEL_H264_22;
1612 case V4L2_MPEG_VIDEO_H264_LEVEL_3_0:
1613 param.level = MMAL_VIDEO_LEVEL_H264_3;
1615 case V4L2_MPEG_VIDEO_H264_LEVEL_3_1:
1616 param.level = MMAL_VIDEO_LEVEL_H264_31;
1618 case V4L2_MPEG_VIDEO_H264_LEVEL_3_2:
1619 param.level = MMAL_VIDEO_LEVEL_H264_32;
1621 case V4L2_MPEG_VIDEO_H264_LEVEL_4_0:
1622 param.level = MMAL_VIDEO_LEVEL_H264_4;
1625 /* Should never get here */
1629 ret = vchiq_mmal_port_parameter_set(ctx->dev->instance,
1630 &ctx->component->output[0],
1631 MMAL_PARAMETER_PROFILE,
1638 static int bcm2835_codec_s_ctrl(struct v4l2_ctrl *ctrl)
1640 struct bcm2835_codec_ctx *ctx =
1641 container_of(ctrl->handler, struct bcm2835_codec_ctx, hdl);
1645 case V4L2_CID_MPEG_VIDEO_BITRATE:
1646 ctx->bitrate = ctrl->val;
1647 if (!ctx->component)
1650 ret = vchiq_mmal_port_parameter_set(ctx->dev->instance,
1651 &ctx->component->output[0],
1652 MMAL_PARAMETER_VIDEO_BIT_RATE,
1657 case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: {
1660 if (!ctx->component)
1663 switch (ctrl->val) {
1665 case V4L2_MPEG_VIDEO_BITRATE_MODE_VBR:
1666 bitrate_mode = MMAL_VIDEO_RATECONTROL_VARIABLE;
1668 case V4L2_MPEG_VIDEO_BITRATE_MODE_CBR:
1669 bitrate_mode = MMAL_VIDEO_RATECONTROL_CONSTANT;
1673 ret = vchiq_mmal_port_parameter_set(ctx->dev->instance,
1674 &ctx->component->output[0],
1675 MMAL_PARAMETER_RATECONTROL,
1677 sizeof(bitrate_mode));
1680 case V4L2_CID_MPEG_VIDEO_REPEAT_SEQ_HEADER:
1681 if (!ctx->component)
1684 ret = vchiq_mmal_port_parameter_set(ctx->dev->instance,
1685 &ctx->component->output[0],
1686 MMAL_PARAMETER_VIDEO_ENCODE_INLINE_HEADER,
1691 case V4L2_CID_MPEG_VIDEO_H264_I_PERIOD:
1692 if (!ctx->component)
1695 ret = vchiq_mmal_port_parameter_set(ctx->dev->instance,
1696 &ctx->component->output[0],
1697 MMAL_PARAMETER_INTRAPERIOD,
1702 case V4L2_CID_MPEG_VIDEO_H264_PROFILE:
1703 case V4L2_CID_MPEG_VIDEO_H264_LEVEL:
1704 if (!ctx->component)
1707 ret = bcm2835_codec_set_level_profile(ctx, ctrl);
1710 case V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME: {
1713 if (!ctx->component)
1716 ret = vchiq_mmal_port_parameter_set(ctx->dev->instance,
1717 &ctx->component->output[0],
1718 MMAL_PARAMETER_VIDEO_REQUEST_I_FRAME,
1725 v4l2_err(&ctx->dev->v4l2_dev, "Invalid control\n");
1730 v4l2_err(&ctx->dev->v4l2_dev, "Failed setting ctrl %08x, ret %d\n",
1732 return ret ? -EINVAL : 0;
1735 static const struct v4l2_ctrl_ops bcm2835_codec_ctrl_ops = {
1736 .s_ctrl = bcm2835_codec_s_ctrl,
1739 static int vidioc_try_decoder_cmd(struct file *file, void *priv,
1740 struct v4l2_decoder_cmd *cmd)
1742 struct bcm2835_codec_ctx *ctx = file2ctx(file);
1744 if (ctx->dev->role != DECODE)
1748 case V4L2_DEC_CMD_STOP:
1749 if (cmd->flags & V4L2_DEC_CMD_STOP_TO_BLACK) {
1750 v4l2_err(&ctx->dev->v4l2_dev, "%s: DEC cmd->flags=%u stop to black not supported",
1751 __func__, cmd->flags);
1755 case V4L2_DEC_CMD_START:
1763 static int vidioc_decoder_cmd(struct file *file, void *priv,
1764 struct v4l2_decoder_cmd *cmd)
1766 struct bcm2835_codec_ctx *ctx = file2ctx(file);
1767 struct bcm2835_codec_q_data *q_data = &ctx->q_data[V4L2_M2M_SRC];
1770 v4l2_dbg(2, debug, &ctx->dev->v4l2_dev, "%s, cmd %u", __func__,
1772 ret = vidioc_try_decoder_cmd(file, priv, cmd);
1777 case V4L2_DEC_CMD_STOP:
1778 if (q_data->eos_buffer_in_use)
1779 v4l2_err(&ctx->dev->v4l2_dev, "EOS buffers already in use\n");
1780 q_data->eos_buffer_in_use = true;
1782 q_data->eos_buffer.mmal.buffer_size = 0;
1783 q_data->eos_buffer.mmal.length = 0;
1784 q_data->eos_buffer.mmal.mmal_flags =
1785 MMAL_BUFFER_HEADER_FLAG_EOS;
1786 q_data->eos_buffer.mmal.pts = 0;
1787 q_data->eos_buffer.mmal.dts = 0;
1789 if (!ctx->component)
1792 ret = vchiq_mmal_submit_buffer(ctx->dev->instance,
1793 &ctx->component->input[0],
1794 &q_data->eos_buffer.mmal);
1796 v4l2_err(&ctx->dev->v4l2_dev,
1797 "%s: EOS buffer submit failed %d\n",
1802 case V4L2_DEC_CMD_START:
1803 /* Do we need to do anything here? */
1813 static int vidioc_try_encoder_cmd(struct file *file, void *priv,
1814 struct v4l2_encoder_cmd *cmd)
1816 struct bcm2835_codec_ctx *ctx = file2ctx(file);
1818 if (ctx->dev->role != ENCODE)
1822 case V4L2_ENC_CMD_STOP:
1825 case V4L2_ENC_CMD_START:
1826 /* Do we need to do anything here? */
1834 static int vidioc_encoder_cmd(struct file *file, void *priv,
1835 struct v4l2_encoder_cmd *cmd)
1837 struct bcm2835_codec_ctx *ctx = file2ctx(file);
1838 struct bcm2835_codec_q_data *q_data = &ctx->q_data[V4L2_M2M_SRC];
1841 v4l2_dbg(2, debug, &ctx->dev->v4l2_dev, "%s, cmd %u", __func__,
1843 ret = vidioc_try_encoder_cmd(file, priv, cmd);
1848 case V4L2_ENC_CMD_STOP:
1849 if (q_data->eos_buffer_in_use)
1850 v4l2_err(&ctx->dev->v4l2_dev, "EOS buffers already in use\n");
1851 q_data->eos_buffer_in_use = true;
1853 q_data->eos_buffer.mmal.buffer_size = 0;
1854 q_data->eos_buffer.mmal.length = 0;
1855 q_data->eos_buffer.mmal.mmal_flags =
1856 MMAL_BUFFER_HEADER_FLAG_EOS;
1857 q_data->eos_buffer.mmal.pts = 0;
1858 q_data->eos_buffer.mmal.dts = 0;
1860 if (!ctx->component)
1863 ret = vchiq_mmal_submit_buffer(ctx->dev->instance,
1864 &ctx->component->input[0],
1865 &q_data->eos_buffer.mmal);
1867 v4l2_err(&ctx->dev->v4l2_dev,
1868 "%s: EOS buffer submit failed %d\n",
1872 case V4L2_ENC_CMD_START:
1873 /* Do we need to do anything here? */
1883 static int vidioc_enum_framesizes(struct file *file, void *fh,
1884 struct v4l2_frmsizeenum *fsize)
1886 struct bcm2835_codec_fmt *fmt;
1888 fmt = find_format_pix_fmt(fsize->pixel_format, file2ctx(file)->dev,
1891 fmt = find_format_pix_fmt(fsize->pixel_format,
1892 file2ctx(file)->dev,
1901 fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE;
1903 fsize->stepwise.min_width = MIN_W;
1904 fsize->stepwise.max_width = MAX_W;
1905 fsize->stepwise.step_width = 1;
1906 fsize->stepwise.min_height = MIN_H;
1907 fsize->stepwise.max_height = MAX_H;
1908 fsize->stepwise.step_height = 1;
1913 static const struct v4l2_ioctl_ops bcm2835_codec_ioctl_ops = {
1914 .vidioc_querycap = vidioc_querycap,
1916 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
1917 .vidioc_g_fmt_vid_cap_mplane = vidioc_g_fmt_vid_cap,
1918 .vidioc_try_fmt_vid_cap_mplane = vidioc_try_fmt_vid_cap,
1919 .vidioc_s_fmt_vid_cap_mplane = vidioc_s_fmt_vid_cap,
1921 .vidioc_enum_fmt_vid_out = vidioc_enum_fmt_vid_out,
1922 .vidioc_g_fmt_vid_out_mplane = vidioc_g_fmt_vid_out,
1923 .vidioc_try_fmt_vid_out_mplane = vidioc_try_fmt_vid_out,
1924 .vidioc_s_fmt_vid_out_mplane = vidioc_s_fmt_vid_out,
1926 .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs,
1927 .vidioc_querybuf = v4l2_m2m_ioctl_querybuf,
1928 .vidioc_qbuf = v4l2_m2m_ioctl_qbuf,
1929 .vidioc_dqbuf = v4l2_m2m_ioctl_dqbuf,
1930 .vidioc_prepare_buf = v4l2_m2m_ioctl_prepare_buf,
1931 .vidioc_create_bufs = v4l2_m2m_ioctl_create_bufs,
1932 .vidioc_expbuf = v4l2_m2m_ioctl_expbuf,
1934 .vidioc_streamon = v4l2_m2m_ioctl_streamon,
1935 .vidioc_streamoff = v4l2_m2m_ioctl_streamoff,
1937 .vidioc_g_selection = vidioc_g_selection,
1938 .vidioc_s_selection = vidioc_s_selection,
1940 .vidioc_g_parm = vidioc_g_parm,
1941 .vidioc_s_parm = vidioc_s_parm,
1943 .vidioc_subscribe_event = vidioc_subscribe_evt,
1944 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
1946 .vidioc_decoder_cmd = vidioc_decoder_cmd,
1947 .vidioc_try_decoder_cmd = vidioc_try_decoder_cmd,
1948 .vidioc_encoder_cmd = vidioc_encoder_cmd,
1949 .vidioc_try_encoder_cmd = vidioc_try_encoder_cmd,
1950 .vidioc_enum_framesizes = vidioc_enum_framesizes,
1953 static int bcm2835_codec_set_ctrls(struct bcm2835_codec_ctx *ctx)
1956 * Query the control handler for the value of the various controls and
1959 const u32 control_ids[] = {
1960 V4L2_CID_MPEG_VIDEO_BITRATE_MODE,
1961 V4L2_CID_MPEG_VIDEO_REPEAT_SEQ_HEADER,
1962 V4L2_CID_MPEG_VIDEO_H264_I_PERIOD,
1963 V4L2_CID_MPEG_VIDEO_H264_LEVEL,
1964 V4L2_CID_MPEG_VIDEO_H264_PROFILE,
1968 for (i = 0; i < ARRAY_SIZE(control_ids); i++) {
1969 struct v4l2_ctrl *ctrl;
1971 ctrl = v4l2_ctrl_find(&ctx->hdl, control_ids[i]);
1973 bcm2835_codec_s_ctrl(ctrl);
1979 static int bcm2835_codec_create_component(struct bcm2835_codec_ctx *ctx)
1981 struct bcm2835_codec_dev *dev = ctx->dev;
1982 unsigned int enable = 1;
1985 ret = vchiq_mmal_component_init(dev->instance, components[dev->role],
1988 v4l2_err(&dev->v4l2_dev, "%s: failed to create component %s\n",
1989 __func__, components[dev->role]);
1993 vchiq_mmal_port_parameter_set(dev->instance, &ctx->component->input[0],
1994 MMAL_PARAMETER_ZERO_COPY, &enable,
1996 vchiq_mmal_port_parameter_set(dev->instance, &ctx->component->output[0],
1997 MMAL_PARAMETER_ZERO_COPY, &enable,
2000 setup_mmal_port_format(ctx, &ctx->q_data[V4L2_M2M_SRC],
2001 &ctx->component->input[0]);
2003 setup_mmal_port_format(ctx, &ctx->q_data[V4L2_M2M_DST],
2004 &ctx->component->output[0]);
2006 ret = vchiq_mmal_port_set_format(dev->instance,
2007 &ctx->component->input[0]);
2009 v4l2_dbg(1, debug, &dev->v4l2_dev,
2010 "%s: vchiq_mmal_port_set_format ip port failed\n",
2012 goto destroy_component;
2015 ret = vchiq_mmal_port_set_format(dev->instance,
2016 &ctx->component->output[0]);
2018 v4l2_dbg(1, debug, &dev->v4l2_dev,
2019 "%s: vchiq_mmal_port_set_format op port failed\n",
2021 goto destroy_component;
2024 if (dev->role == ENCODE) {
2027 if (ctx->q_data[V4L2_M2M_SRC].sizeimage <
2028 ctx->component->output[0].minimum_buffer.size)
2029 v4l2_err(&dev->v4l2_dev, "buffer size mismatch sizeimage %u < min size %u\n",
2030 ctx->q_data[V4L2_M2M_SRC].sizeimage,
2031 ctx->component->output[0].minimum_buffer.size);
2033 /* Now we have a component we can set all the ctrls */
2034 bcm2835_codec_set_ctrls(ctx);
2036 /* Enable SPS Timing header so framerate information is encoded
2037 * in the H264 header.
2039 vchiq_mmal_port_parameter_set(
2041 &ctx->component->output[0],
2042 MMAL_PARAMETER_VIDEO_ENCODE_SPS_TIMING,
2043 ¶m, sizeof(param));
2045 /* Enable inserting headers into the first frame */
2046 vchiq_mmal_port_parameter_set(ctx->dev->instance,
2047 &ctx->component->control,
2048 MMAL_PARAMETER_VIDEO_ENCODE_HEADERS_WITH_FRAME,
2049 ¶m, sizeof(param));
2051 * Avoid fragmenting the buffers over multiple frames (unless
2052 * the frame is bigger than the whole buffer)
2054 vchiq_mmal_port_parameter_set(ctx->dev->instance,
2055 &ctx->component->control,
2056 MMAL_PARAMETER_MINIMISE_FRAGMENTATION,
2057 ¶m, sizeof(param));
2059 if (ctx->q_data[V4L2_M2M_DST].sizeimage <
2060 ctx->component->output[0].minimum_buffer.size)
2061 v4l2_err(&dev->v4l2_dev, "buffer size mismatch sizeimage %u < min size %u\n",
2062 ctx->q_data[V4L2_M2M_DST].sizeimage,
2063 ctx->component->output[0].minimum_buffer.size);
2065 v4l2_dbg(2, debug, &dev->v4l2_dev, "%s: component created as %s\n",
2066 __func__, components[dev->role]);
2071 vchiq_mmal_component_finalise(ctx->dev->instance, ctx->component);
2072 ctx->component = NULL;
2081 static int bcm2835_codec_queue_setup(struct vb2_queue *vq,
2082 unsigned int *nbuffers,
2083 unsigned int *nplanes,
2084 unsigned int sizes[],
2085 struct device *alloc_devs[])
2087 struct bcm2835_codec_ctx *ctx = vb2_get_drv_priv(vq);
2088 struct bcm2835_codec_q_data *q_data;
2089 struct vchiq_mmal_port *port;
2092 q_data = get_q_data(ctx, vq->type);
2096 if (!ctx->component)
2097 if (bcm2835_codec_create_component(ctx))
2100 port = get_port_data(ctx, vq->type);
2102 size = q_data->sizeimage;
2105 return sizes[0] < size ? -EINVAL : 0;
2110 port->current_buffer.size = size;
2112 if (*nbuffers < port->minimum_buffer.num)
2113 *nbuffers = port->minimum_buffer.num;
2114 /* Add one buffer to take an EOS */
2115 port->current_buffer.num = *nbuffers + 1;
2120 static int bcm2835_codec_mmal_buf_cleanup(struct mmal_buffer *mmal_buf)
2122 mmal_vchi_buffer_cleanup(mmal_buf);
2124 if (mmal_buf->dma_buf) {
2125 dma_buf_put(mmal_buf->dma_buf);
2126 mmal_buf->dma_buf = NULL;
2132 static int bcm2835_codec_buf_init(struct vb2_buffer *vb)
2134 struct bcm2835_codec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
2135 struct vb2_v4l2_buffer *vb2 = to_vb2_v4l2_buffer(vb);
2136 struct v4l2_m2m_buffer *m2m = container_of(vb2, struct v4l2_m2m_buffer,
2138 struct m2m_mmal_buffer *buf = container_of(m2m, struct m2m_mmal_buffer,
2141 v4l2_dbg(2, debug, &ctx->dev->v4l2_dev, "%s: ctx:%p, vb %p\n",
2143 buf->mmal.buffer = vb2_plane_vaddr(&buf->m2m.vb.vb2_buf, 0);
2144 buf->mmal.buffer_size = vb2_plane_size(&buf->m2m.vb.vb2_buf, 0);
2146 mmal_vchi_buffer_init(ctx->dev->instance, &buf->mmal);
2151 static int bcm2835_codec_buf_prepare(struct vb2_buffer *vb)
2153 struct bcm2835_codec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
2154 struct bcm2835_codec_q_data *q_data;
2155 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
2156 struct v4l2_m2m_buffer *m2m = container_of(vbuf, struct v4l2_m2m_buffer,
2158 struct m2m_mmal_buffer *buf = container_of(m2m, struct m2m_mmal_buffer,
2160 struct dma_buf *dma_buf;
2163 v4l2_dbg(4, debug, &ctx->dev->v4l2_dev, "%s: type: %d ptr %p\n",
2164 __func__, vb->vb2_queue->type, vb);
2166 q_data = get_q_data(ctx, vb->vb2_queue->type);
2167 if (V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type)) {
2168 if (vbuf->field == V4L2_FIELD_ANY)
2169 vbuf->field = V4L2_FIELD_NONE;
2170 if (vbuf->field != V4L2_FIELD_NONE) {
2171 v4l2_err(&ctx->dev->v4l2_dev, "%s field isn't supported\n",
2177 if (vb2_plane_size(vb, 0) < q_data->sizeimage) {
2178 v4l2_err(&ctx->dev->v4l2_dev, "%s data will not fit into plane (%lu < %lu)\n",
2179 __func__, vb2_plane_size(vb, 0),
2180 (long)q_data->sizeimage);
2184 if (!V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type))
2185 vb2_set_plane_payload(vb, 0, q_data->sizeimage);
2187 switch (vb->memory) {
2188 case VB2_MEMORY_DMABUF:
2189 dma_buf = dma_buf_get(vb->planes[0].m.fd);
2191 if (dma_buf != buf->mmal.dma_buf) {
2192 /* dmabuf either hasn't already been mapped, or it has
2195 if (buf->mmal.dma_buf) {
2196 v4l2_err(&ctx->dev->v4l2_dev,
2197 "%s Buffer changed - why did the core not call cleanup?\n",
2199 bcm2835_codec_mmal_buf_cleanup(&buf->mmal);
2202 buf->mmal.dma_buf = dma_buf;
2204 /* We already have a reference count on the dmabuf, so
2205 * release the one we acquired above.
2207 dma_buf_put(dma_buf);
2211 case VB2_MEMORY_MMAP:
2213 * We want to do this at init, but vb2_core_expbuf checks that
2214 * the index < q->num_buffers, and q->num_buffers only gets
2215 * updated once all the buffers are allocated.
2217 if (!buf->mmal.dma_buf) {
2218 ret = vb2_core_expbuf_dmabuf(vb->vb2_queue,
2219 vb->vb2_queue->type,
2222 &buf->mmal.dma_buf);
2224 v4l2_err(&ctx->dev->v4l2_dev,
2225 "%s: Failed to expbuf idx %d, ret %d\n",
2226 __func__, vb->index, ret);
2239 static void bcm2835_codec_buf_queue(struct vb2_buffer *vb)
2241 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
2242 struct bcm2835_codec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
2244 v4l2_dbg(4, debug, &ctx->dev->v4l2_dev, "%s: type: %d ptr %p vbuf->flags %u, seq %u, bytesused %u\n",
2245 __func__, vb->vb2_queue->type, vb, vbuf->flags, vbuf->sequence,
2246 vb->planes[0].bytesused);
2247 v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf);
2250 static void bcm2835_codec_buffer_cleanup(struct vb2_buffer *vb)
2252 struct bcm2835_codec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
2253 struct vb2_v4l2_buffer *vb2 = to_vb2_v4l2_buffer(vb);
2254 struct v4l2_m2m_buffer *m2m = container_of(vb2, struct v4l2_m2m_buffer,
2256 struct m2m_mmal_buffer *buf = container_of(m2m, struct m2m_mmal_buffer,
2259 v4l2_dbg(2, debug, &ctx->dev->v4l2_dev, "%s: ctx:%p, vb %p\n",
2262 bcm2835_codec_mmal_buf_cleanup(&buf->mmal);
2265 static int bcm2835_codec_start_streaming(struct vb2_queue *q,
2268 struct bcm2835_codec_ctx *ctx = vb2_get_drv_priv(q);
2269 struct bcm2835_codec_dev *dev = ctx->dev;
2270 struct bcm2835_codec_q_data *q_data = get_q_data(ctx, q->type);
2273 v4l2_dbg(1, debug, &ctx->dev->v4l2_dev, "%s: type: %d count %d\n",
2274 __func__, q->type, count);
2275 q_data->sequence = 0;
2277 if (!ctx->component_enabled) {
2278 ret = vchiq_mmal_component_enable(dev->instance,
2281 v4l2_err(&ctx->dev->v4l2_dev, "%s: Failed enabling component, ret %d\n",
2283 ctx->component_enabled = true;
2286 if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
2288 * Create the EOS buffer.
2289 * We only need the MMAL part, and want to NOT attach a memory
2290 * buffer to it as it should only take flags.
2292 memset(&q_data->eos_buffer, 0, sizeof(q_data->eos_buffer));
2293 mmal_vchi_buffer_init(dev->instance,
2294 &q_data->eos_buffer.mmal);
2295 q_data->eos_buffer_in_use = false;
2297 ctx->component->input[0].cb_ctx = ctx;
2298 ret = vchiq_mmal_port_enable(dev->instance,
2299 &ctx->component->input[0],
2302 v4l2_err(&ctx->dev->v4l2_dev, "%s: Failed enabling i/p port, ret %d\n",
2305 ctx->component->output[0].cb_ctx = ctx;
2306 ret = vchiq_mmal_port_enable(dev->instance,
2307 &ctx->component->output[0],
2310 v4l2_err(&ctx->dev->v4l2_dev, "%s: Failed enabling o/p port, ret %d\n",
2316 static void bcm2835_codec_stop_streaming(struct vb2_queue *q)
2318 struct bcm2835_codec_ctx *ctx = vb2_get_drv_priv(q);
2319 struct bcm2835_codec_dev *dev = ctx->dev;
2320 struct bcm2835_codec_q_data *q_data = get_q_data(ctx, q->type);
2321 struct vchiq_mmal_port *port = get_port_data(ctx, q->type);
2322 struct vb2_v4l2_buffer *vbuf;
2325 v4l2_dbg(1, debug, &ctx->dev->v4l2_dev, "%s: type: %d - return buffers\n",
2328 init_completion(&ctx->frame_cmplt);
2330 /* Clear out all buffers held by m2m framework */
2332 if (V4L2_TYPE_IS_OUTPUT(q->type))
2333 vbuf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
2335 vbuf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
2338 v4l2_dbg(1, debug, &ctx->dev->v4l2_dev, "%s: return buffer %p\n",
2341 v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR);
2344 /* Disable MMAL port - this will flush buffers back */
2345 ret = vchiq_mmal_port_disable(dev->instance, port);
2347 v4l2_err(&ctx->dev->v4l2_dev, "%s: Failed disabling %s port, ret %d\n",
2348 __func__, V4L2_TYPE_IS_OUTPUT(q->type) ? "i/p" : "o/p",
2351 while (atomic_read(&port->buffers_with_vpu)) {
2352 v4l2_dbg(1, debug, &ctx->dev->v4l2_dev, "%s: Waiting for buffers to be returned - %d outstanding\n",
2353 __func__, atomic_read(&port->buffers_with_vpu));
2354 ret = wait_for_completion_timeout(&ctx->frame_cmplt, HZ);
2356 v4l2_err(&ctx->dev->v4l2_dev, "%s: Timeout waiting for buffers to be returned - %d outstanding\n",
2358 atomic_read(&port->buffers_with_vpu));
2364 /* If both ports disabled, then disable the component */
2365 if (!ctx->component->input[0].enabled &&
2366 !ctx->component->output[0].enabled) {
2367 ret = vchiq_mmal_component_disable(dev->instance,
2370 v4l2_err(&ctx->dev->v4l2_dev, "%s: Failed enabling component, ret %d\n",
2374 if (V4L2_TYPE_IS_OUTPUT(q->type))
2375 mmal_vchi_buffer_cleanup(&q_data->eos_buffer.mmal);
2377 v4l2_dbg(1, debug, &ctx->dev->v4l2_dev, "%s: done\n", __func__);
2380 static const struct vb2_ops bcm2835_codec_qops = {
2381 .queue_setup = bcm2835_codec_queue_setup,
2382 .buf_init = bcm2835_codec_buf_init,
2383 .buf_prepare = bcm2835_codec_buf_prepare,
2384 .buf_queue = bcm2835_codec_buf_queue,
2385 .buf_cleanup = bcm2835_codec_buffer_cleanup,
2386 .start_streaming = bcm2835_codec_start_streaming,
2387 .stop_streaming = bcm2835_codec_stop_streaming,
2388 .wait_prepare = vb2_ops_wait_prepare,
2389 .wait_finish = vb2_ops_wait_finish,
2392 static int queue_init(void *priv, struct vb2_queue *src_vq,
2393 struct vb2_queue *dst_vq)
2395 struct bcm2835_codec_ctx *ctx = priv;
2398 src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
2399 src_vq->io_modes = VB2_MMAP | VB2_DMABUF;
2400 src_vq->drv_priv = ctx;
2401 src_vq->buf_struct_size = sizeof(struct m2m_mmal_buffer);
2402 src_vq->ops = &bcm2835_codec_qops;
2403 src_vq->mem_ops = &vb2_dma_contig_memops;
2404 src_vq->dev = &ctx->dev->pdev->dev;
2405 src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
2406 src_vq->lock = &ctx->dev->dev_mutex;
2408 ret = vb2_queue_init(src_vq);
2412 dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
2413 dst_vq->io_modes = VB2_MMAP | VB2_DMABUF;
2414 dst_vq->drv_priv = ctx;
2415 dst_vq->buf_struct_size = sizeof(struct m2m_mmal_buffer);
2416 dst_vq->ops = &bcm2835_codec_qops;
2417 dst_vq->mem_ops = &vb2_dma_contig_memops;
2418 dst_vq->dev = &ctx->dev->pdev->dev;
2419 dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
2420 dst_vq->lock = &ctx->dev->dev_mutex;
2422 return vb2_queue_init(dst_vq);
2428 static int bcm2835_codec_open(struct file *file)
2430 struct bcm2835_codec_dev *dev = video_drvdata(file);
2431 struct bcm2835_codec_ctx *ctx = NULL;
2432 struct v4l2_ctrl_handler *hdl;
2435 if (mutex_lock_interruptible(&dev->dev_mutex)) {
2436 v4l2_err(&dev->v4l2_dev, "Mutex fail\n");
2437 return -ERESTARTSYS;
2439 ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
2445 ctx->q_data[V4L2_M2M_SRC].fmt = get_default_format(dev, false);
2446 ctx->q_data[V4L2_M2M_DST].fmt = get_default_format(dev, true);
2448 ctx->q_data[V4L2_M2M_SRC].crop_width = DEFAULT_WIDTH;
2449 ctx->q_data[V4L2_M2M_SRC].crop_height = DEFAULT_HEIGHT;
2450 ctx->q_data[V4L2_M2M_SRC].height = DEFAULT_HEIGHT;
2451 ctx->q_data[V4L2_M2M_SRC].bytesperline =
2452 get_bytesperline(DEFAULT_WIDTH,
2453 ctx->q_data[V4L2_M2M_SRC].fmt);
2454 ctx->q_data[V4L2_M2M_SRC].sizeimage =
2455 get_sizeimage(ctx->q_data[V4L2_M2M_SRC].bytesperline,
2456 ctx->q_data[V4L2_M2M_SRC].crop_width,
2457 ctx->q_data[V4L2_M2M_SRC].height,
2458 ctx->q_data[V4L2_M2M_SRC].fmt);
2460 ctx->q_data[V4L2_M2M_DST].crop_width = DEFAULT_WIDTH;
2461 ctx->q_data[V4L2_M2M_DST].crop_height = DEFAULT_HEIGHT;
2462 ctx->q_data[V4L2_M2M_DST].height = DEFAULT_HEIGHT;
2463 ctx->q_data[V4L2_M2M_DST].bytesperline =
2464 get_bytesperline(DEFAULT_WIDTH,
2465 ctx->q_data[V4L2_M2M_DST].fmt);
2466 ctx->q_data[V4L2_M2M_DST].sizeimage =
2467 get_sizeimage(ctx->q_data[V4L2_M2M_DST].bytesperline,
2468 ctx->q_data[V4L2_M2M_DST].crop_width,
2469 ctx->q_data[V4L2_M2M_DST].height,
2470 ctx->q_data[V4L2_M2M_DST].fmt);
2472 ctx->colorspace = V4L2_COLORSPACE_REC709;
2473 ctx->bitrate = 10 * 1000 * 1000;
2475 ctx->framerate_num = 30;
2476 ctx->framerate_denom = 1;
2478 /* Initialise V4L2 contexts */
2479 v4l2_fh_init(&ctx->fh, video_devdata(file));
2480 file->private_data = &ctx->fh;
2483 if (dev->role == ENCODE) {
2484 /* Encode controls */
2485 v4l2_ctrl_handler_init(hdl, 7);
2487 v4l2_ctrl_new_std_menu(hdl, &bcm2835_codec_ctrl_ops,
2488 V4L2_CID_MPEG_VIDEO_BITRATE_MODE,
2489 V4L2_MPEG_VIDEO_BITRATE_MODE_CBR, 0,
2490 V4L2_MPEG_VIDEO_BITRATE_MODE_VBR);
2491 v4l2_ctrl_new_std(hdl, &bcm2835_codec_ctrl_ops,
2492 V4L2_CID_MPEG_VIDEO_BITRATE,
2493 25 * 1000, 25 * 1000 * 1000,
2494 25 * 1000, 10 * 1000 * 1000);
2495 v4l2_ctrl_new_std(hdl, &bcm2835_codec_ctrl_ops,
2496 V4L2_CID_MPEG_VIDEO_REPEAT_SEQ_HEADER,
2499 v4l2_ctrl_new_std(hdl, &bcm2835_codec_ctrl_ops,
2500 V4L2_CID_MPEG_VIDEO_H264_I_PERIOD,
2503 v4l2_ctrl_new_std_menu(hdl, &bcm2835_codec_ctrl_ops,
2504 V4L2_CID_MPEG_VIDEO_H264_LEVEL,
2505 V4L2_MPEG_VIDEO_H264_LEVEL_4_2,
2506 ~(BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_0) |
2507 BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1B) |
2508 BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_1) |
2509 BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_2) |
2510 BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_3) |
2511 BIT(V4L2_MPEG_VIDEO_H264_LEVEL_2_0) |
2512 BIT(V4L2_MPEG_VIDEO_H264_LEVEL_2_1) |
2513 BIT(V4L2_MPEG_VIDEO_H264_LEVEL_2_2) |
2514 BIT(V4L2_MPEG_VIDEO_H264_LEVEL_3_0) |
2515 BIT(V4L2_MPEG_VIDEO_H264_LEVEL_3_1) |
2516 BIT(V4L2_MPEG_VIDEO_H264_LEVEL_3_2) |
2517 BIT(V4L2_MPEG_VIDEO_H264_LEVEL_4_0) |
2518 BIT(V4L2_MPEG_VIDEO_H264_LEVEL_4_1) |
2519 BIT(V4L2_MPEG_VIDEO_H264_LEVEL_4_2)),
2520 V4L2_MPEG_VIDEO_H264_LEVEL_4_0);
2521 v4l2_ctrl_new_std_menu(hdl, &bcm2835_codec_ctrl_ops,
2522 V4L2_CID_MPEG_VIDEO_H264_PROFILE,
2523 V4L2_MPEG_VIDEO_H264_PROFILE_HIGH,
2524 ~(BIT(V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE) |
2525 BIT(V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE) |
2526 BIT(V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) |
2527 BIT(V4L2_MPEG_VIDEO_H264_PROFILE_HIGH)),
2528 V4L2_MPEG_VIDEO_H264_PROFILE_HIGH);
2529 v4l2_ctrl_new_std(hdl, &bcm2835_codec_ctrl_ops,
2530 V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME,
2534 goto free_ctrl_handler;
2536 ctx->fh.ctrl_handler = hdl;
2537 v4l2_ctrl_handler_setup(hdl);
2538 } else if (dev->role == DECODE) {
2539 v4l2_ctrl_handler_init(hdl, 1);
2541 v4l2_ctrl_new_std(hdl, &bcm2835_codec_ctrl_ops,
2542 V4L2_CID_MIN_BUFFERS_FOR_CAPTURE,
2546 goto free_ctrl_handler;
2548 ctx->fh.ctrl_handler = hdl;
2549 v4l2_ctrl_handler_setup(hdl);
2552 ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(dev->m2m_dev, ctx, &queue_init);
2554 if (IS_ERR(ctx->fh.m2m_ctx)) {
2555 rc = PTR_ERR(ctx->fh.m2m_ctx);
2557 goto free_ctrl_handler;
2560 /* Set both queues as buffered as we have buffering in the VPU. That
2561 * means that we will be scheduled whenever either an input or output
2562 * buffer is available (otherwise one of each are required).
2564 v4l2_m2m_set_src_buffered(ctx->fh.m2m_ctx, true);
2565 v4l2_m2m_set_dst_buffered(ctx->fh.m2m_ctx, true);
2567 v4l2_fh_add(&ctx->fh);
2568 atomic_inc(&dev->num_inst);
2570 mutex_unlock(&dev->dev_mutex);
2574 v4l2_ctrl_handler_free(hdl);
2577 mutex_unlock(&dev->dev_mutex);
2581 static int bcm2835_codec_release(struct file *file)
2583 struct bcm2835_codec_dev *dev = video_drvdata(file);
2584 struct bcm2835_codec_ctx *ctx = file2ctx(file);
2586 v4l2_dbg(1, debug, &dev->v4l2_dev, "%s: Releasing instance %p\n",
2589 v4l2_fh_del(&ctx->fh);
2590 v4l2_fh_exit(&ctx->fh);
2591 v4l2_ctrl_handler_free(&ctx->hdl);
2592 mutex_lock(&dev->dev_mutex);
2593 v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
2596 vchiq_mmal_component_finalise(dev->instance, ctx->component);
2598 mutex_unlock(&dev->dev_mutex);
2601 atomic_dec(&dev->num_inst);
2606 static const struct v4l2_file_operations bcm2835_codec_fops = {
2607 .owner = THIS_MODULE,
2608 .open = bcm2835_codec_open,
2609 .release = bcm2835_codec_release,
2610 .poll = v4l2_m2m_fop_poll,
2611 .unlocked_ioctl = video_ioctl2,
2612 .mmap = v4l2_m2m_fop_mmap,
2615 static const struct video_device bcm2835_codec_videodev = {
2616 .name = MEM2MEM_NAME,
2617 .vfl_dir = VFL_DIR_M2M,
2618 .fops = &bcm2835_codec_fops,
2619 .ioctl_ops = &bcm2835_codec_ioctl_ops,
2621 .release = video_device_release_empty,
2624 static const struct v4l2_m2m_ops m2m_ops = {
2625 .device_run = device_run,
2626 .job_ready = job_ready,
2627 .job_abort = job_abort,
2630 /* Size of the array to provide to the VPU when asking for the list of supported
2632 * The ISP component currently advertises 44 input formats, so add a small
2635 #define MAX_SUPPORTED_ENCODINGS 50
2637 /* Populate dev->supported_fmts with the formats supported by those ports. */
2638 static int bcm2835_codec_get_supported_fmts(struct bcm2835_codec_dev *dev)
2640 struct bcm2835_codec_fmt *list;
2641 struct vchiq_mmal_component *component;
2642 u32 fourccs[MAX_SUPPORTED_ENCODINGS];
2643 u32 param_size = sizeof(fourccs);
2644 unsigned int i, j, num_encodings;
2647 ret = vchiq_mmal_component_init(dev->instance, components[dev->role],
2650 v4l2_err(&dev->v4l2_dev, "%s: failed to create component %s\n",
2651 __func__, components[dev->role]);
2655 ret = vchiq_mmal_port_parameter_get(dev->instance,
2656 &component->input[0],
2657 MMAL_PARAMETER_SUPPORTED_ENCODINGS,
2662 if (ret == MMAL_MSG_STATUS_ENOSPC) {
2663 v4l2_err(&dev->v4l2_dev, "%s: port has more encoding than we provided space for. Some are dropped.\n",
2665 num_encodings = MAX_SUPPORTED_ENCODINGS;
2667 v4l2_err(&dev->v4l2_dev, "%s: get_param ret %u.\n",
2670 goto destroy_component;
2673 num_encodings = param_size / sizeof(u32);
2676 /* Assume at this stage that all encodings will be supported in V4L2.
2677 * Any that aren't supported will waste a very small amount of memory.
2679 list = devm_kzalloc(&dev->pdev->dev,
2680 sizeof(struct bcm2835_codec_fmt) * num_encodings,
2684 goto destroy_component;
2686 dev->supported_fmts[0].list = list;
2688 for (i = 0, j = 0; i < num_encodings; i++) {
2689 const struct bcm2835_codec_fmt *fmt = get_fmt(fourccs[i]);
2696 dev->supported_fmts[0].num_entries = j;
2698 param_size = sizeof(fourccs);
2699 ret = vchiq_mmal_port_parameter_get(dev->instance,
2700 &component->output[0],
2701 MMAL_PARAMETER_SUPPORTED_ENCODINGS,
2706 if (ret == MMAL_MSG_STATUS_ENOSPC) {
2707 v4l2_err(&dev->v4l2_dev, "%s: port has more encoding than we provided space for. Some are dropped.\n",
2709 num_encodings = MAX_SUPPORTED_ENCODINGS;
2712 goto destroy_component;
2715 num_encodings = param_size / sizeof(u32);
2717 /* Assume at this stage that all encodings will be supported in V4L2. */
2718 list = devm_kzalloc(&dev->pdev->dev,
2719 sizeof(struct bcm2835_codec_fmt) * num_encodings,
2723 goto destroy_component;
2725 dev->supported_fmts[1].list = list;
2727 for (i = 0, j = 0; i < num_encodings; i++) {
2728 const struct bcm2835_codec_fmt *fmt = get_fmt(fourccs[i]);
2735 dev->supported_fmts[1].num_entries = j;
2740 vchiq_mmal_component_finalise(dev->instance, component);
2745 static int bcm2835_codec_create(struct bcm2835_codec_driver *drv,
2746 struct bcm2835_codec_dev **new_dev,
2747 enum bcm2835_codec_role role)
2749 struct platform_device *pdev = drv->pdev;
2750 struct bcm2835_codec_dev *dev;
2751 struct video_device *vfd;
2756 dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
2764 ret = vchiq_mmal_init(&dev->instance);
2768 ret = bcm2835_codec_get_supported_fmts(dev);
2770 goto vchiq_finalise;
2772 atomic_set(&dev->num_inst, 0);
2773 mutex_init(&dev->dev_mutex);
2775 /* Initialise the video device */
2776 dev->vfd = bcm2835_codec_videodev;
2779 vfd->lock = &dev->dev_mutex;
2780 vfd->v4l2_dev = &dev->v4l2_dev;
2781 vfd->device_caps = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING;
2782 vfd->v4l2_dev->mdev = &drv->mdev;
2784 ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev);
2786 goto vchiq_finalise;
2790 v4l2_disable_ioctl(vfd, VIDIOC_ENCODER_CMD);
2791 v4l2_disable_ioctl(vfd, VIDIOC_TRY_ENCODER_CMD);
2792 v4l2_disable_ioctl(vfd, VIDIOC_S_PARM);
2793 v4l2_disable_ioctl(vfd, VIDIOC_G_PARM);
2794 function = MEDIA_ENT_F_PROC_VIDEO_DECODER;
2795 video_nr = decode_video_nr;
2798 v4l2_disable_ioctl(vfd, VIDIOC_DECODER_CMD);
2799 v4l2_disable_ioctl(vfd, VIDIOC_TRY_DECODER_CMD);
2800 function = MEDIA_ENT_F_PROC_VIDEO_ENCODER;
2801 video_nr = encode_video_nr;
2804 v4l2_disable_ioctl(vfd, VIDIOC_ENCODER_CMD);
2805 v4l2_disable_ioctl(vfd, VIDIOC_TRY_ENCODER_CMD);
2806 v4l2_disable_ioctl(vfd, VIDIOC_DECODER_CMD);
2807 v4l2_disable_ioctl(vfd, VIDIOC_TRY_DECODER_CMD);
2808 v4l2_disable_ioctl(vfd, VIDIOC_S_PARM);
2809 v4l2_disable_ioctl(vfd, VIDIOC_G_PARM);
2810 function = MEDIA_ENT_F_PROC_VIDEO_SCALER;
2811 video_nr = isp_video_nr;
2818 ret = video_register_device(vfd, VFL_TYPE_GRABBER, video_nr);
2820 v4l2_err(&dev->v4l2_dev, "Failed to register video device\n");
2824 video_set_drvdata(vfd, dev);
2825 snprintf(vfd->name, sizeof(vfd->name), "%s-%s",
2826 bcm2835_codec_videodev.name, roles[role]);
2827 v4l2_info(&dev->v4l2_dev, "Device registered as /dev/video%d\n",
2832 dev->m2m_dev = v4l2_m2m_init(&m2m_ops);
2833 if (IS_ERR(dev->m2m_dev)) {
2834 v4l2_err(&dev->v4l2_dev, "Failed to init mem2mem device\n");
2835 ret = PTR_ERR(dev->m2m_dev);
2839 ret = v4l2_m2m_register_media_controller(dev->m2m_dev, vfd, function);
2843 v4l2_info(&dev->v4l2_dev, "Loaded V4L2 %s\n",
2848 v4l2_m2m_release(dev->m2m_dev);
2849 video_unregister_device(&dev->vfd);
2851 v4l2_device_unregister(&dev->v4l2_dev);
2853 vchiq_mmal_finalise(dev->instance);
2857 static int bcm2835_codec_destroy(struct bcm2835_codec_dev *dev)
2862 v4l2_info(&dev->v4l2_dev, "Removing " MEM2MEM_NAME ", %s\n",
2864 v4l2_m2m_unregister_media_controller(dev->m2m_dev);
2865 v4l2_m2m_release(dev->m2m_dev);
2866 video_unregister_device(&dev->vfd);
2867 v4l2_device_unregister(&dev->v4l2_dev);
2868 vchiq_mmal_finalise(dev->instance);
2873 static int bcm2835_codec_probe(struct platform_device *pdev)
2875 struct bcm2835_codec_driver *drv;
2876 struct media_device *mdev;
2879 drv = devm_kzalloc(&pdev->dev, sizeof(*drv), GFP_KERNEL);
2885 mdev->dev = &pdev->dev;
2887 strscpy(mdev->model, bcm2835_codec_videodev.name, sizeof(mdev->model));
2888 strscpy(mdev->serial, "0000", sizeof(mdev->serial));
2889 snprintf(mdev->bus_info, sizeof(mdev->bus_info), "platform:%s",
2892 /* This should return the vgencmd version information or such .. */
2893 mdev->hw_revision = 1;
2894 media_device_init(mdev);
2896 ret = bcm2835_codec_create(drv, &drv->decode, DECODE);
2900 ret = bcm2835_codec_create(drv, &drv->encode, ENCODE);
2904 ret = bcm2835_codec_create(drv, &drv->isp, ISP);
2908 /* Register the media device node */
2909 if (media_device_register(mdev) < 0)
2912 platform_set_drvdata(pdev, drv);
2918 bcm2835_codec_destroy(drv->isp);
2922 bcm2835_codec_destroy(drv->encode);
2926 bcm2835_codec_destroy(drv->decode);
2932 static int bcm2835_codec_remove(struct platform_device *pdev)
2934 struct bcm2835_codec_driver *drv = platform_get_drvdata(pdev);
2936 media_device_unregister(&drv->mdev);
2938 bcm2835_codec_destroy(drv->isp);
2940 bcm2835_codec_destroy(drv->encode);
2942 bcm2835_codec_destroy(drv->decode);
2944 media_device_cleanup(&drv->mdev);
2949 static struct platform_driver bcm2835_v4l2_codec_driver = {
2950 .probe = bcm2835_codec_probe,
2951 .remove = bcm2835_codec_remove,
2953 .name = "bcm2835-codec",
2954 .owner = THIS_MODULE,
2958 module_platform_driver(bcm2835_v4l2_codec_driver);
2960 MODULE_DESCRIPTION("BCM2835 codec V4L2 driver");
2961 MODULE_AUTHOR("Dave Stevenson, <dave.stevenson@raspberrypi.org>");
2962 MODULE_LICENSE("GPL");
2963 MODULE_VERSION("0.0.1");
2964 MODULE_ALIAS("platform:bcm2835-codec");