summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/plugins/mpegplayer/video_out_rockbox.c284
1 files changed, 169 insertions, 115 deletions
diff --git a/apps/plugins/mpegplayer/video_out_rockbox.c b/apps/plugins/mpegplayer/video_out_rockbox.c
index e3f8ba0264..b55ca8c079 100644
--- a/apps/plugins/mpegplayer/video_out_rockbox.c
+++ b/apps/plugins/mpegplayer/video_out_rockbox.c
@@ -45,147 +45,197 @@ static int output_height;
45 45
46#if defined(SIMULATOR) && defined(HAVE_LCD_COLOR) 46#if defined(SIMULATOR) && defined(HAVE_LCD_COLOR)
47 47
48#define RYFAC (31*257) 48/**
49#define GYFAC (63*257) 49 * |R| |1.000000 -0.000001 1.402000| |Y'|
50#define BYFAC (31*257) 50 * |G| = |1.000000 -0.334136 -0.714136| |Pb|
51#define RVFAC 11170 /* 31 * 257 * 1.402 */ 51 * |B| |1.000000 1.772000 0.000000| |Pr|
52#define GVFAC (-11563) /* 63 * 257 * -0.714136 */ 52 * Scaled, normalized, rounded and tweaked to yield RGB 565:
53#define GUFAC (-5572) /* 63 * 257 * -0.344136 */ 53 * |R| |74 0 101| |Y' - 16| >> 9
54#define BUFAC 14118 /* 31 * 257 * 1.772 */ 54 * |G| = |74 -24 -51| |Cb - 128| >> 8
55 * |B| |74 128 0| |Cr - 128| >> 9
56 */
57#define YFAC (74)
58#define RVFAC (101)
59#define GUFAC (-24)
60#define GVFAC (-51)
61#define BUFAC (128)
55 62
56#define ROUNDOFFS (127*257) 63static inline int clamp(int val, int min, int max)
64{
65 if (val < min)
66 val = min;
67 else if (val > max)
68 val = max;
69 return val;
70}
57 71
58/* Draw a partial YUV colour bitmap - taken from the Rockbox JPEG viewer */ 72/* Draw a partial YUV colour bitmap - similiar behavior to lcd_yuv_blit
73 in the core */
59static void yuv_bitmap_part(unsigned char * const src[3], 74static void yuv_bitmap_part(unsigned char * const src[3],
60 int src_x, int src_y, int stride, 75 int src_x, int src_y, int stride,
61 int x, int y, int width, int height) 76 int x, int y, int width, int height)
62{ 77{
63 fb_data *dst, *dst_end; 78 const unsigned char *ysrc, *usrc, *vsrc;
79 fb_data *dst, *row_end;
80 off_t z;
64 81
65 /* nothing to draw? */ 82 /* width and height must be >= 2 and an even number */
66 if ((width <= 0) || (height <= 0) || (x >= LCD_WIDTH) || (y >= LCD_HEIGHT) 83 width &= ~1;
67 || (x + width <= 0) || (y + height <= 0)) 84 height >>= 1;
68 return;
69 85
70 /* clipping */ 86#if LCD_WIDTH >= LCD_HEIGHT
71 if (x < 0) 87 dst = rb->lcd_framebuffer + LCD_WIDTH * y + x;
72 { 88 row_end = dst + width;
73 width += x; 89#else
74 src_x -= x; 90 dst = rb->lcd_framebuffer + x * LCD_WIDTH + (LCD_WIDTH - y) - 1;
75 x = 0; 91 row_end = dst + LCD_WIDTH * width;
76 } 92#endif
77 if (y < 0) 93
78 { 94 z = stride * src_y;
79 height += y; 95 ysrc = src[0] + z + src_x;
80 src_y -= y; 96 usrc = src[1] + (z >> 2) + (src_x >> 1);
81 y = 0; 97 vsrc = src[2] + (usrc - src[1]);
82 } 98
83 if (x + width > LCD_WIDTH) 99 /* stride => amount to jump from end of last row to start of next */
84 width = LCD_WIDTH - x; 100 stride -= width;
85 if (y + height > LCD_HEIGHT)
86 height = LCD_HEIGHT - y;
87 101
88 dst = rb->lcd_framebuffer + LCD_WIDTH * y + x; 102 /* upsampling, YUV->RGB conversion and reduction to RGB565 in one go */
89 dst_end = dst + LCD_WIDTH * height;
90 103
91 do 104 do
92 { 105 {
93 fb_data *dst_row = dst; 106 do
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 { 107 {
102 /* upsampling, YUV->RGB conversion and reduction to RGB565 in one go */ 108 int y, cb, cr, rv, guv, bu, r, g, b;
103 const unsigned char *usrc = src[1] + (stride/CSUB_X) * (src_y/CSUB_Y) 109
104 + (src_x/CSUB_X); 110 y = YFAC*(*ysrc++ - 16);
105 const unsigned char *vsrc = src[2] + (stride/CSUB_X) * (src_y/CSUB_Y) 111 cb = *usrc++ - 128;
106 + (src_x/CSUB_X); 112 cr = *vsrc++ - 128;
107 int xphase = src_x % CSUB_X; 113
108 int rc, gc, bc; 114 rv = RVFAC*cr;
109 115 guv = GUFAC*cb + GVFAC*cr;
110 u = *usrc++ - 128; 116 bu = BUFAC*cb;
111 v = *vsrc++ - 128; 117
112 rc = RVFAC * v + ROUNDOFFS; 118 r = y + rv;
113 gc = GVFAC * v + GUFAC * u + ROUNDOFFS; 119 g = y + guv;
114 bc = BUFAC * u + ROUNDOFFS; 120 b = y + bu;
115 121
116 do 122 if ((unsigned)(r | g | b) > 63*256)
117 { 123 {
118 y = *ysrc++; 124 r = clamp(r, 0, 63*256);
119 red = RYFAC * y + rc; 125 g = clamp(g, 0, 63*256);
120 green = GYFAC * y + gc; 126 b = clamp(b, 0, 63*256);
121 blue = BYFAC * y + bc; 127 }
122 128
123 if ((unsigned)red > (RYFAC*255+ROUNDOFFS)) 129 *dst = LCD_RGBPACK_LCD(r >> 9, g >> 8, b >> 9);
124 { 130
125 if (red < 0) 131#if LCD_WIDTH >= LCD_HEIGHT
126 red = 0; 132 dst++;
127 else 133#else
128 red = (RYFAC*255+ROUNDOFFS); 134 dst += LCD_WIDTH;
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 135#endif
152 136
153 if (++xphase >= CSUB_X) 137 y = YFAC*(*ysrc++ - 16);
154 { 138 r = y + rv;
155 u = *usrc++ - 128; 139 g = y + guv;
156 v = *vsrc++ - 128; 140 b = y + bu;
157 rc = RVFAC * v + ROUNDOFFS; 141
158 gc = GVFAC * v + GUFAC * u + ROUNDOFFS; 142 if ((unsigned)(r | g | b) > 63*256)
159 bc = BUFAC * u + ROUNDOFFS; 143 {
160 xphase = 0; 144 r = clamp(r, 0, 63*256);
161 } 145 g = clamp(g, 0, 63*256);
146 b = clamp(b, 0, 63*256);
162 } 147 }
163 while (dst_row < row_end); 148
149 *dst = LCD_RGBPACK_LCD(r >> 9, g >> 8, b >> 9);
150
151#if LCD_WIDTH >= LCD_HEIGHT
152 dst++;
153#else
154 dst += LCD_WIDTH;
155#endif
164 } 156 }
165 else /* monochrome */ 157 while (dst < row_end);
158
159 ysrc += stride;
160 usrc -= width >> 1;
161 vsrc -= width >> 1;
162
163#if LCD_WIDTH >= LCD_HEIGHT
164 row_end += LCD_WIDTH;
165 dst += LCD_WIDTH - width;
166#else
167 row_end -= 1;
168 dst -= LCD_WIDTH*width + 1;
169#endif
170
171 do
166 { 172 {
167 do 173 int y, cb, cr, rv, guv, bu, r, g, b;
174
175 y = YFAC*(*ysrc++ - 16);
176 cb = *usrc++ - 128;
177 cr = *vsrc++ - 128;
178
179 rv = RVFAC*cr;
180 guv = GUFAC*cb + GVFAC*cr;
181 bu = BUFAC*cb;
182
183 r = y + rv;
184 g = y + guv;
185 b = y + bu;
186
187 if ((unsigned)(r | g | b) > 63*256)
168 { 188 {
169 y = *ysrc++; 189 r = clamp(r, 0, 63*256);
170 red = RYFAC * y + ROUNDOFFS; /* blue == red */ 190 g = clamp(g, 0, 63*256);
171 green = GYFAC * y + ROUNDOFFS; 191 b = clamp(b, 0, 63*256);
172 rbits = ((unsigned)red) >> 16; 192 }
173 gbits = ((unsigned)green) >> 16; 193
174#if LCD_PIXELFORMAT == RGB565 194 *dst = LCD_RGBPACK_LCD(r >> 9, g >> 8, b >> 9);
175 *dst_row++ = (rbits << 11) | (gbits << 5) | rbits; 195
176#elif LCD_PIXELFORMAT == RGB565SWAPPED 196#if LCD_WIDTH >= LCD_HEIGHT
177 *dst_row++ = swap16((rbits << 11) | (gbits << 5) | rbits); 197 dst++;
198#else
199 dst += LCD_WIDTH;
178#endif 200#endif
201
202 y = YFAC*(*ysrc++ - 16);
203 r = y + rv;
204 g = y + guv;
205 b = y + bu;
206
207 if ((unsigned)(r | g | b) > 63*256)
208 {
209 r = clamp(r, 0, 63*256);
210 g = clamp(g, 0, 63*256);
211 b = clamp(b, 0, 63*256);
179 } 212 }
180 while (dst_row < row_end); 213
214 *dst = LCD_RGBPACK_LCD(r >> 9, g >> 8, b >> 9);
215
216#if LCD_WIDTH >= LCD_HEIGHT
217 dst++;
218#else
219 dst += LCD_WIDTH;
220#endif
181 } 221 }
222 while (dst < row_end);
223
224 ysrc += stride;
225 usrc += stride >> 1;
226 vsrc += stride >> 1;
182 227
183 src_y++; 228#if LCD_WIDTH >= LCD_HEIGHT
184 dst += LCD_WIDTH; 229 row_end += LCD_WIDTH;
230 dst += LCD_WIDTH - width;
231#else
232 row_end -= 1;
233 dst -= LCD_WIDTH*width + 1;
234#endif
185 } 235 }
186 while (dst < dst_end); 236 while (--height > 0);
187} 237}
188#endif 238#endif /* defined(SIMULATOR) && defined(HAVE_LCD_COLOR) */
189 239
190void vo_draw_frame (uint8_t * const * buf) 240void vo_draw_frame (uint8_t * const * buf)
191{ 241{
@@ -193,8 +243,12 @@ void vo_draw_frame (uint8_t * const * buf)
193#ifdef SIMULATOR 243#ifdef SIMULATOR
194 yuv_bitmap_part(buf,0,0,image_width, 244 yuv_bitmap_part(buf,0,0,image_width,
195 output_x,output_y,output_width,output_height); 245 output_x,output_y,output_width,output_height);
246#if LCD_WIDTH >= LCD_HEIGHT
196 rb->lcd_update_rect(output_x,output_y,output_width,output_height); 247 rb->lcd_update_rect(output_x,output_y,output_width,output_height);
197#else 248#else
249 rb->lcd_update_rect(output_y,output_x,output_height,output_width);
250#endif
251#else
198 rb->lcd_yuv_blit(buf, 252 rb->lcd_yuv_blit(buf,
199 0,0,image_width, 253 0,0,image_width,
200 output_x,output_y,output_width,output_height); 254 output_x,output_y,output_width,output_height);