Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[media] v4l: Support extending the v4l2_pix_format structure

The v4l2_pix_format structure has no reserved field. It is embedded in
the v4l2_framebuffer structure which has no reserved fields either, and
in the v4l2_format structure which has reserved fields that were not
previously required to be zeroed out by applications.

To allow extending v4l2_pix_format, inline it in the v4l2_framebuffer
structure, and use the priv field as a magic value to indicate that the
application has set all v4l2_pix_format extended fields and zeroed all
reserved fields following the v4l2_pix_format field in the v4l2_format
structure.

The availability of this API extension is reported to userspace through
the new V4L2_CAP_EXT_PIX_FORMAT capability flag. Just checking that the
priv field is still set to the magic value at [GS]_FMT return wouldn't
be enough, as older kernels don't zero the priv field on return.

To simplify the internal API towards drivers zero the extended fields
and set the priv field to the magic value for applications not aware of
the extensions.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>

authored by

Laurent Pinchart and committed by
Mauro Carvalho Chehab
d52e2381 b04ef7c0

+134 -70
+1 -1
Documentation/DocBook/media/Makefile
··· 174 174 DOCUMENTED = \ 175 175 -e "s/\(enum *\)v4l2_mpeg_cx2341x_video_\([a-z]*_spatial_filter_type\)/\1<link linkend=\"\2\">v4l2_mpeg_cx2341x_video_\2<\/link>/g" \ 176 176 -e "s/\(\(enum\|struct\) *\)\(v4l2_[a-zA-Z0-9_]*\)/\1<link linkend=\"\3\">\3<\/link>/g" \ 177 - -e "s/\(V4L2_PIX_FMT_[A-Z0-9_]\+\) /<link linkend=\"\1\">\1<\/link> /g" \ 177 + -e "s/\(V4L2_PIX_FMT_[A-Z0-9_]\+\)\(\s\+v4l2_fourcc\)/<link linkend=\"\1\">\1<\/link>\2/g" \ 178 178 -e ":a;s/\(linkend=\".*\)_\(.*\">\)/\1-\2/;ta" \ 179 179 -e "s/v4l2\-mpeg\-vbi\-ITV0/v4l2-mpeg-vbi-itv0-1/g" 180 180
+22 -3
Documentation/DocBook/media/v4l/pixfmt.xml
··· 112 112 <row> 113 113 <entry>__u32</entry> 114 114 <entry><structfield>priv</structfield></entry> 115 - <entry>Reserved for custom (driver defined) additional 116 - information about formats. When not used drivers and applications must 117 - set this field to zero.</entry> 115 + <entry><para>This field indicates whether the remaining fields of the 116 + <structname>v4l2_pix_format</structname> structure, also called the extended 117 + fields, are valid. When set to <constant>V4L2_PIX_FMT_PRIV_MAGIC</constant>, it 118 + indicates that the extended fields have been correctly initialized. When set to 119 + any other value it indicates that the extended fields contain undefined values. 120 + </para> 121 + <para>Applications that wish to use the pixel format extended fields must first 122 + ensure that the feature is supported by querying the device for the 123 + <link linkend="querycap"><constant>V4L2_CAP_EXT_PIX_FORMAT</constant></link> 124 + capability. If the capability isn't set the pixel format extended fields are not 125 + supported and using the extended fields will lead to undefined results.</para> 126 + <para>To use the extended fields, applications must set the 127 + <structfield>priv</structfield> field to 128 + <constant>V4L2_PIX_FMT_PRIV_MAGIC</constant>, initialize all the extended fields 129 + and zero the unused bytes of the <structname>v4l2_format</structname> 130 + <structfield>raw_data</structfield> field.</para> 131 + <para>When the <structfield>priv</structfield> field isn't set to 132 + <constant>V4L2_PIX_FMT_PRIV_MAGIC</constant> drivers must act as if all the 133 + extended fields were set to zero. On return drivers must set the 134 + <structfield>priv</structfield> field to 135 + <constant>V4L2_PIX_FMT_PRIV_MAGIC</constant> and all the extended fields to 136 + applicable values.</para></entry> 118 137 </row> 119 138 </tbody> 120 139 </tgroup>
+8
Documentation/DocBook/media/v4l/v4l2.xml
··· 152 152 applications. --> 153 153 154 154 <revision> 155 + <revnumber>3.16</revnumber> 156 + <date>2014-05-27</date> 157 + <authorinitials>lp</authorinitials> 158 + <revremark>Extended &v4l2-pix-format;. 159 + </revremark> 160 + </revision> 161 + 162 + <revision> 155 163 <revnumber>3.15</revnumber> 156 164 <date>2014-02-03</date> 157 165 <authorinitials>hv, ap</authorinitials>
+4 -8
Documentation/DocBook/media/v4l/vidioc-g-fbuf.xml
··· 152 152 framebuffer device (see <xref linkend="osd" />).</entry> 153 153 </row> 154 154 <row> 155 - <entry>&v4l2-pix-format;</entry> 155 + <entry>struct</entry> 156 156 <entry><structfield>fmt</structfield></entry> 157 157 <entry></entry> 158 - <entry>Layout of the frame buffer. The 159 - <structname>v4l2_pix_format</structname> structure is defined in <xref 160 - linkend="pixfmt" />, for clarification the fields and acceptable values 161 - are listed below:</entry> 158 + <entry>Layout of the frame buffer.</entry> 162 159 </row> 163 160 <row> 164 161 <entry></entry> ··· 273 276 <entry></entry> 274 277 <entry>__u32</entry> 275 278 <entry><structfield>priv</structfield></entry> 276 - <entry>Reserved for additional information about custom 277 - (driver defined) formats. When not used drivers and applications must 278 - set this field to zero.</entry> 279 + <entry>Reserved. Drivers and applications must set this field to 280 + zero.</entry> 279 281 </row> 280 282 </tbody> 281 283 </tgroup>
+6
Documentation/DocBook/media/v4l/vidioc-querycap.xml
··· 302 302 <link linkend="sdr">SDR Capture</link> interface.</entry> 303 303 </row> 304 304 <row> 305 + <entry><constant>V4L2_CAP_EXT_PIX_FORMAT</constant></entry> 306 + <entry>0x00200000</entry> 307 + <entry>The device supports the &v4l2-pix-format; extended 308 + fields.</entry> 309 + </row> 310 + <row> 305 311 <entry><constant>V4L2_CAP_READWRITE</constant></entry> 306 312 <entry>0x01000000</entry> 307 313 <entry>The device supports the <link
-2
drivers/media/parport/bw-qcam.c
··· 759 759 pix->sizeimage = pix->width * pix->height; 760 760 /* Just a guess */ 761 761 pix->colorspace = V4L2_COLORSPACE_SRGB; 762 - pix->priv = 0; 763 762 return 0; 764 763 } 765 764 ··· 784 785 pix->sizeimage = pix->width * pix->height; 785 786 /* Just a guess */ 786 787 pix->colorspace = V4L2_COLORSPACE_SRGB; 787 - pix->priv = 0; 788 788 return 0; 789 789 } 790 790
-1
drivers/media/pci/cx18/cx18-ioctl.c
··· 156 156 pixfmt->height = cx->cxhdl.height; 157 157 pixfmt->colorspace = V4L2_COLORSPACE_SMPTE170M; 158 158 pixfmt->field = V4L2_FIELD_INTERLACED; 159 - pixfmt->priv = 0; 160 159 if (id->type == CX18_ENC_STREAM_TYPE_YUV) { 161 160 pixfmt->pixelformat = s->pixelformat; 162 161 pixfmt->sizeimage = s->vb_bytes_per_frame;
-3
drivers/media/pci/cx25821/cx25821-video.c
··· 576 576 f->fmt.pix.bytesperline = (chan->width * chan->fmt->depth) >> 3; 577 577 f->fmt.pix.sizeimage = chan->height * f->fmt.pix.bytesperline; 578 578 f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; 579 - f->fmt.pix.priv = 0; 580 579 581 580 return 0; 582 581 } ··· 614 615 f->fmt.pix.bytesperline = (f->fmt.pix.width * fmt->depth) >> 3; 615 616 f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline; 616 617 f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; 617 - f->fmt.pix.priv = 0; 618 618 619 619 return 0; 620 620 } ··· 865 867 f->fmt.pix.bytesperline = (f->fmt.pix.width * fmt->depth) >> 3; 866 868 f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline; 867 869 f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; 868 - f->fmt.pix.priv = 0; 869 870 return 0; 870 871 } 871 872
-3
drivers/media/pci/ivtv/ivtv-ioctl.c
··· 351 351 pixfmt->height = itv->cxhdl.height; 352 352 pixfmt->colorspace = V4L2_COLORSPACE_SMPTE170M; 353 353 pixfmt->field = V4L2_FIELD_INTERLACED; 354 - pixfmt->priv = 0; 355 354 if (id->type == IVTV_ENC_STREAM_TYPE_YUV) { 356 355 pixfmt->pixelformat = V4L2_PIX_FMT_HM12; 357 356 /* YUV size is (Y=(h*720) + UV=(h*(720/2))) */ ··· 417 418 pixfmt->height = itv->main_rect.height; 418 419 pixfmt->colorspace = V4L2_COLORSPACE_SMPTE170M; 419 420 pixfmt->field = V4L2_FIELD_INTERLACED; 420 - pixfmt->priv = 0; 421 421 if (id->type == IVTV_DEC_STREAM_TYPE_YUV) { 422 422 switch (itv->yuv_info.lace_mode & IVTV_YUV_MODE_MASK) { 423 423 case IVTV_YUV_MODE_INTERLACED: ··· 1382 1384 fb->fmt.bytesperline = fb->fmt.width; 1383 1385 fb->fmt.colorspace = V4L2_COLORSPACE_SMPTE170M; 1384 1386 fb->fmt.field = V4L2_FIELD_INTERLACED; 1385 - fb->fmt.priv = 0; 1386 1387 if (fb->fmt.pixelformat != V4L2_PIX_FMT_PAL8) 1387 1388 fb->fmt.bytesperline *= 2; 1388 1389 if (fb->fmt.pixelformat == V4L2_PIX_FMT_RGB32 ||
-2
drivers/media/pci/meye/meye.c
··· 1166 1166 f->fmt.pix.sizeimage = f->fmt.pix.height * 1167 1167 f->fmt.pix.bytesperline; 1168 1168 f->fmt.pix.colorspace = 0; 1169 - f->fmt.pix.priv = 0; 1170 1169 1171 1170 return 0; 1172 1171 } ··· 1231 1232 f->fmt.pix.sizeimage = f->fmt.pix.height * 1232 1233 f->fmt.pix.bytesperline; 1233 1234 f->fmt.pix.colorspace = 0; 1234 - f->fmt.pix.priv = 0; 1235 1235 1236 1236 return 0; 1237 1237 }
-3
drivers/media/pci/saa7134/saa7134-empress.c
··· 130 130 f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; 131 131 f->fmt.pix.sizeimage = TS_PACKET_SIZE * dev->ts.nr_packets; 132 132 f->fmt.pix.bytesperline = 0; 133 - f->fmt.pix.priv = 0; 134 133 135 134 return 0; 136 135 } ··· 147 148 f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; 148 149 f->fmt.pix.sizeimage = TS_PACKET_SIZE * dev->ts.nr_packets; 149 150 f->fmt.pix.bytesperline = 0; 150 - f->fmt.pix.priv = 0; 151 151 152 152 return 0; 153 153 } ··· 164 166 f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; 165 167 f->fmt.pix.sizeimage = TS_PACKET_SIZE * dev->ts.nr_packets; 166 168 f->fmt.pix.bytesperline = 0; 167 - f->fmt.pix.priv = 0; 168 169 169 170 return 0; 170 171 }
-2
drivers/media/pci/saa7134/saa7134-video.c
··· 1235 1235 f->fmt.pix.sizeimage = 1236 1236 f->fmt.pix.height * f->fmt.pix.bytesperline; 1237 1237 f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; 1238 - f->fmt.pix.priv = 0; 1239 1238 return 0; 1240 1239 } 1241 1240 ··· 1314 1315 f->fmt.pix.sizeimage = 1315 1316 f->fmt.pix.height * f->fmt.pix.bytesperline; 1316 1317 f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; 1317 - f->fmt.pix.priv = 0; 1318 1318 1319 1319 return 0; 1320 1320 }
-1
drivers/media/pci/sta2x11/sta2x11_vip.c
··· 640 640 f->fmt.pix.bytesperline = f->fmt.pix.width * 2; 641 641 f->fmt.pix.sizeimage = f->fmt.pix.width * 2 * f->fmt.pix.height; 642 642 f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; 643 - f->fmt.pix.priv = 0; 644 643 return 0; 645 644 } 646 645
-2
drivers/media/platform/coda.c
··· 613 613 BUG(); 614 614 } 615 615 616 - f->fmt.pix.priv = 0; 617 - 618 616 return 0; 619 617 } 620 618
-1
drivers/media/platform/davinci/vpif_display.c
··· 648 648 pixfmt->width = common->fmt.fmt.pix.width; 649 649 pixfmt->height = common->fmt.fmt.pix.height; 650 650 pixfmt->sizeimage = pixfmt->bytesperline * pixfmt->height * 2; 651 - pixfmt->priv = 0; 652 651 653 652 return 0; 654 653 }
-1
drivers/media/platform/mem2mem_testdev.c
··· 532 532 f->fmt.pix.bytesperline = (f->fmt.pix.width * fmt->depth) >> 3; 533 533 f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline; 534 534 f->fmt.pix.field = V4L2_FIELD_NONE; 535 - f->fmt.pix.priv = 0; 536 535 537 536 return 0; 538 537 }
-2
drivers/media/platform/omap/omap_vout.c
··· 165 165 166 166 pix->pixelformat = omap_formats[ifmt].pixelformat; 167 167 pix->field = V4L2_FIELD_ANY; 168 - pix->priv = 0; 169 168 170 169 switch (pix->pixelformat) { 171 170 case V4L2_PIX_FMT_YUYV: ··· 1895 1896 pix->field = V4L2_FIELD_ANY; 1896 1897 pix->bytesperline = pix->width * 2; 1897 1898 pix->sizeimage = pix->bytesperline * pix->height; 1898 - pix->priv = 0; 1899 1899 pix->colorspace = V4L2_COLORSPACE_JPEG; 1900 1900 1901 1901 vout->bpp = RGB565_BPP;
-2
drivers/media/platform/sh_veu.c
··· 425 425 pix->bytesperline = vfmt->bytesperline; 426 426 pix->sizeimage = vfmt->bytesperline * pix->height * 427 427 vfmt->fmt->depth / vfmt->fmt->ydepth; 428 - pix->priv = 0; 429 428 dev_dbg(veu->dev, "%s(): type: %d, size %u @ %ux%u, fmt %x\n", __func__, 430 429 f->type, pix->sizeimage, pix->width, pix->height, pix->pixelformat); 431 430 ··· 472 473 473 474 pix->pixelformat = fmt->fourcc; 474 475 pix->colorspace = sh_veu_4cc2cspace(pix->pixelformat); 475 - pix->priv = 0; 476 476 477 477 pr_debug("%s(): type: %d, size %u\n", __func__, f->type, pix->sizeimage); 478 478
-5
drivers/media/platform/vino.c
··· 3147 3147 pf->colorspace = 3148 3148 vino_data_formats[tempvcs.data_format].colorspace; 3149 3149 3150 - pf->priv = 0; 3151 3150 return 0; 3152 3151 } 3153 3152 ··· 3173 3174 vcs->decimation; 3174 3175 pf->colorspace = 3175 3176 vino_data_formats[vcs->data_format].colorspace; 3176 - 3177 - pf->priv = 0; 3178 3177 3179 3178 spin_unlock_irqrestore(&vino_drvdata->input_lock, flags); 3180 3179 return 0; ··· 3215 3218 vcs->decimation; 3216 3219 pf->colorspace = 3217 3220 vino_data_formats[vcs->data_format].colorspace; 3218 - 3219 - pf->priv = 0; 3220 3221 3221 3222 spin_unlock_irqrestore(&vino_drvdata->input_lock, flags); 3222 3223 return 0;
-1
drivers/media/platform/vivi.c
··· 1014 1014 f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; 1015 1015 else 1016 1016 f->fmt.pix.colorspace = V4L2_COLORSPACE_SRGB; 1017 - f->fmt.pix.priv = 0; 1018 1017 return 0; 1019 1018 } 1020 1019
-2
drivers/media/usb/cx231xx/cx231xx-417.c
··· 1563 1563 f->fmt.pix.width = dev->ts1.width; 1564 1564 f->fmt.pix.height = dev->ts1.height; 1565 1565 f->fmt.pix.field = V4L2_FIELD_INTERLACED; 1566 - f->fmt.pix.priv = 0; 1567 1566 dprintk(1, "VIDIOC_G_FMT: w: %d, h: %d\n", 1568 1567 dev->ts1.width, dev->ts1.height); 1569 1568 dprintk(3, "exit vidioc_g_fmt_vid_cap()\n"); ··· 1581 1582 f->fmt.pix.sizeimage = mpeglines * mpeglinesize; 1582 1583 f->fmt.pix.field = V4L2_FIELD_INTERLACED; 1583 1584 f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; 1584 - f->fmt.pix.priv = 0; 1585 1585 dprintk(1, "VIDIOC_TRY_FMT: w: %d, h: %d\n", 1586 1586 dev->ts1.width, dev->ts1.height); 1587 1587 dprintk(3, "exit vidioc_try_fmt_vid_cap()\n");
-2
drivers/media/usb/cx231xx/cx231xx-video.c
··· 885 885 f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; 886 886 887 887 f->fmt.pix.field = V4L2_FIELD_INTERLACED; 888 - f->fmt.pix.priv = 0; 889 888 890 889 return 0; 891 890 } ··· 929 930 f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * height; 930 931 f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; 931 932 f->fmt.pix.field = V4L2_FIELD_INTERLACED; 932 - f->fmt.pix.priv = 0; 933 933 934 934 return 0; 935 935 }
+4 -4
drivers/media/usb/gspca/gspca.c
··· 1109 1109 struct gspca_dev *gspca_dev = video_drvdata(file); 1110 1110 1111 1111 fmt->fmt.pix = gspca_dev->pixfmt; 1112 - /* some drivers use priv internally, zero it before giving it to 1113 - userspace */ 1112 + /* some drivers use priv internally, zero it before giving it back to 1113 + the core */ 1114 1114 fmt->fmt.pix.priv = 0; 1115 1115 return 0; 1116 1116 } ··· 1146 1146 fmt->fmt.pix.height = h; 1147 1147 gspca_dev->sd_desc->try_fmt(gspca_dev, fmt); 1148 1148 } 1149 - /* some drivers use priv internally, zero it before giving it to 1150 - userspace */ 1149 + /* some drivers use priv internally, zero it before giving it back to 1150 + the core */ 1151 1151 fmt->fmt.pix.priv = 0; 1152 1152 return mode; /* used when s_fmt */ 1153 1153 }
-1
drivers/media/usb/hdpvr/hdpvr-video.c
··· 1022 1022 f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; 1023 1023 f->fmt.pix.sizeimage = dev->bulk_in_size; 1024 1024 f->fmt.pix.bytesperline = 0; 1025 - f->fmt.pix.priv = 0; 1026 1025 if (f->fmt.pix.width == 720) { 1027 1026 /* SDTV formats */ 1028 1027 f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
-2
drivers/media/usb/stkwebcam/stk-webcam.c
··· 923 923 pix_format->bytesperline = 2 * pix_format->width; 924 924 pix_format->sizeimage = pix_format->bytesperline 925 925 * pix_format->height; 926 - pix_format->priv = 0; 927 926 return 0; 928 927 } 929 928 ··· 966 967 fmtd->fmt.pix.bytesperline = 2 * fmtd->fmt.pix.width; 967 968 fmtd->fmt.pix.sizeimage = fmtd->fmt.pix.bytesperline 968 969 * fmtd->fmt.pix.height; 969 - fmtd->fmt.pix.priv = 0; 970 970 return 0; 971 971 } 972 972
-1
drivers/media/usb/tlg2300/pd-video.c
··· 1321 1321 .bytesperline = 720 * 2, 1322 1322 .sizeimage = 720 * 576 * 2, 1323 1323 .colorspace = V4L2_COLORSPACE_SMPTE170M, 1324 - .priv = 0 1325 1324 }; 1326 1325 } 1327 1326
-2
drivers/media/usb/tm6000/tm6000-video.c
··· 918 918 (f->fmt.pix.width * fh->fmt->depth) >> 3; 919 919 f->fmt.pix.sizeimage = 920 920 f->fmt.pix.height * f->fmt.pix.bytesperline; 921 - f->fmt.pix.priv = 0; 922 921 923 922 return 0; 924 923 } ··· 958 959 f->fmt.pix.width &= ~0x01; 959 960 960 961 f->fmt.pix.field = field; 961 - f->fmt.pix.priv = 0; 962 962 963 963 f->fmt.pix.bytesperline = 964 964 (f->fmt.pix.width * fmt->depth) >> 3;
-3
drivers/media/usb/zr364xx/zr364xx.c
··· 806 806 f->fmt.pix.bytesperline = f->fmt.pix.width * 2; 807 807 f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline; 808 808 f->fmt.pix.colorspace = V4L2_COLORSPACE_JPEG; 809 - f->fmt.pix.priv = 0; 810 809 DBG("%s: V4L2_PIX_FMT_%s (%d) ok!\n", __func__, 811 810 decode_fourcc(f->fmt.pix.pixelformat, pixelformat_name), 812 811 f->fmt.pix.field); ··· 828 829 f->fmt.pix.bytesperline = f->fmt.pix.width * 2; 829 830 f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline; 830 831 f->fmt.pix.colorspace = V4L2_COLORSPACE_JPEG; 831 - f->fmt.pix.priv = 0; 832 832 return 0; 833 833 } 834 834 ··· 864 866 f->fmt.pix.bytesperline = f->fmt.pix.width * 2; 865 867 f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline; 866 868 f->fmt.pix.colorspace = V4L2_COLORSPACE_JPEG; 867 - f->fmt.pix.priv = 0; 868 869 cam->vb_vidq.field = f->fmt.pix.field; 869 870 870 871 if (f->fmt.pix.width == 160 && f->fmt.pix.height == 120)
+14 -5
drivers/media/v4l2-core/v4l2-compat-ioctl32.c
··· 540 540 __u32 capability; 541 541 __u32 flags; 542 542 compat_caddr_t base; 543 - struct v4l2_pix_format fmt; 543 + struct { 544 + __u32 width; 545 + __u32 height; 546 + __u32 pixelformat; 547 + __u32 field; 548 + __u32 bytesperline; 549 + __u32 sizeimage; 550 + __u32 colorspace; 551 + __u32 priv; 552 + } fmt; 544 553 }; 545 554 546 555 static int get_v4l2_framebuffer32(struct v4l2_framebuffer *kp, struct v4l2_framebuffer32 __user *up) ··· 559 550 if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_framebuffer32)) || 560 551 get_user(tmp, &up->base) || 561 552 get_user(kp->capability, &up->capability) || 562 - get_user(kp->flags, &up->flags)) 553 + get_user(kp->flags, &up->flags) || 554 + copy_from_user(&kp->fmt, &up->fmt, sizeof(up->fmt))) 563 555 return -EFAULT; 564 556 kp->base = compat_ptr(tmp); 565 - get_v4l2_pix_format(&kp->fmt, &up->fmt); 566 557 return 0; 567 558 } 568 559 ··· 573 564 if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_framebuffer32)) || 574 565 put_user(tmp, &up->base) || 575 566 put_user(kp->capability, &up->capability) || 576 - put_user(kp->flags, &up->flags)) 567 + put_user(kp->flags, &up->flags) || 568 + copy_to_user(&up->fmt, &kp->fmt, sizeof(up->fmt))) 577 569 return -EFAULT; 578 - put_v4l2_pix_format(&kp->fmt, &up->fmt); 579 570 return 0; 580 571 } 581 572
+61 -4
drivers/media/v4l2-core/v4l2-ioctl.c
··· 973 973 return -EINVAL; 974 974 } 975 975 976 + static void v4l_sanitize_format(struct v4l2_format *fmt) 977 + { 978 + unsigned int offset; 979 + 980 + /* 981 + * The v4l2_pix_format structure has been extended with fields that were 982 + * not previously required to be set to zero by applications. The priv 983 + * field, when set to a magic value, indicates the the extended fields 984 + * are valid. Otherwise they will contain undefined values. To simplify 985 + * the API towards drivers zero the extended fields and set the priv 986 + * field to the magic value when the extended pixel format structure 987 + * isn't used by applications. 988 + */ 989 + 990 + if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE && 991 + fmt->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) 992 + return; 993 + 994 + if (fmt->fmt.pix.priv == V4L2_PIX_FMT_PRIV_MAGIC) 995 + return; 996 + 997 + fmt->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC; 998 + 999 + offset = offsetof(struct v4l2_pix_format, priv) 1000 + + sizeof(fmt->fmt.pix.priv); 1001 + memset(((void *)&fmt->fmt.pix) + offset, 0, 1002 + sizeof(fmt->fmt.pix) - offset); 1003 + } 1004 + 976 1005 static int v4l_querycap(const struct v4l2_ioctl_ops *ops, 977 1006 struct file *file, void *fh, void *arg) 978 1007 { 979 1008 struct v4l2_capability *cap = (struct v4l2_capability *)arg; 1009 + int ret; 980 1010 981 1011 cap->version = LINUX_VERSION_CODE; 982 - return ops->vidioc_querycap(file, fh, cap); 1012 + 1013 + ret = ops->vidioc_querycap(file, fh, cap); 1014 + 1015 + cap->capabilities |= V4L2_CAP_EXT_PIX_FORMAT; 1016 + 1017 + return ret; 983 1018 } 984 1019 985 1020 static int v4l_s_input(const struct v4l2_ioctl_ops *ops, ··· 1138 1103 bool is_sdr = vfd->vfl_type == VFL_TYPE_SDR; 1139 1104 bool is_rx = vfd->vfl_dir != VFL_DIR_TX; 1140 1105 bool is_tx = vfd->vfl_dir != VFL_DIR_RX; 1106 + int ret; 1107 + 1108 + p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC; 1141 1109 1142 1110 switch (p->type) { 1143 1111 case V4L2_BUF_TYPE_VIDEO_CAPTURE: 1144 1112 if (unlikely(!is_rx || !is_vid || !ops->vidioc_g_fmt_vid_cap)) 1145 1113 break; 1146 - return ops->vidioc_g_fmt_vid_cap(file, fh, arg); 1114 + ret = ops->vidioc_g_fmt_vid_cap(file, fh, arg); 1115 + p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC; 1116 + return ret; 1147 1117 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: 1148 1118 if (unlikely(!is_rx || !is_vid || !ops->vidioc_g_fmt_vid_cap_mplane)) 1149 1119 break; ··· 1168 1128 case V4L2_BUF_TYPE_VIDEO_OUTPUT: 1169 1129 if (unlikely(!is_tx || !is_vid || !ops->vidioc_g_fmt_vid_out)) 1170 1130 break; 1171 - return ops->vidioc_g_fmt_vid_out(file, fh, arg); 1131 + ret = ops->vidioc_g_fmt_vid_out(file, fh, arg); 1132 + p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC; 1133 + return ret; 1172 1134 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: 1173 1135 if (unlikely(!is_tx || !is_vid || !ops->vidioc_g_fmt_vid_out_mplane)) 1174 1136 break; ··· 1204 1162 bool is_sdr = vfd->vfl_type == VFL_TYPE_SDR; 1205 1163 bool is_rx = vfd->vfl_dir != VFL_DIR_TX; 1206 1164 bool is_tx = vfd->vfl_dir != VFL_DIR_RX; 1165 + 1166 + v4l_sanitize_format(p); 1207 1167 1208 1168 switch (p->type) { 1209 1169 case V4L2_BUF_TYPE_VIDEO_CAPTURE: ··· 1276 1232 bool is_sdr = vfd->vfl_type == VFL_TYPE_SDR; 1277 1233 bool is_rx = vfd->vfl_dir != VFL_DIR_TX; 1278 1234 bool is_tx = vfd->vfl_dir != VFL_DIR_RX; 1235 + 1236 + v4l_sanitize_format(p); 1279 1237 1280 1238 switch (p->type) { 1281 1239 case V4L2_BUF_TYPE_VIDEO_CAPTURE: ··· 1562 1516 struct v4l2_create_buffers *create = arg; 1563 1517 int ret = check_fmt(file, create->format.type); 1564 1518 1565 - return ret ? ret : ops->vidioc_create_bufs(file, fh, create); 1519 + if (ret) 1520 + return ret; 1521 + 1522 + v4l_sanitize_format(&create->format); 1523 + 1524 + ret = ops->vidioc_create_bufs(file, fh, create); 1525 + 1526 + if (create->format.type == V4L2_BUF_TYPE_VIDEO_CAPTURE || 1527 + create->format.type == V4L2_BUF_TYPE_VIDEO_OUTPUT) 1528 + create->format.fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC; 1529 + 1530 + return ret; 1566 1531 } 1567 1532 1568 1533 static int v4l_prepare_buf(const struct v4l2_ioctl_ops *ops,
+14 -1
include/uapi/linux/videodev2.h
··· 268 268 #define V4L2_CAP_MODULATOR 0x00080000 /* has a modulator */ 269 269 270 270 #define V4L2_CAP_SDR_CAPTURE 0x00100000 /* Is a SDR capture device */ 271 + #define V4L2_CAP_EXT_PIX_FORMAT 0x00200000 /* Supports the extended pixel format */ 271 272 272 273 #define V4L2_CAP_READWRITE 0x01000000 /* read/write systemcalls */ 273 274 #define V4L2_CAP_ASYNCIO 0x02000000 /* async I/O */ ··· 448 447 /* SDR formats - used only for Software Defined Radio devices */ 449 448 #define V4L2_SDR_FMT_CU8 v4l2_fourcc('C', 'U', '0', '8') /* IQ u8 */ 450 449 #define V4L2_SDR_FMT_CU16LE v4l2_fourcc('C', 'U', '1', '6') /* IQ u16le */ 450 + 451 + /* priv field value to indicates that subsequent fields are valid. */ 452 + #define V4L2_PIX_FMT_PRIV_MAGIC 0xfeedcafe 451 453 452 454 /* 453 455 * F O R M A T E N U M E R A T I O N ··· 756 752 /* FIXME: in theory we should pass something like PCI device + memory 757 753 * region + offset instead of some physical address */ 758 754 void *base; 759 - struct v4l2_pix_format fmt; 755 + struct { 756 + __u32 width; 757 + __u32 height; 758 + __u32 pixelformat; 759 + __u32 field; /* enum v4l2_field */ 760 + __u32 bytesperline; /* for padding, zero if unused */ 761 + __u32 sizeimage; 762 + __u32 colorspace; /* enum v4l2_colorspace */ 763 + __u32 priv; /* reserved field, set to 0 */ 764 + } fmt; 760 765 }; 761 766 /* Flags for the 'capability' field. Read only */ 762 767 #define V4L2_FBUF_CAP_EXTERNOVERLAY 0x0001