36897db1c0cbe6b240532da84a9c2d023ac12e8c
[openwrt/staging/yousong.git] / target / linux / brcm2708 / patches-3.10 / 0136-V4L2-Add-support-for-frame-rate-control.patch
1 From 980348ac7301c266ddbed9256ad9835cbda6e719 Mon Sep 17 00:00:00 2001
2 From: Dave Stevenson <dsteve@broadcom.com>
3 Date: Fri, 13 Dec 2013 15:54:13 +0000
4 Subject: [PATCH 136/174] V4L2: Add support for frame rate control.
5
6 Add support for frame rate (or time per frame as V4L2
7 inverts it) control via s_parm.
8
9 Signed-off-by: Dave Stevenson <dsteve@broadcom.com>
10 ---
11 drivers/media/platform/bcm2835/bcm2835-camera.c | 115 +++++++++++++++++++++--
12 drivers/media/platform/bcm2835/bcm2835-camera.h | 4 +-
13 drivers/media/platform/bcm2835/controls.c | 5 +-
14 drivers/media/platform/bcm2835/mmal-parameters.h | 5 +
15 4 files changed, 116 insertions(+), 13 deletions(-)
16
17 --- a/drivers/media/platform/bcm2835/bcm2835-camera.c
18 +++ b/drivers/media/platform/bcm2835/bcm2835-camera.c
19 @@ -55,6 +55,15 @@ MODULE_PARM_DESC(bcm2835_v4l2_debug, "De
20
21 static struct bm2835_mmal_dev *gdev; /* global device data */
22
23 +#define FPS_MIN 1
24 +#define FPS_MAX 30
25 +
26 +/* timeperframe: min/max and default */
27 +static const struct v4l2_fract
28 + tpf_min = {.numerator = 1, .denominator = FPS_MAX},
29 + tpf_max = {.numerator = 1, .denominator = FPS_MIN},
30 + tpf_default = {.numerator = 1000, .denominator = 30000};
31 +
32 /* video formats */
33 static struct mmal_fmt formats[] = {
34 {
35 @@ -869,8 +878,10 @@ static int mmal_setup_components(struct
36 camera_port->es.video.crop.y = 0;
37 camera_port->es.video.crop.width = f->fmt.pix.width;
38 camera_port->es.video.crop.height = f->fmt.pix.height;
39 - camera_port->es.video.frame_rate.num = 30;
40 - camera_port->es.video.frame_rate.den = 1;
41 + camera_port->es.video.frame_rate.num =
42 + dev->capture.timeperframe.denominator;
43 + camera_port->es.video.frame_rate.den =
44 + dev->capture.timeperframe.numerator;
45
46 ret = vchiq_mmal_port_set_format(dev->instance, camera_port);
47
48 @@ -1064,6 +1075,90 @@ static int vidioc_s_fmt_vid_cap(struct f
49 return ret;
50 }
51
52 +/* timeperframe is arbitrary and continous */
53 +static int vidioc_enum_frameintervals(struct file *file, void *priv,
54 + struct v4l2_frmivalenum *fival)
55 +{
56 + if (fival->index)
57 + return -EINVAL;
58 +
59 + /* regarding width & height - we support any */
60 +
61 + fival->type = V4L2_FRMIVAL_TYPE_CONTINUOUS;
62 +
63 + /* fill in stepwise (step=1.0 is requred by V4L2 spec) */
64 + fival->stepwise.min = tpf_min;
65 + fival->stepwise.max = tpf_max;
66 + fival->stepwise.step = (struct v4l2_fract) {1, 1};
67 +
68 + return 0;
69 +}
70 +
71 +static int vidioc_g_parm(struct file *file, void *priv,
72 + struct v4l2_streamparm *parm)
73 +{
74 + struct bm2835_mmal_dev *dev = video_drvdata(file);
75 +
76 + if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
77 + return -EINVAL;
78 +
79 + parm->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
80 + parm->parm.capture.timeperframe = dev->capture.timeperframe;
81 + parm->parm.capture.readbuffers = 1;
82 + return 0;
83 +}
84 +
85 +#define FRACT_CMP(a, OP, b) \
86 + ((u64)(a).numerator * (b).denominator OP \
87 + (u64)(b).numerator * (a).denominator)
88 +
89 +static int vidioc_s_parm(struct file *file, void *priv,
90 + struct v4l2_streamparm *parm)
91 +{
92 + struct bm2835_mmal_dev *dev = video_drvdata(file);
93 + struct v4l2_fract tpf;
94 + struct mmal_parameter_rational fps_param;
95 + int ret;
96 +
97 + if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
98 + return -EINVAL;
99 +
100 + tpf = parm->parm.capture.timeperframe;
101 +
102 + /* tpf: {*, 0} resets timing; clip to [min, max]*/
103 + tpf = tpf.denominator ? tpf : tpf_default;
104 + tpf = FRACT_CMP(tpf, <, tpf_min) ? tpf_min : tpf;
105 + tpf = FRACT_CMP(tpf, >, tpf_max) ? tpf_max : tpf;
106 +
107 + dev->capture.timeperframe = tpf;
108 + parm->parm.capture.timeperframe = tpf;
109 + parm->parm.capture.readbuffers = 1;
110 +
111 + fps_param.num = dev->capture.timeperframe.denominator;
112 + fps_param.den = dev->capture.timeperframe.numerator;
113 + ret = vchiq_mmal_port_parameter_set(dev->instance,
114 + &dev->component[MMAL_COMPONENT_CAMERA]->
115 + output[MMAL_CAMERA_PORT_PREVIEW],
116 + MMAL_PARAMETER_VIDEO_FRAME_RATE,
117 + &fps_param, sizeof(fps_param));
118 + ret += vchiq_mmal_port_parameter_set(dev->instance,
119 + &dev->component[MMAL_COMPONENT_CAMERA]->
120 + output[MMAL_CAMERA_PORT_VIDEO],
121 + MMAL_PARAMETER_VIDEO_FRAME_RATE,
122 + &fps_param, sizeof(fps_param));
123 + ret += vchiq_mmal_port_parameter_set(dev->instance,
124 + &dev->component[MMAL_COMPONENT_CAMERA]->
125 + output[MMAL_CAMERA_PORT_CAPTURE],
126 + MMAL_PARAMETER_VIDEO_FRAME_RATE,
127 + &fps_param, sizeof(fps_param));
128 + if (ret)
129 + v4l2_dbg(0, bcm2835_v4l2_debug, &dev->v4l2_dev,
130 + "Failed to set fps ret %d\n",
131 + ret);
132 +
133 + return 0;
134 +}
135 +
136 static const struct v4l2_ioctl_ops camera0_ioctl_ops = {
137 /* overlay */
138 .vidioc_enum_fmt_vid_overlay = vidioc_enum_fmt_vid_overlay,
139 @@ -1092,6 +1187,9 @@ static const struct v4l2_ioctl_ops camer
140 .vidioc_querybuf = vb2_ioctl_querybuf,
141 .vidioc_qbuf = vb2_ioctl_qbuf,
142 .vidioc_dqbuf = vb2_ioctl_dqbuf,
143 + .vidioc_enum_frameintervals = vidioc_enum_frameintervals,
144 + .vidioc_g_parm = vidioc_g_parm,
145 + .vidioc_s_parm = vidioc_s_parm,
146 .vidioc_streamon = vb2_ioctl_streamon,
147 .vidioc_streamoff = vb2_ioctl_streamoff,
148
149 @@ -1184,8 +1282,10 @@ static int __init mmal_init(struct bm283
150 format->es->video.crop.y = 0;
151 format->es->video.crop.width = 1024;
152 format->es->video.crop.height = 768;
153 - format->es->video.frame_rate.num = PREVIEW_FRAME_RATE_NUM;
154 - format->es->video.frame_rate.den = PREVIEW_FRAME_RATE_DEN;
155 + format->es->video.frame_rate.num =
156 + dev->capture.timeperframe.denominator;
157 + format->es->video.frame_rate.den =
158 + dev->capture.timeperframe.numerator;
159
160 format =
161 &dev->component[MMAL_COMPONENT_CAMERA]->
162 @@ -1200,8 +1300,10 @@ static int __init mmal_init(struct bm283
163 format->es->video.crop.y = 0;
164 format->es->video.crop.width = 1024;
165 format->es->video.crop.height = 768;
166 - format->es->video.frame_rate.num = PREVIEW_FRAME_RATE_NUM;
167 - format->es->video.frame_rate.den = PREVIEW_FRAME_RATE_DEN;
168 + format->es->video.frame_rate.num =
169 + dev->capture.timeperframe.denominator;
170 + format->es->video.frame_rate.den =
171 + dev->capture.timeperframe.numerator;
172
173 format =
174 &dev->component[MMAL_COMPONENT_CAMERA]->
175 @@ -1222,6 +1324,7 @@ static int __init mmal_init(struct bm283
176 dev->capture.height = format->es->video.height;
177 dev->capture.fmt = &formats[0];
178 dev->capture.encode_component = NULL;
179 + dev->capture.timeperframe = tpf_default;
180
181 /* get the preview component ready */
182 ret = vchiq_mmal_component_init(
183 --- a/drivers/media/platform/bcm2835/bcm2835-camera.h
184 +++ b/drivers/media/platform/bcm2835/bcm2835-camera.h
185 @@ -32,9 +32,6 @@ enum {
186 MMAL_CAMERA_PORT_COUNT
187 };
188
189 -#define PREVIEW_FRAME_RATE_NUM 30
190 -#define PREVIEW_FRAME_RATE_DEN 1
191 -
192 #define PREVIEW_LAYER 2
193
194 extern int bcm2835_v4l2_debug;
195 @@ -66,6 +63,7 @@ struct bm2835_mmal_dev {
196 unsigned int height; /* height */
197 unsigned int stride; /* stride */
198 struct mmal_fmt *fmt;
199 + struct v4l2_fract timeperframe;
200
201 /* H264 encode bitrate */
202 int encode_bitrate;
203 --- a/drivers/media/platform/bcm2835/controls.c
204 +++ b/drivers/media/platform/bcm2835/controls.c
205 @@ -152,10 +152,7 @@ static int ctrl_set_rational(struct bm28
206 struct v4l2_ctrl *ctrl,
207 const struct bm2835_mmal_v4l2_ctrl *mmal_ctrl)
208 {
209 - struct {
210 - s32 num; /**< Numerator */
211 - s32 den; /**< Denominator */
212 - } rational_value;
213 + struct mmal_parameter_rational rational_value;
214 struct vchiq_mmal_port *control;
215
216 control = &dev->component[MMAL_COMPONENT_CAMERA]->control;
217 --- a/drivers/media/platform/bcm2835/mmal-parameters.h
218 +++ b/drivers/media/platform/bcm2835/mmal-parameters.h
219 @@ -164,6 +164,11 @@ enum mmal_parameter_camera_type {
220 MMAL_PARAMETER_SHUTTER_SPEED /**< Takes a @ref MMAL_PARAMETER_UINT32_T */
221 };
222
223 +struct mmal_parameter_rational {
224 + s32 num; /**< Numerator */
225 + s32 den; /**< Denominator */
226 +};
227 +
228 enum mmal_parameter_camera_config_timestamp_mode {
229 MMAL_PARAM_TIMESTAMP_MODE_ZERO = 0, /* Always timestamp frames as 0 */
230 MMAL_PARAM_TIMESTAMP_MODE_RAW_STC, /* Use the raw STC value