diff options
author | Jörg Hohensohn <hohensoh@rockbox.org> | 2003-12-15 07:44:43 +0000 |
---|---|---|
committer | Jörg Hohensohn <hohensoh@rockbox.org> | 2003-12-15 07:44:43 +0000 |
commit | bd8f448fd0cb10336c7dbc9a01e0ada0380c1c61 (patch) | |
tree | 92f28d3f57ec946cea2e72b1a62108ccc69dad2c /apps/plugins/video.c | |
parent | 50f63e334aa549f868b4b28c389b7ea34ffa9b4f (diff) | |
download | rockbox-bd8f448fd0cb10336c7dbc9a01e0ada0380c1c61.tar.gz rockbox-bd8f448fd0cb10336c7dbc9a01e0ada0380c1c61.zip |
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/video.c')
-rw-r--r-- | apps/plugins/video.c | 198 |
1 files changed, 198 insertions, 0 deletions
diff --git a/apps/plugins/video.c b/apps/plugins/video.c new file mode 100644 index 0000000000..396d5159ec --- /dev/null +++ b/apps/plugins/video.c | |||
@@ -0,0 +1,198 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Experimental plugin for halftoning | ||
11 | * Reads raw image data from a file | ||
12 | * | ||
13 | * Copyright (C) 2003 Jörg Hohensohn [IDC]Dragon | ||
14 | * | ||
15 | * All files in this archive are subject to the GNU General Public License. | ||
16 | * See the file COPYING in the source tree root for full license agreement. | ||
17 | * | ||
18 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
19 | * KIND, either express or implied. | ||
20 | * | ||
21 | ****************************************************************************/ | ||
22 | #ifdef HAVE_LCD_BITMAP | ||
23 | |||
24 | #include "plugin.h" | ||
25 | #include "system.h" | ||
26 | |||
27 | #define DEFAULT_FILENAME "/default.rvf" | ||
28 | #define SCREENSIZE (LCD_WIDTH*LCD_HEIGHT/8) /* in bytes */ | ||
29 | #define FILEBUFSIZE SCREENSIZE*4 /* must result in a multiple of 512 */ | ||
30 | |||
31 | static struct plugin_api* rb; /* here is a global api struct pointer */ | ||
32 | |||
33 | int WaitForButton(void) | ||
34 | { | ||
35 | int button; | ||
36 | |||
37 | do | ||
38 | { | ||
39 | button = rb->button_get(true); | ||
40 | } while ((button & BUTTON_REL) && button != SYS_USB_CONNECTED); | ||
41 | |||
42 | return button; | ||
43 | } | ||
44 | |||
45 | |||
46 | /* play from memory, loop until OFF is pressed */ | ||
47 | int show_buffer(unsigned char* p_start, int frames) | ||
48 | { | ||
49 | unsigned char* p_current = p_start; | ||
50 | unsigned char* p_end = p_start + SCREENSIZE * frames; | ||
51 | int shown = 0; | ||
52 | int button; | ||
53 | |||
54 | do | ||
55 | { | ||
56 | rb->lcd_blit(p_current, 0, 0, LCD_WIDTH, LCD_HEIGHT/8, LCD_WIDTH); | ||
57 | p_current += SCREENSIZE; | ||
58 | if (p_current >= p_end) | ||
59 | p_current = p_start; /* wrap */ | ||
60 | |||
61 | rb->yield(); /* yield to the other treads */ | ||
62 | shown++; | ||
63 | |||
64 | button = rb->button_get(false); | ||
65 | } while(button != BUTTON_OFF && button != SYS_USB_CONNECTED); | ||
66 | |||
67 | return (button != SYS_USB_CONNECTED) ? shown : SYS_USB_CONNECTED; | ||
68 | } | ||
69 | |||
70 | |||
71 | /* play from file, exit if OFF is pressed */ | ||
72 | int show_file(unsigned char* p_buffer, int fd) | ||
73 | { | ||
74 | int got_now; /* how many gotten for this frame */ | ||
75 | int shown = 0; | ||
76 | int button = BUTTON_NONE; | ||
77 | /* tricky buffer handling to read only whole sectors, then no copying needed */ | ||
78 | unsigned char* p_file = p_buffer; /* file read */ | ||
79 | unsigned char* p_screen = p_buffer; /* display */ | ||
80 | unsigned char* p_end = p_buffer + FILEBUFSIZE; /* for wraparound test */ | ||
81 | int needed; /* read how much data to complete a frame */ | ||
82 | int read_now; /* size to read for this frame, 512 or 1024 */ | ||
83 | |||
84 | do | ||
85 | { | ||
86 | needed = SCREENSIZE - (p_file - p_screen); /* minus what we have */ | ||
87 | read_now = (needed + (SECTOR_SIZE-1)) & ~(SECTOR_SIZE-1); /* round up to whole sectors */ | ||
88 | |||
89 | got_now = rb->read(fd, p_file, read_now); /* read the sector(s) */ | ||
90 | rb->lcd_blit(p_screen, 0, 0, LCD_WIDTH, LCD_HEIGHT/8, LCD_WIDTH); | ||
91 | |||
92 | p_screen += SCREENSIZE; | ||
93 | if (p_screen >= p_end) | ||
94 | p_screen = p_buffer; /* wrap */ | ||
95 | |||
96 | p_file += got_now; | ||
97 | if (p_file >= p_end) | ||
98 | p_file = p_buffer; /* wrap */ | ||
99 | |||
100 | if (read_now < SCREENSIZE) /* below average? time to do something else */ | ||
101 | { | ||
102 | rb->yield(); /* yield to the other treads */ | ||
103 | button = rb->button_get(false); | ||
104 | } | ||
105 | |||
106 | shown++; | ||
107 | |||
108 | } while (got_now >= needed | ||
109 | && button != BUTTON_OFF | ||
110 | && button != SYS_USB_CONNECTED); | ||
111 | |||
112 | return (button != SYS_USB_CONNECTED) ? shown : SYS_USB_CONNECTED; | ||
113 | } | ||
114 | |||
115 | |||
116 | int main(char* filename) | ||
117 | { | ||
118 | char buf[32]; | ||
119 | int buffer_size, file_size; | ||
120 | unsigned char* p_buffer; | ||
121 | int fd; /* file descriptor handle */ | ||
122 | int got_now; /* how many bytes read from file */ | ||
123 | int frames, shown; | ||
124 | long time; | ||
125 | int button; | ||
126 | |||
127 | p_buffer = rb->plugin_get_buffer(&buffer_size); | ||
128 | if (buffer_size < FILEBUFSIZE) | ||
129 | return PLUGIN_ERROR; /* not enough memory */ | ||
130 | |||
131 | /* compose filename if none given */ | ||
132 | if (filename == NULL) | ||
133 | { | ||
134 | filename = DEFAULT_FILENAME; | ||
135 | } | ||
136 | |||
137 | fd = rb->open(filename, O_RDONLY); | ||
138 | if (fd < 0) | ||
139 | return PLUGIN_ERROR; | ||
140 | |||
141 | file_size = rb->filesize(fd); | ||
142 | if (file_size <= buffer_size) | ||
143 | { /* we can read the whole file in advance */ | ||
144 | got_now = rb->read(fd, p_buffer, file_size); | ||
145 | rb->close(fd); | ||
146 | frames = got_now / (LCD_WIDTH*LCD_HEIGHT/8); | ||
147 | time = *rb->current_tick; | ||
148 | shown = show_buffer(p_buffer, frames); | ||
149 | time = *rb->current_tick - time; | ||
150 | } | ||
151 | else | ||
152 | { /* we need to stream */ | ||
153 | time = *rb->current_tick; | ||
154 | shown = show_file(p_buffer, fd); | ||
155 | time = *rb->current_tick - time; | ||
156 | rb->close(fd); | ||
157 | } | ||
158 | |||
159 | rb->close(fd); | ||
160 | and_b(~0x40, &PBDRL); /* hack workaround to get the LED off */ | ||
161 | |||
162 | if (shown == SYS_USB_CONNECTED) /* exception */ | ||
163 | return PLUGIN_USB_CONNECTED; | ||
164 | |||
165 | rb->lcd_clear_display(); | ||
166 | rb->snprintf(buf, sizeof(buf), "%d frames", shown); | ||
167 | rb->lcd_puts(0, 0, buf); | ||
168 | rb->snprintf(buf, sizeof(buf), "%d.%02d seconds", time/HZ, time%HZ); | ||
169 | rb->lcd_puts(0, 1, buf); | ||
170 | rb->snprintf(buf, sizeof(buf), "%d fps", (shown * HZ + time/2) / time); | ||
171 | rb->lcd_puts(0, 2, buf); | ||
172 | rb->snprintf(buf, sizeof(buf), "file: %d bytes", file_size); | ||
173 | rb->lcd_puts(0, 6, buf); | ||
174 | rb->snprintf(buf, sizeof(buf), "buffer: %d bytes", buffer_size); | ||
175 | rb->lcd_puts(0, 7, buf); | ||
176 | rb->lcd_update(); | ||
177 | button = WaitForButton(); | ||
178 | return (button == SYS_USB_CONNECTED) ? PLUGIN_USB_CONNECTED : PLUGIN_OK; | ||
179 | |||
180 | } | ||
181 | |||
182 | |||
183 | /***************** Plugin Entry Point *****************/ | ||
184 | |||
185 | enum plugin_status plugin_start(struct plugin_api* api, void* parameter) | ||
186 | { | ||
187 | /* this macro should be called as the first thing you do in the plugin. | ||
188 | it test that the api version and model the plugin was compiled for | ||
189 | matches the machine it is running on */ | ||
190 | TEST_PLUGIN_API(api); | ||
191 | |||
192 | rb = api; /* copy to global api pointer */ | ||
193 | |||
194 | /* now go ahead and have fun! */ | ||
195 | return main((char*) parameter); | ||
196 | } | ||
197 | |||
198 | #endif // #ifdef HAVE_LCD_BITMAP \ No newline at end of file | ||