29042
|
1 /*
|
|
2 * Copyright (C) 2007 Marc Hoffman <marc.hoffman@analog.com>
|
|
3 * April 20, 2007
|
|
4 *
|
|
5 * Blackfin video color space converter operations
|
|
6 * convert I420 YV12 to RGB in various formats
|
|
7 *
|
|
8 * This file is part of FFmpeg.
|
|
9 *
|
|
10 * FFmpeg is free software; you can redistribute it and/or
|
|
11 * modify it under the terms of the GNU Lesser General Public
|
|
12 * License as published by the Free Software Foundation; either
|
|
13 * version 2.1 of the License, or (at your option) any later version.
|
|
14 *
|
|
15 * FFmpeg is distributed in the hope that it will be useful,
|
|
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
18 * Lesser General Public License for more details.
|
|
19 *
|
|
20 * You should have received a copy of the GNU Lesser General Public
|
|
21 * License along with FFmpeg; if not, write to the Free Software
|
|
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
23 */
|
|
24
|
|
25
|
|
26 /*
|
|
27 YUV420 to RGB565 conversion. This routine takes a YUV 420 planar macroblock
|
|
28 and converts it to RGB565. R:5 bits, G:6 bits, B:5 bits.. packed into shorts.
|
|
29
|
|
30
|
|
31 The following calculation is used for the conversion:
|
|
32
|
|
33 r = clipz((y-oy)*cy + crv*(v-128))
|
|
34 g = clipz((y-oy)*cy + cgv*(v-128) + cgu*(u-128))
|
|
35 b = clipz((y-oy)*cy + cbu*(u-128))
|
|
36
|
|
37 y,u,v are prescaled by a factor of 4 i.e. left-shifted to gain precision.
|
|
38
|
|
39
|
|
40 New factorization to eliminate the truncation error which was
|
|
41 occurring due to the byteop3p.
|
|
42
|
|
43
|
|
44 1) Use the bytop16m to subtract quad bytes we use this in U8 this
|
|
45 then so the offsets need to be renormalized to 8bits.
|
|
46
|
|
47 2) Scale operands up by a factor of 4 not 8 because Blackfin
|
|
48 multiplies include a shift.
|
|
49
|
|
50 3) Compute into the accumulators cy*yx0, cy*yx1.
|
|
51
|
|
52 4) Compute each of the linear equations:
|
|
53 r = clipz((y - oy) * cy + crv * (v - 128))
|
|
54
|
|
55 g = clipz((y - oy) * cy + cgv * (v - 128) + cgu * (u - 128))
|
|
56
|
|
57 b = clipz((y - oy) * cy + cbu * (u - 128))
|
|
58
|
|
59 Reuse of the accumulators requires that we actually multiply
|
|
60 twice once with addition and the second time with a subtraction.
|
|
61
|
|
62 Because of this we need to compute the equations in the order R B
|
|
63 then G saving the writes for B in the case of 24/32 bit color
|
|
64 formats.
|
|
65
|
|
66 API: yuv2rgb_kind (uint8_t *Y, uint8_t *U, uint8_t *V, int *out,
|
|
67 int dW, uint32_t *coeffs);
|
|
68
|
|
69 A B
|
|
70 --- ---
|
|
71 i2 = cb i3 = cr
|
|
72 i1 = coeff i0 = y
|
|
73
|
|
74 Where coeffs have the following layout in memory.
|
|
75
|
|
76 uint32_t oy,oc,zero,cy,crv,rmask,cbu,bmask,cgu,cgv;
|
|
77
|
|
78 coeffs is a pointer to oy.
|
|
79
|
|
80 The {rgb} masks are only utilized by the 565 packing algorithm. Note the data
|
|
81 replication is used to simplify the internal algorithms for the dual Mac
|
|
82 architecture of BlackFin.
|
|
83
|
|
84 All routines are exported with _ff_bfin_ as a symbol prefix.
|
|
85
|
|
86 Rough performance gain compared against -O3:
|
|
87
|
|
88 2779809/1484290 187.28%
|
|
89
|
|
90 which translates to ~33c/pel to ~57c/pel for the reference vs 17.5
|
|
91 c/pel for the optimized implementations. Not sure why there is such a
|
|
92 huge variation on the reference codes on Blackfin I guess it must have
|
|
93 to do with the memory system.
|
|
94 */
|
|
95
|
|
96 #define mL3 .text
|
30430
|
97 #if defined(__FDPIC__) && CONFIG_SRAM
|
29042
|
98 #define mL1 .l1.text
|
|
99 #else
|
|
100 #define mL1 mL3
|
|
101 #endif
|
|
102 #define MEM mL1
|
|
103
|
|
104 #define DEFUN(fname,where,interface) \
|
|
105 .section where; \
|
|
106 .global _ff_bfin_ ## fname; \
|
|
107 .type _ff_bfin_ ## fname, STT_FUNC; \
|
|
108 .align 8; \
|
|
109 _ff_bfin_ ## fname
|
|
110
|
|
111 #define DEFUN_END(fname) \
|
|
112 .size _ff_bfin_ ## fname, . - _ff_bfin_ ## fname
|
|
113
|
|
114
|
|
115 .text
|
|
116
|
|
117 #define COEFF_LEN 11*4
|
|
118 #define COEFF_REL_CY_OFF 4*4
|
|
119
|
|
120 #define ARG_OUT 20
|
|
121 #define ARG_W 24
|
|
122 #define ARG_COEFF 28
|
|
123
|
|
124 DEFUN(yuv2rgb565_line,MEM,
|
|
125 (uint8_t *Y, uint8_t *U, uint8_t *V, int *out, int dW, uint32_t *coeffs)):
|
|
126 link 0;
|
|
127 [--sp] = (r7:4);
|
|
128 p1 = [fp+ARG_OUT];
|
|
129 r3 = [fp+ARG_W];
|
|
130
|
|
131 i0 = r0;
|
|
132 i2 = r1;
|
|
133 i3 = r2;
|
|
134
|
|
135 r0 = [fp+ARG_COEFF];
|
|
136 i1 = r0;
|
|
137 b1 = i1;
|
|
138 l1 = COEFF_LEN;
|
|
139 m0 = COEFF_REL_CY_OFF;
|
|
140 p0 = r3;
|
|
141
|
|
142 r0 = [i0++]; // 2Y
|
|
143 r1.l = w[i2++]; // 2u
|
|
144 r1.h = w[i3++]; // 2v
|
|
145 p0 = p0>>2;
|
|
146
|
|
147 lsetup (.L0565, .L1565) lc0 = p0;
|
|
148
|
|
149 /*
|
|
150 uint32_t oy,oc,zero,cy,crv,rmask,cbu,bmask,cgu,cgv
|
|
151 r0 -- used to load 4ys
|
|
152 r1 -- used to load 2us,2vs
|
|
153 r4 -- y3,y2
|
|
154 r5 -- y1,y0
|
|
155 r6 -- u1,u0
|
|
156 r7 -- v1,v0
|
|
157 */
|
|
158 r2=[i1++]; // oy
|
|
159 .L0565:
|
|
160 /*
|
|
161 rrrrrrrr gggggggg bbbbbbbb
|
|
162 5432109876543210
|
|
163 bbbbb >>3
|
|
164 gggggggg <<3
|
|
165 rrrrrrrr <<8
|
|
166 rrrrrggggggbbbbb
|
|
167 */
|
|
168 (r4,r5) = byteop16m (r1:0, r3:2) || r3=[i1++]; // oc
|
|
169 (r7,r6) = byteop16m (r1:0, r3:2) (r);
|
|
170 r5 = r5 << 2 (v); // y1,y0
|
|
171 r4 = r4 << 2 (v); // y3,y2
|
|
172 r6 = r6 << 2 (v) || r0=[i1++]; // u1,u0, r0=zero
|
|
173 r7 = r7 << 2 (v) || r1=[i1++]; // v1,v0 r1=cy
|
|
174 /* Y' = y*cy */
|
|
175 a1 = r1.h*r5.h, a0 = r1.l*r5.l || r1=[i1++]; // crv
|
|
176
|
|
177 /* R = Y+ crv*(Cr-128) */
|
|
178 r2.h = (a1 += r1.h*r7.l), r2.l = (a0 += r1.l*r7.l);
|
|
179 a1 -= r1.h*r7.l, a0 -= r1.l*r7.l || r5=[i1++]; // rmask
|
|
180 r2 = byteop3p(r3:2, r1:0)(LO) || r1=[i1++]; // cbu
|
|
181 r2 = r2 >> 3 (v);
|
|
182 r3 = r2 & r5;
|
|
183
|
|
184 /* B = Y+ cbu*(Cb-128) */
|
|
185 r2.h = (a1 += r1.h*r6.l), r2.l = (a0 += r1.l*r6.l);
|
|
186 a1 -= r1.h*r6.l, a0 -= r1.l*r6.l || r5=[i1++]; // bmask
|
|
187 r2 = byteop3p(r3:2, r1:0)(LO) || r1=[i1++]; // cgu
|
|
188 r2 = r2 << 8 (v);
|
|
189 r2 = r2 & r5;
|
|
190 r3 = r3 | r2;
|
|
191
|
|
192 /* G = Y+ cgu*(Cb-128)+cgv*(Cr-128) */
|
|
193 a1 += r1.h*r6.l, a0 += r1.l*r6.l || r1=[i1++]; // cgv
|
|
194 r2.h = (a1 += r1.h*r7.l), r2.l = (a0 += r1.l*r7.l);
|
|
195 r2 = byteop3p(r3:2, r1:0)(LO) || r5=[i1++m0]; // gmask
|
|
196 r2 = r2 << 3 (v);
|
|
197 r2 = r2 & r5;
|
|
198 r3 = r3 | r2;
|
|
199 [p1++]=r3 || r1=[i1++]; // cy
|
|
200
|
|
201 /* Y' = y*cy */
|
|
202
|
|
203 a1 = r1.h*r4.h, a0 = r1.l*r4.l || r1=[i1++]; // crv
|
|
204
|
|
205 /* R = Y+ crv*(Cr-128) */
|
|
206 r2.h = (a1 += r1.h*r7.h), r2.l = (a0 += r1.l*r7.h);
|
|
207 a1 -= r1.h*r7.h, a0 -= r1.l*r7.h || r5=[i1++]; // rmask
|
|
208 r2 = byteop3p(r3:2, r1:0)(LO) || r1=[i1++]; // cbu
|
|
209 r2 = r2 >> 3 (v);
|
|
210 r3 = r2 & r5;
|
|
211
|
|
212 /* B = Y+ cbu*(Cb-128) */
|
|
213 r2.h = (a1 += r1.h*r6.h), r2.l = (a0 += r1.l*r6.h);
|
|
214 a1 -= r1.h*r6.h, a0 -= r1.l*r6.h || r5=[i1++]; // bmask
|
|
215 r2 = byteop3p(r3:2, r1:0)(LO) || r1=[i1++]; // cgu
|
|
216 r2 = r2 << 8 (v);
|
|
217 r2 = r2 & r5;
|
|
218 r3 = r3 | r2;
|
|
219
|
|
220 /* G = Y+ cgu*(Cb-128)+cgv*(Cr-128) */
|
|
221 a1 += r1.h*r6.h, a0 += r1.l*r6.h || r1=[i1++]; // cgv
|
|
222 r2.h = (a1 += r1.h*r7.h), r2.l = (a0 += r1.l*r7.h) || r5=[i1++]; // gmask
|
|
223 r2 = byteop3p(r3:2, r1:0)(LO) || r0 = [i0++]; // 2Y
|
|
224 r2 = r2 << 3 (v) || r1.l = w[i2++]; // 2u
|
|
225 r2 = r2 & r5;
|
|
226 r3 = r3 | r2;
|
|
227 [p1++]=r3 || r1.h = w[i3++]; // 2v
|
|
228 .L1565: r2=[i1++]; // oy
|
|
229
|
|
230 l1 = 0;
|
|
231
|
|
232 (r7:4) = [sp++];
|
|
233 unlink;
|
|
234 rts;
|
|
235 DEFUN_END(yuv2rgb565_line)
|
|
236
|
|
237 DEFUN(yuv2rgb555_line,MEM,
|
|
238 (uint8_t *Y, uint8_t *U, uint8_t *V, int *out, int dW, uint32_t *coeffs)):
|
|
239 link 0;
|
|
240 [--sp] = (r7:4);
|
|
241 p1 = [fp+ARG_OUT];
|
|
242 r3 = [fp+ARG_W];
|
|
243
|
|
244 i0 = r0;
|
|
245 i2 = r1;
|
|
246 i3 = r2;
|
|
247
|
|
248 r0 = [fp+ARG_COEFF];
|
|
249 i1 = r0;
|
|
250 b1 = i1;
|
|
251 l1 = COEFF_LEN;
|
|
252 m0 = COEFF_REL_CY_OFF;
|
|
253 p0 = r3;
|
|
254
|
|
255 r0 = [i0++]; // 2Y
|
|
256 r1.l = w[i2++]; // 2u
|
|
257 r1.h = w[i3++]; // 2v
|
|
258 p0 = p0>>2;
|
|
259
|
|
260 lsetup (.L0555, .L1555) lc0 = p0;
|
|
261
|
|
262 /*
|
|
263 uint32_t oy,oc,zero,cy,crv,rmask,cbu,bmask,cgu,cgv
|
|
264 r0 -- used to load 4ys
|
|
265 r1 -- used to load 2us,2vs
|
|
266 r4 -- y3,y2
|
|
267 r5 -- y1,y0
|
|
268 r6 -- u1,u0
|
|
269 r7 -- v1,v0
|
|
270 */
|
|
271 r2=[i1++]; // oy
|
|
272 .L0555:
|
|
273 /*
|
|
274 rrrrrrrr gggggggg bbbbbbbb
|
|
275 5432109876543210
|
|
276 bbbbb >>3
|
|
277 gggggggg <<2
|
|
278 rrrrrrrr <<7
|
|
279 xrrrrrgggggbbbbb
|
|
280 */
|
|
281
|
|
282 (r4,r5) = byteop16m (r1:0, r3:2) || r3=[i1++]; // oc
|
|
283 (r7,r6) = byteop16m (r1:0, r3:2) (r);
|
|
284 r5 = r5 << 2 (v); // y1,y0
|
|
285 r4 = r4 << 2 (v); // y3,y2
|
|
286 r6 = r6 << 2 (v) || r0=[i1++]; // u1,u0, r0=zero
|
|
287 r7 = r7 << 2 (v) || r1=[i1++]; // v1,v0 r1=cy
|
|
288 /* Y' = y*cy */
|
|
289 a1 = r1.h*r5.h, a0 = r1.l*r5.l || r1=[i1++]; // crv
|
|
290
|
|
291 /* R = Y+ crv*(Cr-128) */
|
|
292 r2.h = (a1 += r1.h*r7.l), r2.l = (a0 += r1.l*r7.l);
|
|
293 a1 -= r1.h*r7.l, a0 -= r1.l*r7.l || r5=[i1++]; // rmask
|
|
294 r2 = byteop3p(r3:2, r1:0)(LO) || r1=[i1++]; // cbu
|
|
295 r2 = r2 >> 3 (v);
|
|
296 r3 = r2 & r5;
|
|
297
|
|
298 /* B = Y+ cbu*(Cb-128) */
|
|
299 r2.h = (a1 += r1.h*r6.l), r2.l = (a0 += r1.l*r6.l);
|
|
300 a1 -= r1.h*r6.l, a0 -= r1.l*r6.l || r5=[i1++]; // bmask
|
|
301 r2 = byteop3p(r3:2, r1:0)(LO) || r1=[i1++]; // cgu
|
|
302 r2 = r2 << 7 (v);
|
|
303 r2 = r2 & r5;
|
|
304 r3 = r3 | r2;
|
|
305
|
|
306 /* G = Y+ cgu*(Cb-128)+cgv*(Cr-128) */
|
|
307 a1 += r1.h*r6.l, a0 += r1.l*r6.l || r1=[i1++]; // cgv
|
|
308 r2.h = (a1 += r1.h*r7.l), r2.l = (a0 += r1.l*r7.l);
|
|
309 r2 = byteop3p(r3:2, r1:0)(LO) || r5=[i1++m0]; // gmask
|
|
310 r2 = r2 << 2 (v);
|
|
311 r2 = r2 & r5;
|
|
312 r3 = r3 | r2;
|
|
313 [p1++]=r3 || r1=[i1++]; // cy
|
|
314
|
|
315 /* Y' = y*cy */
|
|
316
|
|
317 a1 = r1.h*r4.h, a0 = r1.l*r4.l || r1=[i1++]; // crv
|
|
318
|
|
319 /* R = Y+ crv*(Cr-128) */
|
|
320 r2.h = (a1 += r1.h*r7.h), r2.l = (a0 += r1.l*r7.h);
|
|
321 a1 -= r1.h*r7.h, a0 -= r1.l*r7.h || r5=[i1++]; // rmask
|
|
322 r2 = byteop3p(r3:2, r1:0)(LO) || r1=[i1++]; // cbu
|
|
323 r2 = r2 >> 3 (v);
|
|
324 r3 = r2 & r5;
|
|
325
|
|
326 /* B = Y+ cbu*(Cb-128) */
|
|
327 r2.h = (a1 += r1.h*r6.h), r2.l = (a0 += r1.l*r6.h);
|
|
328 a1 -= r1.h*r6.h, a0 -= r1.l*r6.h || r5=[i1++]; // bmask
|
|
329 r2 = byteop3p(r3:2, r1:0)(LO) || r1=[i1++]; // cgu
|
|
330 r2 = r2 << 7 (v);
|
|
331 r2 = r2 & r5;
|
|
332 r3 = r3 | r2;
|
|
333
|
|
334 /* G = Y+ cgu*(Cb-128)+cgv*(Cr-128) */
|
|
335 a1 += r1.h*r6.h, a0 += r1.l*r6.h || r1=[i1++]; // cgv
|
|
336 r2.h = (a1 += r1.h*r7.h), r2.l = (a0 += r1.l*r7.h) || r5=[i1++]; // gmask
|
|
337 r2 = byteop3p(r3:2, r1:0)(LO) || r0=[i0++]; // 4Y
|
|
338 r2 = r2 << 2 (v) || r1.l=w[i2++]; // 2u
|
|
339 r2 = r2 & r5;
|
|
340 r3 = r3 | r2;
|
|
341 [p1++]=r3 || r1.h=w[i3++]; // 2v
|
|
342
|
|
343 .L1555: r2=[i1++]; // oy
|
|
344
|
|
345 l1 = 0;
|
|
346
|
|
347 (r7:4) = [sp++];
|
|
348 unlink;
|
|
349 rts;
|
|
350 DEFUN_END(yuv2rgb555_line)
|
|
351
|
|
352 DEFUN(yuv2rgb24_line,MEM,
|
|
353 (uint8_t *Y, uint8_t *U, uint8_t *V, int *out, int dW, uint32_t *coeffs)):
|
|
354 link 0;
|
|
355 [--sp] = (r7:4);
|
|
356 p1 = [fp+ARG_OUT];
|
|
357 r3 = [fp+ARG_W];
|
|
358 p2 = p1;
|
|
359 p2 += 3;
|
|
360
|
|
361 i0 = r0;
|
|
362 i2 = r1;
|
|
363 i3 = r2;
|
|
364
|
|
365 r0 = [fp+ARG_COEFF]; // coeff buffer
|
|
366 i1 = r0;
|
|
367 b1 = i1;
|
|
368 l1 = COEFF_LEN;
|
|
369 m0 = COEFF_REL_CY_OFF;
|
|
370 p0 = r3;
|
|
371
|
|
372 r0 = [i0++]; // 2Y
|
|
373 r1.l = w[i2++]; // 2u
|
|
374 r1.h = w[i3++]; // 2v
|
|
375 p0 = p0>>2;
|
|
376
|
|
377 lsetup (.L0888, .L1888) lc0 = p0;
|
|
378
|
|
379 /*
|
|
380 uint32_t oy,oc,zero,cy,crv,rmask,cbu,bmask,cgu,cgv
|
|
381 r0 -- used to load 4ys
|
|
382 r1 -- used to load 2us,2vs
|
|
383 r4 -- y3,y2
|
|
384 r5 -- y1,y0
|
|
385 r6 -- u1,u0
|
|
386 r7 -- v1,v0
|
|
387 */
|
|
388 r2=[i1++]; // oy
|
|
389 .L0888:
|
|
390 (r4,r5) = byteop16m (r1:0, r3:2) || r3=[i1++]; // oc
|
|
391 (r7,r6) = byteop16m (r1:0, r3:2) (r);
|
|
392 r5 = r5 << 2 (v); // y1,y0
|
|
393 r4 = r4 << 2 (v); // y3,y2
|
|
394 r6 = r6 << 2 (v) || r0=[i1++]; // u1,u0, r0=zero
|
|
395 r7 = r7 << 2 (v) || r1=[i1++]; // v1,v0 r1=cy
|
|
396
|
|
397 /* Y' = y*cy */
|
|
398 a1 = r1.h*r5.h, a0 = r1.l*r5.l || r1=[i1++]; // crv
|
|
399
|
|
400 /* R = Y+ crv*(Cr-128) */
|
|
401 r2.h = (a1 += r1.h*r7.l), r2.l = (a0 += r1.l*r7.l);
|
|
402 a1 -= r1.h*r7.l, a0 -= r1.l*r7.l || r5=[i1++]; // rmask
|
|
403 r2 = byteop3p(r3:2, r1:0)(LO) || r1=[i1++]; // cbu
|
|
404 r2=r2>>16 || B[p1++]=r2;
|
|
405 B[p2++]=r2;
|
|
406
|
|
407 /* B = Y+ cbu*(Cb-128) */
|
|
408 r2.h = (a1 += r1.h*r6.l), r2.l = (a0 += r1.l*r6.l);
|
|
409 a1 -= r1.h*r6.l, a0 -= r1.l*r6.l || r5=[i1++]; // bmask
|
|
410 r3 = byteop3p(r3:2, r1:0)(LO) || r1=[i1++]; // cgu
|
|
411
|
|
412 /* G = Y+ cgu*(Cb-128)+cgv*(Cr-128) */
|
|
413 a1 += r1.h*r6.l, a0 += r1.l*r6.l || r1=[i1++]; // cgv
|
|
414 r2.h = (a1 += r1.h*r7.l), r2.l = (a0 += r1.l*r7.l);
|
|
415 r2 = byteop3p(r3:2, r1:0)(LO) || r5=[i1++m0]; // gmask, oy,cy,zero
|
|
416
|
|
417 r2=r2>>16 || B[p1++]=r2;
|
|
418 B[p2++]=r2;
|
|
419
|
|
420 r3=r3>>16 || B[p1++]=r3;
|
|
421 B[p2++]=r3 || r1=[i1++]; // cy
|
|
422
|
|
423 p1+=3;
|
|
424 p2+=3;
|
|
425 /* Y' = y*cy */
|
|
426 a1 = r1.h*r4.h, a0 = r1.l*r4.l || r1=[i1++]; // crv
|
|
427
|
|
428 /* R = Y+ crv*(Cr-128) */
|
|
429 r2.h = (a1 += r1.h*r7.h), r2.l = (a0 += r1.l*r7.h);
|
|
430 a1 -= r1.h*r7.h, a0 -= r1.l*r7.h || r5=[i1++]; // rmask
|
|
431 r2 = byteop3p(r3:2, r1:0)(LO) || r1=[i1++]; // cbu
|
|
432 r2=r2>>16 || B[p1++]=r2;
|
|
433 B[p2++]=r2;
|
|
434
|
|
435 /* B = Y+ cbu*(Cb-128) */
|
|
436 r2.h = (a1 += r1.h*r6.h), r2.l = (a0 += r1.l*r6.h);
|
|
437 a1 -= r1.h*r6.h, a0 -= r1.l*r6.h || r5=[i1++]; // bmask
|
|
438 r3 = byteop3p(r3:2, r1:0)(LO) || r1=[i1++]; // cgu
|
|
439
|
|
440 /* G = Y+ cgu*(Cb-128)+cgv*(Cr-128) */
|
|
441 a1 += r1.h*r6.h, a0 += r1.l*r6.h || r1=[i1++]; // cgv
|
|
442 r2.h = (a1 += r1.h*r7.h), r2.l = (a0 += r1.l*r7.h);
|
|
443 r2 = byteop3p(r3:2, r1:0)(LO) || r5=[i1++]; // gmask
|
|
444 r2=r2>>16 || B[p1++]=r2 || r0 = [i0++]; // 4y
|
|
445 B[p2++]=r2 || r1.l = w[i2++]; // 2u
|
|
446 r3=r3>>16 || B[p1++]=r3 || r1.h = w[i3++]; // 2v
|
|
447 B[p2++]=r3 || r2=[i1++]; // oy
|
|
448
|
|
449 p1+=3;
|
|
450 .L1888: p2+=3;
|
|
451
|
|
452 l1 = 0;
|
|
453
|
|
454 (r7:4) = [sp++];
|
|
455 unlink;
|
|
456 rts;
|
|
457 DEFUN_END(yuv2rgb24_line)
|
|
458
|
|
459
|
|
460
|
|
461 #define ARG_vdst 20
|
|
462 #define ARG_width 24
|
|
463 #define ARG_height 28
|
|
464 #define ARG_lumStride 32
|
|
465 #define ARG_chromStride 36
|
|
466 #define ARG_srcStride 40
|
|
467
|
|
468 DEFUN(uyvytoyv12, mL3, (const uint8_t *src, uint8_t *ydst, uint8_t *udst, uint8_t *vdst,
|
31113
|
469 long width, long height,
|
|
470 long lumStride, long chromStride, long srcStride)):
|
29042
|
471 link 0;
|
|
472 [--sp] = (r7:4,p5:4);
|
|
473
|
|
474 p0 = r1; // Y top even
|
|
475
|
|
476 i2 = r2; // *u
|
|
477 r2 = [fp + ARG_vdst];
|
|
478 i3 = r2; // *v
|
|
479
|
|
480 r1 = [fp + ARG_srcStride];
|
|
481 r2 = r0 + r1;
|
|
482 i0 = r0; // uyvy_T even
|
|
483 i1 = r2; // uyvy_B odd
|
|
484
|
|
485 p2 = [fp + ARG_lumStride];
|
|
486 p1 = p0 + p2; // Y bot odd
|
|
487
|
|
488 p5 = [fp + ARG_width];
|
|
489 p4 = [fp + ARG_height];
|
|
490 r0 = p5;
|
|
491 p4 = p4 >> 1;
|
|
492 p5 = p5 >> 2;
|
|
493
|
31085
|
494 r2 = r0 << 1;
|
|
495 r1 = r1 << 1;
|
|
496 r1 = r1 - r2; // srcStride + (srcStride - 2*width)
|
|
497 r1 += -8; // i0,i1 is pre read need to correct
|
|
498 m0 = r1;
|
|
499
|
29042
|
500 r2 = [fp + ARG_chromStride];
|
|
501 r0 = r0 >> 1;
|
|
502 r2 = r2 - r0;
|
|
503 m1 = r2;
|
|
504
|
|
505 /* I0,I1 - src input line pointers
|
|
506 * p0,p1 - luma output line pointers
|
|
507 * I2 - dstU
|
|
508 * I3 - dstV
|
|
509 */
|
|
510
|
|
511 lsetup (0f, 1f) lc1 = p4; // H/2
|
|
512 0: r0 = [i0++] || r2 = [i1++];
|
|
513 r1 = [i0++] || r3 = [i1++];
|
|
514 r4 = byteop1p(r1:0, r3:2);
|
|
515 r5 = byteop1p(r1:0, r3:2) (r);
|
|
516 lsetup (2f, 3f) lc0 = p5; // W/4
|
|
517 2: r0 = r0 >> 8(v);
|
|
518 r1 = r1 >> 8(v);
|
|
519 r2 = r2 >> 8(v);
|
|
520 r3 = r3 >> 8(v);
|
|
521 r0 = bytepack(r0, r1);
|
|
522 r2 = bytepack(r2, r3) || [p0++] = r0; // yyyy
|
|
523 r6 = pack(r5.l, r4.l) || [p1++] = r2; // yyyy
|
|
524 r7 = pack(r5.h, r4.h) || r0 = [i0++] || r2 = [i1++];
|
|
525 r6 = bytepack(r6, r7) || r1 = [i0++] || r3 = [i1++];
|
|
526 r4 = byteop1p(r1:0, r3:2) || w[i2++] = r6.l; // uu
|
|
527 3: r5 = byteop1p(r1:0, r3:2) (r) || w[i3++] = r6.h; // vv
|
|
528
|
|
529 i0 += m0;
|
|
530 i1 += m0;
|
|
531 i2 += m1;
|
|
532 i3 += m1;
|
|
533 p0 = p0 + p2;
|
|
534 1: p1 = p1 + p2;
|
|
535
|
|
536 (r7:4,p5:4) = [sp++];
|
|
537 unlink;
|
|
538 rts;
|
|
539 DEFUN_END(uyvytoyv12)
|
|
540
|
|
541 DEFUN(yuyvtoyv12, mL3, (const uint8_t *src, uint8_t *ydst, uint8_t *udst, uint8_t *vdst,
|
31113
|
542 long width, long height,
|
|
543 long lumStride, long chromStride, long srcStride)):
|
29042
|
544 link 0;
|
|
545 [--sp] = (r7:4,p5:4);
|
|
546
|
|
547 p0 = r1; // Y top even
|
|
548
|
|
549 i2 = r2; // *u
|
|
550 r2 = [fp + ARG_vdst];
|
|
551 i3 = r2; // *v
|
|
552
|
|
553 r1 = [fp + ARG_srcStride];
|
|
554 r2 = r0 + r1;
|
|
555
|
|
556 i0 = r0; // uyvy_T even
|
|
557 i1 = r2; // uyvy_B odd
|
|
558
|
|
559 p2 = [fp + ARG_lumStride];
|
|
560 p1 = p0 + p2; // Y bot odd
|
|
561
|
|
562 p5 = [fp + ARG_width];
|
|
563 p4 = [fp + ARG_height];
|
|
564 r0 = p5;
|
|
565 p4 = p4 >> 1;
|
|
566 p5 = p5 >> 2;
|
|
567
|
31085
|
568 r2 = r0 << 1;
|
|
569 r1 = r1 << 1;
|
|
570 r1 = r1 - r2; // srcStride + (srcStride - 2*width)
|
|
571 r1 += -8; // i0,i1 is pre read need to correct
|
|
572 m0 = r1;
|
|
573
|
29042
|
574 r2 = [fp + ARG_chromStride];
|
|
575 r0 = r0 >> 1;
|
|
576 r2 = r2 - r0;
|
|
577 m1 = r2;
|
|
578
|
|
579 /* I0,I1 - src input line pointers
|
|
580 * p0,p1 - luma output line pointers
|
|
581 * I2 - dstU
|
|
582 * I3 - dstV
|
|
583 */
|
|
584
|
|
585 lsetup (0f, 1f) lc1 = p4; // H/2
|
|
586 0: r0 = [i0++] || r2 = [i1++];
|
|
587 r1 = [i0++] || r3 = [i1++];
|
|
588 r4 = bytepack(r0, r1);
|
|
589 r5 = bytepack(r2, r3);
|
|
590 lsetup (2f, 3f) lc0 = p5; // W/4
|
|
591 2: r0 = r0 >> 8(v) || [p0++] = r4; // yyyy-even
|
|
592 r1 = r1 >> 8(v) || [p1++] = r5; // yyyy-odd
|
|
593 r2 = r2 >> 8(v);
|
|
594 r3 = r3 >> 8(v);
|
|
595 r4 = byteop1p(r1:0, r3:2);
|
|
596 r5 = byteop1p(r1:0, r3:2) (r);
|
|
597 r6 = pack(r5.l, r4.l);
|
|
598 r7 = pack(r5.h, r4.h) || r0 = [i0++] || r2 = [i1++];
|
|
599 r6 = bytepack(r6, r7) || r1 = [i0++] || r3 = [i1++];
|
|
600 r4 = bytepack(r0, r1) || w[i2++] = r6.l; // uu
|
|
601 3: r5 = bytepack(r2, r3) || w[i3++] = r6.h; // vv
|
|
602
|
|
603 i0 += m0;
|
|
604 i1 += m0;
|
|
605 i2 += m1;
|
|
606 i3 += m1;
|
|
607 p0 = p0 + p2;
|
|
608 1: p1 = p1 + p2;
|
|
609
|
|
610 (r7:4,p5:4) = [sp++];
|
|
611 unlink;
|
|
612 rts;
|
|
613 DEFUN_END(yuyvtoyv12)
|