summaryrefslogtreecommitdiff
path: root/apps/plugins/mpegplayer/mpegplayer.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/mpegplayer/mpegplayer.c')
-rw-r--r--apps/plugins/mpegplayer/mpegplayer.c246
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
32PLUGIN_HEADER
33
34#ifdef USE_IRAM
35extern char iramcopy[];
36extern char iramstart[];
37extern char iramend[];
38extern char iedata[];
39extern char iend[];
40#endif
41
42struct plugin_api* rb;
43
44#define BUFFER_SIZE 25*1024*1024
45
46static mpeg2dec_t * mpeg2dec;
47static vo_open_t * output_open = NULL;
48static vo_instance_t * output;
49static int total_offset = 0;
50
51extern vo_open_t vo_rockbox_open;
52
53static 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
143static 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
160enum 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}