[media] v4l: Support extending the v4l2_pix_format structure
authorLaurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Tue, 27 May 2014 12:41:05 +0000 (09:41 -0300)
committerMauro Carvalho Chehab <m.chehab@samsung.com>
Thu, 17 Jul 2014 15:44:47 +0000 (12:44 -0300)
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>
31 files changed:
Documentation/DocBook/media/Makefile
Documentation/DocBook/media/v4l/pixfmt.xml
Documentation/DocBook/media/v4l/v4l2.xml
Documentation/DocBook/media/v4l/vidioc-g-fbuf.xml
Documentation/DocBook/media/v4l/vidioc-querycap.xml
drivers/media/parport/bw-qcam.c
drivers/media/pci/cx18/cx18-ioctl.c
drivers/media/pci/cx25821/cx25821-video.c
drivers/media/pci/ivtv/ivtv-ioctl.c
drivers/media/pci/meye/meye.c
drivers/media/pci/saa7134/saa7134-empress.c
drivers/media/pci/saa7134/saa7134-video.c
drivers/media/pci/sta2x11/sta2x11_vip.c
drivers/media/platform/coda.c
drivers/media/platform/davinci/vpif_display.c
drivers/media/platform/mem2mem_testdev.c
drivers/media/platform/omap/omap_vout.c
drivers/media/platform/sh_veu.c
drivers/media/platform/vino.c
drivers/media/platform/vivi.c
drivers/media/usb/cx231xx/cx231xx-417.c
drivers/media/usb/cx231xx/cx231xx-video.c
drivers/media/usb/gspca/gspca.c
drivers/media/usb/hdpvr/hdpvr-video.c
drivers/media/usb/stkwebcam/stk-webcam.c
drivers/media/usb/tlg2300/pd-video.c
drivers/media/usb/tm6000/tm6000-video.c
drivers/media/usb/zr364xx/zr364xx.c
drivers/media/v4l2-core/v4l2-compat-ioctl32.c
drivers/media/v4l2-core/v4l2-ioctl.c
include/uapi/linux/videodev2.h

index 639e74857968ae3a47ae9bdc1aed0bbd4485ec3f..df2962d9e11e1f79e84779557c68bc73ea0f1670 100644 (file)
@@ -174,7 +174,7 @@ FILENAME = \
 DOCUMENTED = \
        -e "s/\(enum *\)v4l2_mpeg_cx2341x_video_\([a-z]*_spatial_filter_type\)/\1<link linkend=\"\2\">v4l2_mpeg_cx2341x_video_\2<\/link>/g" \
        -e "s/\(\(enum\|struct\) *\)\(v4l2_[a-zA-Z0-9_]*\)/\1<link linkend=\"\3\">\3<\/link>/g" \
-       -e "s/\(V4L2_PIX_FMT_[A-Z0-9_]\+\) /<link linkend=\"\1\">\1<\/link> /g" \
+       -e "s/\(V4L2_PIX_FMT_[A-Z0-9_]\+\)\(\s\+v4l2_fourcc\)/<link linkend=\"\1\">\1<\/link>\2/g" \
        -e ":a;s/\(linkend=\".*\)_\(.*\">\)/\1-\2/;ta" \
        -e "s/v4l2\-mpeg\-vbi\-ITV0/v4l2-mpeg-vbi-itv0-1/g"
 
index 91dcbc84f3f8502c298da9f248d09cee4b2b7c99..bb36b3829cf953a2bce2f3f32a2c17693e3ef776 100644 (file)
@@ -112,9 +112,28 @@ see <xref linkend="colorspaces" />.</entry>
        <row>
          <entry>__u32</entry>
          <entry><structfield>priv</structfield></entry>
-         <entry>Reserved for custom (driver defined) additional
-information about formats. When not used drivers and applications must
-set this field to zero.</entry>
+         <entry><para>This field indicates whether the remaining fields of the
+<structname>v4l2_pix_format</structname> structure, also called the extended
+fields, are valid. When set to <constant>V4L2_PIX_FMT_PRIV_MAGIC</constant>, it
+indicates that the extended fields have been correctly initialized. When set to
+any other value it indicates that the extended fields contain undefined values.
+</para>
+<para>Applications that wish to use the pixel format extended fields must first
+ensure that the feature is supported by querying the device for the
+<link linkend="querycap"><constant>V4L2_CAP_EXT_PIX_FORMAT</constant></link>
+capability. If the capability isn't set the pixel format extended fields are not
+supported and using the extended fields will lead to undefined results.</para>
+<para>To use the extended fields, applications must set the
+<structfield>priv</structfield> field to
+<constant>V4L2_PIX_FMT_PRIV_MAGIC</constant>, initialize all the extended fields
+and zero the unused bytes of the <structname>v4l2_format</structname>
+<structfield>raw_data</structfield> field.</para>
+<para>When the <structfield>priv</structfield> field isn't set to
+<constant>V4L2_PIX_FMT_PRIV_MAGIC</constant> drivers must act as if all the
+extended fields were set to zero. On return drivers must set the
+<structfield>priv</structfield> field to
+<constant>V4L2_PIX_FMT_PRIV_MAGIC</constant> and all the extended fields to
+applicable values.</para></entry>
        </row>
       </tbody>
     </tgroup>
