just pass the struct to vo_setup instead of multiple arguments
[Rockbox.git] / apps / plugins / mpegplayer / video_out_rockbox.c
blobe3f8ba02649a28931984673e70675efea95dff8e
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>
6 * This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
7 * See http://libmpeg2.sourceforge.net/ for updates.
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.
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.
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
24 #include "mpeg2dec_config.h"
26 #include "plugin.h"
27 #include "gray.h"
29 extern struct plugin_api* rb;
31 #include "mpeg2.h"
32 #include "video_out.h"
34 #define CSUB_X 2
35 #define CSUB_Y 2
37 static int image_width;
38 static int image_height;
39 static int image_chroma_x;
40 static int image_chroma_y;
41 static int output_x;
42 static int output_y;
43 static int output_width;
44 static int output_height;
46 #if defined(SIMULATOR) && defined(HAVE_LCD_COLOR)
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 */
56 #define ROUNDOFFS (127*257)
58 /* Draw a partial YUV colour bitmap - taken from the Rockbox JPEG viewer */
59 static void 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)
63 fb_data *dst, *dst_end;
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;
70 /* clipping */
71 if (x < 0)
73 width += x;
74 src_x -= x;
75 x = 0;
77 if (y < 0)
79 height += y;
80 src_y -= y;
81 y = 0;
83 if (x + width > LCD_WIDTH)
84 width = LCD_WIDTH - x;
85 if (y + height > LCD_HEIGHT)
86 height = LCD_HEIGHT - y;
88 dst = rb->lcd_framebuffer + LCD_WIDTH * y + x;
89 dst_end = dst + LCD_WIDTH * height;
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;
100 if (CSUB_Y) /* colour */
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;
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;
118 y = *ysrc++;
119 red = RYFAC * y + rc;
120 green = GYFAC * y + gc;
121 blue = BYFAC * y + bc;
123 if ((unsigned)red > (RYFAC*255+ROUNDOFFS))
125 if (red < 0)
126 red = 0;
127 else
128 red = (RYFAC*255+ROUNDOFFS);
130 if ((unsigned)green > (GYFAC*255+ROUNDOFFS))
132 if (green < 0)
133 green = 0;
134 else
135 green = (GYFAC*255+ROUNDOFFS);
137 if ((unsigned)blue > (BYFAC*255+ROUNDOFFS))
139 if (blue < 0)
140 blue = 0;
141 else
142 blue = (BYFAC*255+ROUNDOFFS);
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
153 if (++xphase >= CSUB_X)
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;
163 while (dst_row < row_end);
165 else /* monochrome */
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
180 while (dst_row < row_end);
183 src_y++;
184 dst += LCD_WIDTH;
186 while (dst < dst_end);
188 #endif
190 void vo_draw_frame (uint8_t * const * buf)
192 #ifdef HAVE_LCD_COLOR
193 #ifdef SIMULATOR
194 yuv_bitmap_part(buf,0,0,image_width,
195 output_x,output_y,output_width,output_height);
196 rb->lcd_update_rect(output_x,output_y,output_width,output_height);
197 #else
198 rb->lcd_yuv_blit(buf,
199 0,0,image_width,
200 output_x,output_y,output_width,output_height);
201 #endif
202 #else
203 gray_ub_gray_bitmap_part(buf[0],0,0,image_width,
204 output_x,output_y,output_width,output_height);
205 #endif
208 #if LCD_WIDTH >= LCD_HEIGHT
209 #define SCREEN_WIDTH LCD_WIDTH
210 #define SCREEN_HEIGHT LCD_HEIGHT
211 #else /* Assume the screen is rotates on portraid LCDs */
212 #define SCREEN_WIDTH LCD_HEIGHT
213 #define SCREEN_HEIGHT LCD_WIDTH
214 #endif
216 void vo_setup(const mpeg2_sequence_t * sequence)
218 image_width=sequence->width;
219 image_height=sequence->height;
220 image_chroma_x=image_width/sequence->chroma_width;
221 image_chroma_y=image_height/sequence->chroma_height;
223 if (sequence->display_width >= SCREEN_WIDTH) {
224 output_width = SCREEN_WIDTH;
225 output_x = 0;
226 } else {
227 output_width = sequence->display_width;
228 output_x = (SCREEN_WIDTH-sequence->display_width)/2;
231 if (sequence->display_height >= SCREEN_HEIGHT) {
232 output_height = SCREEN_HEIGHT;
233 output_y = 0;
234 } else {
235 output_height = sequence->display_height;
236 output_y = (SCREEN_HEIGHT-sequence->display_height)/2;