|
@@ -41,18 +41,6 @@
|
|
|
#include <media/tveeprom.h>
|
|
|
#include <media/v4l2-chip-ident.h>
|
|
|
|
|
|
-static struct v4l2_fmtdesc formats[] = {
|
|
|
- { 0, V4L2_BUF_TYPE_VIDEO_CAPTURE, 0,
|
|
|
- "HM12 (YUV 4:1:1)", V4L2_PIX_FMT_HM12, { 0, 0, 0, 0 }
|
|
|
- },
|
|
|
- { 1, V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FMT_FLAG_COMPRESSED,
|
|
|
- "MPEG", V4L2_PIX_FMT_MPEG, { 0, 0, 0, 0 }
|
|
|
- },
|
|
|
- { 2, V4L2_BUF_TYPE_VIDEO_CAPTURE, 0,
|
|
|
- "YUYV 4:2:2", V4L2_PIX_FMT_YUYV, { 0, 0, 0, 0 }
|
|
|
- },
|
|
|
-};
|
|
|
-
|
|
|
u16 cx18_service2vbi(int type)
|
|
|
{
|
|
|
switch (type) {
|
|
@@ -172,8 +160,12 @@ static int cx18_g_fmt_vid_cap(struct file *file, void *fh,
|
|
|
pixfmt->priv = 0;
|
|
|
if (id->type == CX18_ENC_STREAM_TYPE_YUV) {
|
|
|
pixfmt->pixelformat = s->pixelformat;
|
|
|
- /* YUV size is (Y=(h*720) + UV=(h*(720/2))) */
|
|
|
- pixfmt->sizeimage = pixfmt->height * 720 * 3 / 2;
|
|
|
+ /* HM12 YUV size is (Y=(h*720) + UV=(h*(720/2)))
|
|
|
+ UYUV YUV size is (Y=(h*720) + UV=(h*(720))) */
|
|
|
+ if (s->pixelformat == V4L2_PIX_FMT_HM12)
|
|
|
+ pixfmt->sizeimage = pixfmt->height * 720 * 3 / 2;
|
|
|
+ else
|
|
|
+ pixfmt->sizeimage = pixfmt->height * 720 * 2;
|
|
|
pixfmt->bytesperline = 720;
|
|
|
} else {
|
|
|
pixfmt->pixelformat = V4L2_PIX_FMT_MPEG;
|
|
@@ -296,16 +288,15 @@ static int cx18_s_fmt_vid_cap(struct file *file, void *fh,
|
|
|
w = fmt->fmt.pix.width;
|
|
|
h = fmt->fmt.pix.height;
|
|
|
|
|
|
- s->pixelformat = fmt->fmt.pix.pixelformat;
|
|
|
- s->vbheight = h;
|
|
|
- s->vbwidth = w;
|
|
|
-
|
|
|
- if (cx->cxhdl.width == w && cx->cxhdl.height == h)
|
|
|
+ if (cx->cxhdl.width == w && cx->cxhdl.height == h &&
|
|
|
+ s->pixelformat == fmt->fmt.pix.pixelformat)
|
|
|
return 0;
|
|
|
|
|
|
if (atomic_read(&cx->ana_capturing) > 0)
|
|
|
return -EBUSY;
|
|
|
|
|
|
+ s->pixelformat = fmt->fmt.pix.pixelformat;
|
|
|
+
|
|
|
mbus_fmt.width = cx->cxhdl.width = w;
|
|
|
mbus_fmt.height = cx->cxhdl.height = h;
|
|
|
mbus_fmt.code = V4L2_MBUS_FMT_FIXED;
|
|
@@ -557,6 +548,18 @@ static int cx18_g_crop(struct file *file, void *fh, struct v4l2_crop *crop)
|
|
|
static int cx18_enum_fmt_vid_cap(struct file *file, void *fh,
|
|
|
struct v4l2_fmtdesc *fmt)
|
|
|
{
|
|
|
+ static const struct v4l2_fmtdesc formats[] = {
|
|
|
+ { 0, V4L2_BUF_TYPE_VIDEO_CAPTURE, 0,
|
|
|
+ "HM12 (YUV 4:1:1)", V4L2_PIX_FMT_HM12, { 0, 0, 0, 0 }
|
|
|
+ },
|
|
|
+ { 1, V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FMT_FLAG_COMPRESSED,
|
|
|
+ "MPEG", V4L2_PIX_FMT_MPEG, { 0, 0, 0, 0 }
|
|
|
+ },
|
|
|
+ { 2, V4L2_BUF_TYPE_VIDEO_CAPTURE, 0,
|
|
|
+ "UYVY 4:2:2", V4L2_PIX_FMT_UYVY, { 0, 0, 0, 0 }
|
|
|
+ },
|
|
|
+ };
|
|
|
+
|
|
|
if (fmt->index > ARRAY_SIZE(formats) - 1)
|
|
|
return -EINVAL;
|
|
|
*fmt = formats[fmt->index];
|
|
@@ -874,10 +877,12 @@ static int cx18_g_enc_index(struct file *file, void *fh,
|
|
|
static struct videobuf_queue *cx18_vb_queue(struct cx18_open_id *id)
|
|
|
{
|
|
|
struct videobuf_queue *q = NULL;
|
|
|
+ struct cx18 *cx = id->cx;
|
|
|
+ struct cx18_stream *s = &cx->streams[id->type];
|
|
|
|
|
|
- switch (id->vb_type) {
|
|
|
+ switch (s->vb_type) {
|
|
|
case V4L2_BUF_TYPE_VIDEO_CAPTURE:
|
|
|
- q = &id->vbuf_q;
|
|
|
+ q = &s->vbuf_q;
|
|
|
break;
|
|
|
case V4L2_BUF_TYPE_VBI_CAPTURE:
|
|
|
break;
|
|
@@ -895,15 +900,15 @@ static int cx18_streamon(struct file *file, void *priv,
|
|
|
struct cx18_stream *s = &cx->streams[id->type];
|
|
|
|
|
|
/* Start the hardware only if we're the video device */
|
|
|
- if ((id->vb_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
|
|
|
- (id->vb_type != V4L2_BUF_TYPE_VBI_CAPTURE))
|
|
|
+ if ((s->vb_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
|
|
|
+ (s->vb_type != V4L2_BUF_TYPE_VBI_CAPTURE))
|
|
|
return -EINVAL;
|
|
|
|
|
|
if (id->type != CX18_ENC_STREAM_TYPE_YUV)
|
|
|
return -EINVAL;
|
|
|
|
|
|
/* Establish a buffer timeout */
|
|
|
- mod_timer(&s->vb_timeout, jiffies + (HZ * 2));
|
|
|
+ mod_timer(&s->vb_timeout, msecs_to_jiffies(2000) + jiffies);
|
|
|
|
|
|
return videobuf_streamon(cx18_vb_queue(id));
|
|
|
}
|
|
@@ -912,10 +917,12 @@ static int cx18_streamoff(struct file *file, void *priv,
|
|
|
enum v4l2_buf_type type)
|
|
|
{
|
|
|
struct cx18_open_id *id = file->private_data;
|
|
|
+ struct cx18 *cx = id->cx;
|
|
|
+ struct cx18_stream *s = &cx->streams[id->type];
|
|
|
|
|
|
/* Start the hardware only if we're the video device */
|
|
|
- if ((id->vb_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
|
|
|
- (id->vb_type != V4L2_BUF_TYPE_VBI_CAPTURE))
|
|
|
+ if ((s->vb_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
|
|
|
+ (s->vb_type != V4L2_BUF_TYPE_VBI_CAPTURE))
|
|
|
return -EINVAL;
|
|
|
|
|
|
if (id->type != CX18_ENC_STREAM_TYPE_YUV)
|
|
@@ -928,9 +935,11 @@ static int cx18_reqbufs(struct file *file, void *priv,
|
|
|
struct v4l2_requestbuffers *rb)
|
|
|
{
|
|
|
struct cx18_open_id *id = file->private_data;
|
|
|
+ struct cx18 *cx = id->cx;
|
|
|
+ struct cx18_stream *s = &cx->streams[id->type];
|
|
|
|
|
|
- if ((id->vb_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
|
|
|
- (id->vb_type != V4L2_BUF_TYPE_VBI_CAPTURE))
|
|
|
+ if ((s->vb_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
|
|
|
+ (s->vb_type != V4L2_BUF_TYPE_VBI_CAPTURE))
|
|
|
return -EINVAL;
|
|
|
|
|
|
return videobuf_reqbufs(cx18_vb_queue(id), rb);
|
|
@@ -940,9 +949,11 @@ static int cx18_querybuf(struct file *file, void *priv,
|
|
|
struct v4l2_buffer *b)
|
|
|
{
|
|
|
struct cx18_open_id *id = file->private_data;
|
|
|
+ struct cx18 *cx = id->cx;
|
|
|
+ struct cx18_stream *s = &cx->streams[id->type];
|
|
|
|
|
|
- if ((id->vb_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
|
|
|
- (id->vb_type != V4L2_BUF_TYPE_VBI_CAPTURE))
|
|
|
+ if ((s->vb_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
|
|
|
+ (s->vb_type != V4L2_BUF_TYPE_VBI_CAPTURE))
|
|
|
return -EINVAL;
|
|
|
|
|
|
return videobuf_querybuf(cx18_vb_queue(id), b);
|
|
@@ -951,9 +962,11 @@ static int cx18_querybuf(struct file *file, void *priv,
|
|
|
static int cx18_qbuf(struct file *file, void *priv, struct v4l2_buffer *b)
|
|
|
{
|
|
|
struct cx18_open_id *id = file->private_data;
|
|
|
+ struct cx18 *cx = id->cx;
|
|
|
+ struct cx18_stream *s = &cx->streams[id->type];
|
|
|
|
|
|
- if ((id->vb_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
|
|
|
- (id->vb_type != V4L2_BUF_TYPE_VBI_CAPTURE))
|
|
|
+ if ((s->vb_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
|
|
|
+ (s->vb_type != V4L2_BUF_TYPE_VBI_CAPTURE))
|
|
|
return -EINVAL;
|
|
|
|
|
|
return videobuf_qbuf(cx18_vb_queue(id), b);
|
|
@@ -962,8 +975,11 @@ static int cx18_qbuf(struct file *file, void *priv, struct v4l2_buffer *b)
|
|
|
static int cx18_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b)
|
|
|
{
|
|
|
struct cx18_open_id *id = file->private_data;
|
|
|
- if ((id->vb_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
|
|
|
- (id->vb_type != V4L2_BUF_TYPE_VBI_CAPTURE))
|
|
|
+ struct cx18 *cx = id->cx;
|
|
|
+ struct cx18_stream *s = &cx->streams[id->type];
|
|
|
+
|
|
|
+ if ((s->vb_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
|
|
|
+ (s->vb_type != V4L2_BUF_TYPE_VBI_CAPTURE))
|
|
|
return -EINVAL;
|
|
|
|
|
|
return videobuf_dqbuf(cx18_vb_queue(id), b, file->f_flags & O_NONBLOCK);
|