index b445161b912c4329079bada5d11f1e1ab3ceede4..d0a48bebfa524a11c4d18ed8dd3ccbff1bba2d2b 100644 (file)
@@ -151,6 +151,14 @@ structs, ioctls) must be noted in more detail in the history chapter
 (compat.xml), along with the possible impact on existing drivers and
 applications. -->
 
+      <revision>
+       <revnumber>3.16</revnumber>
+       <date>2014-05-27</date>
+       <authorinitials>lp</authorinitials>
+       <revremark>Extended &v4l2-pix-format;.
+       </revremark>
+      </revision>
+
       <revision>
        <revnumber>3.15</revnumber>
        <date>2014-02-03</date>
index 7c63815e7afd0eb964a1848513dea5be14eb677e..20460730b02ca242e0ba5d096761ac00ea8239af 100644 (file)
@@ -152,13 +152,10 @@ a valid base address, so applications can find the corresponding Linux
 framebuffer device (see <xref linkend="osd" />).</entry>
          </row>
          <row>
-           <entry>&v4l2-pix-format;</entry>
+           <entry>struct</entry>
            <entry><structfield>fmt</structfield></entry>
            <entry></entry>
-           <entry>Layout of the frame buffer. The
-<structname>v4l2_pix_format</structname> structure is defined in <xref
-linkend="pixfmt" />, for clarification the fields and acceptable values
-           are listed below:</entry>
+           <entry>Layout of the frame buffer.</entry>
          </row>
          <row>
            <entry></entry>
@@ -276,9 +273,8 @@ see <xref linkend="colorspaces" />.</entry>
            <entry></entry>
            <entry>__u32</entry>
            <entry><structfield>priv</structfield></entry>
-           <entry>Reserved for additional information about custom
-(driver defined) formats. When not used drivers and applications must
-set this field to zero.</entry>
+           <entry>Reserved. Drivers and applications must set this field to
+zero.</entry>
          </row>
        </tbody>
       </tgroup>
index 370d49d6fb64e80077f833ff428cd4c33804af74..d0c5e604f014f3080966510d39cf7877e018d2be 100644 (file)
@@ -300,6 +300,12 @@ modulator programming see
            <entry>0x00100000</entry>
            <entry>The device supports the
 <link linkend="sdr">SDR Capture</link> interface.</entry>
+         </row>
+         <row>
+           <entry><constant>V4L2_CAP_EXT_PIX_FORMAT</constant></entry>
+           <entry>0x00200000</entry>
+           <entry>The device supports the &v4l2-pix-format; extended
+fields.</entry>
          </row>
          <row>
            <entry><constant>V4L2_CAP_READWRITE</constant></entry>
index 3c5dac4c1eab770553bd4b67d289fb50126f48d6..67b9da1dc43f298ab87c936014e71fe580f9eb0f 100644 (file)
@@ -759,7 +759,6 @@ static int qcam_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f
        pix->sizeimage = pix->width * pix->height;
        /* Just a guess */
        pix->colorspace = V4L2_COLORSPACE_SRGB;
-       pix->priv = 0;
        return 0;
 }
 
@@ -785,7 +784,6 @@ static int qcam_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format
        pix->sizeimage = pix->width * pix->height;
        /* Just a guess */
        pix->colorspace = V4L2_COLORSPACE_SRGB;
-       pix->priv = 0;
        return 0;
 }
 
