681 lines
21 KiB
Diff
681 lines
21 KiB
Diff
From 6b3c057ec5705d3c7556d4755103a2650d3aaaf5 Mon Sep 17 00:00:00 2001
|
|
From: Dave Stevenson <dsteve@broadcom.com>
|
|
Date: Wed, 12 Feb 2014 11:18:20 +0000
|
|
Subject: [PATCH 169/174] V4L2: H264 profile & level ctrls, FPS control and
|
|
auto exp pri
|
|
|
|
Several control handling updates.
|
|
H264 profile and level controls.
|
|
Timeperframe/FPS reworked to add V4L2_CID_EXPOSURE_AUTO_PRIORITY to
|
|
select whether AE is allowed to override the framerate specified.
|
|
|
|
Signed-off-by: Dave Stevenson <dsteve@broadcom.com>
|
|
---
|
|
drivers/media/platform/bcm2835/bcm2835-camera.c | 107 ++++++-----
|
|
drivers/media/platform/bcm2835/bcm2835-camera.h | 12 +-
|
|
drivers/media/platform/bcm2835/controls.c | 225 ++++++++++++++++++++++-
|
|
drivers/media/platform/bcm2835/mmal-parameters.h | 87 +++++++++
|
|
4 files changed, 383 insertions(+), 48 deletions(-)
|
|
|
|
--- a/drivers/media/platform/bcm2835/bcm2835-camera.c
|
|
+++ b/drivers/media/platform/bcm2835/bcm2835-camera.c
|
|
@@ -36,7 +36,8 @@
|
|
|
|
#define BM2835_MMAL_VERSION "0.0.2"
|
|
#define BM2835_MMAL_MODULE_NAME "bcm2835-v4l2"
|
|
-
|
|
+#define MIN_WIDTH 16
|
|
+#define MIN_HEIGHT 16
|
|
#define MAX_WIDTH 2592
|
|
#define MAX_HEIGHT 1944
|
|
#define MIN_BUFFER_SIZE (80*1024)
|
|
@@ -56,7 +57,7 @@ MODULE_PARM_DESC(bcm2835_v4l2_debug, "De
|
|
static struct bm2835_mmal_dev *gdev; /* global device data */
|
|
|
|
#define FPS_MIN 1
|
|
-#define FPS_MAX 30
|
|
+#define FPS_MAX 90
|
|
|
|
/* timeperframe: min/max and default */
|
|
static const struct v4l2_fract
|
|
@@ -903,10 +904,8 @@ static int mmal_setup_components(struct
|
|
camera_port->es.video.crop.y = 0;
|
|
camera_port->es.video.crop.width = f->fmt.pix.width;
|
|
camera_port->es.video.crop.height = f->fmt.pix.height;
|
|
- camera_port->es.video.frame_rate.num =
|
|
- dev->capture.timeperframe.denominator;
|
|
- camera_port->es.video.frame_rate.den =
|
|
- dev->capture.timeperframe.numerator;
|
|
+ camera_port->es.video.frame_rate.num = 0;
|
|
+ camera_port->es.video.frame_rate.den = 1;
|
|
|
|
ret = vchiq_mmal_port_set_format(dev->instance, camera_port);
|
|
|
|
@@ -940,8 +939,10 @@ static int mmal_setup_components(struct
|
|
preview_port->es.video.crop.y = 0;
|
|
preview_port->es.video.crop.width = f->fmt.pix.width;
|
|
preview_port->es.video.crop.height = f->fmt.pix.height;
|
|
- preview_port->es.video.frame_rate.num = 30;
|
|
- preview_port->es.video.frame_rate.den = 1;
|
|
+ preview_port->es.video.frame_rate.num =
|
|
+ dev->capture.timeperframe.denominator;
|
|
+ preview_port->es.video.frame_rate.den =
|
|
+ dev->capture.timeperframe.numerator;
|
|
ret = vchiq_mmal_port_set_format(dev->instance, preview_port);
|
|
if (overlay_enabled) {
|
|
ret = vchiq_mmal_port_connect_tunnel(
|
|
@@ -1116,22 +1117,56 @@ static int vidioc_s_fmt_vid_cap(struct f
|
|
}
|
|
|
|
ret = mmal_setup_components(dev, f);
|
|
- if (ret != 0)
|
|
+ if (ret != 0) {
|
|
v4l2_err(&dev->v4l2_dev,
|
|
"%s: failed to setup mmal components: %d\n",
|
|
__func__, ret);
|
|
+ ret = -EINVAL;
|
|
+ }
|
|
|
|
return ret;
|
|
}
|
|
|
|
+int vidioc_enum_framesizes(struct file *file, void *fh,
|
|
+ struct v4l2_frmsizeenum *fsize)
|
|
+{
|
|
+ static const struct v4l2_frmsize_stepwise sizes = {
|
|
+ MIN_WIDTH, MAX_WIDTH, 2,
|
|
+ MIN_HEIGHT, MAX_HEIGHT, 2
|
|
+ };
|
|
+ int i;
|
|
+
|
|
+ if (fsize->index)
|
|
+ return -EINVAL;
|
|
+ for (i = 0; i < ARRAY_SIZE(formats); i++)
|
|
+ if (formats[i].fourcc == fsize->pixel_format)
|
|
+ break;
|
|
+ if (i == ARRAY_SIZE(formats))
|
|
+ return -EINVAL;
|
|
+ fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE;
|
|
+ fsize->stepwise = sizes;
|
|
+ return 0;
|
|
+}
|
|
+
|
|
/* timeperframe is arbitrary and continous */
|
|
static int vidioc_enum_frameintervals(struct file *file, void *priv,
|
|
struct v4l2_frmivalenum *fival)
|
|
{
|
|
+ int i;
|
|
+
|
|
if (fival->index)
|
|
return -EINVAL;
|
|
|
|
- /* regarding width & height - we support any */
|
|
+ for (i = 0; i < ARRAY_SIZE(formats); i++)
|
|
+ if (formats[i].fourcc == fival->pixel_format)
|
|
+ break;
|
|
+ if (i == ARRAY_SIZE(formats))
|
|
+ return -EINVAL;
|
|
+
|
|
+ /* regarding width & height - we support any within range */
|
|
+ if (fival->width < MIN_WIDTH || fival->width > MAX_WIDTH ||
|
|
+ fival->height < MIN_HEIGHT || fival->height > MAX_HEIGHT)
|
|
+ return -EINVAL;
|
|
|
|
fival->type = V4L2_FRMIVAL_TYPE_CONTINUOUS;
|
|
|
|
@@ -1167,7 +1202,6 @@ static int vidioc_s_parm(struct file *fi
|
|
struct bm2835_mmal_dev *dev = video_drvdata(file);
|
|
struct v4l2_fract tpf;
|
|
struct mmal_parameter_rational fps_param;
|
|
- int ret;
|
|
|
|
if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
|
|
return -EINVAL;
|
|
@@ -1183,27 +1217,11 @@ static int vidioc_s_parm(struct file *fi
|
|
parm->parm.capture.timeperframe = tpf;
|
|
parm->parm.capture.readbuffers = 1;
|
|
|
|
- fps_param.num = dev->capture.timeperframe.denominator;
|
|
- fps_param.den = dev->capture.timeperframe.numerator;
|
|
- ret = vchiq_mmal_port_parameter_set(dev->instance,
|
|
- &dev->component[MMAL_COMPONENT_CAMERA]->
|
|
- output[MMAL_CAMERA_PORT_PREVIEW],
|
|
- MMAL_PARAMETER_VIDEO_FRAME_RATE,
|
|
- &fps_param, sizeof(fps_param));
|
|
- ret += vchiq_mmal_port_parameter_set(dev->instance,
|
|
- &dev->component[MMAL_COMPONENT_CAMERA]->
|
|
- output[MMAL_CAMERA_PORT_VIDEO],
|
|
- MMAL_PARAMETER_VIDEO_FRAME_RATE,
|
|
- &fps_param, sizeof(fps_param));
|
|
- ret += vchiq_mmal_port_parameter_set(dev->instance,
|
|
- &dev->component[MMAL_COMPONENT_CAMERA]->
|
|
- output[MMAL_CAMERA_PORT_CAPTURE],
|
|
- MMAL_PARAMETER_VIDEO_FRAME_RATE,
|
|
- &fps_param, sizeof(fps_param));
|
|
- if (ret)
|
|
- v4l2_dbg(0, bcm2835_v4l2_debug, &dev->v4l2_dev,
|
|
- "Failed to set fps ret %d\n",
|
|
- ret);
|
|
+ fps_param.num = 0; /* Select variable fps, and then use
|
|
+ * FPS_RANGE to select the actual limits.
|
|
+ */
|
|
+ fps_param.den = 1;
|
|
+ set_framerate_params(dev);
|
|
|
|
return 0;
|
|
}
|
|
@@ -1236,6 +1254,7 @@ static const struct v4l2_ioctl_ops camer
|
|
.vidioc_querybuf = vb2_ioctl_querybuf,
|
|
.vidioc_qbuf = vb2_ioctl_qbuf,
|
|
.vidioc_dqbuf = vb2_ioctl_dqbuf,
|
|
+ .vidioc_enum_framesizes = vidioc_enum_framesizes,
|
|
.vidioc_enum_frameintervals = vidioc_enum_frameintervals,
|
|
.vidioc_g_parm = vidioc_g_parm,
|
|
.vidioc_s_parm = vidioc_s_parm,
|
|
@@ -1331,10 +1350,8 @@ static int __init mmal_init(struct bm283
|
|
format->es->video.crop.y = 0;
|
|
format->es->video.crop.width = 1024;
|
|
format->es->video.crop.height = 768;
|
|
- format->es->video.frame_rate.num =
|
|
- dev->capture.timeperframe.denominator;
|
|
- format->es->video.frame_rate.den =
|
|
- dev->capture.timeperframe.numerator;
|
|
+ format->es->video.frame_rate.num = 0; /* Rely on fps_range */
|
|
+ format->es->video.frame_rate.den = 1;
|
|
|
|
format =
|
|
&dev->component[MMAL_COMPONENT_CAMERA]->
|
|
@@ -1349,10 +1366,8 @@ static int __init mmal_init(struct bm283
|
|
format->es->video.crop.y = 0;
|
|
format->es->video.crop.width = 1024;
|
|
format->es->video.crop.height = 768;
|
|
- format->es->video.frame_rate.num =
|
|
- dev->capture.timeperframe.denominator;
|
|
- format->es->video.frame_rate.den =
|
|
- dev->capture.timeperframe.numerator;
|
|
+ format->es->video.frame_rate.num = 0; /* Rely on fps_range */
|
|
+ format->es->video.frame_rate.den = 1;
|
|
|
|
format =
|
|
&dev->component[MMAL_COMPONENT_CAMERA]->
|
|
@@ -1366,7 +1381,7 @@ static int __init mmal_init(struct bm283
|
|
format->es->video.crop.y = 0;
|
|
format->es->video.crop.width = 2592;
|
|
format->es->video.crop.height = 1944;
|
|
- format->es->video.frame_rate.num = 30;
|
|
+ format->es->video.frame_rate.num = 0; /* Rely on fps_range */
|
|
format->es->video.frame_rate.den = 1;
|
|
|
|
dev->capture.width = format->es->video.width;
|
|
@@ -1374,6 +1389,8 @@ static int __init mmal_init(struct bm283
|
|
dev->capture.fmt = &formats[0];
|
|
dev->capture.encode_component = NULL;
|
|
dev->capture.timeperframe = tpf_default;
|
|
+ dev->capture.enc_profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH;
|
|
+ dev->capture.enc_level = V4L2_MPEG_VIDEO_H264_LEVEL_4_0;
|
|
|
|
/* get the preview component ready */
|
|
ret = vchiq_mmal_component_init(
|
|
@@ -1420,6 +1437,14 @@ static int __init mmal_init(struct bm283
|
|
}
|
|
|
|
{
|
|
+ struct vchiq_mmal_port *encoder_port =
|
|
+ &dev->component[MMAL_COMPONENT_VIDEO_ENCODE]->output[0];
|
|
+ encoder_port->format.encoding = MMAL_ENCODING_H264;
|
|
+ ret = vchiq_mmal_port_set_format(dev->instance,
|
|
+ encoder_port);
|
|
+ }
|
|
+
|
|
+ {
|
|
unsigned int enable = 1;
|
|
vchiq_mmal_port_parameter_set(
|
|
dev->instance,
|
|
--- a/drivers/media/platform/bcm2835/bcm2835-camera.h
|
|
+++ b/drivers/media/platform/bcm2835/bcm2835-camera.h
|
|
@@ -15,7 +15,7 @@
|
|
* core driver device
|
|
*/
|
|
|
|
-#define V4L2_CTRL_COUNT 21 /* number of v4l controls */
|
|
+#define V4L2_CTRL_COUNT 24 /* number of v4l controls */
|
|
|
|
enum {
|
|
MMAL_COMPONENT_CAMERA = 0,
|
|
@@ -49,7 +49,9 @@ struct bm2835_mmal_dev {
|
|
int hflip;
|
|
int vflip;
|
|
enum mmal_parameter_exposuremode exposure_mode;
|
|
+ enum v4l2_exposure_auto_type exposure_mode_v4l2;
|
|
unsigned int manual_shutter_speed;
|
|
+ bool exp_auto_priority;
|
|
|
|
/* allocated mmal instance and components */
|
|
struct vchiq_mmal_instance *instance;
|
|
@@ -63,12 +65,16 @@ struct bm2835_mmal_dev {
|
|
unsigned int height; /* height */
|
|
unsigned int stride; /* stride */
|
|
struct mmal_fmt *fmt;
|
|
- struct v4l2_fract timeperframe;
|
|
+ struct v4l2_fract timeperframe;
|
|
|
|
/* H264 encode bitrate */
|
|
int encode_bitrate;
|
|
/* H264 bitrate mode. CBR/VBR */
|
|
int encode_bitrate_mode;
|
|
+ /* H264 profile */
|
|
+ enum v4l2_mpeg_video_h264_profile enc_profile;
|
|
+ /* H264 level */
|
|
+ enum v4l2_mpeg_video_h264_level enc_level;
|
|
/* JPEG Q-factor */
|
|
int q_factor;
|
|
|
|
@@ -98,7 +104,7 @@ int bm2835_mmal_init_controls(
|
|
struct v4l2_ctrl_handler *hdl);
|
|
|
|
int bm2835_mmal_set_all_camera_controls(struct bm2835_mmal_dev *dev);
|
|
-
|
|
+int set_framerate_params(struct bm2835_mmal_dev *dev);
|
|
|
|
/* Debug helpers */
|
|
|
|
--- a/drivers/media/platform/bcm2835/controls.c
|
|
+++ b/drivers/media/platform/bcm2835/controls.c
|
|
@@ -69,7 +69,6 @@ static const s64 bitrate_mode_qmenu[] =
|
|
(s64)V4L2_MPEG_VIDEO_BITRATE_MODE_CBR,
|
|
};
|
|
|
|
-
|
|
enum bm2835_mmal_ctrl_type {
|
|
MMAL_CONTROL_TYPE_STD,
|
|
MMAL_CONTROL_TYPE_STD_MENU,
|
|
@@ -329,6 +328,9 @@ static int ctrl_set_exposure(struct bm28
|
|
|
|
}
|
|
dev->exposure_mode = exp_mode;
|
|
+ dev->exposure_mode_v4l2 = ctrl->val;
|
|
+ } else if (mmal_ctrl->id == V4L2_CID_EXPOSURE_AUTO_PRIORITY) {
|
|
+ dev->exp_auto_priority = ctrl->val;
|
|
}
|
|
|
|
if (dev->exposure_mode == MMAL_PARAM_EXPOSUREMODE_OFF)
|
|
@@ -340,6 +342,8 @@ static int ctrl_set_exposure(struct bm28
|
|
ret += vchiq_mmal_port_parameter_set(dev->instance, control,
|
|
MMAL_PARAMETER_EXPOSURE_MODE,
|
|
&exp_mode, sizeof(u32));
|
|
+ ret += set_framerate_params(dev);
|
|
+
|
|
return ret;
|
|
}
|
|
|
|
@@ -540,8 +544,8 @@ static int ctrl_set_colfx(struct bm2835_
|
|
&dev->colourfx, sizeof(dev->colourfx));
|
|
|
|
v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
|
|
- "After: mmal_ctrl:%p ctrl id:0x%x ctrl val:%d ret %d(%d)\n",
|
|
- mmal_ctrl, ctrl->id, ctrl->val, ret,
|
|
+ "%s: After: mmal_ctrl:%p ctrl id:0x%x ctrl val:%d ret %d(%d)\n",
|
|
+ __func__, mmal_ctrl, ctrl->id, ctrl->val, ret,
|
|
(ret == 0 ? 0 : -EINVAL));
|
|
return (ret == 0 ? 0 : EINVAL);
|
|
}
|
|
@@ -623,6 +627,117 @@ static int ctrl_set_video_encode_param_o
|
|
&u32_value, sizeof(u32_value));
|
|
}
|
|
|
|
+static int ctrl_set_video_encode_profile_level(struct bm2835_mmal_dev *dev,
|
|
+ struct v4l2_ctrl *ctrl,
|
|
+ const struct bm2835_mmal_v4l2_ctrl *mmal_ctrl)
|
|
+{
|
|
+ struct mmal_parameter_video_profile param;
|
|
+ int ret = 0;
|
|
+
|
|
+ if (ctrl->id == V4L2_CID_MPEG_VIDEO_H264_PROFILE) {
|
|
+ switch (ctrl->val) {
|
|
+ case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE:
|
|
+ case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE:
|
|
+ case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN:
|
|
+ case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH:
|
|
+ dev->capture.enc_profile = ctrl->val;
|
|
+ break;
|
|
+ default:
|
|
+ ret = -EINVAL;
|
|
+ break;
|
|
+ }
|
|
+ } else if (ctrl->id == V4L2_CID_MPEG_VIDEO_H264_LEVEL) {
|
|
+ switch (ctrl->val) {
|
|
+ case V4L2_MPEG_VIDEO_H264_LEVEL_1_0:
|
|
+ case V4L2_MPEG_VIDEO_H264_LEVEL_1B:
|
|
+ case V4L2_MPEG_VIDEO_H264_LEVEL_1_1:
|
|
+ case V4L2_MPEG_VIDEO_H264_LEVEL_1_2:
|
|
+ case V4L2_MPEG_VIDEO_H264_LEVEL_1_3:
|
|
+ case V4L2_MPEG_VIDEO_H264_LEVEL_2_0:
|
|
+ case V4L2_MPEG_VIDEO_H264_LEVEL_2_1:
|
|
+ case V4L2_MPEG_VIDEO_H264_LEVEL_2_2:
|
|
+ case V4L2_MPEG_VIDEO_H264_LEVEL_3_0:
|
|
+ case V4L2_MPEG_VIDEO_H264_LEVEL_3_1:
|
|
+ case V4L2_MPEG_VIDEO_H264_LEVEL_3_2:
|
|
+ case V4L2_MPEG_VIDEO_H264_LEVEL_4_0:
|
|
+ dev->capture.enc_level = ctrl->val;
|
|
+ break;
|
|
+ default:
|
|
+ ret = -EINVAL;
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (!ret) {
|
|
+ switch (dev->capture.enc_profile) {
|
|
+ case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE:
|
|
+ param.profile = MMAL_VIDEO_PROFILE_H264_BASELINE;
|
|
+ break;
|
|
+ case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE:
|
|
+ param.profile =
|
|
+ MMAL_VIDEO_PROFILE_H264_CONSTRAINED_BASELINE;
|
|
+ break;
|
|
+ case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN:
|
|
+ param.profile = MMAL_VIDEO_PROFILE_H264_MAIN;
|
|
+ break;
|
|
+ case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH:
|
|
+ param.profile = MMAL_VIDEO_PROFILE_H264_HIGH;
|
|
+ break;
|
|
+ default:
|
|
+ /* Should never get here */
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ switch (dev->capture.enc_level) {
|
|
+ case V4L2_MPEG_VIDEO_H264_LEVEL_1_0:
|
|
+ param.level = MMAL_VIDEO_LEVEL_H264_1;
|
|
+ break;
|
|
+ case V4L2_MPEG_VIDEO_H264_LEVEL_1B:
|
|
+ param.level = MMAL_VIDEO_LEVEL_H264_1b;
|
|
+ break;
|
|
+ case V4L2_MPEG_VIDEO_H264_LEVEL_1_1:
|
|
+ param.level = MMAL_VIDEO_LEVEL_H264_11;
|
|
+ break;
|
|
+ case V4L2_MPEG_VIDEO_H264_LEVEL_1_2:
|
|
+ param.level = MMAL_VIDEO_LEVEL_H264_12;
|
|
+ break;
|
|
+ case V4L2_MPEG_VIDEO_H264_LEVEL_1_3:
|
|
+ param.level = MMAL_VIDEO_LEVEL_H264_13;
|
|
+ break;
|
|
+ case V4L2_MPEG_VIDEO_H264_LEVEL_2_0:
|
|
+ param.level = MMAL_VIDEO_LEVEL_H264_2;
|
|
+ break;
|
|
+ case V4L2_MPEG_VIDEO_H264_LEVEL_2_1:
|
|
+ param.level = MMAL_VIDEO_LEVEL_H264_21;
|
|
+ break;
|
|
+ case V4L2_MPEG_VIDEO_H264_LEVEL_2_2:
|
|
+ param.level = MMAL_VIDEO_LEVEL_H264_22;
|
|
+ break;
|
|
+ case V4L2_MPEG_VIDEO_H264_LEVEL_3_0:
|
|
+ param.level = MMAL_VIDEO_LEVEL_H264_3;
|
|
+ break;
|
|
+ case V4L2_MPEG_VIDEO_H264_LEVEL_3_1:
|
|
+ param.level = MMAL_VIDEO_LEVEL_H264_31;
|
|
+ break;
|
|
+ case V4L2_MPEG_VIDEO_H264_LEVEL_3_2:
|
|
+ param.level = MMAL_VIDEO_LEVEL_H264_32;
|
|
+ break;
|
|
+ case V4L2_MPEG_VIDEO_H264_LEVEL_4_0:
|
|
+ param.level = MMAL_VIDEO_LEVEL_H264_4;
|
|
+ break;
|
|
+ default:
|
|
+ /* Should never get here */
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ ret = vchiq_mmal_port_parameter_set(dev->instance,
|
|
+ &dev->component[MMAL_COMPONENT_VIDEO_ENCODE]->output[0],
|
|
+ mmal_ctrl->mmal_id,
|
|
+ ¶m, sizeof(param));
|
|
+ }
|
|
+ return ret;
|
|
+}
|
|
+
|
|
static int bm2835_mmal_s_ctrl(struct v4l2_ctrl *ctrl)
|
|
{
|
|
struct bm2835_mmal_dev *dev =
|
|
@@ -639,6 +754,9 @@ static int bm2835_mmal_s_ctrl(struct v4l
|
|
}
|
|
|
|
ret = mmal_ctrl->setter(dev, ctrl, mmal_ctrl);
|
|
+ if (ret)
|
|
+ pr_warn("ctrl id:%d/MMAL param %08X- returned ret %d\n",
|
|
+ ctrl->id, mmal_ctrl->mmal_id, ret);
|
|
if (mmal_ctrl->ignore_errors)
|
|
ret = 0;
|
|
return ret;
|
|
@@ -725,6 +843,14 @@ static const struct bm2835_mmal_v4l2_ctr
|
|
false
|
|
},
|
|
{
|
|
+ V4L2_CID_EXPOSURE_AUTO_PRIORITY, MMAL_CONTROL_TYPE_STD,
|
|
+ 0, 1,
|
|
+ 0, 1, NULL,
|
|
+ 0, /* Dummy MMAL ID as it gets mapped into FPS range*/
|
|
+ &ctrl_set_exposure,
|
|
+ false
|
|
+ },
|
|
+ {
|
|
V4L2_CID_EXPOSURE_METERING,
|
|
MMAL_CONTROL_TYPE_STD_MENU,
|
|
~0x7, 2, V4L2_EXPOSURE_METERING_AVERAGE, 0, NULL,
|
|
@@ -814,6 +940,39 @@ static const struct bm2835_mmal_v4l2_ctr
|
|
&ctrl_set_video_encode_param_output,
|
|
true /* Errors ignored as requires latest firmware to work */
|
|
},
|
|
+ {
|
|
+ V4L2_CID_MPEG_VIDEO_H264_PROFILE,
|
|
+ MMAL_CONTROL_TYPE_STD_MENU,
|
|
+ ~((1<<V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE) |
|
|
+ (1<<V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE) |
|
|
+ (1<<V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) |
|
|
+ (1<<V4L2_MPEG_VIDEO_H264_PROFILE_HIGH)),
|
|
+ V4L2_MPEG_VIDEO_H264_PROFILE_HIGH,
|
|
+ V4L2_MPEG_VIDEO_H264_PROFILE_HIGH, 1, NULL,
|
|
+ MMAL_PARAMETER_PROFILE,
|
|
+ &ctrl_set_video_encode_profile_level,
|
|
+ false
|
|
+ },
|
|
+ {
|
|
+ V4L2_CID_MPEG_VIDEO_H264_LEVEL, MMAL_CONTROL_TYPE_STD_MENU,
|
|
+ ~((1<<V4L2_MPEG_VIDEO_H264_LEVEL_1_0) |
|
|
+ (1<<V4L2_MPEG_VIDEO_H264_LEVEL_1B) |
|
|
+ (1<<V4L2_MPEG_VIDEO_H264_LEVEL_1_1) |
|
|
+ (1<<V4L2_MPEG_VIDEO_H264_LEVEL_1_2) |
|
|
+ (1<<V4L2_MPEG_VIDEO_H264_LEVEL_1_3) |
|
|
+ (1<<V4L2_MPEG_VIDEO_H264_LEVEL_2_0) |
|
|
+ (1<<V4L2_MPEG_VIDEO_H264_LEVEL_2_1) |
|
|
+ (1<<V4L2_MPEG_VIDEO_H264_LEVEL_2_2) |
|
|
+ (1<<V4L2_MPEG_VIDEO_H264_LEVEL_3_0) |
|
|
+ (1<<V4L2_MPEG_VIDEO_H264_LEVEL_3_1) |
|
|
+ (1<<V4L2_MPEG_VIDEO_H264_LEVEL_3_2) |
|
|
+ (1<<V4L2_MPEG_VIDEO_H264_LEVEL_4_0)),
|
|
+ V4L2_MPEG_VIDEO_H264_LEVEL_4_0,
|
|
+ V4L2_MPEG_VIDEO_H264_LEVEL_4_0, 1, NULL,
|
|
+ MMAL_PARAMETER_PROFILE,
|
|
+ &ctrl_set_video_encode_profile_level,
|
|
+ false
|
|
+ },
|
|
};
|
|
|
|
int bm2835_mmal_set_all_camera_controls(struct bm2835_mmal_dev *dev)
|
|
@@ -825,13 +984,71 @@ int bm2835_mmal_set_all_camera_controls(
|
|
if ((dev->ctrls[c]) && (v4l2_ctrls[c].setter)) {
|
|
ret = v4l2_ctrls[c].setter(dev, dev->ctrls[c],
|
|
&v4l2_ctrls[c]);
|
|
- if (!v4l2_ctrls[c]. ignore_errors && ret)
|
|
+ if (!v4l2_ctrls[c].ignore_errors && ret) {
|
|
+ v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
|
|
+ "Failed when setting default values for ctrl %d\n",
|
|
+ c);
|
|
break;
|
|
+ }
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
+int set_framerate_params(struct bm2835_mmal_dev *dev)
|
|
+{
|
|
+ struct mmal_parameter_fps_range fps_range;
|
|
+ int ret;
|
|
+
|
|
+ if ((dev->exposure_mode_v4l2 == V4L2_EXPOSURE_AUTO ||
|
|
+ dev->exposure_mode_v4l2 == V4L2_EXPOSURE_APERTURE_PRIORITY) &&
|
|
+ (dev->exp_auto_priority)) {
|
|
+ /* Variable FPS. Define min FPS as 1fps.
|
|
+ * Max as max defined FPS.
|
|
+ */
|
|
+ fps_range.fps_low.num = 1;
|
|
+ fps_range.fps_low.den = 1;
|
|
+ fps_range.fps_high.num = dev->capture.timeperframe.denominator;
|
|
+ fps_range.fps_high.den = dev->capture.timeperframe.numerator;
|
|
+ } else {
|
|
+ /* Fixed FPS - set min and max to be the same */
|
|
+ fps_range.fps_low.num = fps_range.fps_high.num =
|
|
+ dev->capture.timeperframe.denominator;
|
|
+ fps_range.fps_low.den = fps_range.fps_high.den =
|
|
+ dev->capture.timeperframe.numerator;
|
|
+ }
|
|
+
|
|
+ v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
|
|
+ "Set fps range to %d/%d to %d/%d\n",
|
|
+ fps_range.fps_low.num,
|
|
+ fps_range.fps_low.den,
|
|
+ fps_range.fps_high.num,
|
|
+ fps_range.fps_high.den
|
|
+ );
|
|
+
|
|
+ ret = vchiq_mmal_port_parameter_set(dev->instance,
|
|
+ &dev->component[MMAL_COMPONENT_CAMERA]->
|
|
+ output[MMAL_CAMERA_PORT_PREVIEW],
|
|
+ MMAL_PARAMETER_FPS_RANGE,
|
|
+ &fps_range, sizeof(fps_range));
|
|
+ ret += vchiq_mmal_port_parameter_set(dev->instance,
|
|
+ &dev->component[MMAL_COMPONENT_CAMERA]->
|
|
+ output[MMAL_CAMERA_PORT_VIDEO],
|
|
+ MMAL_PARAMETER_FPS_RANGE,
|
|
+ &fps_range, sizeof(fps_range));
|
|
+ ret += vchiq_mmal_port_parameter_set(dev->instance,
|
|
+ &dev->component[MMAL_COMPONENT_CAMERA]->
|
|
+ output[MMAL_CAMERA_PORT_CAPTURE],
|
|
+ MMAL_PARAMETER_FPS_RANGE,
|
|
+ &fps_range, sizeof(fps_range));
|
|
+ if (ret)
|
|
+ v4l2_dbg(0, bcm2835_v4l2_debug, &dev->v4l2_dev,
|
|
+ "Failed to set fps ret %d\n",
|
|
+ ret);
|
|
+
|
|
+ return ret;
|
|
+
|
|
+}
|
|
int bm2835_mmal_init_controls(struct bm2835_mmal_dev *dev,
|
|
struct v4l2_ctrl_handler *hdl)
|
|
{
|
|
--- a/drivers/media/platform/bcm2835/mmal-parameters.h
|
|
+++ b/drivers/media/platform/bcm2835/mmal-parameters.h
|
|
@@ -182,6 +182,14 @@ enum mmal_parameter_camera_config_timest
|
|
*/
|
|
};
|
|
|
|
+struct mmal_parameter_fps_range {
|
|
+ /**< Low end of the permitted framerate range */
|
|
+ struct mmal_parameter_rational fps_low;
|
|
+ /**< High end of the permitted framerate range */
|
|
+ struct mmal_parameter_rational fps_high;
|
|
+};
|
|
+
|
|
+
|
|
/* camera configuration parameter */
|
|
struct mmal_parameter_camera_config {
|
|
/* Parameters for setting up the image pools */
|
|
@@ -293,6 +301,85 @@ enum mmal_parameter_rate_control_mode {
|
|
MMAL_VIDEO_RATECONTROL_CONSTANT_SKIP_FRAMES
|
|
};
|
|
|
|
+enum mmal_video_profile {
|
|
+ MMAL_VIDEO_PROFILE_H263_BASELINE,
|
|
+ MMAL_VIDEO_PROFILE_H263_H320CODING,
|
|
+ MMAL_VIDEO_PROFILE_H263_BACKWARDCOMPATIBLE,
|
|
+ MMAL_VIDEO_PROFILE_H263_ISWV2,
|
|
+ MMAL_VIDEO_PROFILE_H263_ISWV3,
|
|
+ MMAL_VIDEO_PROFILE_H263_HIGHCOMPRESSION,
|
|
+ MMAL_VIDEO_PROFILE_H263_INTERNET,
|
|
+ MMAL_VIDEO_PROFILE_H263_INTERLACE,
|
|
+ MMAL_VIDEO_PROFILE_H263_HIGHLATENCY,
|
|
+ MMAL_VIDEO_PROFILE_MP4V_SIMPLE,
|
|
+ MMAL_VIDEO_PROFILE_MP4V_SIMPLESCALABLE,
|
|
+ MMAL_VIDEO_PROFILE_MP4V_CORE,
|
|
+ MMAL_VIDEO_PROFILE_MP4V_MAIN,
|
|
+ MMAL_VIDEO_PROFILE_MP4V_NBIT,
|
|
+ MMAL_VIDEO_PROFILE_MP4V_SCALABLETEXTURE,
|
|
+ MMAL_VIDEO_PROFILE_MP4V_SIMPLEFACE,
|
|
+ MMAL_VIDEO_PROFILE_MP4V_SIMPLEFBA,
|
|
+ MMAL_VIDEO_PROFILE_MP4V_BASICANIMATED,
|
|
+ MMAL_VIDEO_PROFILE_MP4V_HYBRID,
|
|
+ MMAL_VIDEO_PROFILE_MP4V_ADVANCEDREALTIME,
|
|
+ MMAL_VIDEO_PROFILE_MP4V_CORESCALABLE,
|
|
+ MMAL_VIDEO_PROFILE_MP4V_ADVANCEDCODING,
|
|
+ MMAL_VIDEO_PROFILE_MP4V_ADVANCEDCORE,
|
|
+ MMAL_VIDEO_PROFILE_MP4V_ADVANCEDSCALABLE,
|
|
+ MMAL_VIDEO_PROFILE_MP4V_ADVANCEDSIMPLE,
|
|
+ MMAL_VIDEO_PROFILE_H264_BASELINE,
|
|
+ MMAL_VIDEO_PROFILE_H264_MAIN,
|
|
+ MMAL_VIDEO_PROFILE_H264_EXTENDED,
|
|
+ MMAL_VIDEO_PROFILE_H264_HIGH,
|
|
+ MMAL_VIDEO_PROFILE_H264_HIGH10,
|
|
+ MMAL_VIDEO_PROFILE_H264_HIGH422,
|
|
+ MMAL_VIDEO_PROFILE_H264_HIGH444,
|
|
+ MMAL_VIDEO_PROFILE_H264_CONSTRAINED_BASELINE,
|
|
+ MMAL_VIDEO_PROFILE_DUMMY = 0x7FFFFFFF
|
|
+};
|
|
+
|
|
+enum mmal_video_level {
|
|
+ MMAL_VIDEO_LEVEL_H263_10,
|
|
+ MMAL_VIDEO_LEVEL_H263_20,
|
|
+ MMAL_VIDEO_LEVEL_H263_30,
|
|
+ MMAL_VIDEO_LEVEL_H263_40,
|
|
+ MMAL_VIDEO_LEVEL_H263_45,
|
|
+ MMAL_VIDEO_LEVEL_H263_50,
|
|
+ MMAL_VIDEO_LEVEL_H263_60,
|
|
+ MMAL_VIDEO_LEVEL_H263_70,
|
|
+ MMAL_VIDEO_LEVEL_MP4V_0,
|
|
+ MMAL_VIDEO_LEVEL_MP4V_0b,
|
|
+ MMAL_VIDEO_LEVEL_MP4V_1,
|
|
+ MMAL_VIDEO_LEVEL_MP4V_2,
|
|
+ MMAL_VIDEO_LEVEL_MP4V_3,
|
|
+ MMAL_VIDEO_LEVEL_MP4V_4,
|
|
+ MMAL_VIDEO_LEVEL_MP4V_4a,
|
|
+ MMAL_VIDEO_LEVEL_MP4V_5,
|
|
+ MMAL_VIDEO_LEVEL_MP4V_6,
|
|
+ MMAL_VIDEO_LEVEL_H264_1,
|
|
+ MMAL_VIDEO_LEVEL_H264_1b,
|
|
+ MMAL_VIDEO_LEVEL_H264_11,
|
|
+ MMAL_VIDEO_LEVEL_H264_12,
|
|
+ MMAL_VIDEO_LEVEL_H264_13,
|
|
+ MMAL_VIDEO_LEVEL_H264_2,
|
|
+ MMAL_VIDEO_LEVEL_H264_21,
|
|
+ MMAL_VIDEO_LEVEL_H264_22,
|
|
+ MMAL_VIDEO_LEVEL_H264_3,
|
|
+ MMAL_VIDEO_LEVEL_H264_31,
|
|
+ MMAL_VIDEO_LEVEL_H264_32,
|
|
+ MMAL_VIDEO_LEVEL_H264_4,
|
|
+ MMAL_VIDEO_LEVEL_H264_41,
|
|
+ MMAL_VIDEO_LEVEL_H264_42,
|
|
+ MMAL_VIDEO_LEVEL_H264_5,
|
|
+ MMAL_VIDEO_LEVEL_H264_51,
|
|
+ MMAL_VIDEO_LEVEL_DUMMY = 0x7FFFFFFF
|
|
+};
|
|
+
|
|
+struct mmal_parameter_video_profile {
|
|
+ enum mmal_video_profile profile;
|
|
+ enum mmal_video_level level;
|
|
+};
|
|
+
|
|
/* video parameters */
|
|
|
|
enum mmal_parameter_video_type {
|