summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/plugin.c4
-rw-r--r--apps/plugin.h4
-rw-r--r--apps/plugins/mpegplayer/video_out_rockbox.c3
-rw-r--r--firmware/export/lcd.h3
-rwxr-xr-xfirmware/target/coldfire/iaudio/x5/lcd-x5.c109
5 files changed, 115 insertions, 8 deletions
diff --git a/apps/plugin.c b/apps/plugin.c
index 6641fe2ee1..c9278c8897 100644
--- a/apps/plugin.c
+++ b/apps/plugin.c
@@ -463,9 +463,7 @@ static const struct plugin_api rockbox_api = {
463 lcd_remote_bitmap, 463 lcd_remote_bitmap,
464#endif 464#endif
465 465
466#if (CONFIG_LCD == LCD_IPODCOLOR || CONFIG_LCD == LCD_IPODNANO \ 466#if defined(HAVE_LCD_COLOR) && !defined(SIMULATOR)
467 || CONFIG_LCD == LCD_H300 || CONFIG_LCD == LCD_IPODVIDEO) && \
468 !defined(SIMULATOR)
469 lcd_yuv_blit, 467 lcd_yuv_blit,
470#endif 468#endif
471 469
diff --git a/apps/plugin.h b/apps/plugin.h
index 9f17fa6480..505e7ec666 100644
--- a/apps/plugin.h
+++ b/apps/plugin.h
@@ -539,9 +539,7 @@ struct plugin_api {
539 void (*lcd_remote_bitmap)(const fb_remote_data *src, int x, int y, int width, 539 void (*lcd_remote_bitmap)(const fb_remote_data *src, int x, int y, int width,
540 int height); 540 int height);
541#endif 541#endif
542#if (CONFIG_LCD == LCD_IPODCOLOR || CONFIG_LCD == LCD_IPODNANO \ 542#if defined(HAVE_LCD_COLOR) && !defined(SIMULATOR)
543 || CONFIG_LCD == LCD_H300 || CONFIG_LCD == LCD_IPODVIDEO) && \
544 !defined(SIMULATOR)
545 void (*lcd_yuv_blit)(unsigned char * const src[3], 543 void (*lcd_yuv_blit)(unsigned char * const src[3],
546 int src_x, int src_y, int stride, 544 int src_x, int src_y, int stride,
547 int x, int y, int width, int height); 545 int x, int y, int width, int height);
diff --git a/apps/plugins/mpegplayer/video_out_rockbox.c b/apps/plugins/mpegplayer/video_out_rockbox.c
index 174921e837..cac5cf3d5c 100644
--- a/apps/plugins/mpegplayer/video_out_rockbox.c
+++ b/apps/plugins/mpegplayer/video_out_rockbox.c
@@ -201,7 +201,8 @@ static void rockbox_draw_frame (vo_instance_t * instance,
201 (void)instance; 201 (void)instance;
202 202
203#if (CONFIG_LCD == LCD_IPODCOLOR || CONFIG_LCD == LCD_IPODNANO \ 203#if (CONFIG_LCD == LCD_IPODCOLOR || CONFIG_LCD == LCD_IPODNANO \
204 || CONFIG_LCD == LCD_H300 || CONFIG_LCD == LCD_IPODVIDEO) \ 204 || CONFIG_LCD == LCD_H300 || CONFIG_LCD == LCD_IPODVIDEO \
205 || CONFIG_LCD == LCD_X5) \
205 && !defined(SIMULATOR) 206 && !defined(SIMULATOR)
206 rb->lcd_yuv_blit(buf, 207 rb->lcd_yuv_blit(buf,
207 0,0,image_width, 208 0,0,image_width,
diff --git a/firmware/export/lcd.h b/firmware/export/lcd.h
index 5c362c2b53..147940fa4f 100644
--- a/firmware/export/lcd.h
+++ b/firmware/export/lcd.h
@@ -72,7 +72,8 @@ extern void lcd_puts_scroll_style(int x, int y, const unsigned char* string,
72extern void lcd_icon(int icon, bool enable); 72extern void lcd_icon(int icon, bool enable);
73 73
74#if CONFIG_LCD == LCD_IPODCOLOR || CONFIG_LCD == LCD_IPODNANO \ 74#if CONFIG_LCD == LCD_IPODCOLOR || CONFIG_LCD == LCD_IPODNANO \
75 || CONFIG_LCD == LCD_H300 || CONFIG_LCD == LCD_IPODVIDEO 75 || CONFIG_LCD == LCD_H300 || CONFIG_LCD == LCD_IPODVIDEO \
76 || CONFIG_LCD == LCD_X5
76void lcd_yuv_blit(unsigned char * const src[3], 77void lcd_yuv_blit(unsigned char * const src[3],
77 int src_x, int src_y, int stride, 78 int src_x, int src_y, int stride,
78 int x, int y, int width, int height); 79 int x, int y, int width, int height);
diff --git a/firmware/target/coldfire/iaudio/x5/lcd-x5.c b/firmware/target/coldfire/iaudio/x5/lcd-x5.c
index f66b8801dc..57b4789070 100755
--- a/firmware/target/coldfire/iaudio/x5/lcd-x5.c
+++ b/firmware/target/coldfire/iaudio/x5/lcd-x5.c
@@ -423,6 +423,115 @@ void lcd_blit(const fb_data* data, int x, int by, int width,
423 /*if(display_on)*/ 423 /*if(display_on)*/
424} 424}
425 425
426/* Performance function to blit a YUV bitmap directly to the LCD */
427/* Assumes YCrCb 4:2:0. */
428/*
429 See http://en.wikipedia.org/wiki/YCbCr
430 ITU-R BT.601 (formerly CCIR 601):
431 |Y'| | 0.299000 0.587000 0.114000| |R|
432 |Pb| = |-0.168736 -0.331264 0.500000| |G| or 0.564334 * (B - Y')
433 |Pr| | 0.500000 -0.418688 0.081312| |B| or 0.713267 * (R - Y')
434 Scaled, normalized and rounded:
435 |Y'| | 65 129 25| |R| + 16 : 16->235
436 |Cb| = |-38 -74 112| |G| + 128 : 16->240
437 |Cr| |112 -94 -18| |B| + 128 : 16->240
438
439 The inverse:
440 |R| |1.000000 -0.000001 1.402000| |Y'|
441 |G| = |1.000000 -0.334136 -0.714136| |Pb|
442 |B| |1.000000 1.772000 0.000000| |Pr|
443 Scaled, normalized, rounded and tweaked to yield RGB 666:
444 |R| |298 0 409| |Y' - 16| / 1024
445 |G| = |298 -100 -208| |Cb - 128| / 1024
446 |B| |298 516 0| |Cr - 128| / 1024
447*/
448void lcd_yuv_blit(unsigned char * const [3], int, int, int,
449 int, int, int, int) ICODE_ATTR;
450void lcd_yuv_blit(unsigned char * const src[3],
451 int src_x, int src_y, int stride,
452 int x, int y, int width, int height)
453{
454 const unsigned char *ysrc, *usrc, *vsrc;
455 int uv_stepper, uv_step, y_end;
456
457 if (!display_on)
458 return;
459
460 width = (width + 1) & ~1;
461 height = (height + 1) & ~1;
462 y_end = y + height;
463
464 /* Set start position and window */
465 lcd_write_reg(R_RAM_ADDR_SET, (x << 8) |
466 (((y + roll_offset) & 127) + y_offset));
467 lcd_write_reg(R_VERT_RAM_ADDR_POS, ((x + width - 1) << 8) | x);
468
469 lcd_begin_write_gram();
470
471 ysrc = src[0] + src_y*stride + src_x;
472 usrc = src[1] + (src_y*stride >> 2) + (src_x >> 1);
473 vsrc = src[2] + (usrc - src[1]);
474
475 stride = stride - width; /* Use end of current line->start of next */
476 uv_stepper = (stride >> 1) - (width >> 1);
477 uv_step = uv_stepper - (stride >> 1);
478
479 do
480 {
481 const unsigned char *ysrc_end = ysrc + width;
482
483 do
484 {
485 int lum, cb, cr;
486 int rv, guv, bu;
487 int r, g, b;
488
489 lum = 298* *ysrc++ - 4768; /* 298*16 */
490 cb = *usrc++ - 128;
491 cr = *vsrc++ - 128;
492 bu = 516*cb;
493 guv = -100*cb - 208*cr;
494 rv = 409*cr;
495
496 r = (lum + rv) >> 10;
497 g = (lum + guv) >> 10;
498 b = (lum + bu) >> 10;
499
500 if ((unsigned)r > 63)
501 r = (r < 0) ? 0 : 63;
502 if ((unsigned)g > 63)
503 g = (g < 0) ? 0 : 63;
504 if ((unsigned)b > 63)
505 b = (b < 0) ? 0 : 63;
506
507 LCD_DATA = (r << 3) | (g >> 3);
508 LCD_DATA = (g << 6) | b;
509
510 lum = 298* *ysrc++ - 4768; /* 298*16 */
511 r = (lum + rv) >> 10;
512 g = (lum + guv) >> 10;
513 b = (lum + bu) >> 10;
514
515 if ((unsigned)r > 63)
516 r = (r < 0) ? 0 : 63;
517 if ((unsigned)g > 63)
518 g = (g < 0) ? 0 : 63;
519 if ((unsigned)b > 63)
520 b = (b < 0) ? 0 : 63;
521
522 LCD_DATA = (r << 3) | (g >> 3);
523 LCD_DATA = (g << 6) | b;
524 }
525 while (ysrc < ysrc_end);
526
527 usrc += uv_step;
528 vsrc += uv_step;
529 uv_step = uv_stepper - uv_step;
530
531 ysrc += stride;
532 }
533 while (++y < y_end);
534}
426 535
427/* Update the display. 536/* Update the display.
428 This must be called after all other LCD functions that change the 537 This must be called after all other LCD functions that change the