index fefb2cd358385bcd34234eefc7f732fee5a1c15f..6f2b59042b7383ed8dbcbc415bd0dadf8f23e232 100644 (file)
@@ -156,7 +156,6 @@ static int cx18_g_fmt_vid_cap(struct file *file, void *fh,
        pixfmt->height = cx->cxhdl.height;
        pixfmt->colorspace = V4L2_COLORSPACE_SMPTE170M;
        pixfmt->field = V4L2_FIELD_INTERLACED;
-       pixfmt->priv = 0;
        if (id->type == CX18_ENC_STREAM_TYPE_YUV) {
                pixfmt->pixelformat = s->pixelformat;
                pixfmt->sizeimage = s->vb_bytes_per_frame;
index 8d2f1abeef77b098b50d8f6d5d3991f4550073be..3a419f13458458564eeacc085db63da3febec81d 100644 (file)
@@ -576,7 +576,6 @@ static int cx25821_vidioc_g_fmt_vid_cap(struct file *file, void *priv,
        f->fmt.pix.bytesperline = (chan->width * chan->fmt->depth) >> 3;
        f->fmt.pix.sizeimage = chan->height * f->fmt.pix.bytesperline;
        f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
-       f->fmt.pix.priv = 0;
 
        return 0;
 }
@@ -615,7 +614,6 @@ static int cx25821_vidioc_try_fmt_vid_cap(struct file *file, void *priv,
        f->fmt.pix.bytesperline = (f->fmt.pix.width * fmt->depth) >> 3;
        f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
        f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
-       f->fmt.pix.priv = 0;
 
        return 0;
 }
@@ -867,7 +865,6 @@ static int cx25821_vidioc_try_fmt_vid_out(struct file *file, void *priv,
        f->fmt.pix.bytesperline = (f->fmt.pix.width * fmt->depth) >> 3;
        f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
        f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
-       f->fmt.pix.priv = 0;
        return 0;
 }
 
index b3667a00db3a85dc056591c29d7fad2b333ee121..3e0cb77d5930fb7647db825081628fba2351cc8c 100644 (file)
@@ -351,7 +351,6 @@ static int ivtv_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f
        pixfmt->height = itv->cxhdl.height;
        pixfmt->colorspace = V4L2_COLORSPACE_SMPTE170M;
        pixfmt->field = V4L2_FIELD_INTERLACED;
-       pixfmt->priv = 0;
        if (id->type == IVTV_ENC_STREAM_TYPE_YUV) {
                pixfmt->pixelformat = V4L2_PIX_FMT_HM12;
                /* YUV size is (Y=(h*720) + UV=(h*(720/2))) */
@@ -418,7 +417,6 @@ static int ivtv_g_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *f
        pixfmt->height = itv->main_rect.height;
        pixfmt->colorspace = V4L2_COLORSPACE_SMPTE170M;
        pixfmt->field = V4L2_FIELD_INTERLACED;
-       pixfmt->priv = 0;
        if (id->type == IVTV_DEC_STREAM_TYPE_YUV) {
                switch (itv->yuv_info.lace_mode & IVTV_YUV_MODE_MASK) {
                case IVTV_YUV_MODE_INTERLACED:
@@ -1384,7 +1382,6 @@ static int ivtv_g_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb)
        fb->fmt.bytesperline = fb->fmt.width;
        fb->fmt.colorspace = V4L2_COLORSPACE_SMPTE170M;
        fb->fmt.field = V4L2_FIELD_INTERLACED;
-       fb->fmt.priv = 0;
        if (fb->fmt.pixelformat != V4L2_PIX_FMT_PAL8)
                fb->fmt.bytesperline *= 2;
        if (fb->fmt.pixelformat == V4L2_PIX_FMT_RGB32 ||
index 1a77f8dfafa555f35f8c2815dc3d283aad88e7dd..aeae5470881130b72ed18edb5f03c92f131b9ec8 100644 (file)
@@ -1166,7 +1166,6 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *fh,
        f->fmt.pix.sizeimage = f->fmt.pix.height *
                               f->fmt.pix.bytesperline;
        f->fmt.pix.colorspace = 0;
-       f->fmt.pix.priv = 0;
 
        return 0;
 }
@@ -1232,7 +1231,6 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *fh,
        f->fmt.pix.sizeimage = f->fmt.pix.height *
                               f->fmt.pix.bytesperline;
        f->fmt.pix.colorspace = 0;
-       f->fmt.pix.priv = 0;
 
        return 0;
 }
index 5526ed5444fb6bd93ca3aec5c45a6e08d8a6f824..ef39261c1f20365a84958e026b690f8d2ab6e90a 100644 (file)
@@ -130,7 +130,6 @@ static int empress_g_fmt_vid_cap(struct file *file, void *priv,
        f->fmt.pix.pixelformat  = V4L2_PIX_FMT_MPEG;
        f->fmt.pix.sizeimage    = TS_PACKET_SIZE * dev->ts.nr_packets;
        f->fmt.pix.bytesperline = 0;
-       f->fmt.pix.priv = 0;
 
        return 0;
 }
@@ -148,7 +147,6 @@ static int empress_s_fmt_vid_cap(struct file *file, void *priv,
        f->fmt.pix.pixelformat  = V4L2_PIX_FMT_MPEG;
        f->fmt.pix.sizeimage    = TS_PACKET_SIZE * dev->ts.nr_packets;
        f->fmt.pix.bytesperline = 0;
-       f->fmt.pix.priv = 0;
 
        return 0;
 }
@@ -166,7 +164,6 @@ static int empress_try_fmt_vid_cap(struct file *file, void *priv,
        f->fmt.pix.pixelformat  = V4L2_PIX_FMT_MPEG;
        f->fmt.pix.sizeimage    = TS_PACKET_SIZE * dev->ts.nr_packets;
        f->fmt.pix.bytesperline = 0;
-       f->fmt.pix.priv = 0;
 
        return 0;
 }
index d3759998076869c91ae907c2e86e3b132dbb80fc..0cfa2ca6a32ad2c1e3a03a952792fdcb590cc146 100644 (file)
@@ -1235,7 +1235,6 @@ static int saa7134_g_fmt_vid_cap(struct file *file, void *priv,
        f->fmt.pix.sizeimage =
                f->fmt.pix.height * f->fmt.pix.bytesperline;
        f->fmt.pix.colorspace   = V4L2_COLORSPACE_SMPTE170M;
-       f->fmt.pix.priv = 0;
        return 0;
 }
 
@@ -1315,7 +1314,6 @@ static int saa7134_try_fmt_vid_cap(struct file *file, void *priv,
        f->fmt.pix.sizeimage =
                f->fmt.pix.height * f->fmt.pix.bytesperline;
        f->fmt.pix.colorspace   = V4L2_COLORSPACE_SMPTE170M;
-       f->fmt.pix.priv = 0;
 
        return 0;
 }
index f2d8c70d35f561b4bcd3bd68b7b7f428cd1df893..365bd21301baa494744238eea568fea16ec29e5d 100644 (file)
@@ -640,7 +640,6 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
        f->fmt.pix.bytesperline = f->fmt.pix.width * 2;
        f->fmt.pix.sizeimage = f->fmt.pix.width * 2 * f->fmt.pix.height;
        f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
-       f->fmt.pix.priv = 0;
        return 0;
 }
 
index b1783791d426583ec4b01562f42ed6017775e783..54886606ed68a8d988851290486ab4978e903a94 100644 (file)
@@ -613,8 +613,6 @@ static int coda_try_fmt(struct coda_ctx *ctx, struct coda_codec *codec,
                BUG();
        }
 
-       f->fmt.pix.priv = 0;
-
        return 0;
 }
 
index 877b46e8b2e49ea2dc5edbc4b96cb36e44b013ed..0bd6dcb13cbcf8fd4108e85df6740662e2cb81b4 100644 (file)
@@ -648,7 +648,6 @@ static int vpif_try_fmt_vid_out(struct file *file, void *priv,
        pixfmt->width = common->fmt.fmt.pix.width;
        pixfmt->height = common->fmt.fmt.pix.height;
        pixfmt->sizeimage = pixfmt->bytesperline * pixfmt->height * 2;
-       pixfmt->priv = 0;
 
        return 0;
 }
index 0714070ed7fab4ea5fd90597c1c130979c486916..c1b03cfd6dedf3a719e152ac8fe495845fca4a96 100644 (file)
@@ -532,7 +532,6 @@ static int vidioc_try_fmt(struct v4l2_format *f, struct m2mtest_fmt *fmt)
        f->fmt.pix.bytesperline = (f->fmt.pix.width * fmt->depth) >> 3;
        f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
        f->fmt.pix.field = V4L2_FIELD_NONE;
-       f->fmt.pix.priv = 0;
 
        return 0;
 }
