Skip to content

Commit

Permalink
[media] v4l: Support extending the v4l2_pix_format structure
Browse files Browse the repository at this point in the history
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 <[email protected]>
Signed-off-by: Mauro Carvalho Chehab <[email protected]>
  • Loading branch information
Laurent Pinchart authored and mchehab committed Jul 17, 2014
1 parent b04ef7c commit d52e238
Show file tree
Hide file tree
Showing 31 changed files with 134 additions and 70 deletions.
2 changes: 1 addition & 1 deletion Documentation/DocBook/media/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand Down
25 changes: 22 additions & 3 deletions Documentation/DocBook/media/v4l/pixfmt.xml
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down
8 changes: 8 additions & 0 deletions Documentation/DocBook/media/v4l/v4l2.xml
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down
12 changes: 4 additions & 8 deletions Documentation/DocBook/media/v4l/vidioc-g-fbuf.xml
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -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>
Expand Down
6 changes: 6 additions & 0 deletions Documentation/DocBook/media/v4l/vidioc-querycap.xml
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down
2 changes: 0 additions & 2 deletions drivers/media/parport/bw-qcam.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand All @@ -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;
}

Expand Down
1 change: 0 additions & 1 deletion drivers/media/pci/cx18/cx18-ioctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
3 changes: 0 additions & 3 deletions drivers/media/pci/cx25821/cx25821-video.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
}

Expand Down
3 changes: 0 additions & 3 deletions drivers/media/pci/ivtv/ivtv-ioctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -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))) */
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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 ||
Expand Down
2 changes: 0 additions & 2 deletions drivers/media/pci/meye/meye.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
}
Expand Down
3 changes: 0 additions & 3 deletions drivers/media/pci/saa7134/saa7134-empress.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand All @@ -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;
}
Expand All @@ -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;
}
Expand Down
2 changes: 0 additions & 2 deletions drivers/media/pci/saa7134/saa7134-video.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down Expand Up @@ -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;
}
Expand Down
1 change: 0 additions & 1 deletion drivers/media/pci/sta2x11/sta2x11_vip.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
2 changes: 0 additions & 2 deletions drivers/media/platform/coda.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
1 change: 0 additions & 1 deletion drivers/media/platform/davinci/vpif_display.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
1 change: 0 additions & 1 deletion drivers/media/platform/mem2mem_testdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
2 changes: 0 additions & 2 deletions drivers/media/platform/omap/omap_vout.c
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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;
Expand Down
2 changes: 0 additions & 2 deletions drivers/media/platform/sh_veu.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down Expand Up @@ -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);

Expand Down
5 changes: 0 additions & 5 deletions drivers/media/platform/vino.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
}
Expand Down
1 change: 0 additions & 1 deletion drivers/media/platform/vivi.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
2 changes: 0 additions & 2 deletions drivers/media/usb/cx231xx/cx231xx-417.c
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand All @@ -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");
Expand Down
2 changes: 0 additions & 2 deletions drivers/media/usb/cx231xx/cx231xx-video.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
}
Expand Down
8 changes: 4 additions & 4 deletions drivers/media/usb/gspca/gspca.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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 */
}
Expand Down
1 change: 0 additions & 1 deletion drivers/media/usb/hdpvr/hdpvr-video.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Loading

0 comments on commit d52e238

Please sign in to comment.