summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJörg Hohensohn <hohensoh@rockbox.org>2003-12-15 07:44:43 +0000
committerJörg Hohensohn <hohensoh@rockbox.org>2003-12-15 07:44:43 +0000
commitbd8f448fd0cb10336c7dbc9a01e0ada0380c1c61 (patch)
tree92f28d3f57ec946cea2e72b1a62108ccc69dad2c
parent50f63e334aa549f868b4b28c389b7ea34ffa9b4f (diff)
downloadrockbox-bd8f448fd0cb10336c7dbc9a01e0ada0380c1c61.zip
rockbox-bd8f448fd0cb10336c7dbc9a01e0ada0380c1c61.tar.gz
rockbox-bd8f448fd0cb10336c7dbc9a01e0ada0380c1c61.tar.bz2
rockbox-bd8f448fd0cb10336c7dbc9a01e0ada0380c1c61.tar.xz
the video player plugin and file the type / plugin API for it
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@4145 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/plugin.c8
-rw-r--r--apps/plugin.h9
-rw-r--r--apps/plugins/video.c198
-rw-r--r--apps/tree.c6
-rw-r--r--apps/tree.h1
5 files changed, 221 insertions, 1 deletions
diff --git a/apps/plugin.c b/apps/plugin.c
index 7a88a89..d711027 100644
--- a/apps/plugin.c
+++ b/apps/plugin.c
@@ -155,6 +155,14 @@ static struct plugin_api rockbox_api = {
atoi,
get_time,
plugin_get_buffer,
+
+ /* new stuff at the end, sort into place next time the API gets incompatible */
+
+#ifndef HAVE_LCD_CHARCELLS
+ &lcd_framebuffer[0][0],
+ lcd_blit,
+#endif
+ yield,
};
int plugin_load(char* plugin, void* parameter)
diff --git a/apps/plugin.h b/apps/plugin.h
index e7ec86a..819d75d 100644
--- a/apps/plugin.h
+++ b/apps/plugin.h
@@ -43,7 +43,7 @@
#include "mpeg.h"
/* increase this every time the api struct changes */
-#define PLUGIN_API_VERSION 7
+#define PLUGIN_API_VERSION 8
/* update this to latest version if a change to the api struct breaks
backwards compatibility */
@@ -181,6 +181,13 @@ struct plugin_api {
int (*atoi)(const char *str);
struct tm* (*get_time)(void);
void* (*plugin_get_buffer)(int* buffer_size);
+ /* new stuff */
+#ifndef HAVE_LCD_CHARCELLS
+ unsigned char* lcd_framebuffer;
+ /* performance function */
+ void (*lcd_blit) (unsigned char* p_data, int x, int y, int width, int height, int stride);
+#endif
+ void (*yield)(void);
};
/* defined by the plugin loader (plugin.c) */
diff --git a/apps/plugins/video.c b/apps/plugins/video.c
new file mode 100644
index 0000000..396d515
--- /dev/null
+++ b/apps/plugins/video.c
@@ -0,0 +1,198 @@
+/***************************************************************************
+* __________ __ ___.
+* Open \______ \ ____ ____ | | _\_ |__ _______ ___
+* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+* \/ \/ \/ \/ \/
+* $Id$
+*
+* Experimental plugin for halftoning
+* Reads raw image data from a file
+*
+* Copyright (C) 2003 Jörg Hohensohn [IDC]Dragon
+*
+* All files in this archive are subject to the GNU General Public License.
+* See the file COPYING in the source tree root for full license agreement.
+*
+* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+* KIND, either express or implied.
+*
+****************************************************************************/
+#ifdef HAVE_LCD_BITMAP
+
+#include "plugin.h"
+#include "system.h"
+
+#define DEFAULT_FILENAME "/default.rvf"
+#define SCREENSIZE (LCD_WIDTH*LCD_HEIGHT/8) /* in bytes */
+#define FILEBUFSIZE SCREENSIZE*4 /* must result in a multiple of 512 */
+
+static struct plugin_api* rb; /* here is a global api struct pointer */
+
+int WaitForButton(void)
+{
+ int button;
+
+ do
+ {
+ button = rb->button_get(true);
+ } while ((button & BUTTON_REL) && button != SYS_USB_CONNECTED);
+
+ return button;
+}
+
+
+/* play from memory, loop until OFF is pressed */
+int show_buffer(unsigned char* p_start, int frames)
+{
+ unsigned char* p_current = p_start;
+ unsigned char* p_end = p_start + SCREENSIZE * frames;
+ int shown = 0;
+ int button;
+
+ do
+ {
+ rb->lcd_blit(p_current, 0, 0, LCD_WIDTH, LCD_HEIGHT/8, LCD_WIDTH);
+ p_current += SCREENSIZE;
+ if (p_current >= p_end)
+ p_current = p_start; /* wrap */
+
+ rb->yield(); /* yield to the other treads */
+ shown++;
+
+ button = rb->button_get(false);
+ } while(button != BUTTON_OFF && button != SYS_USB_CONNECTED);
+
+ return (button != SYS_USB_CONNECTED) ? shown : SYS_USB_CONNECTED;
+}
+
+
+/* play from file, exit if OFF is pressed */
+int show_file(unsigned char* p_buffer, int fd)
+{
+ int got_now; /* how many gotten for this frame */
+ int shown = 0;
+ int button = BUTTON_NONE;
+ /* tricky buffer handling to read only whole sectors, then no copying needed */
+ unsigned char* p_file = p_buffer; /* file read */
+ unsigned char* p_screen = p_buffer; /* display */
+ unsigned char* p_end = p_buffer + FILEBUFSIZE; /* for wraparound test */
+ int needed; /* read how much data to complete a frame */
+ int read_now; /* size to read for this frame, 512 or 1024 */
+
+ do
+ {
+ needed = SCREENSIZE - (p_file - p_screen); /* minus what we have */
+ read_now = (needed + (SECTOR_SIZE-1)) & ~(SECTOR_SIZE-1); /* round up to whole sectors */
+
+ got_now = rb->read(fd, p_file, read_now); /* read the sector(s) */
+ rb->lcd_blit(p_screen, 0, 0, LCD_WIDTH, LCD_HEIGHT/8, LCD_WIDTH);
+
+ p_screen += SCREENSIZE;
+ if (p_screen >= p_end)
+ p_screen = p_buffer; /* wrap */
+
+ p_file += got_now;
+ if (p_file >= p_end)
+ p_file = p_buffer; /* wrap */
+
+ if (read_now < SCREENSIZE) /* below average? time to do something else */
+ {
+ rb->yield(); /* yield to the other treads */
+ button = rb->button_get(false);
+ }
+
+ shown++;
+
+ } while (got_now >= needed
+ && button != BUTTON_OFF
+ && button != SYS_USB_CONNECTED);
+
+ return (button != SYS_USB_CONNECTED) ? shown : SYS_USB_CONNECTED;
+}
+
+
+int main(char* filename)
+{
+ char buf[32];
+ int buffer_size, file_size;
+ unsigned char* p_buffer;
+ int fd; /* file descriptor handle */
+ int got_now; /* how many bytes read from file */
+ int frames, shown;
+ long time;
+ int button;
+
+ p_buffer = rb->plugin_get_buffer(&buffer_size);
+ if (buffer_size < FILEBUFSIZE)
+ return PLUGIN_ERROR; /* not enough memory */
+
+ /* compose filename if none given */
+ if (filename == NULL)
+ {
+ filename = DEFAULT_FILENAME;
+ }
+
+ fd = rb->open(filename, O_RDONLY);
+ if (fd < 0)
+ return PLUGIN_ERROR;
+
+ file_size = rb->filesize(fd);
+ if (file_size <= buffer_size)
+ { /* we can read the whole file in advance */
+ got_now = rb->read(fd, p_buffer, file_size);
+ rb->close(fd);
+ frames = got_now / (LCD_WIDTH*LCD_HEIGHT/8);
+ time = *rb->current_tick;
+ shown = show_buffer(p_buffer, frames);
+ time = *rb->current_tick - time;
+ }
+ else
+ { /* we need to stream */
+ time = *rb->current_tick;
+ shown = show_file(p_buffer, fd);
+ time = *rb->current_tick - time;
+ rb->close(fd);
+ }
+
+ rb->close(fd);
+ and_b(~0x40, &PBDRL); /* hack workaround to get the LED off */
+
+ if (shown == SYS_USB_CONNECTED) /* exception */
+ return PLUGIN_USB_CONNECTED;
+
+ rb->lcd_clear_display();
+ rb->snprintf(buf, sizeof(buf), "%d frames", shown);
+ rb->lcd_puts(0, 0, buf);
+ rb->snprintf(buf, sizeof(buf), "%d.%02d seconds", time/HZ, time%HZ);
+ rb->lcd_puts(0, 1, buf);
+ rb->snprintf(buf, sizeof(buf), "%d fps", (shown * HZ + time/2) / time);
+ rb->lcd_puts(0, 2, buf);
+ rb->snprintf(buf, sizeof(buf), "file: %d bytes", file_size);
+ rb->lcd_puts(0, 6, buf);
+ rb->snprintf(buf, sizeof(buf), "buffer: %d bytes", buffer_size);
+ rb->lcd_puts(0, 7, buf);
+ rb->lcd_update();
+ button = WaitForButton();
+ return (button == SYS_USB_CONNECTED) ? PLUGIN_USB_CONNECTED : PLUGIN_OK;
+
+}
+
+
+/***************** Plugin Entry Point *****************/
+
+enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
+{
+ /* this macro should be called as the first thing you do in the plugin.
+ it test that the api version and model the plugin was compiled for
+ matches the machine it is running on */
+ TEST_PLUGIN_API(api);
+
+ rb = api; /* copy to global api pointer */
+
+ /* now go ahead and have fun! */
+ return main((char*) parameter);
+}
+
+#endif // #ifdef HAVE_LCD_BITMAP \ No newline at end of file
diff --git a/apps/tree.c b/apps/tree.c
index 62b9ce2..392328b 100644
--- a/apps/tree.c
+++ b/apps/tree.c
@@ -82,6 +82,7 @@ static struct
#ifdef HAVE_LCD_BITMAP
{ ".fnt", TREE_ATTR_FONT,Font },
{ ".ch8", TREE_ATTR_CH8, -1 },
+ { ".rvf", TREE_ATTR_RVF, Text },
#endif
#ifndef SIMULATOR
#ifdef HAVE_LCD_BITMAP
@@ -1068,6 +1069,11 @@ static bool dirbrowse(char *root, int *dirfilter)
plugin_load("/.rockbox/rocks/chip8.rock",buf);
break;
+ /* "movie" animation */
+ case TREE_ATTR_RVF:
+ plugin_load("/.rockbox/rocks/video.rock",buf);
+ break;
+
case TREE_ATTR_FONT:
font_load(buf);
set_file(buf, global_settings.font_file,
diff --git a/apps/tree.h b/apps/tree.h
index fdc9641..87cd469 100644
--- a/apps/tree.h
+++ b/apps/tree.h
@@ -38,6 +38,7 @@ struct entry {
#define TREE_ATTR_ROCK 0x0900 /* binary rockbox plugin */
#define TREE_ATTR_UCL 0x0A00 /* rockbox flash image */
#define TREE_ATTR_CH8 0x0B00 /* chip-8 game */
+#define TREE_ATTR_RVF 0x0C00 /* rockbox video file */
#define TREE_ATTR_MASK 0xFFC0 /* which bits tree.c uses (above) */
void tree_init(void);