index 9a726eacb29be8dcaef7c41cfdebd8e07c9c8443..2d177fa5847168f65d58b33b664c4e40ee3dd638 100644 (file)
@@ -165,7 +165,6 @@ static int omap_vout_try_format(struct v4l2_pix_format *pix)
 
        pix->pixelformat = omap_formats[ifmt].pixelformat;
        pix->field = V4L2_FIELD_ANY;
-       pix->priv = 0;
 
        switch (pix->pixelformat) {
        case V4L2_PIX_FMT_YUYV:
@@ -1896,7 +1895,6 @@ static int __init omap_vout_setup_video_data(struct omap_vout_device *vout)
        pix->field = V4L2_FIELD_ANY;
        pix->bytesperline = pix->width * 2;
        pix->sizeimage = pix->bytesperline * pix->height;
-       pix->priv = 0;
        pix->colorspace = V4L2_COLORSPACE_JPEG;
 
        vout->bpp = RGB565_BPP;
index 744e43b480bcc217f3da9522cc992061fa7f691a..8dc279d4d5610fac3219cb253aa9d383108ab3d4 100644 (file)
@@ -425,7 +425,6 @@ static int sh_veu_g_fmt(struct sh_veu_file *veu_file, struct v4l2_format *f)
        pix->bytesperline       = vfmt->bytesperline;
        pix->sizeimage          = vfmt->bytesperline * pix->height *
                vfmt->fmt->depth / vfmt->fmt->ydepth;
-       pix->priv               = 0;
        dev_dbg(veu->dev, "%s(): type: %d, size %u @ %ux%u, fmt %x\n", __func__,
                f->type, pix->sizeimage, pix->width, pix->height, pix->pixelformat);
 
@@ -473,7 +472,6 @@ static int sh_veu_try_fmt(struct v4l2_format *f, const struct sh_veu_format *fmt
 
        pix->pixelformat        = fmt->fourcc;
        pix->colorspace         = sh_veu_4cc2cspace(pix->pixelformat);
-       pix->priv               = 0;
 
        pr_debug("%s(): type: %d, size %u\n", __func__, f->type, pix->sizeimage);
 
index 470d35336119743ab9c46138f6c1156d14af7178..91d44ea16f275257cfc4f57d5c420b674a0495c3 100644 (file)
@@ -3147,7 +3147,6 @@ static int vino_try_fmt_vid_cap(struct file *file, void *__fh,
        pf->colorspace =
                vino_data_formats[tempvcs.data_format].colorspace;
 
-       pf->priv = 0;
        return 0;
 }
 
@@ -3175,8 +3174,6 @@ static int vino_g_fmt_vid_cap(struct file *file, void *__fh,
        pf->colorspace =
                vino_data_formats[vcs->data_format].colorspace;
 
-       pf->priv = 0;
-
        spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
        return 0;
 }
@@ -3219,8 +3216,6 @@ static int vino_s_fmt_vid_cap(struct file *file, void *__fh,
        pf->colorspace =
                vino_data_formats[vcs->data_format].colorspace;
 
-       pf->priv = 0;
-
        spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
        return 0;
 }
index 7542b5dd99103319d0924f0b67482289b71e3748..80333714ffa7498e3a63af827d3549468d0664de 100644 (file)
@@ -1014,7 +1014,6 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
                f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
        else
                f->fmt.pix.colorspace = V4L2_COLORSPACE_SRGB;
-       f->fmt.pix.priv = 0;
        return 0;
 }
 
index f0400e260eb7b1d10c4d12909b1082f13d4e64b6..459bb0e9897151014a05ec172606cbc21f1b9a80 100644 (file)
@@ -1563,7 +1563,6 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
        f->fmt.pix.width = dev->ts1.width;
        f->fmt.pix.height = dev->ts1.height;
        f->fmt.pix.field = V4L2_FIELD_INTERLACED;
-       f->fmt.pix.priv = 0;
        dprintk(1, "VIDIOC_G_FMT: w: %d, h: %d\n",
                dev->ts1.width, dev->ts1.height);
        dprintk(3, "exit vidioc_g_fmt_vid_cap()\n");
@@ -1582,7 +1581,6 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
        f->fmt.pix.sizeimage = mpeglines * mpeglinesize;
        f->fmt.pix.field = V4L2_FIELD_INTERLACED;
        f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
-       f->fmt.pix.priv = 0;
        dprintk(1, "VIDIOC_TRY_FMT: w: %d, h: %d\n",
                dev->ts1.width, dev->ts1.height);
        dprintk(3, "exit vidioc_try_fmt_vid_cap()\n");
index ae31ca2fc9a1fede2ce4fc715d495fc7f67ae0de..3b3ada6562cad73bec31887fce1c4776643c900f 100644 (file)
@@ -885,7 +885,6 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
        f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
 
        f->fmt.pix.field = V4L2_FIELD_INTERLACED;
-       f->fmt.pix.priv = 0;
 
        return 0;
 }
@@ -930,7 +929,6 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
        f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * height;
        f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
        f->fmt.pix.field = V4L2_FIELD_INTERLACED;
-       f->fmt.pix.priv = 0;
 
        return 0;
 }
index 42d223239206a8b3c84c191c1ba4894447b093b5..e8cf23c91cefc0b570391f5146b831733f5d14be 100644 (file)
@@ -1109,8 +1109,8 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
        struct gspca_dev *gspca_dev = video_drvdata(file);
 
        fmt->fmt.pix = gspca_dev->pixfmt;
-       /* some drivers use priv internally, zero it before giving it to
-          userspace */
+       /* some drivers use priv internally, zero it before giving it back to
+          the core */
        fmt->fmt.pix.priv = 0;
        return 0;
 }
@@ -1146,8 +1146,8 @@ static int try_fmt_vid_cap(struct gspca_dev *gspca_dev,
                fmt->fmt.pix.height = h;
                gspca_dev->sd_desc->try_fmt(gspca_dev, fmt);
        }
-       /* some drivers use priv internally, zero it before giving it to
-          userspace */
+       /* some drivers use priv internally, zero it before giving it back to
+          the core */
        fmt->fmt.pix.priv = 0;
        return mode;                    /* used when s_fmt */
 }
index dca4b65053aabf29ac8f5674d75a9fce8f7edf1e..4b7653fd4b0bf29d01061de1957b09e7db4d9a92 100644 (file)
@@ -1022,7 +1022,6 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *_fh,
        f->fmt.pix.pixelformat  = V4L2_PIX_FMT_MPEG;
        f->fmt.pix.sizeimage    = dev->bulk_in_size;
        f->fmt.pix.bytesperline = 0;
