summaryrefslogtreecommitdiff
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/multimedia/opieplayer2/yuv2rgb_arm2.c1
1 files changed, 1 insertions, 0 deletions
diff --git a/noncore/multimedia/opieplayer2/yuv2rgb_arm2.c b/noncore/multimedia/opieplayer2/yuv2rgb_arm2.c
index cbd32e8..91cd0b1 100644
--- a/noncore/multimedia/opieplayer2/yuv2rgb_arm2.c
+++ b/noncore/multimedia/opieplayer2/yuv2rgb_arm2.c
@@ -1,326 +1,327 @@
1/* 1/*
2 * yuv2rgb_arm2.c 2 * yuv2rgb_arm2.c
3 * Copyright (C) 2002 Frederic 'dilb' Boulay. 3 * Copyright (C) 2002 Frederic 'dilb' Boulay.
4 * All Rights Reserved. 4 * All Rights Reserved.
5 * 5 *
6 * Author: Frederic Boulay <dilb@handhelds.org> 6 * Author: Frederic Boulay <dilb@handhelds.org>
7 * 7 *
8 * you can redistribute this file and/or modify 8 * you can redistribute this file and/or modify
9 * it under the terms of the GNU General Public License (version 2) 9 * it under the terms of the GNU General Public License (version 2)
10 * as published by the Free Software Foundation. 10 * as published by the Free Software Foundation.
11 * 11 *
12 * This file is distributed in the hope that it will be useful, 12 * This file is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details. 15 * GNU General Public License for more details.
16 * 16 *
17 * You should have received a copy of the GNU General Public License 17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software 18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 * 20 *
21 * 21 *
22 * The function defined in this file, are derived from work done in the xine 22 * The function defined in this file, are derived from work done in the xine
23 * project. 23 * project.
24 * In order to improve performance, by strongly reducing memory bandwidth 24 * In order to improve performance, by strongly reducing memory bandwidth
25 * needed, the scaling functions are merged with the yuv2rgb function. 25 * needed, the scaling functions are merged with the yuv2rgb function.
26 */ 26 */
27 27
28#ifdef __arm__ 28#ifdef __arm__
29 29
30#include <stdio.h> 30#include <stdio.h>
31#include <stdlib.h> 31#include <stdlib.h>
32#include <string.h> 32#include <string.h>
33#include <inttypes.h> 33#include <inttypes.h>
34 34
35#include "yuv2rgb.h" 35#include "yuv2rgb.h"
36#include <xine/xineutils.h> 36#include <xine/xineutils.h>
37 37
38/* Prototypes of the "local" functions available here: */ 38/* Prototypes of the "local" functions available here: */
39/* first prototype, function called when no scaling is needed: */ 39/* first prototype, function called when no scaling is needed: */
40static void arm_rgb16_noscale(yuv2rgb_t*, uint8_t*, uint8_t*, uint8_t*, uint8_t*); 40static void arm_rgb16_noscale(yuv2rgb_t*, uint8_t*, uint8_t*, uint8_t*, uint8_t*);
41/* second prototype, function called when no horizontal scaling is needed: */ 41/* second prototype, function called when no horizontal scaling is needed: */
42static void arm_rgb16_step_dx_32768(yuv2rgb_t*, uint8_t*, uint8_t*, uint8_t*, uint8_t*); 42static void arm_rgb16_step_dx_32768(yuv2rgb_t*, uint8_t*, uint8_t*, uint8_t*, uint8_t*);
43/* third prototype, function called when scaling is needed for zooming in: */ 43/* third prototype, function called when scaling is needed for zooming in: */
44static void arm_rgb16_step_dx_inf_32768(yuv2rgb_t*, uint8_t*, uint8_t*, uint8_t*, uint8_t*); 44static void arm_rgb16_step_dx_inf_32768(yuv2rgb_t*, uint8_t*, uint8_t*, uint8_t*, uint8_t*);
45/* fourth prototype, function called when scaling is needed for zooming out (between 1x and 2x): */ 45/* fourth prototype, function called when scaling is needed for zooming out (between 1x and 2x): */
46static void arm_rgb16_step_dx_bet_32768_65536(yuv2rgb_t*, uint8_t*, uint8_t*, uint8_t*, uint8_t*); 46static void arm_rgb16_step_dx_bet_32768_65536(yuv2rgb_t*, uint8_t*, uint8_t*, uint8_t*, uint8_t*);
47/* fifth prototype, function called when scaling is needed for zooming out (greater than 2x): */ 47/* fifth prototype, function called when scaling is needed for zooming out (greater than 2x): */
48static void arm_rgb16_step_dx_sup_65536(yuv2rgb_t*, uint8_t*, uint8_t*, uint8_t*, uint8_t*); 48static void arm_rgb16_step_dx_sup_65536(yuv2rgb_t*, uint8_t*, uint8_t*, uint8_t*, uint8_t*);
49/* sixth prototype, function where the decision of the scaling function to use is made.*/ 49/* sixth prototype, function where the decision of the scaling function to use is made.*/
50static void arm_rgb16_2 (yuv2rgb_t*, uint8_t*, uint8_t*, uint8_t*, uint8_t*); 50static void arm_rgb16_2 (yuv2rgb_t*, uint8_t*, uint8_t*, uint8_t*, uint8_t*);
51 51
52 52
53 53
54 54
55/* extern function: */ 55/* extern function: */
56 56
57/* Function: */ 57/* Function: */
58void yuv2rgb_init_arm (yuv2rgb_factory_t *this) 58void yuv2rgb_init_arm (yuv2rgb_factory_t *this)
59/* This function initialise the member yuv2rgb_fun, if everything is right 59/* This function initialise the member yuv2rgb_fun, if everything is right
60the function optimised for the arm target should be used.*/ 60the function optimised for the arm target should be used.*/
61 { 61 {
62 if (this->swapped) 62 if (this->swapped)
63 return; /*no swapped pixel output upto now*/ 63 return; /*no swapped pixel output upto now*/
64 64
65 switch (this->mode) 65 switch (this->mode)
66 { 66 {
67 case MODE_16_RGB: 67 case MODE_16_RGB:
68 this->yuv2rgb_fun = arm_rgb16_2; 68 this->yuv2rgb_fun = arm_rgb16_2;
69 break; 69 break;
70 default: 70 default:
71 break;
71 } 72 }
72 } 73 }
73 74
74 75
75 76
76/* local functions: */ 77/* local functions: */
77 78
78/* Function: */ 79/* Function: */
79static void arm_rgb16_2 (yuv2rgb_t *this, uint8_t * _dst, uint8_t * _py, uint8_t * _pu, uint8_t * _pv) 80static void arm_rgb16_2 (yuv2rgb_t *this, uint8_t * _dst, uint8_t * _py, uint8_t * _pu, uint8_t * _pv)
80/* This function takes care of applying the right scaling conversion 81/* This function takes care of applying the right scaling conversion
81(yuv2rgb is included in each scaling function!)*/ 82(yuv2rgb is included in each scaling function!)*/
82 { 83 {
83 if (!this->do_scale) 84 if (!this->do_scale)
84 { 85 {
85 arm_rgb16_noscale(this, _dst, _py, _pu, _pv); 86 arm_rgb16_noscale(this, _dst, _py, _pu, _pv);
86 return; 87 return;
87 } 88 }
88 if (this->step_dx<32768) 89 if (this->step_dx<32768)
89 { 90 {
90 arm_rgb16_step_dx_inf_32768(this, _dst, _py, _pu, _pv); 91 arm_rgb16_step_dx_inf_32768(this, _dst, _py, _pu, _pv);
91 return; 92 return;
92 } 93 }
93 if (this->step_dx==32768) 94 if (this->step_dx==32768)
94 { 95 {
95 arm_rgb16_step_dx_32768(this, _dst, _py, _pu, _pv); 96 arm_rgb16_step_dx_32768(this, _dst, _py, _pu, _pv);
96 return; 97 return;
97 } 98 }
98 if (this->step_dx<65536) 99 if (this->step_dx<65536)
99 { 100 {
100 arm_rgb16_step_dx_bet_32768_65536(this, _dst, _py, _pu, _pv); 101 arm_rgb16_step_dx_bet_32768_65536(this, _dst, _py, _pu, _pv);
101 return; 102 return;
102 } 103 }
103 arm_rgb16_step_dx_sup_65536(this, _dst, _py, _pu, _pv); 104 arm_rgb16_step_dx_sup_65536(this, _dst, _py, _pu, _pv);
104 return; 105 return;
105 } 106 }
106 107
107 108
108/* Function: */ 109/* Function: */
109static void arm_rgb16_noscale(yuv2rgb_t *this, uint8_t * _dst, uint8_t * _py, uint8_t * _pu, uint8_t * _pv) 110static void arm_rgb16_noscale(yuv2rgb_t *this, uint8_t * _dst, uint8_t * _py, uint8_t * _pu, uint8_t * _pv)
110/* This function is called when the source and the destination pictures have the same size. 111/* This function is called when the source and the destination pictures have the same size.
111 In this case, scaling part is not needed. 112 In this case, scaling part is not needed.
112 (This code is probably far from being optimised, in particular, the asm 113 (This code is probably far from being optimised, in particular, the asm
113 generated is not the most efficient, a pure asm version will probably 114 generated is not the most efficient, a pure asm version will probably
114 emerge sooner or later). But at least, this version is faster than what 115 emerge sooner or later). But at least, this version is faster than what
115 was used before.*/ 116 was used before.*/
116 { 117 {
117 int height; 118 int height;
118 119
119 height=this->dest_height; 120 height=this->dest_height;
120 121
121 while (height>0) 122 while (height>0)
122 { 123 {
123 uint16_t *r, *g, *b; 124 uint16_t *r, *g, *b;
124 uint8_t *py, *py2, *pu, *pv; 125 uint8_t *py, *py2, *pu, *pv;
125 uint16_t *dst, *dst2; 126 uint16_t *dst, *dst2;
126 int width; 127 int width;
127 register uint8_t p1y, p1u, p1v; 128 register uint8_t p1y, p1u, p1v;
128 129
129 height-=2; 130 height-=2;
130 width=this->dest_width; 131 width=this->dest_width;
131 dst = _dst; 132 dst = _dst;
132 dst2 = _dst + this->rgb_stride; 133 dst2 = _dst + this->rgb_stride;
133 py = _py; 134 py = _py;
134 py2 = _py + this->y_stride; 135 py2 = _py + this->y_stride;
135 pu = _pu; 136 pu = _pu;
136 pv = _pv; 137 pv = _pv;
137 138
138 while (width>0) 139 while (width>0)
139 { 140 {
140 width-=2; 141 width-=2;
141 p1y=*py++; 142 p1y=*py++;
142 p1u=*pu++; 143 p1u=*pu++;
143 p1v=*pv++; 144 p1v=*pv++;
144 145
145 r = this->table_rV[p1v]; 146 r = this->table_rV[p1v];
146 g = (void *) (((uint8_t *)this->table_gU[p1u]) + this->table_gV[p1v]); 147 g = (void *) (((uint8_t *)this->table_gU[p1u]) + this->table_gV[p1v]);
147 b = this->table_bU[p1u]; 148 b = this->table_bU[p1u];
148 149
149 *dst++ = r[p1y] + g[p1y] + b[p1y]; 150 *dst++ = r[p1y] + g[p1y] + b[p1y];
150 p1y=*py++; 151 p1y=*py++;
151 *dst++ = r[p1y] + g[p1y] + b[p1y]; 152 *dst++ = r[p1y] + g[p1y] + b[p1y];
152 153
153 p1y=*py2++; 154 p1y=*py2++;
154 155
155 *dst2++ = r[p1y] + g[p1y] + b[p1y]; 156 *dst2++ = r[p1y] + g[p1y] + b[p1y];
156 p1y=*py2++; 157 p1y=*py2++;
157 *dst2++ = r[p1y] + g[p1y] + b[p1y]; 158 *dst2++ = r[p1y] + g[p1y] + b[p1y];
158 } 159 }
159 _dst += (this->rgb_stride)<<1; 160 _dst += (this->rgb_stride)<<1;
160 _py += (this->y_stride)<<1; 161 _py += (this->y_stride)<<1;
161 _pu += this->uv_stride; 162 _pu += this->uv_stride;
162 _pv += this->uv_stride; 163 _pv += this->uv_stride;
163 } 164 }
164 } 165 }
165 166
166 167
167/* Function: */ 168/* Function: */
168static void arm_rgb16_step_dx_inf_32768(yuv2rgb_t *this, uint8_t * _dst, uint8_t * _py, uint8_t * _pu, uint8_t * _pv) 169static void arm_rgb16_step_dx_inf_32768(yuv2rgb_t *this, uint8_t * _dst, uint8_t * _py, uint8_t * _pu, uint8_t * _pv)
169/* This function is called when the destination picture is bigger than the size 170/* This function is called when the destination picture is bigger than the size
170 of the source picture. 171 of the source picture.
171*/ 172*/
172 { 173 {
173 int recal_uv, height; /* Note about recal_uv: bit0 is for 174 int recal_uv, height; /* Note about recal_uv: bit0 is for
174applying scale on u and v, bit1 is for increments of u and v pointers.*/ 175applying scale on u and v, bit1 is for increments of u and v pointers.*/
175 int dy; 176 int dy;
176 177
177 dy = 0; 178 dy = 0;
178 height = this->dest_height; 179 height = this->dest_height;
179 recal_uv=1; // 1 for evaluation of scale_line, needed the first time 180 recal_uv=1; // 1 for evaluation of scale_line, needed the first time
180 181
181 while(1) 182 while(1)
182 { 183 {
183 register int dxy; 184 register int dxy;
184 register int dxuv; 185 register int dxuv;
185 register uint8_t p1y, p2y; 186 register uint8_t p1y, p2y;
186 uint8_t dest1y, dest2y; 187 uint8_t dest1y, dest2y;
187 register uint8_t p1u, p2u; 188 register uint8_t p1u, p2u;
188 register uint8_t p1v, p2v; 189 register uint8_t p1v, p2v;
189 uint8_t dest1u; 190 uint8_t dest1u;
190 uint8_t dest1v; 191 uint8_t dest1v;
191 int width; 192 int width;
192 uint8_t *u_buffer; 193 uint8_t *u_buffer;
193 uint8_t *v_buffer; 194 uint8_t *v_buffer;
194 uint16_t *r, *g, *b; 195 uint16_t *r, *g, *b;
195 uint8_t *py, *pu, *pv; 196 uint8_t *py, *pu, *pv;
196 uint16_t *dst; 197 uint16_t *dst;
197 198
198 dxy = 0; 199 dxy = 0;
199 dxuv = 0; 200 dxuv = 0;
200 width = this->dest_width; 201 width = this->dest_width;
201 u_buffer=this->u_buffer; 202 u_buffer=this->u_buffer;
202 v_buffer=this->v_buffer; 203 v_buffer=this->v_buffer;
203 dst = (uint16_t*)_dst; 204 dst = (uint16_t*)_dst;
204 py = _py; 205 py = _py;
205 pu = _pu; 206 pu = _pu;
206 pv = _pv; 207 pv = _pv;
207 208
208 //proceed with line scaling/conversion 209 //proceed with line scaling/conversion
209 if ((recal_uv&1)!=0) 210 if ((recal_uv&1)!=0)
210 { 211 {
211 recal_uv^=1; //reset bit0. 212 recal_uv^=1; //reset bit0.
212 // init values: 213 // init values:
213 p1u = *pu++; 214 p1u = *pu++;
214 p2u = *pu++; 215 p2u = *pu++;
215 p1v = *pv++; 216 p1v = *pv++;
216 p2v = *pv++; 217 p2v = *pv++;
217 p1y = *py++; 218 p1y = *py++;
218 p2y = *py++; 219 p2y = *py++;
219 220
220 //width loop (compute all data for a line). 221 //width loop (compute all data for a line).
221 while (width>0) 222 while (width>0)
222 { 223 {
223 // proceed with u and v first (ok, and y too finally :)) [scaling part]: 224 // proceed with u and v first (ok, and y too finally :)) [scaling part]:
224 // evaluate 1u, 1v, and 2y 225 // evaluate 1u, 1v, and 2y
225 //block1_uvy 226 //block1_uvy
226 dest1u=p1u + ((dxuv*(p2u-p1u))>>15); 227 dest1u=p1u + ((dxuv*(p2u-p1u))>>15);
227 dest1v=p1v + ((dxuv*(p2v-p1v))>>15); 228 dest1v=p1v + ((dxuv*(p2v-p1v))>>15);
228 // as u and v are evaluated, better save them now 229 // as u and v are evaluated, better save them now
229 *u_buffer++ = (uint8_t)dest1u; 230 *u_buffer++ = (uint8_t)dest1u;
230 *v_buffer++ = (uint8_t)dest1v; 231 *v_buffer++ = (uint8_t)dest1v;
231 232
232 dest1y=p1y + ((dxy*(p2y-p1y))>>15); 233 dest1y=p1y + ((dxy*(p2y-p1y))>>15);
233 234
234 dxuv += this->step_dx; 235 dxuv += this->step_dx;
235 dxy += this->step_dx; 236 dxy += this->step_dx;
236 if (dxuv > 32768) 237 if (dxuv > 32768)
237 { 238 {
238 dxuv -= 32768; 239 dxuv -= 32768;
239 p1u = p2u; 240 p1u = p2u;
240 p2u = *pu++; //idee pour asm, cf cas then, un merge est possible!!! 241 p2u = *pu++; //idee pour asm, cf cas then, un merge est possible!!!
241 p1v = p2v; 242 p1v = p2v;
242 p2v = *pv++; 243 p2v = *pv++;
243 } 244 }
244 if (dxy > 32768) 245 if (dxy > 32768)
245 { 246 {
246 dxy -= 32768; 247 dxy -= 32768;
247 p1y = p2y; 248 p1y = p2y;
248 p2y = *py++; 249 p2y = *py++;
249 } 250 }
250 //end block1_uvy 251 //end block1_uvy
251 252
252 //block2_y 253 //block2_y
253 dest2y=p1y + ((dxy*(p2y-p1y))>>15); 254 dest2y=p1y + ((dxy*(p2y-p1y))>>15);
254 255
255 dxy += this->step_dx; 256 dxy += this->step_dx;
256 if (dxy > 32768) 257 if (dxy > 32768)
257 { 258 {
258 dxy -= 32768; 259 dxy -= 32768;
259 p1y = p2y; 260 p1y = p2y;
260 p2y = *py++; // idee pour asm, cf cas then, un merge est possible!!! 261 p2y = *py++; // idee pour asm, cf cas then, un merge est possible!!!
261 } 262 }
262 //end block2_y 263 //end block2_y
263 264
264 // proceed now with YUV2RGB [conversion part]: 265 // proceed now with YUV2RGB [conversion part]:
265 // u and v are currently in dest1u and dest1v 266 // u and v are currently in dest1u and dest1v
266 // the 2 y are in dest1y and dest2y. 267 // the 2 y are in dest1y and dest2y.
267 // RGB(0),DST1(0), RGB(1), DST1(1) 268 // RGB(0),DST1(0), RGB(1), DST1(1)
268 r = this->table_rV[dest1v]; 269 r = this->table_rV[dest1v];
269 g = (void *) (((uint8_t *)this->table_gU[dest1u]) + this->table_gV[dest1v]); 270 g = (void *) (((uint8_t *)this->table_gU[dest1u]) + this->table_gV[dest1v]);
270 b = this->table_bU[dest1u]; 271 b = this->table_bU[dest1u];
271 272
272 *dst++ = r[dest1y] + g[dest1y] + b[dest1y]; 273 *dst++ = r[dest1y] + g[dest1y] + b[dest1y];
273 *dst++ = r[dest2y] + g[dest2y] + b[dest2y]; 274 *dst++ = r[dest2y] + g[dest2y] + b[dest2y];
274 275
275 width -=2; 276 width -=2;
276 } 277 }
277 } 278 }
278 else 279 else
279 { 280 {
280 // this case is simple, u and v are already evaluated, 281 // this case is simple, u and v are already evaluated,
281 // Note pour moi: r, g et b pourraient etre reutilises!! 282 // Note pour moi: r, g et b pourraient etre reutilises!!
282 283
283 // init values: 284 // init values:
284 p1y = *py++; 285 p1y = *py++;
285 p2y = *py++; 286 p2y = *py++;
286 287
287 //width loop (compute all data for a line). 288 //width loop (compute all data for a line).
288 while (width>0) 289 while (width>0)
289 { 290 {
290 // proceed with y [scaling part]: 291 // proceed with y [scaling part]:
291 // evaluate 2y 292 // evaluate 2y
292 //block1_y 293 //block1_y
293 dest1y=p1y + ((dxy*(p2y-p1y))>>15); 294 dest1y=p1y + ((dxy*(p2y-p1y))>>15);
294 295
295 dxy += this->step_dx; 296 dxy += this->step_dx;
296 if (dxy > 32768) 297 if (dxy > 32768)
297 { 298 {
298 dxy -= 32768; 299 dxy -= 32768;
299 p1y = p2y; 300 p1y = p2y;
300 p2y = *py++; 301 p2y = *py++;
301 } 302 }
302 //end block1_uvy 303 //end block1_uvy
303 304
304 //block2_y 305 //block2_y
305 dest2y=p1y + ((dxy*(p2y-p1y))>>15); 306 dest2y=p1y + ((dxy*(p2y-p1y))>>15);
306 307
307 dxy += this->step_dx; 308 dxy += this->step_dx;
308 if (dxy > 32768) 309 if (dxy > 32768)
309 { 310 {
310 dxy -= 32768; 311 dxy -= 32768;
311 p1y = p2y; 312 p1y = p2y;
312 p2y = *py++; // idee pour asm, cf cas then, un merge est possible!!! 313 p2y = *py++; // idee pour asm, cf cas then, un merge est possible!!!
313 } 314 }
314 //end block2_y 315 //end block2_y
315 316
316 // proceed now with YUV2RGB [conversion part]: 317 // proceed now with YUV2RGB [conversion part]:
317 // u and v are currently in dest1u and dest1v 318 // u and v are currently in dest1u and dest1v
318 // the 2 y are in dest1y and dest2y. 319 // the 2 y are in dest1y and dest2y.
319 // RGB(0),DST1(0) 320 // RGB(0),DST1(0)
320 dest1u=*u_buffer++; 321 dest1u=*u_buffer++;
321 dest1v=*v_buffer++; 322 dest1v=*v_buffer++;
322 r = this->table_rV[dest1v]; 323 r = this->table_rV[dest1v];
323 g = (void *) (((uint8_t *)this->table_gU[dest1u]) + this->table_gV[dest1v]); 324 g = (void *) (((uint8_t *)this->table_gU[dest1u]) + this->table_gV[dest1v]);
324 b = this->table_bU[dest1u]; 325 b = this->table_bU[dest1u];
325 326
326 *dst++ = r[dest1y] + g[dest1y] + b[dest1y]; 327 *dst++ = r[dest1y] + g[dest1y] + b[dest1y];