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"
29 extern struct plugin_api
* rb
;
32 #include "video_out.h"
37 static int image_width
;
38 static int image_height
;
39 static int image_chroma_x
;
40 static int image_chroma_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))
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
;
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
)
105 const unsigned char *vsrc
= src
[2] + (stride
/CSUB_X
) * (src_y
/CSUB_Y
)
107 int xphase
= src_x
% CSUB_X
;
112 rc
= RVFAC
* v
+ ROUNDOFFS
;
113 gc
= GVFAC
* v
+ GUFAC
* u
+ ROUNDOFFS
;
114 bc
= BUFAC
* u
+ ROUNDOFFS
;
119 red
= RYFAC
* y
+ rc
;
120 green
= GYFAC
* y
+ gc
;
121 blue
= BYFAC
* y
+ bc
;
123 if ((unsigned)red
> (RYFAC
*255+ROUNDOFFS
))
128 red
= (RYFAC
*255+ROUNDOFFS
);
130 if ((unsigned)green
> (GYFAC
*255+ROUNDOFFS
))
135 green
= (GYFAC
*255+ROUNDOFFS
);
137 if ((unsigned)blue
> (BYFAC
*255+ROUNDOFFS
))
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
);
153 if (++xphase
>= CSUB_X
)
157 rc
= RVFAC
* v
+ ROUNDOFFS
;
158 gc
= GVFAC
* v
+ GUFAC
* u
+ ROUNDOFFS
;
159 bc
= BUFAC
* u
+ ROUNDOFFS
;
163 while (dst_row
< row_end
);
165 else /* monochrome */
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
);
180 while (dst_row
< row_end
);
186 while (dst
< dst_end
);
190 void vo_draw_frame (uint8_t * const * buf
)
192 #ifdef HAVE_LCD_COLOR
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
);
198 rb
->lcd_yuv_blit(buf
,
200 output_x
,output_y
,output_width
,output_height
);
203 gray_ub_gray_bitmap_part(buf
[0],0,0,image_width
,
204 output_x
,output_y
,output_width
,output_height
);
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
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
;
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
;
235 output_height
= sequence
->display_height
;
236 output_y
= (SCREEN_HEIGHT
-sequence
->display_height
)/2;