-       f->fmt.pix.priv         = 0;
        if (f->fmt.pix.width == 720) {
                /* SDTV formats */
                f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
index d76860b6a0b810f87afa86ad13f390b32fd60bab..3588dc38db874077ad24c62fb7f04daf9df44793 100644 (file)
@@ -923,7 +923,6 @@ static int stk_vidioc_g_fmt_vid_cap(struct file *filp,
                pix_format->bytesperline = 2 * pix_format->width;
        pix_format->sizeimage = pix_format->bytesperline
                                * pix_format->height;
-       pix_format->priv = 0;
        return 0;
 }
 
@@ -967,7 +966,6 @@ static int stk_try_fmt_vid_cap(struct file *filp,
                fmtd->fmt.pix.bytesperline = 2 * fmtd->fmt.pix.width;
        fmtd->fmt.pix.sizeimage = fmtd->fmt.pix.bytesperline
                * fmtd->fmt.pix.height;
-       fmtd->fmt.pix.priv = 0;
        return 0;
 }
 
index 8df668d06552bb4323ab0213889d12105e09422f..8cd7f02fcf9fc7080ea6444bfb56c50854c6c80e 100644 (file)
@@ -1321,7 +1321,6 @@ static void init_video_context(struct running_context *context)
                                .bytesperline   = 720 * 2,
                                .sizeimage      = 720 * 576 * 2,
                                .colorspace     = V4L2_COLORSPACE_SMPTE170M,
-                               .priv           = 0
                        };
 }
 
index 9bde0642ffd1e49a7ed4de237208a66f025b2f20..793577fc46336ea417a4aeb49337690ff32220b2 100644 (file)
@@ -918,7 +918,6 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
                (f->fmt.pix.width * fh->fmt->depth) >> 3;
        f->fmt.pix.sizeimage =
                f->fmt.pix.height * f->fmt.pix.bytesperline;
-       f->fmt.pix.priv = 0;
 
        return 0;
 }
@@ -959,7 +958,6 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
        f->fmt.pix.width &= ~0x01;
 
        f->fmt.pix.field = field;
-       f->fmt.pix.priv = 0;
 
        f->fmt.pix.bytesperline =
                (f->fmt.pix.width * fmt->depth) >> 3;
index 3b80579a82c5dfc6703f5e411cd93432e2ef2afd..5c006277b8b15ab405bc8f8e9c35695975d25c64 100644 (file)
@@ -806,7 +806,6 @@ static int zr364xx_vidioc_try_fmt_vid_cap(struct file *file, void *priv,
        f->fmt.pix.bytesperline = f->fmt.pix.width * 2;
        f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
        f->fmt.pix.colorspace = V4L2_COLORSPACE_JPEG;
-       f->fmt.pix.priv = 0;
        DBG("%s: V4L2_PIX_FMT_%s (%d) ok!\n", __func__,
            decode_fourcc(f->fmt.pix.pixelformat, pixelformat_name),
            f->fmt.pix.field);
@@ -829,7 +828,6 @@ static int zr364xx_vidioc_g_fmt_vid_cap(struct file *file, void *priv,
        f->fmt.pix.bytesperline = f->fmt.pix.width * 2;
        f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
        f->fmt.pix.colorspace = V4L2_COLORSPACE_JPEG;
-       f->fmt.pix.priv = 0;
        return 0;
 }
 
@@ -866,7 +864,6 @@ static int zr364xx_vidioc_s_fmt_vid_cap(struct file *file, void *priv,
        f->fmt.pix.bytesperline = f->fmt.pix.width * 2;
        f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
        f->fmt.pix.colorspace = V4L2_COLORSPACE_JPEG;
-       f->fmt.pix.priv = 0;
        cam->vb_vidq.field = f->fmt.pix.field;
 
        if (f->fmt.pix.width == 160 && f->fmt.pix.height == 120)
index 7e2411c36419c394b3d23a81eb5bdd4b5fee88c2..cca6c2f76b3a3ed75c4398a2f67d302be41ee384 100644 (file)
@@ -540,7 +540,16 @@ struct v4l2_framebuffer32 {
        __u32                   capability;
        __u32                   flags;
        compat_caddr_t          base;
-       struct v4l2_pix_format  fmt;
+       struct {
+               __u32           width;
+               __u32           height;
+               __u32           pixelformat;
+               __u32           field;
+               __u32           bytesperline;
+               __u32           sizeimage;
+               __u32           colorspace;
+               __u32           priv;
+       } fmt;
 };
 
 static int get_v4l2_framebuffer32(struct v4l2_framebuffer *kp, struct v4l2_framebuffer32 __user *up)
@@ -550,10 +559,10 @@ static int get_v4l2_framebuffer32(struct v4l2_framebuffer *kp, struct v4l2_frame
        if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_framebuffer32)) ||
                get_user(tmp, &up->base) ||
                get_user(kp->capability, &up->capability) ||
-               get_user(kp->flags, &up->flags))
+               get_user(kp->flags, &up->flags) ||
+               copy_from_user(&kp->fmt, &up->fmt, sizeof(up->fmt)))
                        return -EFAULT;
        kp->base = compat_ptr(tmp);
