aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
authorMagnus Damm <damm@igel.co.jp>2008-10-14 11:46:59 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2008-10-17 16:24:53 -0400
commit74d7c5af78234467fed522c0f0ff47ef765cecb8 (patch)
tree85f6163f6990e5dd2491878b1fd6488d70145969 /drivers/media
parentd54c17e43514ecf0dceffbe13a324d4b6df5b6e0 (diff)
V4L/DVB (9235): Precalculate vivi yuv values
This patch improves the color space conversion code in vivi.c to directly draw with precalculated YUV values as palette instead of drawing with YUV that is calculated from RGB for every two pixels. This way we eliminate the need for 9 multiplications every two pixels. A side effect of this patch is that the time counter is changed from green text on black background to white text on black background. 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.c117
1 files changed, 58 insertions, 59 deletions
diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c
index 65c8af18e767..0d1ad7f63d09 100644
--- a/drivers/media/video/vivi.c
+++ b/drivers/media/video/vivi.c
@@ -190,6 +190,7 @@ struct vivi_fh {
190 struct videobuf_queue vb_vidq; 190 struct videobuf_queue vb_vidq;
191 191
192 enum v4l2_buf_type type; 192 enum v4l2_buf_type type;
193 unsigned char bars[8][3];
193}; 194};
194 195
195/* ------------------------------------------------------------------ 196/* ------------------------------------------------------------------
@@ -234,13 +235,41 @@ static u8 bars[8][3] = {
234#define TSTAMP_MAX_Y TSTAMP_MIN_Y+15 235#define TSTAMP_MAX_Y TSTAMP_MIN_Y+15
235#define TSTAMP_MIN_X 64 236#define TSTAMP_MIN_X 64
236 237
237static void gen_line(char *basep, int inipos, int wmax, 238static void gen_twopix(struct vivi_fh *fh, unsigned char *buf, int colorpos)
239{
240 unsigned char r_y, g_u, b_v;
241 unsigned char *p;
242 int color;
243
244 r_y = fh->bars[colorpos][0]; /* R or precalculated Y */
245 g_u = fh->bars[colorpos][1]; /* G or precalculated U */
246 b_v = fh->bars[colorpos][2]; /* B or precalculated V */
247
248 for (color = 0; color < 4; color++) {
249 p = buf + color;
250
251 switch (color) {
252 case 0:
253 case 2:
254 *p = r_y;
255 break;
256 case 1:
257 *p = g_u;
258 break;
259 case 3:
260 *p = b_v;
261 break;
262 }
263 }
264}
265
266static void gen_line(struct vivi_fh *fh, char *basep, int inipos, int wmax,
238 int hmax, int line, int count, char *timestr) 267 int hmax, int line, int count, char *timestr)
239{ 268{
240 int w, i, j, y; 269 int w, i, j;
241 int pos = inipos; 270 int pos = inipos;
242 char *p, *s; 271 char *s;
243 u8 chr, r, g, b, color; 272 u8 chr;
244 273
245 /* We will just duplicate the second pixel at the packet */ 274 /* We will just duplicate the second pixel at the packet */
246 wmax /= 2; 275 wmax /= 2;
@@ -248,27 +277,9 @@ static void gen_line(char *basep, int inipos, int wmax,
248 /* Generate a standard color bar pattern */ 277 /* Generate a standard color bar pattern */
249 for (w = 0; w < wmax; w++) { 278 for (w = 0; w < wmax; w++) {
250 int colorpos = ((w + count) * 8/(wmax + 1)) % 8; 279 int colorpos = ((w + count) * 8/(wmax + 1)) % 8;
251 r = bars[colorpos][0]; 280
252 g = bars[colorpos][1]; 281 gen_twopix(fh, basep + pos, colorpos);
253 b = bars[colorpos][2]; 282 pos += 4; /* only 16 bpp supported for now */
254
255 for (color = 0; color < 4; color++) {
256 p = basep + pos;
257
258 switch (color) {
259 case 0:
260 case 2:
261 *p = TO_Y(r, g, b); /* Luma */
262 break;
263 case 1:
264 *p = TO_U(r, g, b); /* Cb */
265 break;
266 case 3:
267 *p = TO_V(r, g, b); /* Cr */
268 break;
269 }
270 pos++;
271 }
272 } 283 }
273 284
274 /* Checks if it is possible to show timestamp */ 285 /* Checks if it is possible to show timestamp */
@@ -283,38 +294,12 @@ static void gen_line(char *basep, int inipos, int wmax,
283 for (s = timestr; *s; s++) { 294 for (s = timestr; *s; s++) {
284 chr = rom8x16_bits[(*s-0x30)*16+line-TSTAMP_MIN_Y]; 295 chr = rom8x16_bits[(*s-0x30)*16+line-TSTAMP_MIN_Y];
285 for (i = 0; i < 7; i++) { 296 for (i = 0; i < 7; i++) {
286 if (chr & 1 << (7 - i)) {
287 /* Font color*/
288 r = 0;
289 g = 198;
290 b = 0;
291 } else {
292 /* Background color */
293 r = bars[BLACK][0];
294 g = bars[BLACK][1];
295 b = bars[BLACK][2];
296 }
297
298 pos = inipos + j * 2; 297 pos = inipos + j * 2;
299 for (color = 0; color < 4; color++) { 298 /* Draw white font on black background */
300 p = basep + pos; 299 if (chr & 1 << (7 - i))
301 300 gen_twopix(fh, basep + pos, WHITE);
302 y = TO_Y(r, g, b); 301 else
303 302 gen_twopix(fh, basep + pos, BLACK);
304 switch (color) {
305 case 0:
306 case 2:
307 *p = TO_Y(r, g, b); /* Luma */
308 break;
309 case 1:
310 *p = TO_U(r, g, b); /* Cb */
311 break;
312 case 3:
313 *p = TO_V(r, g, b); /* Cr */
314 break;
315 }
316 pos++;
317 }
318 j++; 303 j++;
319 } 304 }
320 } 305 }
@@ -324,8 +309,9 @@ end:
324 return; 309 return;
325} 310}
326 311
327static void vivi_fillbuff(struct vivi_dev *dev, struct vivi_buffer *buf) 312static void vivi_fillbuff(struct vivi_fh *fh, struct vivi_buffer *buf)
328{ 313{
314 struct vivi_dev *dev = fh->dev;
329 int h , pos = 0; 315 int h , pos = 0;
330 int hmax = buf->vb.height; 316 int hmax = buf->vb.height;
331 int wmax = buf->vb.width; 317 int wmax = buf->vb.width;
@@ -341,7 +327,7 @@ static void vivi_fillbuff(struct vivi_dev *dev, struct vivi_buffer *buf)
341 return; 327 return;
342 328
343 for (h = 0; h < hmax; h++) { 329 for (h = 0; h < hmax; h++) {
344 gen_line(tmpbuf, 0, wmax, hmax, h, dev->mv_count, 330 gen_line(fh, tmpbuf, 0, wmax, hmax, h, dev->mv_count,
345 dev->timestr); 331 dev->timestr);
346 memcpy(vbuf + pos, tmpbuf, wmax * 2); 332 memcpy(vbuf + pos, tmpbuf, wmax * 2);
347 pos += wmax*2; 333 pos += wmax*2;
@@ -410,7 +396,7 @@ static void vivi_thread_tick(struct vivi_fh *fh)
410 do_gettimeofday(&buf->vb.ts); 396 do_gettimeofday(&buf->vb.ts);
411 397
412 /* Fill buffer */ 398 /* Fill buffer */
413 vivi_fillbuff(dev, buf); 399 vivi_fillbuff(fh, buf);
414 dprintk(dev, 1, "filled buffer %p\n", buf); 400 dprintk(dev, 1, "filled buffer %p\n", buf);
415 401
416 wake_up(&buf->vb.done); 402 wake_up(&buf->vb.done);
@@ -714,6 +700,8 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
714{ 700{
715 struct vivi_fh *fh = priv; 701 struct vivi_fh *fh = priv;
716 struct videobuf_queue *q = &fh->vb_vidq; 702 struct videobuf_queue *q = &fh->vb_vidq;
703 unsigned char r, g, b;
704 int k;
717 705
718 int ret = vidioc_try_fmt_vid_cap(file, fh, f); 706 int ret = vidioc_try_fmt_vid_cap(file, fh, f);
719 if (ret < 0) 707 if (ret < 0)
@@ -733,6 +721,17 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
733 fh->vb_vidq.field = f->fmt.pix.field; 721 fh->vb_vidq.field = f->fmt.pix.field;
734 fh->type = f->type; 722 fh->type = f->type;
735 723
724 /* precalculate color bar values to speed up rendering */
725 for (k = 0; k < 8; k++) {
726 r = bars[k][0];
727 g = bars[k][1];
728 b = bars[k][2];
729
730 fh->bars[k][0] = TO_Y(r, g, b); /* Luma */
731 fh->bars[k][1] = TO_U(r, g, b); /* Cb */
732 fh->bars[k][2] = TO_V(r, g, b); /* Cr */
733 }
734
736 ret = 0; 735 ret = 0;
737out: 736out:
738 mutex_unlock(&q->vb_lock); 737 mutex_unlock(&q->vb_lock);