diff options
-rw-r--r-- | apps/plugin.c | 4 | ||||
-rw-r--r-- | apps/plugin.h | 4 | ||||
-rw-r--r-- | apps/plugins/mpegplayer/video_out_rockbox.c | 3 | ||||
-rw-r--r-- | firmware/export/lcd.h | 3 | ||||
-rwxr-xr-x | firmware/target/coldfire/iaudio/x5/lcd-x5.c | 109 |
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, | |||
72 | extern void lcd_icon(int icon, bool enable); | 72 | extern 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 | ||
76 | void lcd_yuv_blit(unsigned char * const src[3], | 77 | void 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 | */ | ||
448 | void lcd_yuv_blit(unsigned char * const [3], int, int, int, | ||
449 | int, int, int, int) ICODE_ATTR; | ||
450 | void 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 |