-       get_v4l2_pix_format(&kp->fmt, &up->fmt);
        return 0;
 }
 
@@ -564,9 +573,9 @@ static int put_v4l2_framebuffer32(struct v4l2_framebuffer *kp, struct v4l2_frame
        if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_framebuffer32)) ||
                put_user(tmp, &up->base) ||
                put_user(kp->capability, &up->capability) ||
-               put_user(kp->flags, &up->flags))
+               put_user(kp->flags, &up->flags) ||
+               copy_to_user(&up->fmt, &kp->fmt, sizeof(up->fmt)))
                        return -EFAULT;
-       put_v4l2_pix_format(&kp->fmt, &up->fmt);
        return 0;
 }
 
index 96bc117f66b2a9a0f75cf76ac4d272f187bde645..2e630005676f906d91f0bde4aa8f9fb79d767749 100644 (file)
@@ -973,13 +973,48 @@ static int check_fmt(struct file *file, enum v4l2_buf_type type)
        return -EINVAL;
 }
 
+static void v4l_sanitize_format(struct v4l2_format *fmt)
+{
+       unsigned int offset;
+
+       /*
+        * The v4l2_pix_format structure has been extended with fields that were
+        * not previously required to be set to zero by applications. The priv
+        * field, when set to a magic value, indicates the the extended fields
+        * are valid. Otherwise they will contain undefined values. To simplify
+        * the API towards drivers zero the extended fields and set the priv
+        * field to the magic value when the extended pixel format structure
+        * isn't used by applications.
+        */
+
+       if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
+           fmt->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
+               return;
+
+       if (fmt->fmt.pix.priv == V4L2_PIX_FMT_PRIV_MAGIC)
+               return;
+
+       fmt->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
+
+       offset = offsetof(struct v4l2_pix_format, priv)
+              + sizeof(fmt->fmt.pix.priv);
+       memset(((void *)&fmt->fmt.pix) + offset, 0,
+              sizeof(fmt->fmt.pix) - offset);
+}
+
 static int v4l_querycap(const struct v4l2_ioctl_ops *ops,
                                struct file *file, void *fh, void *arg)
 {
        struct v4l2_capability *cap = (struct v4l2_capability *)arg;
+       int ret;
 
        cap->version = LINUX_VERSION_CODE;
-       return ops->vidioc_querycap(file, fh, cap);
+
+       ret = ops->vidioc_querycap(file, fh, cap);
+
+       cap->capabilities |= V4L2_CAP_EXT_PIX_FORMAT;
+
+       return ret;
 }
 
 static int v4l_s_input(const struct v4l2_ioctl_ops *ops,
@@ -1103,12 +1138,17 @@ static int v4l_g_fmt(const struct v4l2_ioctl_ops *ops,
        bool is_sdr = vfd->vfl_type == VFL_TYPE_SDR;
        bool is_rx = vfd->vfl_dir != VFL_DIR_TX;
        bool is_tx = vfd->vfl_dir != VFL_DIR_RX;
+       int ret;
+
+       p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
 
        switch (p->type) {
        case V4L2_BUF_TYPE_VIDEO_CAPTURE:
                if (unlikely(!is_rx || !is_vid || !ops->vidioc_g_fmt_vid_cap))
                        break;
-               return ops->vidioc_g_fmt_vid_cap(file, fh, arg);
+               ret = ops->vidioc_g_fmt_vid_cap(file, fh, arg);
+               p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
+               return ret;
        case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
                if (unlikely(!is_rx || !is_vid || !ops->vidioc_g_fmt_vid_cap_mplane))
                        break;
@@ -1128,7 +1168,9 @@ static int v4l_g_fmt(const struct v4l2_ioctl_ops *ops,
        case V4L2_BUF_TYPE_VIDEO_OUTPUT:
                if (unlikely(!is_tx || !is_vid || !ops->vidioc_g_fmt_vid_out))
                        break;
-               return ops->vidioc_g_fmt_vid_out(file, fh, arg);
+               ret = ops->vidioc_g_fmt_vid_out(file, fh, arg);
+               p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
+               return ret;
        case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
                if (unlikely(!is_tx || !is_vid || !ops->vidioc_g_fmt_vid_out_mplane))
                        break;
@@ -1163,6 +1205,8 @@ static int v4l_s_fmt(const struct v4l2_ioctl_ops *ops,
        bool is_rx = vfd->vfl_dir != VFL_DIR_TX;
        bool is_tx = vfd->vfl_dir != VFL_DIR_RX;
 
+       v4l_sanitize_format(p);
+
        switch (p->type) {
        case V4L2_BUF_TYPE_VIDEO_CAPTURE:
                if (unlikely(!is_rx || !is_vid || !ops->vidioc_s_fmt_vid_cap))
@@ -1233,6 +1277,8 @@ static int v4l_try_fmt(const struct v4l2_ioctl_ops *ops,
        bool is_rx = vfd->vfl_dir != VFL_DIR_TX;
        bool is_tx = vfd->vfl_dir != VFL_DIR_RX;
 
+       v4l_sanitize_format(p);
+
        switch (p->type) {
        case V4L2_BUF_TYPE_VIDEO_CAPTURE:
                if (unlikely(!is_rx || !is_vid || !ops->vidioc_try_fmt_vid_cap))
@@ -1516,7 +1562,18 @@ static int v4l_create_bufs(const struct v4l2_ioctl_ops *ops,
        struct v4l2_create_buffers *create = arg;
        int ret = check_fmt(file, create->format.type);
 
-       return ret ? ret : ops->vidioc_create_bufs(file, fh, create);
+       if (ret)
+               return ret;
+
+       v4l_sanitize_format(&create->format);
+
+       ret = ops->vidioc_create_bufs(file, fh, create);
+
+       if (create->format.type == V4L2_BUF_TYPE_VIDEO_CAPTURE ||
+           create->format.type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
+               create->format.fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
+
+       return ret;
 }
 
 static int v4l_prepare_buf(const struct v4l2_ioctl_ops *ops,
index a498d8b586790ae7e2da5b97c8c9da908a6e9a5c..eb3bdd33816b7f4e4ed579dce9ccf0478cf27765 100644 (file)
@@ -268,6 +268,7 @@ struct v4l2_capability {
 #define V4L2_CAP_MODULATOR             0x00080000  /* has a modulator */
 
 #define V4L2_CAP_SDR_CAPTURE           0x00100000  /* Is a SDR capture device */
+#define V4L2_CAP_EXT_PIX_FORMAT                0x00200000  /* Supports the extended pixel format */
 
 #define V4L2_CAP_READWRITE              0x01000000  /* read/write systemcalls */
 #define V4L2_CAP_ASYNCIO                0x02000000  /* async I/O */
@@ -448,6 +449,9 @@ struct v4l2_pix_format {
 #define V4L2_SDR_FMT_CU8          v4l2_fourcc('C', 'U', '0', '8') /* IQ u8 */
 #define V4L2_SDR_FMT_CU16LE       v4l2_fourcc('C', 'U', '1', '6') /* IQ u16le */
 
+/* priv field value to indicates that subsequent fields are valid. */
+#define V4L2_PIX_FMT_PRIV_MAGIC                0xfeedcafe
+
 /*
  *     F O R M A T   E N U M E R A T I O N
  */
@@ -752,7 +756,16 @@ struct v4l2_framebuffer {
 /* FIXME: in theory we should pass something like PCI device + memory
  * region + offset instead of some physical address */
        void                    *base;
-       struct v4l2_pix_format  fmt;
+       struct {
+               __u32           width;
+               __u32           height;
+               __u32           pixelformat;
+               __u32           field;          /* enum v4l2_field */
+               __u32           bytesperline;   /* for padding, zero if unused */
+               __u32           sizeimage;
+               __u32           colorspace;     /* enum v4l2_colorspace */
+               __u32           priv;           /* reserved field, set to 0 */
+       } fmt;
 };
 /*  Flags for the 'capability' field. Read only */
 #define V4L2_FBUF_CAP_EXTERNOVERLAY    0x0001