diff options
author | Magnus Damm <damm@igel.co.jp> | 2008-10-14 11:47:09 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2008-10-17 16:24:57 -0400 |
commit | d891f475812bf849c2bb2b2ac60424f9fc8e1cc6 (patch) | |
tree | a5a77d1025a674d0c1a97547d8d27eaade463e33 /drivers/media | |
parent | 74d7c5af78234467fed522c0f0ff47ef765cecb8 (diff) |
V4L/DVB (9236): Teach vivi about multiple pixel formats
This patch contains the ground work to add support for multiple
pixel formats to vivi.c
Signed-off-by: Magnus Damm <damm@igel.co.jp>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media')
-rw-r--r-- | drivers/media/video/vivi.c | 97 |
1 files changed, 67 insertions, 30 deletions
diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c index 0d1ad7f63d09..523f78c48472 100644 --- a/drivers/media/video/vivi.c +++ b/drivers/media/video/vivi.c | |||
@@ -128,12 +128,31 @@ struct vivi_fmt { | |||
128 | int depth; | 128 | int depth; |
129 | }; | 129 | }; |
130 | 130 | ||
131 | static struct vivi_fmt format = { | 131 | static struct vivi_fmt formats[] = { |
132 | .name = "4:2:2, packed, YUYV", | 132 | { |
133 | .fourcc = V4L2_PIX_FMT_YUYV, | 133 | .name = "4:2:2, packed, YUYV", |
134 | .depth = 16, | 134 | .fourcc = V4L2_PIX_FMT_YUYV, |
135 | .depth = 16, | ||
136 | }, | ||
135 | }; | 137 | }; |
136 | 138 | ||
139 | static struct vivi_fmt *get_format(struct v4l2_format *f) | ||
140 | { | ||
141 | struct vivi_fmt *fmt; | ||
142 | unsigned int k; | ||
143 | |||
144 | for (k = 0; k < ARRAY_SIZE(formats); k++) { | ||
145 | fmt = &formats[k]; | ||
146 | if (fmt->fourcc == f->fmt.pix.pixelformat) | ||
147 | break; | ||
148 | } | ||
149 | |||
150 | if (k == ARRAY_SIZE(formats)) | ||
151 | return NULL; | ||
152 | |||
153 | return &formats[k]; | ||
154 | } | ||
155 | |||
137 | struct sg_to_addr { | 156 | struct sg_to_addr { |
138 | int pos; | 157 | int pos; |
139 | struct scatterlist *sg; | 158 | struct scatterlist *sg; |
@@ -248,16 +267,20 @@ static void gen_twopix(struct vivi_fh *fh, unsigned char *buf, int colorpos) | |||
248 | for (color = 0; color < 4; color++) { | 267 | for (color = 0; color < 4; color++) { |
249 | p = buf + color; | 268 | p = buf + color; |
250 | 269 | ||
251 | switch (color) { | 270 | switch (fh->fmt->fourcc) { |
252 | case 0: | 271 | case V4L2_PIX_FMT_YUYV: |
253 | case 2: | 272 | switch (color) { |
254 | *p = r_y; | 273 | case 0: |
255 | break; | 274 | case 2: |
256 | case 1: | 275 | *p = r_y; |
257 | *p = g_u; | 276 | break; |
258 | break; | 277 | case 1: |
259 | case 3: | 278 | *p = g_u; |
260 | *p = b_v; | 279 | break; |
280 | case 3: | ||
281 | *p = b_v; | ||
282 | break; | ||
283 | } | ||
261 | break; | 284 | break; |
262 | } | 285 | } |
263 | } | 286 | } |
@@ -622,11 +645,15 @@ static int vidioc_querycap(struct file *file, void *priv, | |||
622 | static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, | 645 | static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, |
623 | struct v4l2_fmtdesc *f) | 646 | struct v4l2_fmtdesc *f) |
624 | { | 647 | { |
625 | if (f->index > 0) | 648 | struct vivi_fmt *fmt; |
649 | |||
650 | if (f->index >= ARRAY_SIZE(formats)) | ||
626 | return -EINVAL; | 651 | return -EINVAL; |
627 | 652 | ||
628 | strlcpy(f->description, format.name, sizeof(f->description)); | 653 | fmt = &formats[f->index]; |
629 | f->pixelformat = format.fourcc; | 654 | |
655 | strlcpy(f->description, fmt->name, sizeof(f->description)); | ||
656 | f->pixelformat = fmt->fourcc; | ||
630 | return 0; | 657 | return 0; |
631 | } | 658 | } |
632 | 659 | ||
@@ -656,13 +683,12 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, | |||
656 | enum v4l2_field field; | 683 | enum v4l2_field field; |
657 | unsigned int maxw, maxh; | 684 | unsigned int maxw, maxh; |
658 | 685 | ||
659 | if (format.fourcc != f->fmt.pix.pixelformat) { | 686 | fmt = get_format(f); |
660 | dprintk(dev, 1, "Fourcc format (0x%08x) invalid. " | 687 | if (!fmt) { |
661 | "Driver accepts only 0x%08x\n", | 688 | dprintk(dev, 1, "Fourcc format (0x%08x) invalid.\n", |
662 | f->fmt.pix.pixelformat, format.fourcc); | 689 | f->fmt.pix.pixelformat); |
663 | return -EINVAL; | 690 | return -EINVAL; |
664 | } | 691 | } |
665 | fmt = &format; | ||
666 | 692 | ||
667 | field = f->fmt.pix.field; | 693 | field = f->fmt.pix.field; |
668 | 694 | ||
@@ -701,7 +727,7 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, | |||
701 | struct vivi_fh *fh = priv; | 727 | struct vivi_fh *fh = priv; |
702 | struct videobuf_queue *q = &fh->vb_vidq; | 728 | struct videobuf_queue *q = &fh->vb_vidq; |
703 | unsigned char r, g, b; | 729 | unsigned char r, g, b; |
704 | int k; | 730 | int k, is_yuv; |
705 | 731 | ||
706 | int ret = vidioc_try_fmt_vid_cap(file, fh, f); | 732 | int ret = vidioc_try_fmt_vid_cap(file, fh, f); |
707 | if (ret < 0) | 733 | if (ret < 0) |
@@ -715,7 +741,7 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, | |||
715 | goto out; | 741 | goto out; |
716 | } | 742 | } |
717 | 743 | ||
718 | fh->fmt = &format; | 744 | fh->fmt = get_format(f); |
719 | fh->width = f->fmt.pix.width; | 745 | fh->width = f->fmt.pix.width; |
720 | fh->height = f->fmt.pix.height; | 746 | fh->height = f->fmt.pix.height; |
721 | fh->vb_vidq.field = f->fmt.pix.field; | 747 | fh->vb_vidq.field = f->fmt.pix.field; |
@@ -726,10 +752,23 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, | |||
726 | r = bars[k][0]; | 752 | r = bars[k][0]; |
727 | g = bars[k][1]; | 753 | g = bars[k][1]; |
728 | b = bars[k][2]; | 754 | b = bars[k][2]; |
755 | is_yuv = 0; | ||
729 | 756 | ||
730 | fh->bars[k][0] = TO_Y(r, g, b); /* Luma */ | 757 | switch (fh->fmt->fourcc) { |
731 | fh->bars[k][1] = TO_U(r, g, b); /* Cb */ | 758 | case V4L2_PIX_FMT_YUYV: |
732 | fh->bars[k][2] = TO_V(r, g, b); /* Cr */ | 759 | is_yuv = 1; |
760 | break; | ||
761 | } | ||
762 | |||
763 | if (is_yuv) { | ||
764 | fh->bars[k][0] = TO_Y(r, g, b); /* Luma */ | ||
765 | fh->bars[k][1] = TO_U(r, g, b); /* Cb */ | ||
766 | fh->bars[k][2] = TO_V(r, g, b); /* Cr */ | ||
767 | } else { | ||
768 | fh->bars[k][0] = r; | ||
769 | fh->bars[k][1] = g; | ||
770 | fh->bars[k][2] = b; | ||
771 | } | ||
733 | } | 772 | } |
734 | 773 | ||
735 | ret = 0; | 774 | ret = 0; |
@@ -885,8 +924,6 @@ static int vidioc_s_ctrl(struct file *file, void *priv, | |||
885 | File operations for the device | 924 | File operations for the device |
886 | ------------------------------------------------------------------*/ | 925 | ------------------------------------------------------------------*/ |
887 | 926 | ||
888 | #define line_buf_size(norm) (norm_maxw(norm)*(format.depth+7)/8) | ||
889 | |||
890 | static int vivi_open(struct inode *inode, struct file *file) | 927 | static int vivi_open(struct inode *inode, struct file *file) |
891 | { | 928 | { |
892 | int minor = iminor(inode); | 929 | int minor = iminor(inode); |
@@ -935,7 +972,7 @@ unlock: | |||
935 | fh->dev = dev; | 972 | fh->dev = dev; |
936 | 973 | ||
937 | fh->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | 974 | fh->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
938 | fh->fmt = &format; | 975 | fh->fmt = &formats[0]; |
939 | fh->width = 640; | 976 | fh->width = 640; |
940 | fh->height = 480; | 977 | fh->height = 480; |
941 | 978 | ||