root/drivers/media/v4l2-core/v4l2-common.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. v4l2_ctrl_query_fill
  2. clamp_align
  3. clamp_roundup
  4. v4l_bound_align_image
  5. __v4l2_find_nearest_size
  6. v4l2_g_parm_cap
  7. v4l2_s_parm_cap
  8. v4l2_format_block_width
  9. v4l2_format_block_height
  10. v4l2_apply_frmsize_constraints
  11. v4l2_fill_pixfmt_mp
  12. v4l2_fill_pixfmt

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  *      Video for Linux Two
   4  *
   5  *      A generic video device interface for the LINUX operating system
   6  *      using a set of device structures/vectors for low level operations.
   7  *
   8  *      This file replaces the videodev.c file that comes with the
   9  *      regular kernel distribution.
  10  *
  11  * Author:      Bill Dirks <bill@thedirks.org>
  12  *              based on code by Alan Cox, <alan@cymru.net>
  13  */
  14 
  15 /*
  16  * Video capture interface for Linux
  17  *
  18  *      A generic video device interface for the LINUX operating system
  19  *      using a set of device structures/vectors for low level operations.
  20  *
  21  * Author:      Alan Cox, <alan@lxorguk.ukuu.org.uk>
  22  *
  23  * Fixes:
  24  */
  25 
  26 /*
  27  * Video4linux 1/2 integration by Justin Schoeman
  28  * <justin@suntiger.ee.up.ac.za>
  29  * 2.4 PROCFS support ported from 2.4 kernels by
  30  *  Iñaki García Etxebarria <garetxe@euskalnet.net>
  31  * Makefile fix by "W. Michael Petullo" <mike@flyn.org>
  32  * 2.4 devfs support ported from 2.4 kernels by
  33  *  Dan Merillat <dan@merillat.org>
  34  * Added Gerd Knorrs v4l1 enhancements (Justin Schoeman)
  35  */
  36 
  37 #include <linux/module.h>
  38 #include <linux/types.h>
  39 #include <linux/kernel.h>
  40 #include <linux/mm.h>
  41 #include <linux/string.h>
  42 #include <linux/errno.h>
  43 #include <linux/uaccess.h>
  44 #include <asm/pgtable.h>
  45 #include <asm/io.h>
  46 #include <asm/div64.h>
  47 #include <media/v4l2-common.h>
  48 #include <media/v4l2-device.h>
  49 #include <media/v4l2-ctrls.h>
  50 
  51 #include <linux/videodev2.h>
  52 
  53 /*
  54  *
  55  *      V 4 L 2   D R I V E R   H E L P E R   A P I
  56  *
  57  */
  58 
  59 /*
  60  *  Video Standard Operations (contributed by Michael Schimek)
  61  */
  62 
  63 /* Helper functions for control handling                             */
  64 
  65 /* Fill in a struct v4l2_queryctrl */
  66 int v4l2_ctrl_query_fill(struct v4l2_queryctrl *qctrl, s32 _min, s32 _max, s32 _step, s32 _def)
  67 {
  68         const char *name;
  69         s64 min = _min;
  70         s64 max = _max;
  71         u64 step = _step;
  72         s64 def = _def;
  73 
  74         v4l2_ctrl_fill(qctrl->id, &name, &qctrl->type,
  75                        &min, &max, &step, &def, &qctrl->flags);
  76 
  77         if (name == NULL)
  78                 return -EINVAL;
  79 
  80         qctrl->minimum = min;
  81         qctrl->maximum = max;
  82         qctrl->step = step;
  83         qctrl->default_value = def;
  84         qctrl->reserved[0] = qctrl->reserved[1] = 0;
  85         strscpy(qctrl->name, name, sizeof(qctrl->name));
  86         return 0;
  87 }
  88 EXPORT_SYMBOL(v4l2_ctrl_query_fill);
  89 
  90 /* Clamp x to be between min and max, aligned to a multiple of 2^align.  min
  91  * and max don't have to be aligned, but there must be at least one valid
  92  * value.  E.g., min=17,max=31,align=4 is not allowed as there are no multiples
  93  * of 16 between 17 and 31.  */
  94 static unsigned int clamp_align(unsigned int x, unsigned int min,
  95                                 unsigned int max, unsigned int align)
  96 {
  97         /* Bits that must be zero to be aligned */
  98         unsigned int mask = ~((1 << align) - 1);
  99 
 100         /* Clamp to aligned min and max */
 101         x = clamp(x, (min + ~mask) & mask, max & mask);
 102 
 103         /* Round to nearest aligned value */
 104         if (align)
 105                 x = (x + (1 << (align - 1))) & mask;
 106 
 107         return x;
 108 }
 109 
 110 static unsigned int clamp_roundup(unsigned int x, unsigned int min,
 111                                    unsigned int max, unsigned int alignment)
 112 {
 113         x = clamp(x, min, max);
 114         if (alignment)
 115                 x = round_up(x, alignment);
 116 
 117         return x;
 118 }
 119 
 120 void v4l_bound_align_image(u32 *w, unsigned int wmin, unsigned int wmax,
 121                            unsigned int walign,
 122                            u32 *h, unsigned int hmin, unsigned int hmax,
 123                            unsigned int halign, unsigned int salign)
 124 {
 125         *w = clamp_align(*w, wmin, wmax, walign);
 126         *h = clamp_align(*h, hmin, hmax, halign);
 127 
 128         /* Usually we don't need to align the size and are done now. */
 129         if (!salign)
 130                 return;
 131 
 132         /* How much alignment do we have? */
 133         walign = __ffs(*w);
 134         halign = __ffs(*h);
 135         /* Enough to satisfy the image alignment? */
 136         if (walign + halign < salign) {
 137                 /* Max walign where there is still a valid width */
 138                 unsigned int wmaxa = __fls(wmax ^ (wmin - 1));
 139                 /* Max halign where there is still a valid height */
 140                 unsigned int hmaxa = __fls(hmax ^ (hmin - 1));
 141 
 142                 /* up the smaller alignment until we have enough */
 143                 do {
 144                         if (halign >= hmaxa ||
 145                             (walign <= halign && walign < wmaxa)) {
 146                                 *w = clamp_align(*w, wmin, wmax, walign + 1);
 147                                 walign = __ffs(*w);
 148                         } else {
 149                                 *h = clamp_align(*h, hmin, hmax, halign + 1);
 150                                 halign = __ffs(*h);
 151                         }
 152                 } while (halign + walign < salign);
 153         }
 154 }
 155 EXPORT_SYMBOL_GPL(v4l_bound_align_image);
 156 
 157 const void *
 158 __v4l2_find_nearest_size(const void *array, size_t array_size,
 159                          size_t entry_size, size_t width_offset,
 160                          size_t height_offset, s32 width, s32 height)
 161 {
 162         u32 error, min_error = U32_MAX;
 163         const void *best = NULL;
 164         unsigned int i;
 165 
 166         if (!array)
 167                 return NULL;
 168 
 169         for (i = 0; i < array_size; i++, array += entry_size) {
 170                 const u32 *entry_width = array + width_offset;
 171                 const u32 *entry_height = array + height_offset;
 172 
 173                 error = abs(*entry_width - width) + abs(*entry_height - height);
 174                 if (error > min_error)
 175                         continue;
 176 
 177                 min_error = error;
 178                 best = array;
 179                 if (!error)
 180                         break;
 181         }
 182 
 183         return best;
 184 }
 185 EXPORT_SYMBOL_GPL(__v4l2_find_nearest_size);
 186 
 187 int v4l2_g_parm_cap(struct video_device *vdev,
 188                     struct v4l2_subdev *sd, struct v4l2_streamparm *a)
 189 {
 190         struct v4l2_subdev_frame_interval ival = { 0 };
 191         int ret;
 192 
 193         if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
 194             a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
 195                 return -EINVAL;
 196 
 197         if (vdev->device_caps & V4L2_CAP_READWRITE)
 198                 a->parm.capture.readbuffers = 2;
 199         if (v4l2_subdev_has_op(sd, video, g_frame_interval))
 200                 a->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
 201         ret = v4l2_subdev_call(sd, video, g_frame_interval, &ival);
 202         if (!ret)
 203                 a->parm.capture.timeperframe = ival.interval;
 204         return ret;
 205 }
 206 EXPORT_SYMBOL_GPL(v4l2_g_parm_cap);
 207 
 208 int v4l2_s_parm_cap(struct video_device *vdev,
 209                     struct v4l2_subdev *sd, struct v4l2_streamparm *a)
 210 {
 211         struct v4l2_subdev_frame_interval ival = {
 212                 .interval = a->parm.capture.timeperframe
 213         };
 214         int ret;
 215 
 216         if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
 217             a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
 218                 return -EINVAL;
 219 
 220         memset(&a->parm, 0, sizeof(a->parm));
 221         if (vdev->device_caps & V4L2_CAP_READWRITE)
 222                 a->parm.capture.readbuffers = 2;
 223         else
 224                 a->parm.capture.readbuffers = 0;
 225 
 226         if (v4l2_subdev_has_op(sd, video, g_frame_interval))
 227                 a->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
 228         ret = v4l2_subdev_call(sd, video, s_frame_interval, &ival);
 229         if (!ret)
 230                 a->parm.capture.timeperframe = ival.interval;
 231         return ret;
 232 }
 233 EXPORT_SYMBOL_GPL(v4l2_s_parm_cap);
 234 
 235 const struct v4l2_format_info *v4l2_format_info(u32 format)
 236 {
 237         static const struct v4l2_format_info formats[] = {
 238                 /* RGB formats */
 239                 { .format = V4L2_PIX_FMT_BGR24,   .mem_planes = 1, .comp_planes = 1, .bpp = { 3, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
 240                 { .format = V4L2_PIX_FMT_RGB24,   .mem_planes = 1, .comp_planes = 1, .bpp = { 3, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
 241                 { .format = V4L2_PIX_FMT_HSV24,   .mem_planes = 1, .comp_planes = 1, .bpp = { 3, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
 242                 { .format = V4L2_PIX_FMT_BGR32,   .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
 243                 { .format = V4L2_PIX_FMT_XBGR32,  .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
 244                 { .format = V4L2_PIX_FMT_BGRX32,  .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
 245                 { .format = V4L2_PIX_FMT_RGB32,   .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
 246                 { .format = V4L2_PIX_FMT_XRGB32,  .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
 247                 { .format = V4L2_PIX_FMT_RGBX32,  .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
 248                 { .format = V4L2_PIX_FMT_HSV32,   .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
 249                 { .format = V4L2_PIX_FMT_ARGB32,  .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
 250                 { .format = V4L2_PIX_FMT_RGBA32,  .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
 251                 { .format = V4L2_PIX_FMT_ABGR32,  .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
 252                 { .format = V4L2_PIX_FMT_BGRA32,  .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
 253                 { .format = V4L2_PIX_FMT_GREY,    .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
 254 
 255                 /* YUV packed formats */
 256                 { .format = V4L2_PIX_FMT_YUYV,    .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 2, .vdiv = 1 },
 257                 { .format = V4L2_PIX_FMT_YVYU,    .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 2, .vdiv = 1 },
 258                 { .format = V4L2_PIX_FMT_UYVY,    .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 2, .vdiv = 1 },
 259                 { .format = V4L2_PIX_FMT_VYUY,    .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 2, .vdiv = 1 },
 260 
 261                 /* YUV planar formats */
 262                 { .format = V4L2_PIX_FMT_NV12,    .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 2 },
 263                 { .format = V4L2_PIX_FMT_NV21,    .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 2 },
 264                 { .format = V4L2_PIX_FMT_NV16,    .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 1 },
 265                 { .format = V4L2_PIX_FMT_NV61,    .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 1 },
 266                 { .format = V4L2_PIX_FMT_NV24,    .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 1, .vdiv = 1 },
 267                 { .format = V4L2_PIX_FMT_NV42,    .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 1, .vdiv = 1 },
 268 
 269                 { .format = V4L2_PIX_FMT_YUV410,  .mem_planes = 1, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 4, .vdiv = 4 },
 270                 { .format = V4L2_PIX_FMT_YVU410,  .mem_planes = 1, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 4, .vdiv = 4 },
 271                 { .format = V4L2_PIX_FMT_YUV411P, .mem_planes = 1, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 4, .vdiv = 1 },
 272                 { .format = V4L2_PIX_FMT_YUV420,  .mem_planes = 1, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 2, .vdiv = 2 },
 273                 { .format = V4L2_PIX_FMT_YVU420,  .mem_planes = 1, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 2, .vdiv = 2 },
 274                 { .format = V4L2_PIX_FMT_YUV422P, .mem_planes = 1, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 2, .vdiv = 1 },
 275 
 276                 /* YUV planar formats, non contiguous variant */
 277                 { .format = V4L2_PIX_FMT_YUV420M, .mem_planes = 3, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 2, .vdiv = 2 },
 278                 { .format = V4L2_PIX_FMT_YVU420M, .mem_planes = 3, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 2, .vdiv = 2 },
 279                 { .format = V4L2_PIX_FMT_YUV422M, .mem_planes = 3, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 2, .vdiv = 1 },
 280                 { .format = V4L2_PIX_FMT_YVU422M, .mem_planes = 3, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 2, .vdiv = 1 },
 281                 { .format = V4L2_PIX_FMT_YUV444M, .mem_planes = 3, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 1, .vdiv = 1 },
 282                 { .format = V4L2_PIX_FMT_YVU444M, .mem_planes = 3, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 1, .vdiv = 1 },
 283 
 284                 { .format = V4L2_PIX_FMT_NV12M,   .mem_planes = 2, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 2 },
 285                 { .format = V4L2_PIX_FMT_NV21M,   .mem_planes = 2, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 2 },
 286                 { .format = V4L2_PIX_FMT_NV16M,   .mem_planes = 2, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 1 },
 287                 { .format = V4L2_PIX_FMT_NV61M,   .mem_planes = 2, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 1 },
 288 
 289                 /* Bayer RGB formats */
 290                 { .format = V4L2_PIX_FMT_SBGGR8,        .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
 291                 { .format = V4L2_PIX_FMT_SGBRG8,        .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
 292                 { .format = V4L2_PIX_FMT_SGRBG8,        .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
 293                 { .format = V4L2_PIX_FMT_SRGGB8,        .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
 294                 { .format = V4L2_PIX_FMT_SBGGR10,       .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
 295                 { .format = V4L2_PIX_FMT_SGBRG10,       .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
 296                 { .format = V4L2_PIX_FMT_SGRBG10,       .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
 297                 { .format = V4L2_PIX_FMT_SRGGB10,       .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
 298                 { .format = V4L2_PIX_FMT_SBGGR10ALAW8,  .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
 299                 { .format = V4L2_PIX_FMT_SGBRG10ALAW8,  .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
 300                 { .format = V4L2_PIX_FMT_SGRBG10ALAW8,  .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
 301                 { .format = V4L2_PIX_FMT_SRGGB10ALAW8,  .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
 302                 { .format = V4L2_PIX_FMT_SBGGR10DPCM8,  .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
 303                 { .format = V4L2_PIX_FMT_SGBRG10DPCM8,  .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
 304                 { .format = V4L2_PIX_FMT_SGRBG10DPCM8,  .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
 305                 { .format = V4L2_PIX_FMT_SRGGB10DPCM8,  .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
 306                 { .format = V4L2_PIX_FMT_SBGGR12,       .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
 307                 { .format = V4L2_PIX_FMT_SGBRG12,       .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
 308                 { .format = V4L2_PIX_FMT_SGRBG12,       .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
 309                 { .format = V4L2_PIX_FMT_SRGGB12,       .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
 310         };
 311         unsigned int i;
 312 
 313         for (i = 0; i < ARRAY_SIZE(formats); ++i)
 314                 if (formats[i].format == format)
 315                         return &formats[i];
 316         return NULL;
 317 }
 318 EXPORT_SYMBOL(v4l2_format_info);
 319 
 320 static inline unsigned int v4l2_format_block_width(const struct v4l2_format_info *info, int plane)
 321 {
 322         if (!info->block_w[plane])
 323                 return 1;
 324         return info->block_w[plane];
 325 }
 326 
 327 static inline unsigned int v4l2_format_block_height(const struct v4l2_format_info *info, int plane)
 328 {
 329         if (!info->block_h[plane])
 330                 return 1;
 331         return info->block_h[plane];
 332 }
 333 
 334 void v4l2_apply_frmsize_constraints(u32 *width, u32 *height,
 335                                     const struct v4l2_frmsize_stepwise *frmsize)
 336 {
 337         if (!frmsize)
 338                 return;
 339 
 340         /*
 341          * Clamp width/height to meet min/max constraints and round it up to
 342          * macroblock alignment.
 343          */
 344         *width = clamp_roundup(*width, frmsize->min_width, frmsize->max_width,
 345                                frmsize->step_width);
 346         *height = clamp_roundup(*height, frmsize->min_height, frmsize->max_height,
 347                                 frmsize->step_height);
 348 }
 349 EXPORT_SYMBOL_GPL(v4l2_apply_frmsize_constraints);
 350 
 351 int v4l2_fill_pixfmt_mp(struct v4l2_pix_format_mplane *pixfmt,
 352                         u32 pixelformat, u32 width, u32 height)
 353 {
 354         const struct v4l2_format_info *info;
 355         struct v4l2_plane_pix_format *plane;
 356         int i;
 357 
 358         info = v4l2_format_info(pixelformat);
 359         if (!info)
 360                 return -EINVAL;
 361 
 362         pixfmt->width = width;
 363         pixfmt->height = height;
 364         pixfmt->pixelformat = pixelformat;
 365         pixfmt->num_planes = info->mem_planes;
 366 
 367         if (info->mem_planes == 1) {
 368                 plane = &pixfmt->plane_fmt[0];
 369                 plane->bytesperline = ALIGN(width, v4l2_format_block_width(info, 0)) * info->bpp[0];
 370                 plane->sizeimage = 0;
 371 
 372                 for (i = 0; i < info->comp_planes; i++) {
 373                         unsigned int hdiv = (i == 0) ? 1 : info->hdiv;
 374                         unsigned int vdiv = (i == 0) ? 1 : info->vdiv;
 375                         unsigned int aligned_width;
 376                         unsigned int aligned_height;
 377 
 378                         aligned_width = ALIGN(width, v4l2_format_block_width(info, i));
 379                         aligned_height = ALIGN(height, v4l2_format_block_height(info, i));
 380 
 381                         plane->sizeimage += info->bpp[i] *
 382                                 DIV_ROUND_UP(aligned_width, hdiv) *
 383                                 DIV_ROUND_UP(aligned_height, vdiv);
 384                 }
 385         } else {
 386                 for (i = 0; i < info->comp_planes; i++) {
 387                         unsigned int hdiv = (i == 0) ? 1 : info->hdiv;
 388                         unsigned int vdiv = (i == 0) ? 1 : info->vdiv;
 389                         unsigned int aligned_width;
 390                         unsigned int aligned_height;
 391 
 392                         aligned_width = ALIGN(width, v4l2_format_block_width(info, i));
 393                         aligned_height = ALIGN(height, v4l2_format_block_height(info, i));
 394 
 395                         plane = &pixfmt->plane_fmt[i];
 396                         plane->bytesperline =
 397                                 info->bpp[i] * DIV_ROUND_UP(aligned_width, hdiv);
 398                         plane->sizeimage =
 399                                 plane->bytesperline * DIV_ROUND_UP(aligned_height, vdiv);
 400                 }
 401         }
 402         return 0;
 403 }
 404 EXPORT_SYMBOL_GPL(v4l2_fill_pixfmt_mp);
 405 
 406 int v4l2_fill_pixfmt(struct v4l2_pix_format *pixfmt, u32 pixelformat,
 407                      u32 width, u32 height)
 408 {
 409         const struct v4l2_format_info *info;
 410         int i;
 411 
 412         info = v4l2_format_info(pixelformat);
 413         if (!info)
 414                 return -EINVAL;
 415 
 416         /* Single planar API cannot be used for multi plane formats. */
 417         if (info->mem_planes > 1)
 418                 return -EINVAL;
 419 
 420         pixfmt->width = width;
 421         pixfmt->height = height;
 422         pixfmt->pixelformat = pixelformat;
 423         pixfmt->bytesperline = ALIGN(width, v4l2_format_block_width(info, 0)) * info->bpp[0];
 424         pixfmt->sizeimage = 0;
 425 
 426         for (i = 0; i < info->comp_planes; i++) {
 427                 unsigned int hdiv = (i == 0) ? 1 : info->hdiv;
 428                 unsigned int vdiv = (i == 0) ? 1 : info->vdiv;
 429                 unsigned int aligned_width;
 430                 unsigned int aligned_height;
 431 
 432                 aligned_width = ALIGN(width, v4l2_format_block_width(info, i));
 433                 aligned_height = ALIGN(height, v4l2_format_block_height(info, i));
 434 
 435                 pixfmt->sizeimage += info->bpp[i] *
 436                         DIV_ROUND_UP(aligned_width, hdiv) *
 437                         DIV_ROUND_UP(aligned_height, vdiv);
 438         }
 439         return 0;
 440 }
 441 EXPORT_SYMBOL_GPL(v4l2_fill_pixfmt);

/* [<][>][^][v][top][bottom][index][help] */