ixp4xx: remove linux 3.10 support
[openwrt.git] / target / linux / brcm2708 / patches-3.10 / 0169-V4L2-H264-profile-level-ctrls-FPS-control-and-auto-e.patch
1 From 94cf90dae250a9dcb3b52b655a94e2106a422698 Mon Sep 17 00:00:00 2001
2 From: Dave Stevenson <dsteve@broadcom.com>
3 Date: Wed, 12 Feb 2014 11:18:20 +0000
4 Subject: [PATCH 169/196] V4L2: H264 profile & level ctrls, FPS control and
5  auto exp pri
6
7 Several control handling updates.
8 H264 profile and level controls.
9 Timeperframe/FPS reworked to add V4L2_CID_EXPOSURE_AUTO_PRIORITY to
10 select whether AE is allowed to override the framerate specified.
11
12 Signed-off-by: Dave Stevenson <dsteve@broadcom.com>
13 ---
14  drivers/media/platform/bcm2835/bcm2835-camera.c  | 107 ++++++-----
15  drivers/media/platform/bcm2835/bcm2835-camera.h  |  12 +-
16  drivers/media/platform/bcm2835/controls.c        | 225 ++++++++++++++++++++++-
17  drivers/media/platform/bcm2835/mmal-parameters.h |  87 +++++++++
18  4 files changed, 383 insertions(+), 48 deletions(-)
19
20 diff --git a/drivers/media/platform/bcm2835/bcm2835-camera.c b/drivers/media/platform/bcm2835/bcm2835-camera.c
21 index 7f99a14..6d0d77a 100644
22 --- a/drivers/media/platform/bcm2835/bcm2835-camera.c
23 +++ b/drivers/media/platform/bcm2835/bcm2835-camera.c
24 @@ -36,7 +36,8 @@
25  
26  #define BM2835_MMAL_VERSION "0.0.2"
27  #define BM2835_MMAL_MODULE_NAME "bcm2835-v4l2"
28 -
29 +#define MIN_WIDTH 16
30 +#define MIN_HEIGHT 16
31  #define MAX_WIDTH 2592
32  #define MAX_HEIGHT 1944
33  #define MIN_BUFFER_SIZE (80*1024)
34 @@ -56,7 +57,7 @@ MODULE_PARM_DESC(bcm2835_v4l2_debug, "Debug level 0-2");
35  static struct bm2835_mmal_dev *gdev;   /* global device data */
36  
37  #define FPS_MIN 1
38 -#define FPS_MAX 30
39 +#define FPS_MAX 90
40  
41  /* timeperframe: min/max and default */
42  static const struct v4l2_fract
43 @@ -903,10 +904,8 @@ static int mmal_setup_components(struct bm2835_mmal_dev *dev,
44         camera_port->es.video.crop.y = 0;
45         camera_port->es.video.crop.width = f->fmt.pix.width;
46         camera_port->es.video.crop.height = f->fmt.pix.height;
47 -       camera_port->es.video.frame_rate.num =
48 -                       dev->capture.timeperframe.denominator;
49 -       camera_port->es.video.frame_rate.den =
50 -                       dev->capture.timeperframe.numerator;
51 +       camera_port->es.video.frame_rate.num = 0;
52 +       camera_port->es.video.frame_rate.den = 1;
53  
54         ret = vchiq_mmal_port_set_format(dev->instance, camera_port);
55  
56 @@ -940,8 +939,10 @@ static int mmal_setup_components(struct bm2835_mmal_dev *dev,
57                 preview_port->es.video.crop.y = 0;
58                 preview_port->es.video.crop.width = f->fmt.pix.width;
59                 preview_port->es.video.crop.height = f->fmt.pix.height;
60 -               preview_port->es.video.frame_rate.num = 30;
61 -               preview_port->es.video.frame_rate.den = 1;
62 +               preview_port->es.video.frame_rate.num =
63 +                                         dev->capture.timeperframe.denominator;
64 +               preview_port->es.video.frame_rate.den =
65 +                                         dev->capture.timeperframe.numerator;
66                 ret = vchiq_mmal_port_set_format(dev->instance, preview_port);
67                 if (overlay_enabled) {
68                         ret = vchiq_mmal_port_connect_tunnel(
69 @@ -1116,22 +1117,56 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
70         }
71  
72         ret = mmal_setup_components(dev, f);
73 -       if (ret != 0)
74 +       if (ret != 0) {
75                 v4l2_err(&dev->v4l2_dev,
76                          "%s: failed to setup mmal components: %d\n",
77                          __func__, ret);
78 +               ret = -EINVAL;
79 +       }
80  
81         return ret;
82  }
83  
84 +int vidioc_enum_framesizes(struct file *file, void *fh,
85 +                          struct v4l2_frmsizeenum *fsize)
86 +{
87 +       static const struct v4l2_frmsize_stepwise sizes = {
88 +               MIN_WIDTH, MAX_WIDTH, 2,
89 +               MIN_HEIGHT, MAX_HEIGHT, 2
90 +       };
91 +       int i;
92 +
93 +       if (fsize->index)
94 +               return -EINVAL;
95 +       for (i = 0; i < ARRAY_SIZE(formats); i++)
96 +               if (formats[i].fourcc == fsize->pixel_format)
97 +                       break;
98 +       if (i == ARRAY_SIZE(formats))
99 +               return -EINVAL;
100 +       fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE;
101 +       fsize->stepwise = sizes;
102 +       return 0;
103 +}
104 +
105  /* timeperframe is arbitrary and continous */
106  static int vidioc_enum_frameintervals(struct file *file, void *priv,
107                                              struct v4l2_frmivalenum *fival)
108  {
109 +       int i;
110 +
111         if (fival->index)
112                 return -EINVAL;
113  
114 -       /* regarding width & height - we support any */
115 +       for (i = 0; i < ARRAY_SIZE(formats); i++)
116 +               if (formats[i].fourcc == fival->pixel_format)
117 +                       break;
118 +       if (i == ARRAY_SIZE(formats))
119 +               return -EINVAL;
120 +
121 +       /* regarding width & height - we support any within range */
122 +       if (fival->width < MIN_WIDTH || fival->width > MAX_WIDTH ||
123 +           fival->height < MIN_HEIGHT || fival->height > MAX_HEIGHT)
124 +               return -EINVAL;
125  
126         fival->type = V4L2_FRMIVAL_TYPE_CONTINUOUS;
127  
128 @@ -1167,7 +1202,6 @@ static int vidioc_s_parm(struct file *file, void *priv,
129         struct bm2835_mmal_dev *dev = video_drvdata(file);
130         struct v4l2_fract tpf;
131         struct mmal_parameter_rational fps_param;
132 -       int ret;
133  
134         if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
135                 return -EINVAL;
136 @@ -1183,27 +1217,11 @@ static int vidioc_s_parm(struct file *file, void *priv,
137         parm->parm.capture.timeperframe = tpf;
138         parm->parm.capture.readbuffers  = 1;
139  
140 -       fps_param.num = dev->capture.timeperframe.denominator;
141 -       fps_param.den = dev->capture.timeperframe.numerator;
142 -       ret = vchiq_mmal_port_parameter_set(dev->instance,
143 -                                     &dev->component[MMAL_COMPONENT_CAMERA]->
144 -                                       output[MMAL_CAMERA_PORT_PREVIEW],
145 -                                     MMAL_PARAMETER_VIDEO_FRAME_RATE,
146 -                                     &fps_param, sizeof(fps_param));
147 -       ret += vchiq_mmal_port_parameter_set(dev->instance,
148 -                                     &dev->component[MMAL_COMPONENT_CAMERA]->
149 -                                       output[MMAL_CAMERA_PORT_VIDEO],
150 -                                     MMAL_PARAMETER_VIDEO_FRAME_RATE,
151 -                                     &fps_param, sizeof(fps_param));
152 -       ret += vchiq_mmal_port_parameter_set(dev->instance,
153 -                                     &dev->component[MMAL_COMPONENT_CAMERA]->
154 -                                       output[MMAL_CAMERA_PORT_CAPTURE],
155 -                                     MMAL_PARAMETER_VIDEO_FRAME_RATE,
156 -                                     &fps_param, sizeof(fps_param));
157 -       if (ret)
158 -               v4l2_dbg(0, bcm2835_v4l2_debug, &dev->v4l2_dev,
159 -                "Failed to set fps ret %d\n",
160 -                ret);
161 +       fps_param.num = 0;      /* Select variable fps, and then use
162 +                                * FPS_RANGE to select the actual limits.
163 +                                */
164 +       fps_param.den = 1;
165 +       set_framerate_params(dev);
166  
167         return 0;
168  }
169 @@ -1236,6 +1254,7 @@ static const struct v4l2_ioctl_ops camera0_ioctl_ops = {
170         .vidioc_querybuf = vb2_ioctl_querybuf,
171         .vidioc_qbuf = vb2_ioctl_qbuf,
172         .vidioc_dqbuf = vb2_ioctl_dqbuf,
173 +       .vidioc_enum_framesizes = vidioc_enum_framesizes,
174         .vidioc_enum_frameintervals = vidioc_enum_frameintervals,
175         .vidioc_g_parm        = vidioc_g_parm,
176         .vidioc_s_parm        = vidioc_s_parm,
177 @@ -1331,10 +1350,8 @@ static int __init mmal_init(struct bm2835_mmal_dev *dev)
178         format->es->video.crop.y = 0;
179         format->es->video.crop.width = 1024;
180         format->es->video.crop.height = 768;
181 -       format->es->video.frame_rate.num =
182 -                       dev->capture.timeperframe.denominator;
183 -       format->es->video.frame_rate.den =
184 -                       dev->capture.timeperframe.numerator;
185 +       format->es->video.frame_rate.num = 0; /* Rely on fps_range */
186 +       format->es->video.frame_rate.den = 1;
187  
188         format =
189             &dev->component[MMAL_COMPONENT_CAMERA]->
190 @@ -1349,10 +1366,8 @@ static int __init mmal_init(struct bm2835_mmal_dev *dev)
191         format->es->video.crop.y = 0;
192         format->es->video.crop.width = 1024;
193         format->es->video.crop.height = 768;
194 -       format->es->video.frame_rate.num =
195 -                       dev->capture.timeperframe.denominator;
196 -       format->es->video.frame_rate.den =
197 -                       dev->capture.timeperframe.numerator;
198 +       format->es->video.frame_rate.num = 0; /* Rely on fps_range */
199 +       format->es->video.frame_rate.den = 1;
200  
201         format =
202             &dev->component[MMAL_COMPONENT_CAMERA]->
203 @@ -1366,7 +1381,7 @@ static int __init mmal_init(struct bm2835_mmal_dev *dev)
204         format->es->video.crop.y = 0;
205         format->es->video.crop.width = 2592;
206         format->es->video.crop.height = 1944;
207 -       format->es->video.frame_rate.num = 30;
208 +       format->es->video.frame_rate.num = 0; /* Rely on fps_range */
209         format->es->video.frame_rate.den = 1;
210  
211         dev->capture.width = format->es->video.width;
212 @@ -1374,6 +1389,8 @@ static int __init mmal_init(struct bm2835_mmal_dev *dev)
213         dev->capture.fmt = &formats[0];
214         dev->capture.encode_component = NULL;
215         dev->capture.timeperframe = tpf_default;
216 +       dev->capture.enc_profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH;
217 +       dev->capture.enc_level = V4L2_MPEG_VIDEO_H264_LEVEL_4_0;
218  
219         /* get the preview component ready */
220         ret = vchiq_mmal_component_init(
221 @@ -1420,6 +1437,14 @@ static int __init mmal_init(struct bm2835_mmal_dev *dev)
222         }
223  
224         {
225 +               struct vchiq_mmal_port *encoder_port =
226 +                       &dev->component[MMAL_COMPONENT_VIDEO_ENCODE]->output[0];
227 +               encoder_port->format.encoding = MMAL_ENCODING_H264;
228 +               ret = vchiq_mmal_port_set_format(dev->instance,
229 +                       encoder_port);
230 +       }
231 +
232 +       {
233                 unsigned int enable = 1;
234                 vchiq_mmal_port_parameter_set(
235                         dev->instance,
236 diff --git a/drivers/media/platform/bcm2835/bcm2835-camera.h b/drivers/media/platform/bcm2835/bcm2835-camera.h
237 index 25aa91f..8822a1a 100644
238 --- a/drivers/media/platform/bcm2835/bcm2835-camera.h
239 +++ b/drivers/media/platform/bcm2835/bcm2835-camera.h
240 @@ -15,7 +15,7 @@
241   * core driver device
242   */
243  
244 -#define V4L2_CTRL_COUNT 21 /* number of v4l controls */
245 +#define V4L2_CTRL_COUNT 24 /* number of v4l controls */
246  
247  enum {
248         MMAL_COMPONENT_CAMERA = 0,
249 @@ -49,7 +49,9 @@ struct bm2835_mmal_dev {
250         int                       hflip;
251         int                       vflip;
252         enum mmal_parameter_exposuremode exposure_mode;
253 +       enum v4l2_exposure_auto_type exposure_mode_v4l2;
254         unsigned int              manual_shutter_speed;
255 +       bool                      exp_auto_priority;
256  
257         /* allocated mmal instance and components */
258         struct vchiq_mmal_instance   *instance;
259 @@ -63,12 +65,16 @@ struct bm2835_mmal_dev {
260                 unsigned int     height;  /* height */
261                 unsigned int     stride;  /* stride */
262                 struct mmal_fmt  *fmt;
263 -               struct v4l2_fract          timeperframe;
264 +               struct v4l2_fract timeperframe;
265  
266                 /* H264 encode bitrate */
267                 int         encode_bitrate;
268                 /* H264 bitrate mode. CBR/VBR */
269                 int         encode_bitrate_mode;
270 +               /* H264 profile */
271 +               enum v4l2_mpeg_video_h264_profile enc_profile;
272 +               /* H264 level */
273 +               enum v4l2_mpeg_video_h264_level enc_level;
274                 /* JPEG Q-factor */
275                 int         q_factor;
276  
277 @@ -98,7 +104,7 @@ int bm2835_mmal_init_controls(
278                         struct v4l2_ctrl_handler *hdl);
279  
280  int bm2835_mmal_set_all_camera_controls(struct bm2835_mmal_dev *dev);
281 -
282 +int set_framerate_params(struct bm2835_mmal_dev *dev);
283  
284  /* Debug helpers */
285  
286 diff --git a/drivers/media/platform/bcm2835/controls.c b/drivers/media/platform/bcm2835/controls.c
287 index cb062a9..45cf790 100644
288 --- a/drivers/media/platform/bcm2835/controls.c
289 +++ b/drivers/media/platform/bcm2835/controls.c
290 @@ -69,7 +69,6 @@ static const s64 bitrate_mode_qmenu[] = {
291         (s64)V4L2_MPEG_VIDEO_BITRATE_MODE_CBR,
292  };
293  
294 -
295  enum bm2835_mmal_ctrl_type {
296         MMAL_CONTROL_TYPE_STD,
297         MMAL_CONTROL_TYPE_STD_MENU,
298 @@ -329,6 +328,9 @@ static int ctrl_set_exposure(struct bm2835_mmal_dev *dev,
299  
300                 }
301                 dev->exposure_mode = exp_mode;
302 +               dev->exposure_mode_v4l2 = ctrl->val;
303 +       } else if (mmal_ctrl->id == V4L2_CID_EXPOSURE_AUTO_PRIORITY) {
304 +               dev->exp_auto_priority = ctrl->val;
305         }
306  
307         if (dev->exposure_mode == MMAL_PARAM_EXPOSUREMODE_OFF)
308 @@ -340,6 +342,8 @@ static int ctrl_set_exposure(struct bm2835_mmal_dev *dev,
309         ret += vchiq_mmal_port_parameter_set(dev->instance, control,
310                                              MMAL_PARAMETER_EXPOSURE_MODE,
311                                              &exp_mode, sizeof(u32));
312 +       ret += set_framerate_params(dev);
313 +
314         return ret;
315  }
316  
317 @@ -540,8 +544,8 @@ static int ctrl_set_colfx(struct bm2835_mmal_dev *dev,
318                                         &dev->colourfx, sizeof(dev->colourfx));
319  
320         v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
321 -                "After: mmal_ctrl:%p ctrl id:0x%x ctrl val:%d ret %d(%d)\n",
322 -                       mmal_ctrl, ctrl->id, ctrl->val, ret,
323 +                "%s: After: mmal_ctrl:%p ctrl id:0x%x ctrl val:%d ret %d(%d)\n",
324 +                       __func__, mmal_ctrl, ctrl->id, ctrl->val, ret,
325                         (ret == 0 ? 0 : -EINVAL));
326         return (ret == 0 ? 0 : EINVAL);
327  }
328 @@ -623,6 +627,117 @@ static int ctrl_set_video_encode_param_output(struct bm2835_mmal_dev *dev,
329                                              &u32_value, sizeof(u32_value));
330  }
331  
332 +static int ctrl_set_video_encode_profile_level(struct bm2835_mmal_dev *dev,
333 +                     struct v4l2_ctrl *ctrl,
334 +                     const struct bm2835_mmal_v4l2_ctrl *mmal_ctrl)
335 +{
336 +       struct mmal_parameter_video_profile param;
337 +       int ret = 0;
338 +
339 +       if (ctrl->id == V4L2_CID_MPEG_VIDEO_H264_PROFILE) {
340 +               switch (ctrl->val) {
341 +               case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE:
342 +               case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE:
343 +               case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN:
344 +               case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH:
345 +                       dev->capture.enc_profile = ctrl->val;
346 +                       break;
347 +               default:
348 +                       ret = -EINVAL;
349 +                       break;
350 +               }
351 +       } else if (ctrl->id == V4L2_CID_MPEG_VIDEO_H264_LEVEL) {
352 +               switch (ctrl->val) {
353 +               case V4L2_MPEG_VIDEO_H264_LEVEL_1_0:
354 +               case V4L2_MPEG_VIDEO_H264_LEVEL_1B:
355 +               case V4L2_MPEG_VIDEO_H264_LEVEL_1_1:
356 +               case V4L2_MPEG_VIDEO_H264_LEVEL_1_2:
357 +               case V4L2_MPEG_VIDEO_H264_LEVEL_1_3:
358 +               case V4L2_MPEG_VIDEO_H264_LEVEL_2_0:
359 +               case V4L2_MPEG_VIDEO_H264_LEVEL_2_1:
360 +               case V4L2_MPEG_VIDEO_H264_LEVEL_2_2:
361 +               case V4L2_MPEG_VIDEO_H264_LEVEL_3_0:
362 +               case V4L2_MPEG_VIDEO_H264_LEVEL_3_1:
363 +               case V4L2_MPEG_VIDEO_H264_LEVEL_3_2:
364 +               case V4L2_MPEG_VIDEO_H264_LEVEL_4_0:
365 +                       dev->capture.enc_level = ctrl->val;
366 +                       break;
367 +               default:
368 +                       ret = -EINVAL;
369 +                       break;
370 +               }
371 +       }
372 +
373 +       if (!ret) {
374 +               switch (dev->capture.enc_profile) {
375 +               case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE:
376 +                       param.profile = MMAL_VIDEO_PROFILE_H264_BASELINE;
377 +                       break;
378 +               case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE:
379 +                       param.profile =
380 +                               MMAL_VIDEO_PROFILE_H264_CONSTRAINED_BASELINE;
381 +                       break;
382 +               case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN:
383 +                       param.profile = MMAL_VIDEO_PROFILE_H264_MAIN;
384 +                       break;
385 +               case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH:
386 +                       param.profile = MMAL_VIDEO_PROFILE_H264_HIGH;
387 +                       break;
388 +               default:
389 +                       /* Should never get here */
390 +                       break;
391 +               }
392 +
393 +               switch (dev->capture.enc_level) {
394 +               case V4L2_MPEG_VIDEO_H264_LEVEL_1_0:
395 +                       param.level = MMAL_VIDEO_LEVEL_H264_1;
396 +                       break;
397 +               case V4L2_MPEG_VIDEO_H264_LEVEL_1B:
398 +                       param.level = MMAL_VIDEO_LEVEL_H264_1b;
399 +                       break;
400 +               case V4L2_MPEG_VIDEO_H264_LEVEL_1_1:
401 +                       param.level = MMAL_VIDEO_LEVEL_H264_11;
402 +                       break;
403 +               case V4L2_MPEG_VIDEO_H264_LEVEL_1_2:
404 +                       param.level = MMAL_VIDEO_LEVEL_H264_12;
405 +                       break;
406 +               case V4L2_MPEG_VIDEO_H264_LEVEL_1_3:
407 +                       param.level = MMAL_VIDEO_LEVEL_H264_13;
408 +                       break;
409 +               case V4L2_MPEG_VIDEO_H264_LEVEL_2_0:
410 +                       param.level = MMAL_VIDEO_LEVEL_H264_2;
411 +                       break;
412 +               case V4L2_MPEG_VIDEO_H264_LEVEL_2_1:
413 +                       param.level = MMAL_VIDEO_LEVEL_H264_21;
414 +                       break;
415 +               case V4L2_MPEG_VIDEO_H264_LEVEL_2_2:
416 +                       param.level = MMAL_VIDEO_LEVEL_H264_22;
417 +                       break;
418 +               case V4L2_MPEG_VIDEO_H264_LEVEL_3_0:
419 +                       param.level = MMAL_VIDEO_LEVEL_H264_3;
420 +                       break;
421 +               case V4L2_MPEG_VIDEO_H264_LEVEL_3_1:
422 +                       param.level = MMAL_VIDEO_LEVEL_H264_31;
423 +                       break;
424 +               case V4L2_MPEG_VIDEO_H264_LEVEL_3_2:
425 +                       param.level = MMAL_VIDEO_LEVEL_H264_32;
426 +                       break;
427 +               case V4L2_MPEG_VIDEO_H264_LEVEL_4_0:
428 +                       param.level = MMAL_VIDEO_LEVEL_H264_4;
429 +                       break;
430 +               default:
431 +                       /* Should never get here */
432 +                       break;
433 +               }
434 +
435 +               ret = vchiq_mmal_port_parameter_set(dev->instance,
436 +                       &dev->component[MMAL_COMPONENT_VIDEO_ENCODE]->output[0],
437 +                       mmal_ctrl->mmal_id,
438 +                       &param, sizeof(param));
439 +       }
440 +       return ret;
441 +}
442 +
443  static int bm2835_mmal_s_ctrl(struct v4l2_ctrl *ctrl)
444  {
445         struct bm2835_mmal_dev *dev =
446 @@ -639,6 +754,9 @@ static int bm2835_mmal_s_ctrl(struct v4l2_ctrl *ctrl)
447         }
448  
449         ret = mmal_ctrl->setter(dev, ctrl, mmal_ctrl);
450 +       if (ret)
451 +               pr_warn("ctrl id:%d/MMAL param %08X- returned ret %d\n",
452 +                               ctrl->id, mmal_ctrl->mmal_id, ret);
453         if (mmal_ctrl->ignore_errors)
454                 ret = 0;
455         return ret;
456 @@ -725,6 +843,14 @@ static const struct bm2835_mmal_v4l2_ctrl v4l2_ctrls[V4L2_CTRL_COUNT] = {
457                 false
458         },
459         {
460 +               V4L2_CID_EXPOSURE_AUTO_PRIORITY, MMAL_CONTROL_TYPE_STD,
461 +               0, 1,
462 +               0, 1, NULL,
463 +               0,      /* Dummy MMAL ID as it gets mapped into FPS range*/
464 +               &ctrl_set_exposure,
465 +               false
466 +       },
467 +       {
468                 V4L2_CID_EXPOSURE_METERING,
469                 MMAL_CONTROL_TYPE_STD_MENU,
470                 ~0x7, 2, V4L2_EXPOSURE_METERING_AVERAGE, 0, NULL,
471 @@ -814,6 +940,39 @@ static const struct bm2835_mmal_v4l2_ctrl v4l2_ctrls[V4L2_CTRL_COUNT] = {
472                 &ctrl_set_video_encode_param_output,
473                 true    /* Errors ignored as requires latest firmware to work */
474         },
475 +       {
476 +               V4L2_CID_MPEG_VIDEO_H264_PROFILE,
477 +               MMAL_CONTROL_TYPE_STD_MENU,
478 +               ~((1<<V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE) |
479 +                       (1<<V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE) |
480 +                       (1<<V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) |
481 +                       (1<<V4L2_MPEG_VIDEO_H264_PROFILE_HIGH)),
482 +               V4L2_MPEG_VIDEO_H264_PROFILE_HIGH,
483 +               V4L2_MPEG_VIDEO_H264_PROFILE_HIGH, 1, NULL,
484 +               MMAL_PARAMETER_PROFILE,
485 +               &ctrl_set_video_encode_profile_level,
486 +               false
487 +       },
488 +       {
489 +               V4L2_CID_MPEG_VIDEO_H264_LEVEL, MMAL_CONTROL_TYPE_STD_MENU,
490 +               ~((1<<V4L2_MPEG_VIDEO_H264_LEVEL_1_0) |
491 +                       (1<<V4L2_MPEG_VIDEO_H264_LEVEL_1B) |
492 +                       (1<<V4L2_MPEG_VIDEO_H264_LEVEL_1_1) |
493 +                       (1<<V4L2_MPEG_VIDEO_H264_LEVEL_1_2) |
494 +                       (1<<V4L2_MPEG_VIDEO_H264_LEVEL_1_3) |
495 +                       (1<<V4L2_MPEG_VIDEO_H264_LEVEL_2_0) |
496 +                       (1<<V4L2_MPEG_VIDEO_H264_LEVEL_2_1) |
497 +                       (1<<V4L2_MPEG_VIDEO_H264_LEVEL_2_2) |
498 +                       (1<<V4L2_MPEG_VIDEO_H264_LEVEL_3_0) |
499 +                       (1<<V4L2_MPEG_VIDEO_H264_LEVEL_3_1) |
500 +                       (1<<V4L2_MPEG_VIDEO_H264_LEVEL_3_2) |
501 +                       (1<<V4L2_MPEG_VIDEO_H264_LEVEL_4_0)),
502 +               V4L2_MPEG_VIDEO_H264_LEVEL_4_0,
503 +               V4L2_MPEG_VIDEO_H264_LEVEL_4_0, 1, NULL,
504 +               MMAL_PARAMETER_PROFILE,
505 +               &ctrl_set_video_encode_profile_level,
506 +               false
507 +       },
508  };
509  
510  int bm2835_mmal_set_all_camera_controls(struct bm2835_mmal_dev *dev)
511 @@ -825,13 +984,71 @@ int bm2835_mmal_set_all_camera_controls(struct bm2835_mmal_dev *dev)
512                 if ((dev->ctrls[c]) && (v4l2_ctrls[c].setter)) {
513                         ret = v4l2_ctrls[c].setter(dev, dev->ctrls[c],
514                                                    &v4l2_ctrls[c]);
515 -                       if (!v4l2_ctrls[c]. ignore_errors && ret)
516 +                       if (!v4l2_ctrls[c].ignore_errors && ret) {
517 +                               v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
518 +                                       "Failed when setting default values for ctrl %d\n",
519 +                                       c);
520                                 break;
521 +                       }
522                 }
523         }
524         return ret;
525  }
526  
527 +int set_framerate_params(struct bm2835_mmal_dev *dev)
528 +{
529 +       struct mmal_parameter_fps_range fps_range;
530 +       int ret;
531 +
532 +       if ((dev->exposure_mode_v4l2 == V4L2_EXPOSURE_AUTO ||
533 +            dev->exposure_mode_v4l2 == V4L2_EXPOSURE_APERTURE_PRIORITY) &&
534 +            (dev->exp_auto_priority)) {
535 +               /* Variable FPS. Define min FPS as 1fps.
536 +                * Max as max defined FPS.
537 +                */
538 +               fps_range.fps_low.num = 1;
539 +               fps_range.fps_low.den = 1;
540 +               fps_range.fps_high.num = dev->capture.timeperframe.denominator;
541 +               fps_range.fps_high.den = dev->capture.timeperframe.numerator;
542 +       } else {
543 +               /* Fixed FPS - set min and max to be the same */
544 +               fps_range.fps_low.num = fps_range.fps_high.num =
545 +                       dev->capture.timeperframe.denominator;
546 +               fps_range.fps_low.den = fps_range.fps_high.den =
547 +                       dev->capture.timeperframe.numerator;
548 +       }
549 +
550 +       v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
551 +                        "Set fps range to %d/%d to %d/%d\n",
552 +                        fps_range.fps_low.num,
553 +                        fps_range.fps_low.den,
554 +                        fps_range.fps_high.num,
555 +                        fps_range.fps_high.den
556 +                );
557 +
558 +       ret = vchiq_mmal_port_parameter_set(dev->instance,
559 +                                     &dev->component[MMAL_COMPONENT_CAMERA]->
560 +                                       output[MMAL_CAMERA_PORT_PREVIEW],
561 +                                     MMAL_PARAMETER_FPS_RANGE,
562 +                                     &fps_range, sizeof(fps_range));
563 +       ret += vchiq_mmal_port_parameter_set(dev->instance,
564 +                                     &dev->component[MMAL_COMPONENT_CAMERA]->
565 +                                       output[MMAL_CAMERA_PORT_VIDEO],
566 +                                     MMAL_PARAMETER_FPS_RANGE,
567 +                                     &fps_range, sizeof(fps_range));
568 +       ret += vchiq_mmal_port_parameter_set(dev->instance,
569 +                                     &dev->component[MMAL_COMPONENT_CAMERA]->
570 +                                       output[MMAL_CAMERA_PORT_CAPTURE],
571 +                                     MMAL_PARAMETER_FPS_RANGE,
572 +                                     &fps_range, sizeof(fps_range));
573 +       if (ret)
574 +               v4l2_dbg(0, bcm2835_v4l2_debug, &dev->v4l2_dev,
575 +                "Failed to set fps ret %d\n",
576 +                ret);
577 +
578 +       return ret;
579 +
580 +}
581  int bm2835_mmal_init_controls(struct bm2835_mmal_dev *dev,
582                               struct v4l2_ctrl_handler *hdl)
583  {
584 diff --git a/drivers/media/platform/bcm2835/mmal-parameters.h b/drivers/media/platform/bcm2835/mmal-parameters.h
585 index b08a4b0..ae8fef9 100644
586 --- a/drivers/media/platform/bcm2835/mmal-parameters.h
587 +++ b/drivers/media/platform/bcm2835/mmal-parameters.h
588 @@ -182,6 +182,14 @@ enum mmal_parameter_camera_config_timestamp_mode {
589                                               */
590  };
591  
592 +struct mmal_parameter_fps_range {
593 +       /**< Low end of the permitted framerate range */
594 +       struct mmal_parameter_rational  fps_low;
595 +       /**< High end of the permitted framerate range */
596 +       struct mmal_parameter_rational  fps_high;
597 +};
598 +
599 +
600  /* camera configuration parameter */
601  struct mmal_parameter_camera_config {
602         /* Parameters for setting up the image pools */
603 @@ -293,6 +301,85 @@ enum mmal_parameter_rate_control_mode {
604         MMAL_VIDEO_RATECONTROL_CONSTANT_SKIP_FRAMES
605  };
606  
607 +enum mmal_video_profile {
608 +       MMAL_VIDEO_PROFILE_H263_BASELINE,
609 +       MMAL_VIDEO_PROFILE_H263_H320CODING,
610 +       MMAL_VIDEO_PROFILE_H263_BACKWARDCOMPATIBLE,
611 +       MMAL_VIDEO_PROFILE_H263_ISWV2,
612 +       MMAL_VIDEO_PROFILE_H263_ISWV3,
613 +       MMAL_VIDEO_PROFILE_H263_HIGHCOMPRESSION,
614 +       MMAL_VIDEO_PROFILE_H263_INTERNET,
615 +       MMAL_VIDEO_PROFILE_H263_INTERLACE,
616 +       MMAL_VIDEO_PROFILE_H263_HIGHLATENCY,
617 +       MMAL_VIDEO_PROFILE_MP4V_SIMPLE,
618 +       MMAL_VIDEO_PROFILE_MP4V_SIMPLESCALABLE,
619 +       MMAL_VIDEO_PROFILE_MP4V_CORE,
620 +       MMAL_VIDEO_PROFILE_MP4V_MAIN,
621 +       MMAL_VIDEO_PROFILE_MP4V_NBIT,
622 +       MMAL_VIDEO_PROFILE_MP4V_SCALABLETEXTURE,
623 +       MMAL_VIDEO_PROFILE_MP4V_SIMPLEFACE,
624 +       MMAL_VIDEO_PROFILE_MP4V_SIMPLEFBA,
625 +       MMAL_VIDEO_PROFILE_MP4V_BASICANIMATED,
626 +       MMAL_VIDEO_PROFILE_MP4V_HYBRID,
627 +       MMAL_VIDEO_PROFILE_MP4V_ADVANCEDREALTIME,
628 +       MMAL_VIDEO_PROFILE_MP4V_CORESCALABLE,
629 +       MMAL_VIDEO_PROFILE_MP4V_ADVANCEDCODING,
630 +       MMAL_VIDEO_PROFILE_MP4V_ADVANCEDCORE,
631 +       MMAL_VIDEO_PROFILE_MP4V_ADVANCEDSCALABLE,
632 +       MMAL_VIDEO_PROFILE_MP4V_ADVANCEDSIMPLE,
633 +       MMAL_VIDEO_PROFILE_H264_BASELINE,
634 +       MMAL_VIDEO_PROFILE_H264_MAIN,
635 +       MMAL_VIDEO_PROFILE_H264_EXTENDED,
636 +       MMAL_VIDEO_PROFILE_H264_HIGH,
637 +       MMAL_VIDEO_PROFILE_H264_HIGH10,
638 +       MMAL_VIDEO_PROFILE_H264_HIGH422,
639 +       MMAL_VIDEO_PROFILE_H264_HIGH444,
640 +       MMAL_VIDEO_PROFILE_H264_CONSTRAINED_BASELINE,
641 +       MMAL_VIDEO_PROFILE_DUMMY = 0x7FFFFFFF
642 +};
643 +
644 +enum mmal_video_level {
645 +       MMAL_VIDEO_LEVEL_H263_10,
646 +       MMAL_VIDEO_LEVEL_H263_20,
647 +       MMAL_VIDEO_LEVEL_H263_30,
648 +       MMAL_VIDEO_LEVEL_H263_40,
649 +       MMAL_VIDEO_LEVEL_H263_45,
650 +       MMAL_VIDEO_LEVEL_H263_50,
651 +       MMAL_VIDEO_LEVEL_H263_60,
652 +       MMAL_VIDEO_LEVEL_H263_70,
653 +       MMAL_VIDEO_LEVEL_MP4V_0,
654 +       MMAL_VIDEO_LEVEL_MP4V_0b,
655 +       MMAL_VIDEO_LEVEL_MP4V_1,
656 +       MMAL_VIDEO_LEVEL_MP4V_2,
657 +       MMAL_VIDEO_LEVEL_MP4V_3,
658 +       MMAL_VIDEO_LEVEL_MP4V_4,
659 +       MMAL_VIDEO_LEVEL_MP4V_4a,
660 +       MMAL_VIDEO_LEVEL_MP4V_5,
661 +       MMAL_VIDEO_LEVEL_MP4V_6,
662 +       MMAL_VIDEO_LEVEL_H264_1,
663 +       MMAL_VIDEO_LEVEL_H264_1b,
664 +       MMAL_VIDEO_LEVEL_H264_11,
665 +       MMAL_VIDEO_LEVEL_H264_12,
666 +       MMAL_VIDEO_LEVEL_H264_13,
667 +       MMAL_VIDEO_LEVEL_H264_2,
668 +       MMAL_VIDEO_LEVEL_H264_21,
669 +       MMAL_VIDEO_LEVEL_H264_22,
670 +       MMAL_VIDEO_LEVEL_H264_3,
671 +       MMAL_VIDEO_LEVEL_H264_31,
672 +       MMAL_VIDEO_LEVEL_H264_32,
673 +       MMAL_VIDEO_LEVEL_H264_4,
674 +       MMAL_VIDEO_LEVEL_H264_41,
675 +       MMAL_VIDEO_LEVEL_H264_42,
676 +       MMAL_VIDEO_LEVEL_H264_5,
677 +       MMAL_VIDEO_LEVEL_H264_51,
678 +       MMAL_VIDEO_LEVEL_DUMMY = 0x7FFFFFFF
679 +};
680 +
681 +struct mmal_parameter_video_profile {
682 +       enum mmal_video_profile profile;
683 +       enum mmal_video_level level;
684 +};
685 +
686  /* video parameters */
687  
688  enum mmal_parameter_video_type {
689 -- 
690 1.9.1
691