summaryrefslogtreecommitdiff
path: root/apps/plugins
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 /apps/plugins
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
Diffstat (limited to 'apps/plugins')
-rw-r--r--apps/plugins/video.c198
1 files changed, 198 insertions, 0 deletions
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