diff options
Diffstat (limited to 'apps/plugins/mpegplayer/mpegplayer.c')
-rw-r--r-- | apps/plugins/mpegplayer/mpegplayer.c | 246 |
1 files changed, 246 insertions, 0 deletions
diff --git a/apps/plugins/mpegplayer/mpegplayer.c b/apps/plugins/mpegplayer/mpegplayer.c new file mode 100644 index 0000000000..ce4199a1d0 --- /dev/null +++ b/apps/plugins/mpegplayer/mpegplayer.c | |||
@@ -0,0 +1,246 @@ | |||
1 | /* | ||
2 | * mpegplayer.c - based on mpeg2dec.c | ||
3 | * | ||
4 | * Copyright (C) 2000-2003 Michel Lespinasse <walken@zoy.org> | ||
5 | * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca> | ||
6 | * | ||
7 | * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. | ||
8 | * See http://libmpeg2.sourceforge.net/ for updates. | ||
9 | * | ||
10 | * mpeg2dec is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License as published by | ||
12 | * the Free Software Foundation; either version 2 of the License, or | ||
13 | * (at your option) any later version. | ||
14 | * | ||
15 | * mpeg2dec is distributed in the hope that it will be useful, | ||
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
18 | * GNU General Public License for more details. | ||
19 | * | ||
20 | * You should have received a copy of the GNU General Public License | ||
21 | * along with this program; if not, write to the Free Software | ||
22 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
23 | */ | ||
24 | |||
25 | #include "mpeg2dec_config.h" | ||
26 | |||
27 | #include "plugin.h" | ||
28 | |||
29 | #include "mpeg2.h" | ||
30 | #include "video_out.h" | ||
31 | |||
32 | PLUGIN_HEADER | ||
33 | |||
34 | #ifdef USE_IRAM | ||
35 | extern char iramcopy[]; | ||
36 | extern char iramstart[]; | ||
37 | extern char iramend[]; | ||
38 | extern char iedata[]; | ||
39 | extern char iend[]; | ||
40 | #endif | ||
41 | |||
42 | struct plugin_api* rb; | ||
43 | |||
44 | #define BUFFER_SIZE 25*1024*1024 | ||
45 | |||
46 | static mpeg2dec_t * mpeg2dec; | ||
47 | static vo_open_t * output_open = NULL; | ||
48 | static vo_instance_t * output; | ||
49 | static int total_offset = 0; | ||
50 | |||
51 | extern vo_open_t vo_rockbox_open; | ||
52 | |||
53 | static void decode_mpeg2 (uint8_t * current, uint8_t * end) | ||
54 | { | ||
55 | const mpeg2_info_t * info; | ||
56 | mpeg2_state_t state; | ||
57 | vo_setup_result_t setup_result; | ||
58 | |||
59 | mpeg2_buffer (mpeg2dec, current, end); | ||
60 | total_offset += end - current; | ||
61 | |||
62 | info = mpeg2_info (mpeg2dec); | ||
63 | while (1) { | ||
64 | state = mpeg2_parse (mpeg2dec); | ||
65 | |||
66 | switch (state) { | ||
67 | case STATE_BUFFER: | ||
68 | return; | ||
69 | case STATE_SEQUENCE: | ||
70 | /* might set nb fbuf, convert format, stride */ | ||
71 | /* might set fbufs */ | ||
72 | if (output->setup (output, info->sequence->width, | ||
73 | info->sequence->height, | ||
74 | info->sequence->chroma_width, | ||
75 | info->sequence->chroma_height, &setup_result)) { | ||
76 | //fprintf (stderr, "display setup failed\n"); | ||
77 | return; | ||
78 | } | ||
79 | if (setup_result.convert && | ||
80 | mpeg2_convert (mpeg2dec, setup_result.convert, NULL)) { | ||
81 | //fprintf (stderr, "color conversion setup failed\n"); | ||
82 | return; | ||
83 | } | ||
84 | if (output->set_fbuf) { | ||
85 | uint8_t * buf[3]; | ||
86 | void * id; | ||
87 | |||
88 | mpeg2_custom_fbuf (mpeg2dec, 1); | ||
89 | output->set_fbuf (output, buf, &id); | ||
90 | mpeg2_set_buf (mpeg2dec, buf, id); | ||
91 | output->set_fbuf (output, buf, &id); | ||
92 | mpeg2_set_buf (mpeg2dec, buf, id); | ||
93 | } else if (output->setup_fbuf) { | ||
94 | uint8_t * buf[3]; | ||
95 | void * id; | ||
96 | |||
97 | output->setup_fbuf (output, buf, &id); | ||
98 | mpeg2_set_buf (mpeg2dec, buf, id); | ||
99 | output->setup_fbuf (output, buf, &id); | ||
100 | mpeg2_set_buf (mpeg2dec, buf, id); | ||
101 | output->setup_fbuf (output, buf, &id); | ||
102 | mpeg2_set_buf (mpeg2dec, buf, id); | ||
103 | } | ||
104 | mpeg2_skip (mpeg2dec, (output->draw == NULL)); | ||
105 | break; | ||
106 | case STATE_PICTURE: | ||
107 | /* might skip */ | ||
108 | /* might set fbuf */ | ||
109 | if (output->set_fbuf) { | ||
110 | uint8_t * buf[3]; | ||
111 | void * id; | ||
112 | |||
113 | output->set_fbuf (output, buf, &id); | ||
114 | mpeg2_set_buf (mpeg2dec, buf, id); | ||
115 | } | ||
116 | if (output->start_fbuf) | ||
117 | output->start_fbuf (output, info->current_fbuf->buf, | ||
118 | info->current_fbuf->id); | ||
119 | break; | ||
120 | case STATE_SLICE: | ||
121 | case STATE_END: | ||
122 | case STATE_INVALID_END: | ||
123 | /* draw current picture */ | ||
124 | /* might free frame buffer */ | ||
125 | if (info->display_fbuf) { | ||
126 | if (output->draw) | ||
127 | output->draw (output, info->display_fbuf->buf, | ||
128 | info->display_fbuf->id); | ||
129 | //print_fps (0); | ||
130 | } | ||
131 | if (output->discard && info->discard_fbuf) | ||
132 | output->discard (output, info->discard_fbuf->buf, | ||
133 | info->discard_fbuf->id); | ||
134 | break; | ||
135 | default: | ||
136 | break; | ||
137 | } | ||
138 | |||
139 | rb->yield(); | ||
140 | } | ||
141 | } | ||
142 | |||
143 | static void es_loop (int in_file) | ||
144 | { | ||
145 | static uint8_t* buffer; | ||
146 | uint8_t * end; | ||
147 | |||
148 | buffer=mpeg2_malloc(BUFFER_SIZE,0); | ||
149 | |||
150 | if (buffer==NULL) | ||
151 | return; | ||
152 | |||
153 | do { | ||
154 | rb->splash(0,true,"Buffering..."); | ||
155 | end = buffer + rb->read (in_file, buffer, BUFFER_SIZE); | ||
156 | decode_mpeg2 (buffer, end); | ||
157 | } while (end == buffer + BUFFER_SIZE); | ||
158 | } | ||
159 | |||
160 | enum plugin_status plugin_start(struct plugin_api* api, void* parameter) | ||
161 | { | ||
162 | (void)parameter; | ||
163 | void* audiobuf; | ||
164 | int audiosize; | ||
165 | int in_file; | ||
166 | |||
167 | rb = api; | ||
168 | |||
169 | /* This also stops audio playback - so we do it before using IRAM */ | ||
170 | audiobuf = rb->plugin_get_audio_buffer(&audiosize); | ||
171 | |||
172 | /* Initialise our malloc buffer */ | ||
173 | mpeg2_alloc_init(audiobuf,audiosize); | ||
174 | |||
175 | #ifdef USE_IRAM | ||
176 | rb->memcpy(iramstart, iramcopy, iramend-iramstart); | ||
177 | rb->memset(iedata, 0, iend - iedata); | ||
178 | #endif | ||
179 | |||
180 | #ifdef HAVE_LCD_COLOR | ||
181 | rb->lcd_set_foreground(LCD_WHITE); | ||
182 | rb->lcd_set_background(LCD_BLACK); | ||
183 | #endif | ||
184 | rb->lcd_clear_display(); | ||
185 | rb->lcd_update(); | ||
186 | |||
187 | if (parameter == NULL) { | ||
188 | return PLUGIN_ERROR; | ||
189 | } | ||
190 | |||
191 | in_file = rb->open((char*)parameter,O_RDONLY); | ||
192 | |||
193 | if (in_file < 0) { | ||
194 | //fprintf(stderr,"Could not open %s\n",argv[1]); | ||
195 | return PLUGIN_ERROR; | ||
196 | } | ||
197 | |||
198 | output_open = vo_rockbox_open; | ||
199 | |||
200 | if (output_open == NULL) { | ||
201 | //fprintf (stderr, "output_open is NULL\n"); | ||
202 | return PLUGIN_ERROR; | ||
203 | } | ||
204 | |||
205 | output = output_open (); | ||
206 | |||
207 | if (output == NULL) { | ||
208 | //fprintf (stderr, "Can not open output\n"); | ||
209 | return PLUGIN_ERROR; | ||
210 | } | ||
211 | |||
212 | mpeg2dec = mpeg2_init (); | ||
213 | |||
214 | if (mpeg2dec == NULL) | ||
215 | return PLUGIN_ERROR; | ||
216 | |||
217 | /* make sure the backlight is always on when viewing video | ||
218 | (actually it should also set the timeout when plugged in, | ||
219 | but the function backlight_set_timeout_plugged is not | ||
220 | available in plugins) */ | ||
221 | #ifdef CONFIG_BACKLIGHT | ||
222 | if (rb->global_settings->backlight_timeout > 0) | ||
223 | rb->backlight_set_timeout(1); | ||
224 | #endif | ||
225 | |||
226 | #ifdef HAVE_ADJUSTABLE_CPU_FREQ | ||
227 | rb->cpu_boost(true); | ||
228 | #endif | ||
229 | |||
230 | es_loop (in_file); | ||
231 | |||
232 | mpeg2_close (mpeg2dec); | ||
233 | |||
234 | rb->close (in_file); | ||
235 | |||
236 | #ifdef HAVE_ADJUSTABLE_CPU_FREQ | ||
237 | rb->cpu_boost(false); | ||
238 | #endif | ||
239 | |||
240 | #ifdef CONFIG_BACKLIGHT | ||
241 | /* reset backlight settings */ | ||
242 | rb->backlight_set_timeout(rb->global_settings->backlight_timeout); | ||
243 | #endif | ||
244 | |||
245 | return PLUGIN_OK; | ||
246 | } | ||