summaryrefslogtreecommitdiff
path: root/apps/plugins/mpegplayer/video_out_rockbox.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/mpegplayer/video_out_rockbox.c')
-rw-r--r--apps/plugins/mpegplayer/video_out_rockbox.c285
1 files changed, 285 insertions, 0 deletions
diff --git a/apps/plugins/mpegplayer/video_out_rockbox.c b/apps/plugins/mpegplayer/video_out_rockbox.c
new file mode 100644
index 0000000000..786d9d0e14
--- /dev/null
+++ b/apps/plugins/mpegplayer/video_out_rockbox.c
@@ -0,0 +1,285 @@
1/*
2 * video_out_null.c
3 * Copyright (C) 2000-2003 Michel Lespinasse <walken@zoy.org>
4 * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
5 *
6 * This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
7 * See http://libmpeg2.sourceforge.net/ for updates.
8 *
9 * mpeg2dec is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * mpeg2dec is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */
23
24#include "mpeg2dec_config.h"
25
26#include "plugin.h"
27
28extern struct plugin_api* rb;
29
30#include "mpeg2.h"
31#include "video_out.h"
32
33static int starttick;
34
35#define CSUB_X 2
36#define CSUB_Y 2
37
38static int image_x;
39static int image_y;
40static int image_width;
41static int image_height;
42static int image_chroma_x;
43static int image_chroma_y;
44
45#if (LCD_DEPTH == 16) && \
46 ((LCD_PIXELFORMAT == RGB565) || (LCD_PIXELFORMAT == RGB565SWAPPED))
47
48#define RYFAC (31*257)
49#define GYFAC (63*257)
50#define BYFAC (31*257)
51#define RVFAC 11170 /* 31 * 257 * 1.402 */
52#define GVFAC (-11563) /* 63 * 257 * -0.714136 */
53#define GUFAC (-5572) /* 63 * 257 * -0.344136 */
54#define BUFAC 14118 /* 31 * 257 * 1.772 */
55
56#define ROUNDOFFS (127*257)
57
58/* Draw a partial YUV colour bitmap - taken from the Rockbox JPEG viewer */
59void yuv_bitmap_part(unsigned char * const src[3],
60 int src_x, int src_y, int stride,
61 int x, int y, int width, int height)
62{
63 fb_data *dst, *dst_end;
64
65 /* nothing to draw? */
66 if ((width <= 0) || (height <= 0) || (x >= LCD_WIDTH) || (y >= LCD_HEIGHT)
67 || (x + width <= 0) || (y + height <= 0))
68 return;
69
70 /* clipping */
71 if (x < 0)
72 {
73 width += x;
74 src_x -= x;
75 x = 0;
76 }
77 if (y < 0)
78 {
79 height += y;
80 src_y -= y;
81 y = 0;
82 }
83 if (x + width > LCD_WIDTH)
84 width = LCD_WIDTH - x;
85 if (y + height > LCD_HEIGHT)
86 height = LCD_HEIGHT - y;
87
88 dst = rb->lcd_framebuffer + LCD_WIDTH * y + x;
89 dst_end = dst + LCD_WIDTH * height;
90
91 do
92 {
93 fb_data *dst_row = dst;
94 fb_data *row_end = dst_row + width;
95 const unsigned char *ysrc = src[0] + stride * src_y + src_x;
96 int y, u, v;
97 int red, green, blue;
98 unsigned rbits, gbits, bbits;
99
100 if (CSUB_Y) /* colour */
101 {
102 /* upsampling, YUV->RGB conversion and reduction to RGB565 in one go */
103 const unsigned char *usrc = src[1] + (stride/CSUB_X) * (src_y/CSUB_Y)
104 + (src_x/CSUB_X);
105 const unsigned char *vsrc = src[2] + (stride/CSUB_X) * (src_y/CSUB_Y)
106 + (src_x/CSUB_X);
107 int xphase = src_x % CSUB_X;
108 int rc, gc, bc;
109
110 u = *usrc++ - 128;
111 v = *vsrc++ - 128;
112 rc = RVFAC * v + ROUNDOFFS;
113 gc = GVFAC * v + GUFAC * u + ROUNDOFFS;
114 bc = BUFAC * u + ROUNDOFFS;
115
116 do
117 {
118 y = *ysrc++;
119 red = RYFAC * y + rc;
120 green = GYFAC * y + gc;
121 blue = BYFAC * y + bc;
122
123 if ((unsigned)red > (RYFAC*255+ROUNDOFFS))
124 {
125 if (red < 0)
126 red = 0;
127 else
128 red = (RYFAC*255+ROUNDOFFS);
129 }
130 if ((unsigned)green > (GYFAC*255+ROUNDOFFS))
131 {
132 if (green < 0)
133 green = 0;
134 else
135 green = (GYFAC*255+ROUNDOFFS);
136 }
137 if ((unsigned)blue > (BYFAC*255+ROUNDOFFS))
138 {
139 if (blue < 0)
140 blue = 0;
141 else
142 blue = (BYFAC*255+ROUNDOFFS);
143 }
144 rbits = ((unsigned)red) >> 16 ;
145 gbits = ((unsigned)green) >> 16 ;
146 bbits = ((unsigned)blue) >> 16 ;
147#if LCD_PIXELFORMAT == RGB565
148 *dst_row++ = (rbits << 11) | (gbits << 5) | bbits;
149#elif LCD_PIXELFORMAT == RGB565SWAPPED
150 *dst_row++ = swap16((rbits << 11) | (gbits << 5) | bbits);
151#endif
152
153 if (++xphase >= CSUB_X)
154 {
155 u = *usrc++ - 128;
156 v = *vsrc++ - 128;
157 rc = RVFAC * v + ROUNDOFFS;
158 gc = GVFAC * v + GUFAC * u + ROUNDOFFS;
159 bc = BUFAC * u + ROUNDOFFS;
160 xphase = 0;
161 }
162 }
163 while (dst_row < row_end);
164 }
165 else /* monochrome */
166 {
167 do
168 {
169 y = *ysrc++;
170 red = RYFAC * y + ROUNDOFFS; /* blue == red */
171 green = GYFAC * y + ROUNDOFFS;
172 rbits = ((unsigned)red) >> 16;
173 gbits = ((unsigned)green) >> 16;
174#if LCD_PIXELFORMAT == RGB565
175 *dst_row++ = (rbits << 11) | (gbits << 5) | rbits;
176#elif LCD_PIXELFORMAT == RGB565SWAPPED
177 *dst_row++ = swap16((rbits << 11) | (gbits << 5) | rbits);
178#endif
179 }
180 while (dst_row < row_end);
181 }
182
183 src_y++;
184 dst += LCD_WIDTH;
185 }
186 while (dst < dst_end);
187}
188#endif
189
190static void rockbox_draw_frame (vo_instance_t * instance,
191 uint8_t * const * buf, void * id)
192{
193 char str[80];
194 static int frame=0;
195 int ticks,fps;
196
197 (void)id;
198 (void)instance;
199
200#if (CONFIG_LCD == LCD_IPODCOLOR || CONFIG_LCD == LCD_IPODNANO) && \
201 !defined(SIMULATOR)
202 rb->lcd_yuv_blit(buf,
203 0,0,image_width,
204 image_x,image_y,image_width,image_height);
205#elif (LCD_DEPTH == 16) && \
206 ((LCD_PIXELFORMAT == RGB565) || (LCD_PIXELFORMAT == RGB565SWAPPED))
207 yuv_bitmap_part(buf,0,0,image_width,
208 image_x,image_y,image_width,image_height);
209 rb->lcd_update_rect(image_x,image_y,image_width,image_height);
210#endif
211
212 if (starttick==0) starttick=*rb->current_tick-1; /* Avoid divby0 */
213
214 /* Calculate fps */
215 frame++;
216 if ((frame % 125) == 0) {
217 ticks=(*rb->current_tick)-starttick;
218
219 fps=(frame*1000)/ticks;
220 rb->snprintf(str,sizeof(str),"%d.%d",(fps/10),fps%10);
221 rb->lcd_putsxy(0,0,str);
222
223 rb->lcd_update_rect(0,0,80,8);
224 }
225}
226
227vo_instance_t static_instance;
228
229static vo_instance_t * internal_open (int setup (vo_instance_t *, unsigned int,
230 unsigned int, unsigned int,
231 unsigned int,
232 vo_setup_result_t *),
233 void draw (vo_instance_t *,
234 uint8_t * const *, void *))
235{
236 vo_instance_t * instance;
237
238 instance = (vo_instance_t *) &static_instance;
239 if (instance == NULL)
240 return NULL;
241
242 instance->setup = setup;
243 instance->setup_fbuf = NULL;
244 instance->set_fbuf = NULL;
245 instance->start_fbuf = NULL;
246 instance->draw = draw;
247 instance->discard = NULL;
248 //instance->close = (void (*) (vo_instance_t *)) free;
249
250 return instance;
251}
252
253static int rockbox_setup (vo_instance_t * instance, unsigned int width,
254 unsigned int height, unsigned int chroma_width,
255 unsigned int chroma_height,
256 vo_setup_result_t * result)
257{
258 (void)instance;
259
260 result->convert = NULL;
261
262 image_width=width;
263 image_height=height;
264 image_chroma_x=image_width/chroma_width;
265 image_chroma_y=image_height/chroma_height;
266
267 if (image_width >= LCD_WIDTH) {
268 image_x = 0;
269 } else {
270 image_x = (LCD_WIDTH-image_width)/2;
271 }
272
273 if (image_height >= LCD_HEIGHT) {
274 image_y = 0;
275 } else {
276 image_y = (LCD_HEIGHT-image_height)/2;
277 }
278
279 return 0;
280}
281
282vo_instance_t * vo_rockbox_open (void)
283{
284 return internal_open (rockbox_setup, rockbox_draw_frame);
285}