forked from len0rd/rockbox
Dithering option for mpegplayer on gigabeat-f/x and e200. Assembly IDCT for ARm just to make it all work more nicely. Move UI simulator YUV code to its core to adapt it.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@14851 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
24327ddf7b
commit
287d6223d3
14 changed files with 935 additions and 809 deletions
|
@ -1,14 +1,15 @@
|
|||
alloc.c
|
||||
decode.c
|
||||
header.c
|
||||
idct.c
|
||||
|
||||
motion_comp.c
|
||||
|
||||
#ifdef CPU_ARM
|
||||
idct_arm_c.c
|
||||
motion_comp_arm_c.c
|
||||
motion_comp_arm_s.S
|
||||
#else /* other CPU or SIM */
|
||||
idct.c
|
||||
motion_comp_c.c
|
||||
#endif /* CPU_* */
|
||||
|
||||
|
|
|
@ -9,41 +9,87 @@ extern struct plugin_api* rb;
|
|||
struct mpeg_settings settings;
|
||||
static struct mpeg_settings old_settings;
|
||||
|
||||
#define SETTINGS_VERSION 1
|
||||
#define SETTINGS_VERSION 2
|
||||
#define SETTINGS_MIN_VERSION 1
|
||||
#define SETTINGS_FILENAME "mpegplayer.cfg"
|
||||
|
||||
static char* showfps_options[] = {"No", "Yes"};
|
||||
static char* limitfps_options[] = {"No", "Yes"};
|
||||
static char* skipframes_options[] = {"No", "Yes"};
|
||||
|
||||
static struct configdata config[] =
|
||||
{
|
||||
{TYPE_ENUM, 0, 2, &settings.showfps, "Show FPS", showfps_options, NULL},
|
||||
{TYPE_ENUM, 0, 2, &settings.limitfps, "Limit FPS", limitfps_options, NULL},
|
||||
{TYPE_ENUM, 0, 2, &settings.skipframes, "Skip frames", skipframes_options, NULL},
|
||||
{TYPE_ENUM, 0, 2, &settings.showfps, "Show FPS",
|
||||
(char *[]){ "No", "Yes" }, NULL},
|
||||
{TYPE_ENUM, 0, 2, &settings.limitfps, "Limit FPS",
|
||||
(char *[]){ "No", "Yes" }, NULL},
|
||||
{TYPE_ENUM, 0, 2, &settings.skipframes, "Skip frames",
|
||||
(char *[]){ "No", "Yes" }, NULL},
|
||||
#if defined(TOSHIBA_GIGABEAT_F) || defined(SANSA_E200)
|
||||
{TYPE_INT, 0, INT_MAX, &settings.displayoptions, "Display options",
|
||||
NULL, NULL},
|
||||
#endif
|
||||
};
|
||||
|
||||
enum mpeg_menu_ids
|
||||
{
|
||||
__MPEG_OPTION_START = -1,
|
||||
#if defined(TOSHIBA_GIGABEAT_F) || defined(SANSA_E200)
|
||||
MPEG_OPTION_DISPLAY_SETTINGS,
|
||||
#endif
|
||||
MPEG_OPTION_DISPLAY_FPS,
|
||||
MPEG_OPTION_LIMIT_FPS,
|
||||
MPEG_OPTION_SKIP_FRAMES,
|
||||
MPEG_OPTION_QUIT,
|
||||
};
|
||||
|
||||
static const struct opt_items noyes[2] = {
|
||||
{ "No", -1 },
|
||||
{ "Yes", -1 },
|
||||
};
|
||||
|
||||
#if defined(TOSHIBA_GIGABEAT_F) || defined(SANSA_E200)
|
||||
static bool set_option_dithering(void)
|
||||
{
|
||||
int val = (settings.displayoptions & LCD_YUV_DITHER) ? 1 : 0;
|
||||
rb->set_option("Dithering", &val, INT, noyes, 2, NULL);
|
||||
settings.displayoptions = (settings.displayoptions & ~LCD_YUV_DITHER)
|
||||
| ((val != 0) ? LCD_YUV_DITHER : 0);
|
||||
rb->lcd_yuv_set_options(settings.displayoptions);
|
||||
return false;
|
||||
}
|
||||
|
||||
static void display_options(void)
|
||||
{
|
||||
static const struct menu_item items[] = {
|
||||
{ "Dithering", set_option_dithering },
|
||||
};
|
||||
|
||||
int m = menu_init(rb, items, ARRAYLEN(items),
|
||||
NULL, NULL, NULL, NULL);
|
||||
menu_run(m);
|
||||
menu_exit(m);
|
||||
}
|
||||
#endif /* #ifdef TOSHIBA_GIGABEAT_F */
|
||||
|
||||
bool mpeg_menu(void)
|
||||
{
|
||||
int m;
|
||||
int result;
|
||||
int menu_quit=0;
|
||||
|
||||
static const struct opt_items noyes[2] = {
|
||||
{ "No", -1 },
|
||||
{ "Yes", -1 },
|
||||
};
|
||||
|
||||
static const struct menu_item items[] = {
|
||||
{ "Display FPS", NULL },
|
||||
{ "Limit FPS", NULL },
|
||||
{ "Skip frames", NULL },
|
||||
{ "Quit mpegplayer", NULL },
|
||||
#if defined(TOSHIBA_GIGABEAT_F) || defined(SANSA_E200)
|
||||
[MPEG_OPTION_DISPLAY_SETTINGS] =
|
||||
{ "Display Options", NULL },
|
||||
#endif
|
||||
[MPEG_OPTION_DISPLAY_FPS] =
|
||||
{ "Display FPS", NULL },
|
||||
[MPEG_OPTION_LIMIT_FPS] =
|
||||
{ "Limit FPS", NULL },
|
||||
[MPEG_OPTION_SKIP_FRAMES] =
|
||||
{ "Skip frames", NULL },
|
||||
[MPEG_OPTION_QUIT] =
|
||||
{ "Quit mpegplayer", NULL },
|
||||
};
|
||||
|
||||
m = menu_init(rb, items, sizeof(items) / sizeof(*items),
|
||||
NULL, NULL, NULL, NULL);
|
||||
m = menu_init(rb, items, ARRAYLEN(items), NULL, NULL, NULL, NULL);
|
||||
|
||||
rb->button_clear_queue();
|
||||
|
||||
|
@ -52,22 +98,28 @@ bool mpeg_menu(void)
|
|||
|
||||
switch(result)
|
||||
{
|
||||
case 0: /* Show FPS */
|
||||
#if defined(TOSHIBA_GIGABEAT_F) || defined(SANSA_E200)
|
||||
case MPEG_OPTION_DISPLAY_SETTINGS:
|
||||
display_options();
|
||||
break;
|
||||
#endif
|
||||
case MPEG_OPTION_DISPLAY_FPS:
|
||||
rb->set_option("Display FPS",&settings.showfps,INT,
|
||||
noyes, 2, NULL);
|
||||
break;
|
||||
case 1: /* Limit FPS */
|
||||
case MPEG_OPTION_LIMIT_FPS:
|
||||
rb->set_option("Limit FPS",&settings.limitfps,INT,
|
||||
noyes, 2, NULL);
|
||||
break;
|
||||
case 2: /* Skip frames */
|
||||
case MPEG_OPTION_SKIP_FRAMES:
|
||||
rb->set_option("Skip frames",&settings.skipframes,INT,
|
||||
noyes, 2, NULL);
|
||||
break;
|
||||
case MPEG_OPTION_QUIT:
|
||||
default:
|
||||
menu_quit=1;
|
||||
if (result == MENU_ATTACHED_USB)
|
||||
result = 3;
|
||||
result = MPEG_OPTION_QUIT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -77,7 +129,7 @@ bool mpeg_menu(void)
|
|||
rb->lcd_clear_display();
|
||||
rb->lcd_update();
|
||||
|
||||
return (result==3);
|
||||
return (result==MPEG_OPTION_QUIT);
|
||||
}
|
||||
|
||||
|
||||
|
@ -87,6 +139,9 @@ void init_settings(void)
|
|||
settings.showfps = 0; /* Do not show FPS */
|
||||
settings.limitfps = 1; /* Limit FPS */
|
||||
settings.skipframes = 1; /* Skip frames */
|
||||
#if defined(TOSHIBA_GIGABEAT_F) || defined(SANSA_E200)
|
||||
settings.displayoptions = 0; /* No visual effects */
|
||||
#endif
|
||||
|
||||
configfile_init(rb);
|
||||
|
||||
|
@ -105,6 +160,9 @@ void init_settings(void)
|
|||
/* Keep a copy of the saved version of the settings - so we can check if
|
||||
the settings have changed when we quit */
|
||||
old_settings = settings;
|
||||
#if defined(TOSHIBA_GIGABEAT_F) || defined(SANSA_E200)
|
||||
rb->lcd_yuv_set_options(settings.displayoptions);
|
||||
#endif
|
||||
}
|
||||
|
||||
void save_settings(void)
|
||||
|
|
|
@ -5,6 +5,9 @@ struct mpeg_settings {
|
|||
int showfps;
|
||||
int limitfps;
|
||||
int skipframes;
|
||||
#if defined(TOSHIBA_GIGABEAT_F) || defined(SANSA_E200)
|
||||
unsigned displayoptions;
|
||||
#endif
|
||||
};
|
||||
|
||||
extern struct mpeg_settings settings;
|
||||
|
|
|
@ -40,216 +40,12 @@ static int output_y;
|
|||
static int output_width;
|
||||
static int output_height;
|
||||
|
||||
#if defined(SIMULATOR) && defined(HAVE_LCD_COLOR)
|
||||
|
||||
/**
|
||||
* |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)
|
||||
|
||||
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 - 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)
|
||||
{
|
||||
const unsigned char *ysrc, *usrc, *vsrc;
|
||||
fb_data *dst, *row_end;
|
||||
off_t z;
|
||||
|
||||
/* width and height must be >= 2 and an even number */
|
||||
width &= ~1;
|
||||
height >>= 1;
|
||||
|
||||
#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;
|
||||
|
||||
/* upsampling, YUV->RGB conversion and reduction to RGB565 in one go */
|
||||
|
||||
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) > 64*256-1)
|
||||
{
|
||||
r = clamp(r, 0, 64*256-1);
|
||||
g = clamp(g, 0, 64*256-1);
|
||||
b = clamp(b, 0, 64*256-1);
|
||||
}
|
||||
|
||||
*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) > 64*256-1)
|
||||
{
|
||||
r = clamp(r, 0, 64*256-1);
|
||||
g = clamp(g, 0, 64*256-1);
|
||||
b = clamp(b, 0, 64*256-1);
|
||||
}
|
||||
|
||||
*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 -= 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
|
||||
{
|
||||
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) > 64*256-1)
|
||||
{
|
||||
r = clamp(r, 0, 64*256-1);
|
||||
g = clamp(g, 0, 64*256-1);
|
||||
b = clamp(b, 0, 64*256-1);
|
||||
}
|
||||
|
||||
*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) > 64*256-1)
|
||||
{
|
||||
r = clamp(r, 0, 64*256-1);
|
||||
g = clamp(g, 0, 64*256-1);
|
||||
b = clamp(b, 0, 64*256-1);
|
||||
}
|
||||
|
||||
*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;
|
||||
|
||||
#if LCD_WIDTH >= LCD_HEIGHT
|
||||
row_end += LCD_WIDTH;
|
||||
dst += LCD_WIDTH - width;
|
||||
#else
|
||||
row_end -= 1;
|
||||
dst -= LCD_WIDTH*width + 1;
|
||||
#endif
|
||||
}
|
||||
while (--height > 0);
|
||||
}
|
||||
#endif /* defined(SIMULATOR) && defined(HAVE_LCD_COLOR) */
|
||||
|
||||
void vo_draw_frame (uint8_t * const * buf)
|
||||
{
|
||||
#ifdef HAVE_LCD_COLOR
|
||||
#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);
|
||||
#endif
|
||||
#else
|
||||
gray_ub_gray_bitmap_part(buf[0],0,0,image_width,
|
||||
output_x,output_y,output_width,output_height);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue