summaryrefslogtreecommitdiffstats
path: root/apps
diff options
context:
space:
mode:
authorMichael Sevakis <jethead71@rockbox.org>2007-04-24 02:46:32 +0000
committerMichael Sevakis <jethead71@rockbox.org>2007-04-24 02:46:32 +0000
commit0d032d1fa1a6b1aa45515bc96a66918f4a7b45f1 (patch)
tree0cf23e68ea2603e8e5230a3245a4ddb34b6a609a /apps
parent2e2cf06dc91ad80077230cf024d7c0d82c464d03 (diff)
downloadrockbox-0d032d1fa1a6b1aa45515bc96a66918f4a7b45f1.tar.gz
rockbox-0d032d1fa1a6b1aa45515bc96a66918f4a7b45f1.zip
mpeglayer: Give the simulator YCbCr blit similar behavior to the target.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@13253 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps')
-rw-r--r--apps/plugins/mpegplayer/video_out_rockbox.c284
1 files changed, 169 insertions, 115 deletions
diff --git a/apps/plugins/mpegplayer/video_out_rockbox.c b/apps/plugins/mpegplayer/video_out_rockbox.c
index e3f8ba0264..b55ca8c079 100644
--- a/apps/plugins/mpegplayer/video_out_rockbox.c
+++ b/apps/plugins/mpegplayer/video_out_rockbox.c
@@ -45,147 +45,197 @@ static int output_height;
#if defined(SIMULATOR) && defined(HAVE_LCD_COLOR)
-#define RYFAC (31*257)
-#define GYFAC (63*257)
-#define BYFAC (31*257)
-#define RVFAC 11170 /* 31 * 257 * 1.402 */
-#define GVFAC (-11563) /* 63 * 257 * -0.714136 */
-#define GUFAC (-5572) /* 63 * 257 * -0.344136 */
-#define BUFAC 14118 /* 31 * 257 * 1.772 */
+/**
+ * |R| |1.000000 -0.000001 1.402000| |Y'|
+ * |G| = |1.000000 -0.334136 -0.714136| |Pb|
+ * |B| |1.000000 1.772000 0.000000| |Pr|
+ * Scaled, normalized, rounded and tweaked to yield RGB 565:
+ * |R| |74 0 101| |Y' - 16| >> 9
+ * |G| = |74 -24 -51| |Cb - 128| >> 8
+ * |B| |74 128 0| |Cr - 128| >> 9
+ */
+#define YFAC (74)
+#define RVFAC (101)
+#define GUFAC (-24)
+#define GVFAC (-51)
+#define BUFAC (128)
-#define ROUNDOFFS (127*257)
+static inline int clamp(int val, int min, int max)
+{
+ if (val < min)
+ val = min;
+ else if (val > max)
+ val = max;
+ return val;
+}
-/* Draw a partial YUV colour bitmap - taken from the Rockbox JPEG viewer */
+/* Draw a partial YUV colour bitmap - similiar behavior to lcd_yuv_blit
+ in the core */
static void yuv_bitmap_part(unsigned char * const src[3],
int src_x, int src_y, int stride,
int x, int y, int width, int height)
{
- fb_data *dst, *dst_end;
+ const unsigned char *ysrc, *usrc, *vsrc;
+ fb_data *dst, *row_end;
+ off_t z;
- /* nothing to draw? */
- if ((width <= 0) || (height <= 0) || (x >= LCD_WIDTH) || (y >= LCD_HEIGHT)
- || (x + width <= 0) || (y + height <= 0))
- return;
+ /* width and height must be >= 2 and an even number */
+ width &= ~1;
+ height >>= 1;
- /* clipping */
- if (x < 0)
- {
- width += x;
- src_x -= x;
- x = 0;
- }
- if (y < 0)
- {
- height += y;
- src_y -= y;
- y = 0;
- }
- if (x + width > LCD_WIDTH)
- width = LCD_WIDTH - x;
- if (y + height > LCD_HEIGHT)
- height = LCD_HEIGHT - y;
+#if LCD_WIDTH >= LCD_HEIGHT
+ dst = rb->lcd_framebuffer + LCD_WIDTH * y + x;
+ row_end = dst + width;
+#else
+ dst = rb->lcd_framebuffer + x * LCD_WIDTH + (LCD_WIDTH - y) - 1;
+ row_end = dst + LCD_WIDTH * width;
+#endif
+
+ z = stride * src_y;
+ ysrc = src[0] + z + src_x;
+ usrc = src[1] + (z >> 2) + (src_x >> 1);
+ vsrc = src[2] + (usrc - src[1]);
+
+ /* stride => amount to jump from end of last row to start of next */
+ stride -= width;
- dst = rb->lcd_framebuffer + LCD_WIDTH * y + x;
- dst_end = dst + LCD_WIDTH * height;
+ /* upsampling, YUV->RGB conversion and reduction to RGB565 in one go */
do
{
- fb_data *dst_row = dst;
- fb_data *row_end = dst_row + width;
- const unsigned char *ysrc = src[0] + stride * src_y + src_x;
- int y, u, v;
- int red, green, blue;
- unsigned rbits, gbits, bbits;
-
- if (CSUB_Y) /* colour */
+ do
{
- /* upsampling, YUV->RGB conversion and reduction to RGB565 in one go */
- const unsigned char *usrc = src[1] + (stride/CSUB_X) * (src_y/CSUB_Y)
- + (src_x/CSUB_X);
- const unsigned char *vsrc = src[2] + (stride/CSUB_X) * (src_y/CSUB_Y)
- + (src_x/CSUB_X);
- int xphase = src_x % CSUB_X;
- int rc, gc, bc;
-
- u = *usrc++ - 128;
- v = *vsrc++ - 128;
- rc = RVFAC * v + ROUNDOFFS;
- gc = GVFAC * v + GUFAC * u + ROUNDOFFS;
- bc = BUFAC * u + ROUNDOFFS;
-
- do
+ int y, cb, cr, rv, guv, bu, r, g, b;
+
+ y = YFAC*(*ysrc++ - 16);
+ cb = *usrc++ - 128;
+ cr = *vsrc++ - 128;
+
+ rv = RVFAC*cr;
+ guv = GUFAC*cb + GVFAC*cr;
+ bu = BUFAC*cb;
+
+ r = y + rv;
+ g = y + guv;
+ b = y + bu;
+
+ if ((unsigned)(r | g | b) > 63*256)
{
- y = *ysrc++;
- red = RYFAC * y + rc;
- green = GYFAC * y + gc;
- blue = BYFAC * y + bc;
-
- if ((unsigned)red > (RYFAC*255+ROUNDOFFS))
- {
- if (red < 0)
- red = 0;
- else
- red = (RYFAC*255+ROUNDOFFS);
- }
- if ((unsigned)green > (GYFAC*255+ROUNDOFFS))
- {
- if (green < 0)
- green = 0;
- else
- green = (GYFAC*255+ROUNDOFFS);
- }
- if ((unsigned)blue > (BYFAC*255+ROUNDOFFS))
- {
- if (blue < 0)
- blue = 0;
- else
- blue = (BYFAC*255+ROUNDOFFS);
- }
- rbits = ((unsigned)red) >> 16 ;
- gbits = ((unsigned)green) >> 16 ;
- bbits = ((unsigned)blue) >> 16 ;
-#if LCD_PIXELFORMAT == RGB565
- *dst_row++ = (rbits << 11) | (gbits << 5) | bbits;
-#elif LCD_PIXELFORMAT == RGB565SWAPPED
- *dst_row++ = swap16((rbits << 11) | (gbits << 5) | bbits);
+ r = clamp(r, 0, 63*256);
+ g = clamp(g, 0, 63*256);
+ b = clamp(b, 0, 63*256);
+ }
+
+ *dst = LCD_RGBPACK_LCD(r >> 9, g >> 8, b >> 9);
+
+#if LCD_WIDTH >= LCD_HEIGHT
+ dst++;
+#else
+ dst += LCD_WIDTH;
#endif
- if (++xphase >= CSUB_X)
- {
- u = *usrc++ - 128;
- v = *vsrc++ - 128;
- rc = RVFAC * v + ROUNDOFFS;
- gc = GVFAC * v + GUFAC * u + ROUNDOFFS;
- bc = BUFAC * u + ROUNDOFFS;
- xphase = 0;
- }
+ y = YFAC*(*ysrc++ - 16);
+ r = y + rv;
+ g = y + guv;
+ b = y + bu;
+
+ if ((unsigned)(r | g | b) > 63*256)
+ {
+ r = clamp(r, 0, 63*256);
+ g = clamp(g, 0, 63*256);
+ b = clamp(b, 0, 63*256);
}
- while (dst_row < row_end);
+
+ *dst = LCD_RGBPACK_LCD(r >> 9, g >> 8, b >> 9);
+
+#if LCD_WIDTH >= LCD_HEIGHT
+ dst++;
+#else
+ dst += LCD_WIDTH;
+#endif
}
- else /* monochrome */
+ while (dst < row_end);
+
+ ysrc += stride;
+ usrc -= width >> 1;
+ vsrc -= width >> 1;
+
+#if LCD_WIDTH >= LCD_HEIGHT
+ row_end += LCD_WIDTH;
+ dst += LCD_WIDTH - width;
+#else
+ row_end -= 1;
+ dst -= LCD_WIDTH*width + 1;
+#endif
+
+ do
{
- do
+ int y, cb, cr, rv, guv, bu, r, g, b;
+
+ y = YFAC*(*ysrc++ - 16);
+ cb = *usrc++ - 128;
+ cr = *vsrc++ - 128;
+
+ rv = RVFAC*cr;
+ guv = GUFAC*cb + GVFAC*cr;
+ bu = BUFAC*cb;
+
+ r = y + rv;
+ g = y + guv;
+ b = y + bu;
+
+ if ((unsigned)(r | g | b) > 63*256)
{
- y = *ysrc++;
- red = RYFAC * y + ROUNDOFFS; /* blue == red */
- green = GYFAC * y + ROUNDOFFS;
- rbits = ((unsigned)red) >> 16;
- gbits = ((unsigned)green) >> 16;
-#if LCD_PIXELFORMAT == RGB565
- *dst_row++ = (rbits << 11) | (gbits << 5) | rbits;
-#elif LCD_PIXELFORMAT == RGB565SWAPPED
- *dst_row++ = swap16((rbits << 11) | (gbits << 5) | rbits);
+ r = clamp(r, 0, 63*256);
+ g = clamp(g, 0, 63*256);
+ b = clamp(b, 0, 63*256);
+ }
+
+ *dst = LCD_RGBPACK_LCD(r >> 9, g >> 8, b >> 9);
+
+#if LCD_WIDTH >= LCD_HEIGHT
+ dst++;
+#else
+ dst += LCD_WIDTH;
#endif
+
+ y = YFAC*(*ysrc++ - 16);
+ r = y + rv;
+ g = y + guv;
+ b = y + bu;
+
+ if ((unsigned)(r | g | b) > 63*256)
+ {
+ r = clamp(r, 0, 63*256);
+ g = clamp(g, 0, 63*256);
+ b = clamp(b, 0, 63*256);
}
- while (dst_row < row_end);
+
+ *dst = LCD_RGBPACK_LCD(r >> 9, g >> 8, b >> 9);
+
+#if LCD_WIDTH >= LCD_HEIGHT
+ dst++;
+#else
+ dst += LCD_WIDTH;
+#endif
}
+ while (dst < row_end);
+
+ ysrc += stride;
+ usrc += stride >> 1;
+ vsrc += stride >> 1;
- src_y++;
- dst += LCD_WIDTH;
+#if LCD_WIDTH >= LCD_HEIGHT
+ row_end += LCD_WIDTH;
+ dst += LCD_WIDTH - width;
+#else
+ row_end -= 1;
+ dst -= LCD_WIDTH*width + 1;
+#endif
}
- while (dst < dst_end);
+ while (--height > 0);
}
-#endif
+#endif /* defined(SIMULATOR) && defined(HAVE_LCD_COLOR) */
void vo_draw_frame (uint8_t * const * buf)
{
@@ -193,8 +243,12 @@ void vo_draw_frame (uint8_t * const * buf)
#ifdef SIMULATOR
yuv_bitmap_part(buf,0,0,image_width,
output_x,output_y,output_width,output_height);
+#if LCD_WIDTH >= LCD_HEIGHT
rb->lcd_update_rect(output_x,output_y,output_width,output_height);
#else
+ rb->lcd_update_rect(output_y,output_x,output_height,output_width);
+#endif
+#else
rb->lcd_yuv_blit(buf,
0,0,image_width,
output_x,output_y,output_width,output_height);