aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@redhat.com>2009-01-11 08:29:43 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-03-30 11:42:20 -0400
commite164b58a84cc9fdff0653dfe38470c0216df31d2 (patch)
tree21c11370d328b3dc43cc1503ea1562c46db032a3 /drivers/media
parent0d34fb8e93ceba7b6dad0062dbb4a0813bacd75b (diff)
V4L/DVB (10211): vivi: Implements 4 inputs on vivi
This patch adds the capability of selecting between 4 different inputs on vivi driver. Input 0 is the normal color bar, while inputs 1-3 are modified color bars. This allows testing input selection on userspace applications and serves as an implementation model for other drivers. The current approach allows a maximum of 10 different inputs, since the input name generator assumes that we need just one digit to present the input. It shouldn't be hard to modify it to present a bigger name of inputs, but, in fact, it doesn't make much sense of doing it for this test driver. Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/video/vivi.c186
1 files changed, 142 insertions, 44 deletions
diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c
index 81d5aa5cf331..13e7bd06a80c 100644
--- a/drivers/media/video/vivi.c
+++ b/drivers/media/video/vivi.c
@@ -223,6 +223,9 @@ struct vivi_dev {
223 char timestr[13]; 223 char timestr[13];
224 224
225 int mv_count; /* Controls bars movement */ 225 int mv_count; /* Controls bars movement */
226
227 /* Input Number */
228 int input;
226}; 229};
227 230
228struct vivi_fh { 231struct vivi_fh {
@@ -235,6 +238,7 @@ struct vivi_fh {
235 238
236 enum v4l2_buf_type type; 239 enum v4l2_buf_type type;
237 unsigned char bars[8][3]; 240 unsigned char bars[8][3];
241 int input; /* Input Number on bars */
238}; 242};
239 243
240/* ------------------------------------------------------------------ 244/* ------------------------------------------------------------------
@@ -254,18 +258,72 @@ enum colors {
254 BLACK, 258 BLACK,
255}; 259};
256 260
257static u8 bars[8][3] = {
258 /* R G B */ 261 /* R G B */
259 {204, 204, 204}, /* white */ 262#define COLOR_WHITE {204, 204, 204}
260 {208, 208, 0}, /* ambar */ 263#define COLOR_AMBAR {208, 208, 0}
261 { 0, 206, 206}, /* cyan */ 264#define COLOR_CIAN { 0, 206, 206}
262 { 0, 239, 0}, /* green */ 265#define COLOR_GREEN { 0, 239, 0}
263 {239, 0, 239}, /* magenta */ 266#define COLOR_MAGENTA {239, 0, 239}
264 {205, 0, 0}, /* red */ 267#define COLOR_RED {205, 0, 0}
265 { 0, 0, 255}, /* blue */ 268#define COLOR_BLUE { 0, 0, 255}
266 { 0, 0, 0}, /* black */ 269#define COLOR_BLACK { 0, 0, 0}
270
271struct bar_std {
272 u8 bar[8][3];
273};
274
275/* Maximum number of bars are 10 - otherwise, the input print code
276 should be modified */
277static struct bar_std bars[] = {
278 { /* Standard ITU-R color bar sequence */
279 {
280 COLOR_WHITE,
281 COLOR_AMBAR,
282 COLOR_CIAN,
283 COLOR_GREEN,
284 COLOR_MAGENTA,
285 COLOR_RED,
286 COLOR_BLUE,
287 COLOR_BLACK,
288 }
289 }, {
290 {
291 COLOR_WHITE,
292 COLOR_AMBAR,
293 COLOR_BLACK,
294 COLOR_WHITE,
295 COLOR_AMBAR,
296 COLOR_BLACK,
297 COLOR_WHITE,
298 COLOR_AMBAR,
299 }
300 }, {
301 {
302 COLOR_WHITE,
303 COLOR_CIAN,
304 COLOR_BLACK,
305 COLOR_WHITE,
306 COLOR_CIAN,
307 COLOR_BLACK,
308 COLOR_WHITE,
309 COLOR_CIAN,
310 }
311 }, {
312 {
313 COLOR_WHITE,
314 COLOR_GREEN,
315 COLOR_BLACK,
316 COLOR_WHITE,
317 COLOR_GREEN,
318 COLOR_BLACK,
319 COLOR_WHITE,
320 COLOR_GREEN,
321 }
322 },
267}; 323};
268 324
325#define NUM_INPUTS ARRAY_SIZE(bars)
326
269#define TO_Y(r, g, b) \ 327#define TO_Y(r, g, b) \
270 (((16829 * r + 33039 * g + 6416 * b + 32768) >> 16) + 16) 328 (((16829 * r + 33039 * g + 6416 * b + 32768) >> 16) + 16)
271/* RGB to V(Cr) Color transform */ 329/* RGB to V(Cr) Color transform */
@@ -275,9 +333,10 @@ static u8 bars[8][3] = {
275#define TO_U(r, g, b) \ 333#define TO_U(r, g, b) \
276 (((-9714 * r - 19070 * g + 28784 * b + 32768) >> 16) + 128) 334 (((-9714 * r - 19070 * g + 28784 * b + 32768) >> 16) + 128)
277 335
278#define TSTAMP_MIN_Y 24 336#define TSTAMP_MIN_Y 24
279#define TSTAMP_MAX_Y TSTAMP_MIN_Y+15 337#define TSTAMP_MAX_Y (TSTAMP_MIN_Y + 15)
280#define TSTAMP_MIN_X 64 338#define TSTAMP_INPUT_X 10
339#define TSTAMP_MIN_X (54 + TSTAMP_INPUT_X)
281 340
282static void gen_twopix(struct vivi_fh *fh, unsigned char *buf, int colorpos) 341static void gen_twopix(struct vivi_fh *fh, unsigned char *buf, int colorpos)
283{ 342{
@@ -392,9 +451,29 @@ static void gen_line(struct vivi_fh *fh, char *basep, int inipos, int wmax,
392 pos += 4; /* only 16 bpp supported for now */ 451 pos += 4; /* only 16 bpp supported for now */
393 } 452 }
394 453
395 /* Checks if it is possible to show timestamp */ 454 /* Prints input entry number */
455
456 /* Checks if it is possible to input number */
396 if (TSTAMP_MAX_Y >= hmax) 457 if (TSTAMP_MAX_Y >= hmax)
397 goto end; 458 goto end;
459
460 if (TSTAMP_INPUT_X + strlen(timestr) >= wmax)
461 goto end;
462
463 if (line >= TSTAMP_MIN_Y && line <= TSTAMP_MAX_Y) {
464 chr = rom8x16_bits[fh->input * 16 + line - TSTAMP_MIN_Y];
465 pos = TSTAMP_INPUT_X;
466 for (i = 0; i < 7; i++) {
467 /* Draw white font on black background */
468 if (chr & 1 << (7 - i))
469 gen_twopix(fh, basep + pos, WHITE);
470 else
471 gen_twopix(fh, basep + pos, BLACK);
472 pos += 2;
473 }
474 }
475
476 /* Checks if it is possible to show timestamp */
398 if (TSTAMP_MIN_X + strlen(timestr) >= wmax) 477 if (TSTAMP_MIN_X + strlen(timestr) >= wmax)
399 goto end; 478 goto end;
400 479
@@ -807,38 +886,19 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
807 return 0; 886 return 0;
808} 887}
809 888
810/*FIXME: This seems to be generic enough to be at videodev2 */ 889/* precalculate color bar values to speed up rendering */
811static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, 890static void precalculate_bars(struct vivi_fh *fh)
812 struct v4l2_format *f)
813{ 891{
814 struct vivi_fh *fh = priv; 892 struct vivi_dev *dev = fh->dev;
815 struct videobuf_queue *q = &fh->vb_vidq;
816 unsigned char r, g, b; 893 unsigned char r, g, b;
817 int k, is_yuv; 894 int k, is_yuv;
818 895
819 int ret = vidioc_try_fmt_vid_cap(file, fh, f); 896 fh->input = dev->input;
820 if (ret < 0)
821 return (ret);
822
823 mutex_lock(&q->vb_lock);
824
825 if (videobuf_queue_is_busy(&fh->vb_vidq)) {
826 dprintk(fh->dev, 1, "%s queue busy\n", __func__);
827 ret = -EBUSY;
828 goto out;
829 }
830 897
831 fh->fmt = get_format(f);
832 fh->width = f->fmt.pix.width;
833 fh->height = f->fmt.pix.height;
834 fh->vb_vidq.field = f->fmt.pix.field;
835 fh->type = f->type;
836
837 /* precalculate color bar values to speed up rendering */
838 for (k = 0; k < 8; k++) { 898 for (k = 0; k < 8; k++) {
839 r = bars[k][0]; 899 r = bars[fh->input].bar[k][0];
840 g = bars[k][1]; 900 g = bars[fh->input].bar[k][1];
841 b = bars[k][2]; 901 b = bars[fh->input].bar[k][2];
842 is_yuv = 0; 902 is_yuv = 0;
843 903
844 switch (fh->fmt->fourcc) { 904 switch (fh->fmt->fourcc) {
@@ -871,11 +931,40 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
871 } 931 }
872 } 932 }
873 933
934}
935
936/*FIXME: This seems to be generic enough to be at videodev2 */
937static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
938 struct v4l2_format *f)
939{
940 struct vivi_fh *fh = priv;
941 struct videobuf_queue *q = &fh->vb_vidq;
942
943 int ret = vidioc_try_fmt_vid_cap(file, fh, f);
944 if (ret < 0)
945 return ret;
946
947 mutex_lock(&q->vb_lock);
948
949 if (videobuf_queue_is_busy(&fh->vb_vidq)) {
950 dprintk(fh->dev, 1, "%s queue busy\n", __func__);
951 ret = -EBUSY;
952 goto out;
953 }
954
955 fh->fmt = get_format(f);
956 fh->width = f->fmt.pix.width;
957 fh->height = f->fmt.pix.height;
958 fh->vb_vidq.field = f->fmt.pix.field;
959 fh->type = f->type;
960
961 precalculate_bars(fh);
962
874 ret = 0; 963 ret = 0;
875out: 964out:
876 mutex_unlock(&q->vb_lock); 965 mutex_unlock(&q->vb_lock);
877 966
878 return (ret); 967 return ret;
879} 968}
880 969
881static int vidioc_reqbufs(struct file *file, void *priv, 970static int vidioc_reqbufs(struct file *file, void *priv,
@@ -950,27 +1039,36 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *i)
950static int vidioc_enum_input(struct file *file, void *priv, 1039static int vidioc_enum_input(struct file *file, void *priv,
951 struct v4l2_input *inp) 1040 struct v4l2_input *inp)
952{ 1041{
953 if (inp->index != 0) 1042 if (inp->index >= NUM_INPUTS)
954 return -EINVAL; 1043 return -EINVAL;
955 1044
956 inp->type = V4L2_INPUT_TYPE_CAMERA; 1045 inp->type = V4L2_INPUT_TYPE_CAMERA;
957 inp->std = V4L2_STD_525_60; 1046 inp->std = V4L2_STD_525_60;
958 strcpy(inp->name, "Camera"); 1047 sprintf(inp->name, "Camera %u", inp->index);
959 1048
960 return (0); 1049 return (0);
961} 1050}
962 1051
963static int vidioc_g_input(struct file *file, void *priv, unsigned int *i) 1052static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
964{ 1053{
965 *i = 0; 1054 struct vivi_fh *fh = priv;
1055 struct vivi_dev *dev = fh->dev;
1056
1057 *i = dev->input;
966 1058
967 return (0); 1059 return (0);
968} 1060}
969static int vidioc_s_input(struct file *file, void *priv, unsigned int i) 1061static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
970{ 1062{
971 if (i > 0) 1063 struct vivi_fh *fh = priv;
1064 struct vivi_dev *dev = fh->dev;
1065
1066 if (i >= NUM_INPUTS)
972 return -EINVAL; 1067 return -EINVAL;
973 1068
1069 dev->input = i;
1070 precalculate_bars(fh);
1071
974 return (0); 1072 return (0);
975} 1073}
976 1074