~ubuntu-branches/ubuntu/maverick/vlc/maverick

« back to all changes in this revision

Viewing changes to modules/video_filter/swscale/yuv2rgb_altivec.c

  • Committer: Bazaar Package Importer
  • Author(s): Reinhard Tartler
  • Date: 2008-09-17 21:56:14 UTC
  • mfrom: (1.1.17 upstream)
  • Revision ID: james.westby@ubuntu.com-20080917215614-tj0vx8xzd57e52t8
Tags: 0.9.2-1ubuntu1
* New Upstream Release, exception granted by
    - dktrkranz, norsetto, Hobbsee (via irc). LP: #270404

Changes done in ubuntu:

* add libxul-dev to build-depends
* make sure that vlc is build against libxul in configure. This doesn't
  change anything in the package, but makes it more robust if building
  in an 'unclean' chroot or when modifying the package.
* debian/control: make Vcs-* fields point to the motumedia branch
* add libx264-dev and libass-dev to build-depends
  LP: #210354, #199870
* actually enable libass support by passing --enable-libass to configure
* enable libdca: add libdca-dev to build depends and --enable-libdca
* install the x264 plugin.

Changes already in the pkg-multimedia branch in debian:

* don't install usr/share/vlc/mozilla in debian/mozilla-plugin-vlc.install  
* new upstream .desktop file now registers flash video mimetype LP: #261567
* add Xb-Npp-Applications to mozilla-plugin-vlc
* remove duplicate entries in debian/vlc-nox.install

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
  marc.hoffman@analog.com    March 8, 2004
3
 
 
4
 
  Altivec Acceleration for Color Space Conversion revision 0.2
5
 
 
6
 
  convert I420 YV12 to RGB in various formats,
7
 
    it rejects images that are not in 420 formats
8
 
    it rejects images that don't have widths of multiples of 16
9
 
    it rejects images that don't have heights of multiples of 2
10
 
  reject defers to C simulation codes.
11
 
 
12
 
  lots of optimizations to be done here
13
 
 
14
 
  1. need to fix saturation code, I just couldn't get it to fly with packs and adds.
15
 
     so we currently use max min to clip
16
 
 
17
 
  2. the inefficient use of chroma loading needs a bit of brushing up
18
 
 
19
 
  3. analysis of pipeline stalls needs to be done, use shark to identify pipeline stalls
20
 
 
21
 
 
22
 
  MODIFIED to calculate coeffs from currently selected color space.
23
 
  MODIFIED core to be a macro which you spec the output format.
24
 
  ADDED UYVY conversion which is never called due to some thing in SWSCALE.
25
 
  CORRECTED algorithim selection to be strict on input formats.
26
 
  ADDED runtime detection of altivec.
27
 
 
28
 
  ADDED altivec_yuv2packedX vertical scl + RGB converter
29
 
 
30
 
  March 27,2004
31
 
  PERFORMANCE ANALYSIS
32
 
 
33
 
  The C version use 25% of the processor or ~250Mips for D1 video rawvideo used as test
34
 
  The ALTIVEC version uses 10% of the processor or ~100Mips for D1 video same sequence
35
 
 
36
 
  720*480*30  ~10MPS
37
 
 
38
 
  so we have roughly 10clocks per pixel this is too high something has to be wrong.
39
 
 
40
 
  OPTIMIZED clip codes to utilize vec_max and vec_packs removing the need for vec_min.
41
 
 
42
 
  OPTIMIZED DST OUTPUT cache/dma controls. we are pretty much
43
 
  guaranteed to have the input video frame it was just decompressed so
44
 
  it probably resides in L1 caches.  However we are creating the
45
 
  output video stream this needs to use the DSTST instruction to
46
 
  optimize for the cache.  We couple this with the fact that we are
47
 
  not going to be visiting the input buffer again so we mark it Least
48
 
  Recently Used.  This shaves 25% of the processor cycles off.
49
 
 
50
 
  Now MEMCPY is the largest mips consumer in the system, probably due
51
 
  to the inefficient X11 stuff.
52
 
 
53
 
  GL libraries seem to be very slow on this machine 1.33Ghz PB running
54
 
  Jaguar, this is not the case for my 1Ghz PB.  I thought it might be
55
 
  a versioning issues, however i have libGL.1.2.dylib for both
56
 
  machines. ((We need to figure this out now))
57
 
 
58
 
  GL2 libraries work now with patch for RGB32
59
 
 
60
 
  NOTE quartz vo driver ARGB32_to_RGB24 consumes 30% of the processor
61
 
 
62
 
  Integrated luma prescaling adjustment for saturation/contrast/brightness adjustment. 
63
 
 
64
 
*/
65
 
#include <stdio.h>
66
 
#include <stdlib.h>
67
 
#include <string.h>
68
 
#include <inttypes.h>
69
 
#include <assert.h>
70
 
#include "config.h"
71
 
#include "rgb2rgb.h"
72
 
#include "swscale.h"
73
 
#include "swscale_internal.h"
74
 
#include "mangle.h"
75
 
#include "img_format.h" //FIXME try to reduce dependency of such stuff
76
 
 
77
 
#undef PROFILE_THE_BEAST
78
 
#undef INC_SCALING
79
 
 
80
 
typedef unsigned char ubyte;
81
 
typedef signed char   sbyte;
82
 
 
83
 
 
84
 
/* RGB interleaver, 16 planar pels 8-bit samples per channel in
85
 
   homogeneous vector registers x0,x1,x2 are interleaved with the
86
 
   following technique:
87
 
 
88
 
      o0 = vec_mergeh (x0,x1);
89
 
      o1 = vec_perm (o0, x2, perm_rgb_0);
90
 
      o2 = vec_perm (o0, x2, perm_rgb_1);
91
 
      o3 = vec_mergel (x0,x1);
92
 
      o4 = vec_perm (o3,o2,perm_rgb_2);
93
 
      o5 = vec_perm (o3,o2,perm_rgb_3);
94
 
 
95
 
  perm_rgb_0:   o0(RG).h v1(B) --> o1*
96
 
              0   1  2   3   4
97
 
             rgbr|gbrg|brgb|rgbr
98
 
             0010 0100 1001 0010
99
 
             0102 3145 2673 894A
100
 
 
101
 
  perm_rgb_1:   o0(RG).h v1(B) --> o2
102
 
              0   1  2   3   4
103
 
             gbrg|brgb|bbbb|bbbb
104
 
             0100 1001 1111 1111
105
 
             B5CD 6EF7 89AB CDEF
106
 
 
107
 
  perm_rgb_2:   o3(RG).l o2(rgbB.l) --> o4*
108
 
              0   1  2   3   4
109
 
             gbrg|brgb|rgbr|gbrg
110
 
             1111 1111 0010 0100
111
 
             89AB CDEF 0182 3945
112
 
 
113
 
  perm_rgb_2:   o3(RG).l o2(rgbB.l) ---> o5*
114
 
              0   1  2   3   4
115
 
             brgb|rgbr|gbrg|brgb
116
 
             1001 0010 0100 1001
117
 
             a67b 89cA BdCD eEFf
118
 
 
119
 
*/
120
 
static
121
 
const vector unsigned char
122
 
  perm_rgb_0 = (vector unsigned char)(0x00,0x01,0x10,0x02,0x03,0x11,0x04,0x05,
123
 
                                      0x12,0x06,0x07,0x13,0x08,0x09,0x14,0x0a),
124
 
  perm_rgb_1 = (vector unsigned char)(0x0b,0x15,0x0c,0x0d,0x16,0x0e,0x0f,0x17,
125
 
                                      0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f),
126
 
  perm_rgb_2 = (vector unsigned char)(0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
127
 
                                      0x00,0x01,0x18,0x02,0x03,0x19,0x04,0x05),
128
 
  perm_rgb_3 = (vector unsigned char)(0x1a,0x06,0x07,0x1b,0x08,0x09,0x1c,0x0a,
129
 
                                      0x0b,0x1d,0x0c,0x0d,0x1e,0x0e,0x0f,0x1f);
130
 
 
131
 
#define vec_merge3(x2,x1,x0,y0,y1,y2)    \
132
 
do {                                     \
133
 
  typeof(x0) o0,o2,o3;                   \
134
 
      o0 = vec_mergeh (x0,x1);           \
135
 
      y0 = vec_perm (o0, x2, perm_rgb_0);\
136
 
      o2 = vec_perm (o0, x2, perm_rgb_1);\
137
 
      o3 = vec_mergel (x0,x1);           \
138
 
      y1 = vec_perm (o3,o2,perm_rgb_2);  \
139
 
      y2 = vec_perm (o3,o2,perm_rgb_3);  \
140
 
} while(0)
141
 
 
142
 
#define vec_mstrgb24(x0,x1,x2,ptr)        \
143
 
do {                                     \
144
 
  typeof(x0) _0,_1,_2;                   \
145
 
  vec_merge3 (x0,x1,x2,_0,_1,_2);        \
146
 
  vec_st (_0, 0, ptr++);                 \
147
 
  vec_st (_1, 0, ptr++);                 \
148
 
  vec_st (_2, 0, ptr++);                 \
149
 
}  while (0);
150
 
 
151
 
#define vec_mstbgr24(x0,x1,x2,ptr)       \
152
 
do {                                     \
153
 
  typeof(x0) _0,_1,_2;                   \
154
 
  vec_merge3 (x2,x1,x0,_0,_1,_2);        \
155
 
  vec_st (_0, 0, ptr++);                 \
156
 
  vec_st (_1, 0, ptr++);                 \
157
 
  vec_st (_2, 0, ptr++);                 \
158
 
}  while (0);
159
 
 
160
 
/* pack the pixels in rgb0 format
161
 
   msb R
162
 
   lsb 0
163
 
*/
164
 
#define vec_mstrgb32(T,x0,x1,x2,x3,ptr)                                                \
165
 
do {                                                                                   \
166
 
  T _0,_1,_2,_3;                                                                       \
167
 
  _0 = vec_mergeh (x0,x1);                                                             \
168
 
  _1 = vec_mergeh (x2,x3);                                                             \
169
 
  _2 = (T)vec_mergeh ((vector unsigned short)_0,(vector unsigned short)_1);            \
170
 
  _3 = (T)vec_mergel ((vector unsigned short)_0,(vector unsigned short)_1);            \
171
 
  vec_st (_2, 0*16, (T *)ptr);                                                         \
172
 
  vec_st (_3, 1*16, (T *)ptr);                                                         \
173
 
  _0 = vec_mergel (x0,x1);                                                             \
174
 
  _1 = vec_mergel (x2,x3);                                                             \
175
 
  _2 = (T)vec_mergeh ((vector unsigned short)_0,(vector unsigned short)_1);            \
176
 
  _3 = (T)vec_mergel ((vector unsigned short)_0,(vector unsigned short)_1);            \
177
 
  vec_st (_2, 2*16, (T *)ptr);                                                         \
178
 
  vec_st (_3, 3*16, (T *)ptr);                                                         \
179
 
  ptr += 4;                                                                            \
180
 
}  while (0);
181
 
 
182
 
/*
183
 
 
184
 
  | 1     0       1.4021   | | Y |
185
 
  | 1    -0.3441 -0.7142   |x| Cb|
186
 
  | 1     1.7718  0        | | Cr|
187
 
 
188
 
 
189
 
  Y:      [-128 127]
190
 
  Cb/Cr : [-128 127]
191
 
 
192
 
  typical yuv conversion work on Y: 0-255 this version has been optimized for jpeg decode.
193
 
 
194
 
*/
195
 
 
196
 
 
197
 
 
198
 
 
199
 
#define vec_unh(x) \
200
 
  (vector signed short) \
201
 
    vec_perm(x,(typeof(x))(0),\
202
 
             (vector unsigned char)(0x10,0x00,0x10,0x01,0x10,0x02,0x10,0x03,\
203
 
                                    0x10,0x04,0x10,0x05,0x10,0x06,0x10,0x07))
204
 
#define vec_unl(x) \
205
 
  (vector signed short) \
206
 
    vec_perm(x,(typeof(x))(0),\
207
 
             (vector unsigned char)(0x10,0x08,0x10,0x09,0x10,0x0A,0x10,0x0B,\
208
 
                                    0x10,0x0C,0x10,0x0D,0x10,0x0E,0x10,0x0F))
209
 
 
210
 
#define vec_clip(x) \
211
 
  vec_max (vec_min (x, (typeof(x))(255)), (typeof(x))(0))
212
 
 
213
 
#define vec_packclp_a(x,y) \
214
 
  (vector unsigned char)vec_pack (vec_clip (x), vec_clip (y))
215
 
 
216
 
#define vec_packclp(x,y) \
217
 
  (vector unsigned char)vec_packs \
218
 
      ((vector unsigned short)vec_max (x,(vector signed short) (0)), \
219
 
       (vector unsigned short)vec_max (y,(vector signed short) (0)))
220
 
 
221
 
//#define out_pixels(a,b,c,ptr) vec_mstrgb32(typeof(a),((typeof (a))(0)),a,a,a,ptr)
222
 
 
223
 
 
224
 
static inline void cvtyuvtoRGB (SwsContext *c,
225
 
                           vector signed short Y, vector signed short U, vector signed short V,
226
 
                           vector signed short *R, vector signed short *G, vector signed short *B)
227
 
{
228
 
  vector signed   short vx,ux,uvx;
229
 
 
230
 
  Y = vec_mradds (Y, c->CY, c->OY);
231
 
 
232
 
  U = vec_sub (U,(vector signed short)(128));
233
 
  V = vec_sub (V,(vector signed short)(128));
234
 
 
235
 
  //   ux  = (CBU*(u<<c->CSHIFT)+0x4000)>>15;
236
 
  ux = vec_sl (U, c->CSHIFT);
237
 
  *B = vec_mradds (ux, c->CBU, Y);
238
 
 
239
 
  // vx  = (CRV*(v<<c->CSHIFT)+0x4000)>>15;
240
 
  vx = vec_sl (V, c->CSHIFT);
241
 
  *R = vec_mradds (vx, c->CRV, Y);
242
 
 
243
 
  // uvx = ((CGU*u) + (CGV*v))>>15;
244
 
  uvx = vec_mradds (U, c->CGU, Y);
245
 
  *G = vec_mradds (V, c->CGV, uvx);
246
 
}
247
 
 
248
 
 
249
 
/*
250
 
  ------------------------------------------------------------------------------
251
 
  CS converters
252
 
  ------------------------------------------------------------------------------
253
 
*/
254
 
 
255
 
 
256
 
#define DEFCSP420_CVT(name,out_pixels)                                     \
257
 
static int altivec_##name (SwsContext *c,                                  \
258
 
                                unsigned char **in, int *instrides,        \
259
 
                                int srcSliceY,  int srcSliceH,             \
260
 
                                unsigned char **oplanes, int *outstrides)  \
261
 
{                                                                          \
262
 
  int w = c->srcW;                                                         \
263
 
  int h = srcSliceH;                                                       \
264
 
  int i,j;                                                                 \
265
 
  int instrides_scl[3];                                                    \
266
 
  vector unsigned char y0,y1;                                              \
267
 
                                                                           \
268
 
  vector signed char  u,v;                                                 \
269
 
                                                                           \
270
 
  vector signed short Y0,Y1,Y2,Y3;                                         \
271
 
  vector signed short U,V;                                                 \
272
 
  vector signed short vx,ux,uvx;                                           \
273
 
  vector signed short vx0,ux0,uvx0;                                        \
274
 
  vector signed short vx1,ux1,uvx1;                                        \
275
 
  vector signed short R0,G0,B0;                                            \
276
 
  vector signed short R1,G1,B1;                                            \
277
 
  vector unsigned char R,G,B;                                              \
278
 
                                                                           \
279
 
  vector unsigned char *uivP, *vivP;                                       \
280
 
  vector unsigned char align_perm;                                         \
281
 
                                                                           \
282
 
  vector signed short                                                      \
283
 
    lCY  = c->CY,                                                          \
284
 
    lOY  = c->OY,                                                          \
285
 
    lCRV = c->CRV,                                                         \
286
 
    lCBU = c->CBU,                                                         \
287
 
    lCGU = c->CGU,                                                         \
288
 
    lCGV = c->CGV;                                                         \
289
 
                                                                           \
290
 
  vector unsigned short lCSHIFT = c->CSHIFT;                               \
291
 
                                                                           \
292
 
  ubyte *y1i   = in[0];                                                    \
293
 
  ubyte *y2i   = in[0]+w;                                                  \
294
 
  ubyte *ui    = in[1];                                                    \
295
 
  ubyte *vi    = in[2];                                                    \
296
 
                                                                           \
297
 
  vector unsigned char *oute                                               \
298
 
    = (vector unsigned char *)                                             \
299
 
        (oplanes[0]+srcSliceY*outstrides[0]);                              \
300
 
  vector unsigned char *outo                                               \
301
 
    = (vector unsigned char *)                                             \
302
 
        (oplanes[0]+srcSliceY*outstrides[0]+outstrides[0]);                \
303
 
                                                                           \
304
 
                                                                           \
305
 
  instrides_scl[0] = instrides[0];                                         \
306
 
  instrides_scl[1] = instrides[1]-w/2;  /* the loop moves ui by w/2 */     \
307
 
  instrides_scl[2] = instrides[2]-w/2;  /* the loop moves vi by w/2 */     \
308
 
                                                                           \
309
 
                                                                           \
310
 
  for (i=0;i<h/2;i++) {                                                    \
311
 
    vec_dstst (outo, (0x02000002|(((w*3+32)/32)<<16)), 0);                 \
312
 
    vec_dstst (oute, (0x02000002|(((w*3+32)/32)<<16)), 1);                 \
313
 
                                                                           \
314
 
    for (j=0;j<w/16;j++) {                                                 \
315
 
                                                                           \
316
 
      y0 = vec_ldl (0,y1i);                                                \
317
 
      y1 = vec_ldl (0,y2i);                                                \
318
 
      uivP = (vector unsigned char *)ui;                                   \
319
 
      vivP = (vector unsigned char *)vi;                                   \
320
 
                                                                           \
321
 
      align_perm = vec_lvsl (0, ui);                                       \
322
 
      u = (vector signed char)vec_perm (uivP[0], uivP[1], align_perm);     \
323
 
                                                                           \
324
 
      align_perm = vec_lvsl (0, vi);                                       \
325
 
      v = (vector signed char)vec_perm (vivP[0], vivP[1], align_perm);     \
326
 
                                                                           \
327
 
      u  = (vector signed char)vec_sub (u, (vector signed char)(128));     \
328
 
      v  = (vector signed char)vec_sub (v, (vector signed char)(128));     \
329
 
      U  = vec_unpackh (u);                                                \
330
 
      V  = vec_unpackh (v);                                                \
331
 
                                                                           \
332
 
                                                                           \
333
 
        Y0 = vec_unh (y0);                                                 \
334
 
        Y1 = vec_unl (y0);                                                 \
335
 
        Y2 = vec_unh (y1);                                                 \
336
 
        Y3 = vec_unl (y1);                                                 \
337
 
                                                                           \
338
 
        Y0 = vec_mradds (Y0, lCY, lOY);                                    \
339
 
        Y1 = vec_mradds (Y1, lCY, lOY);                                    \
340
 
        Y2 = vec_mradds (Y2, lCY, lOY);                                    \
341
 
        Y3 = vec_mradds (Y3, lCY, lOY);                                    \
342
 
                                                                           \
343
 
        /*   ux  = (CBU*(u<<CSHIFT)+0x4000)>>15 */                         \
344
 
        ux = vec_sl (U, lCSHIFT);                                          \
345
 
        ux = vec_mradds (ux, lCBU, (vector signed short)(0));              \
346
 
        ux0  = vec_mergeh (ux,ux);                                         \
347
 
        ux1  = vec_mergel (ux,ux);                                         \
348
 
                                                                           \
349
 
        /* vx  = (CRV*(v<<CSHIFT)+0x4000)>>15;  */                         \
350
 
        vx = vec_sl (V, lCSHIFT);                                          \
351
 
        vx = vec_mradds (vx, lCRV, (vector signed short)(0));              \
352
 
        vx0  = vec_mergeh (vx,vx);                                         \
353
 
        vx1  = vec_mergel (vx,vx);                                         \
354
 
                                                                           \
355
 
        /* uvx = ((CGU*u) + (CGV*v))>>15 */                                \
356
 
        uvx = vec_mradds (U, lCGU, (vector signed short)(0));              \
357
 
        uvx = vec_mradds (V, lCGV, uvx);                                   \
358
 
        uvx0 = vec_mergeh (uvx,uvx);                                       \
359
 
        uvx1 = vec_mergel (uvx,uvx);                                       \
360
 
                                                                           \
361
 
        R0 = vec_add (Y0,vx0);                                             \
362
 
        G0 = vec_add (Y0,uvx0);                                            \
363
 
        B0 = vec_add (Y0,ux0);                                             \
364
 
        R1 = vec_add (Y1,vx1);                                             \
365
 
        G1 = vec_add (Y1,uvx1);                                            \
366
 
        B1 = vec_add (Y1,ux1);                                             \
367
 
                                                                           \
368
 
        R  = vec_packclp (R0,R1);                                          \
369
 
        G  = vec_packclp (G0,G1);                                          \
370
 
        B  = vec_packclp (B0,B1);                                          \
371
 
                                                                           \
372
 
        out_pixels(R,G,B,oute);                                            \
373
 
                                                                           \
374
 
        R0 = vec_add (Y2,vx0);                                             \
375
 
        G0 = vec_add (Y2,uvx0);                                            \
376
 
        B0 = vec_add (Y2,ux0);                                             \
377
 
        R1 = vec_add (Y3,vx1);                                             \
378
 
        G1 = vec_add (Y3,uvx1);                                            \
379
 
        B1 = vec_add (Y3,ux1);                                             \
380
 
        R  = vec_packclp (R0,R1);                                          \
381
 
        G  = vec_packclp (G0,G1);                                          \
382
 
        B  = vec_packclp (B0,B1);                                          \
383
 
                                                                           \
384
 
                                                                           \
385
 
        out_pixels(R,G,B,outo);                                            \
386
 
                                                                           \
387
 
      y1i  += 16;                                                          \
388
 
      y2i  += 16;                                                          \
389
 
      ui   += 8;                                                           \
390
 
      vi   += 8;                                                           \
391
 
                                                                           \
392
 
    }                                                                      \
393
 
                                                                           \
394
 
    outo += (outstrides[0])>>4;                                            \
395
 
    oute += (outstrides[0])>>4;                                            \
396
 
                                                                           \
397
 
    ui    += instrides_scl[1];                                             \
398
 
    vi    += instrides_scl[2];                                             \
399
 
    y1i   += instrides_scl[0];                                             \
400
 
    y2i   += instrides_scl[0];                                             \
401
 
  }                                                                        \
402
 
  return srcSliceH;                                                        \
403
 
}
404
 
 
405
 
 
406
 
#define out_abgr(a,b,c,ptr)  vec_mstrgb32(typeof(a),((typeof (a))(0)),c,b,a,ptr)
407
 
#define out_bgra(a,b,c,ptr)  vec_mstrgb32(typeof(a),c,b,a,((typeof (a))(0)),ptr)
408
 
#define out_rgba(a,b,c,ptr)  vec_mstrgb32(typeof(a),a,b,c,((typeof (a))(0)),ptr)
409
 
#define out_argb(a,b,c,ptr)  vec_mstrgb32(typeof(a),((typeof (a))(0)),a,b,c,ptr)
410
 
#define out_rgb24(a,b,c,ptr) vec_mstrgb24(a,b,c,ptr)
411
 
#define out_bgr24(a,b,c,ptr) vec_mstrgb24(c,b,a,ptr)
412
 
 
413
 
DEFCSP420_CVT (yuv2_abgr32, out_abgr)
414
 
DEFCSP420_CVT (yuv2_bgra32, out_argb)
415
 
DEFCSP420_CVT (yuv2_rgba32, out_rgba)
416
 
DEFCSP420_CVT (yuv2_argb32, out_argb)
417
 
DEFCSP420_CVT (yuv2_rgb24,  out_rgb24)
418
 
DEFCSP420_CVT (yuv2_bgr24,  out_bgr24)
419
 
 
420
 
 
421
 
// uyvy|uyvy|uyvy|uyvy
422
 
// 0123 4567 89ab cdef
423
 
static
424
 
const vector unsigned char
425
 
  demux_u = (vector unsigned char)(0x10,0x00,0x10,0x00,
426
 
                                   0x10,0x04,0x10,0x04,
427
 
                                   0x10,0x08,0x10,0x08,
428
 
                                   0x10,0x0c,0x10,0x0c),
429
 
  demux_v = (vector unsigned char)(0x10,0x02,0x10,0x02,
430
 
                                   0x10,0x06,0x10,0x06,
431
 
                                   0x10,0x0A,0x10,0x0A,
432
 
                                   0x10,0x0E,0x10,0x0E),
433
 
  demux_y = (vector unsigned char)(0x10,0x01,0x10,0x03,
434
 
                                   0x10,0x05,0x10,0x07,
435
 
                                   0x10,0x09,0x10,0x0B,
436
 
                                   0x10,0x0D,0x10,0x0F);
437
 
 
438
 
/*
439
 
  this is so I can play live CCIR raw video
440
 
*/
441
 
static int altivec_uyvy_rgb32 (SwsContext *c,
442
 
                               unsigned char **in, int *instrides,
443
 
                               int srcSliceY,   int srcSliceH,
444
 
                               unsigned char **oplanes, int *outstrides)
445
 
{
446
 
  int w = c->srcW;
447
 
  int h = srcSliceH;
448
 
  int i,j;
449
 
  vector unsigned char uyvy;
450
 
  vector signed   short Y,U,V;
451
 
  vector signed   short vx,ux,uvx;
452
 
  vector signed   short R0,G0,B0,R1,G1,B1;
453
 
  vector unsigned char  R,G,B;
454
 
  vector unsigned char *out;
455
 
  ubyte *img;
456
 
 
457
 
  img = in[0];
458
 
  out = (vector unsigned char *)(oplanes[0]+srcSliceY*outstrides[0]);
459
 
 
460
 
  for (i=0;i<h;i++) {
461
 
    for (j=0;j<w/16;j++) {
462
 
      uyvy = vec_ld (0, img);
463
 
      U = (vector signed short)
464
 
        vec_perm (uyvy, (vector unsigned char)(0), demux_u);
465
 
 
466
 
      V = (vector signed short)
467
 
        vec_perm (uyvy, (vector unsigned char)(0), demux_v);
468
 
 
469
 
      Y = (vector signed short)
470
 
        vec_perm (uyvy, (vector unsigned char)(0), demux_y);
471
 
 
472
 
      cvtyuvtoRGB (c, Y,U,V,&R0,&G0,&B0);
473
 
 
474
 
      uyvy = vec_ld (16, img);
475
 
      U = (vector signed short)
476
 
        vec_perm (uyvy, (vector unsigned char)(0), demux_u);
477
 
 
478
 
      V = (vector signed short)
479
 
        vec_perm (uyvy, (vector unsigned char)(0), demux_v);
480
 
 
481
 
      Y = (vector signed short)
482
 
        vec_perm (uyvy, (vector unsigned char)(0), demux_y);
483
 
 
484
 
      cvtyuvtoRGB (c, Y,U,V,&R1,&G1,&B1);
485
 
 
486
 
      R  = vec_packclp (R0,R1);
487
 
      G  = vec_packclp (G0,G1);
488
 
      B  = vec_packclp (B0,B1);
489
 
 
490
 
      //      vec_mstbgr24 (R,G,B, out);
491
 
      out_rgba (R,G,B,out);
492
 
 
493
 
      img += 32;
494
 
    }
495
 
  }
496
 
  return srcSliceH;
497
 
}
498
 
 
499
 
 
500
 
 
501
 
/* Ok currently the acceleration routine only supports
502
 
   inputs of widths a multiple of 16
503
 
   and heights a multiple 2
504
 
 
505
 
   So we just fall back to the C codes for this.
506
 
*/
507
 
SwsFunc yuv2rgb_init_altivec (SwsContext *c)
508
 
{
509
 
  if (!(c->flags & SWS_CPU_CAPS_ALTIVEC))    
510
 
    return NULL;
511
 
 
512
 
  /*
513
 
    and this seems not to matter too much I tried a bunch of 
514
 
    videos with abnormal widths and mplayer crashes else where.
515
 
    mplayer -vo x11 -rawvideo on:w=350:h=240 raw-350x240.eyuv 
516
 
    boom with X11 bad match.
517
 
    
518
 
  */
519
 
  if ((c->srcW & 0xf) != 0)    return NULL;
520
 
 
521
 
  switch (c->srcFormat) {
522
 
  case IMGFMT_YVU9:
523
 
  case IMGFMT_IF09:
524
 
  case IMGFMT_YV12:
525
 
  case IMGFMT_I420:
526
 
  case IMGFMT_IYUV:
527
 
  case IMGFMT_CLPL:
528
 
  case IMGFMT_Y800:
529
 
  case IMGFMT_Y8:
530
 
  case IMGFMT_NV12:
531
 
  case IMGFMT_NV21:
532
 
    if ((c->srcH & 0x1) != 0)
533
 
      return NULL;
534
 
 
535
 
    switch(c->dstFormat){
536
 
    case IMGFMT_RGB24:
537
 
      MSG_WARN("ALTIVEC: Color Space RGB24\n");
538
 
      return altivec_yuv2_rgb24;
539
 
    case IMGFMT_BGR24:
540
 
      MSG_WARN("ALTIVEC: Color Space BGR24\n");
541
 
      return altivec_yuv2_bgr24;
542
 
    case IMGFMT_RGB32:
543
 
      MSG_WARN("ALTIVEC: Color Space ARGB32\n");
544
 
      return altivec_yuv2_argb32;
545
 
    case IMGFMT_BGR32:
546
 
      MSG_WARN("ALTIVEC: Color Space BGRA32\n");
547
 
      //      return profile_altivec_bgra32;
548
 
 
549
 
      return altivec_yuv2_bgra32;
550
 
    default: return NULL;
551
 
    }
552
 
    break;
553
 
 
554
 
  case IMGFMT_UYVY:
555
 
    switch(c->dstFormat){
556
 
    case IMGFMT_RGB32:
557
 
      MSG_WARN("ALTIVEC: Color Space UYVY -> RGB32\n");
558
 
      return altivec_uyvy_rgb32;
559
 
    default: return NULL;
560
 
    }
561
 
    break;
562
 
 
563
 
  }
564
 
  return NULL;
565
 
}
566
 
 
567
 
void yuv2rgb_altivec_init_tables (SwsContext *c, const int inv_table[4])
568
 
{
569
 
  vector signed short CY, CRV, CBU, CGU, CGV, OY, Y0;
570
 
  int64_t crv __attribute__ ((aligned(16))) = inv_table[0];
571
 
  int64_t cbu __attribute__ ((aligned(16))) = inv_table[1];
572
 
  int64_t cgu __attribute__ ((aligned(16))) = inv_table[2];
573
 
  int64_t cgv __attribute__ ((aligned(16))) = inv_table[3];
574
 
  int64_t cy = (1<<16)-1;
575
 
  int64_t oy = 0;
576
 
  short tmp __attribute__ ((aligned(16)));
577
 
 
578
 
  if ((c->flags & SWS_CPU_CAPS_ALTIVEC) == 0)
579
 
    return;
580
 
 
581
 
  cy = (cy *c->contrast             )>>17;
582
 
  crv= (crv*c->contrast * c->saturation)>>32;
583
 
  cbu= (cbu*c->contrast * c->saturation)>>32;
584
 
  cgu= (cgu*c->contrast * c->saturation)>>32;
585
 
  cgv= (cgv*c->contrast * c->saturation)>>32;
586
 
 
587
 
  oy -= 256*c->brightness;
588
 
 
589
 
  tmp = cy;
590
 
  CY = vec_lde (0, &tmp);
591
 
  CY  = vec_splat (CY, 0);
592
 
 
593
 
  tmp = oy;
594
 
  OY = vec_lde (0, &tmp);
595
 
  OY  = vec_splat (OY, 0);
596
 
 
597
 
  tmp = crv>>3;
598
 
  CRV = vec_lde (0, &tmp);
599
 
  CRV  = vec_splat (CRV, 0);
600
 
  tmp = cbu>>3;
601
 
  CBU = vec_lde (0, &tmp);
602
 
  CBU  = vec_splat (CBU, 0);
603
 
 
604
 
  tmp = -(cgu>>1);
605
 
  CGU = vec_lde (0, &tmp);
606
 
  CGU  = vec_splat (CGU, 0);
607
 
  tmp = -(cgv>>1);
608
 
  CGV = vec_lde (0, &tmp);
609
 
  CGV  = vec_splat (CGV, 0);
610
 
 
611
 
  c->CSHIFT = (vector unsigned short)(2);
612
 
  c->CY = CY;
613
 
  c->OY = OY;
614
 
  c->CRV = CRV;
615
 
  c->CBU = CBU;
616
 
  c->CGU = CGU;
617
 
  c->CGV = CGV;
618
 
 
619
 
#if 0
620
 
  printf ("cy:  %hvx\n", CY);
621
 
  printf ("oy:  %hvx\n", OY);
622
 
  printf ("crv: %hvx\n", CRV);
623
 
  printf ("cbu: %hvx\n", CBU);
624
 
  printf ("cgv: %hvx\n", CGV);
625
 
  printf ("cgu: %hvx\n", CGU);
626
 
#endif
627
 
 
628
 
 return;
629
 
}
630
 
 
631
 
 
632
 
void
633
 
altivec_yuv2packedX (SwsContext *c,
634
 
                       int16_t *lumFilter, int16_t **lumSrc, int lumFilterSize,
635
 
                       int16_t *chrFilter, int16_t **chrSrc, int chrFilterSize,
636
 
                       uint8_t *dest, int dstW, int dstY)
637
 
{
638
 
  int i,j;
639
 
  short tmp __attribute__((aligned (16)));
640
 
  short *p;
641
 
  short *f;
642
 
  vector signed short X,X0,X1,Y0,U0,V0,Y1,U1,V1,U,V;
643
 
  vector signed short R0,G0,B0,R1,G1,B1;
644
 
 
645
 
  vector unsigned char R,G,B,pels[3];
646
 
  vector unsigned char *out,*nout;
647
 
  vector signed short   RND = (vector signed short)(1<<3);
648
 
  vector unsigned short SCL = (vector unsigned short)(4);
649
 
  unsigned long scratch[16] __attribute__ ((aligned (16)));
650
 
 
651
 
  vector signed short *vYCoeffsBank, *vCCoeffsBank;
652
 
 
653
 
  vector signed short *YCoeffs, *CCoeffs;
654
 
 
655
 
  vYCoeffsBank = malloc (sizeof (vector signed short)*lumFilterSize*dstW);
656
 
  vCCoeffsBank = malloc (sizeof (vector signed short)*chrFilterSize*dstW);
657
 
 
658
 
  for (i=0;i<lumFilterSize*dstW;i++) {
659
 
    tmp = c->vLumFilter[i];
660
 
    p = &vYCoeffsBank[i];
661
 
    for (j=0;j<8;j++)
662
 
      p[j] = tmp;
663
 
  }
664
 
 
665
 
  for (i=0;i<chrFilterSize*dstW;i++) {
666
 
    tmp = c->vChrFilter[i];
667
 
    p = &vCCoeffsBank[i];
668
 
    for (j=0;j<8;j++)
669
 
      p[j] = tmp;
670
 
  }
671
 
 
672
 
  YCoeffs = vYCoeffsBank+dstY*lumFilterSize;
673
 
  CCoeffs = vCCoeffsBank+dstY*chrFilterSize;
674
 
 
675
 
  out = (vector unsigned char *)dest;
676
 
 
677
 
  for(i=0; i<dstW; i+=16){
678
 
    Y0 = RND;
679
 
    Y1 = RND;
680
 
    /* extract 16 coeffs from lumSrc */
681
 
    for(j=0; j<lumFilterSize; j++) {
682
 
      X0 = vec_ld (0,  &lumSrc[j][i]);
683
 
      X1 = vec_ld (16, &lumSrc[j][i]);
684
 
      Y0 = vec_mradds (X0, YCoeffs[j], Y0);
685
 
      Y1 = vec_mradds (X1, YCoeffs[j], Y1);
686
 
    }
687
 
 
688
 
    U = RND;
689
 
    V = RND;
690
 
    /* extract 8 coeffs from U,V */
691
 
    for(j=0; j<chrFilterSize; j++) {
692
 
      X  = vec_ld (0, &chrSrc[j][i/2]);
693
 
      U  = vec_mradds (X, CCoeffs[j], U);
694
 
      X  = vec_ld (0, &chrSrc[j][i/2+2048]);
695
 
      V  = vec_mradds (X, CCoeffs[j], V);
696
 
    }
697
 
 
698
 
    /* scale and clip signals */
699
 
    Y0 = vec_sra (Y0, SCL);
700
 
    Y1 = vec_sra (Y1, SCL);
701
 
    U  = vec_sra (U,  SCL);
702
 
    V  = vec_sra (V,  SCL);
703
 
 
704
 
    Y0 = vec_clip (Y0);
705
 
    Y1 = vec_clip (Y1);
706
 
    U  = vec_clip (U);
707
 
    V  = vec_clip (V);
708
 
 
709
 
    /* now we have
710
 
      Y0= y0 y1 y2 y3 y4 y5 y6 y7     Y1= y8 y9 y10 y11 y12 y13 y14 y15
711
 
      U= u0 u1 u2 u3 u4 u5 u6 u7      V= v0 v1 v2 v3 v4 v5 v6 v7
712
 
 
713
 
      Y0= y0 y1 y2 y3 y4 y5 y6 y7    Y1= y8 y9 y10 y11 y12 y13 y14 y15
714
 
      U0= u0 u0 u1 u1 u2 u2 u3 u3    U1= u4 u4 u5 u5 u6 u6 u7 u7
715
 
      V0= v0 v0 v1 v1 v2 v2 v3 v3    V1= v4 v4 v5 v5 v6 v6 v7 v7
716
 
    */
717
 
 
718
 
    U0 = vec_mergeh (U,U);
719
 
    V0 = vec_mergeh (V,V);
720
 
 
721
 
    U1 = vec_mergel (U,U);
722
 
    V1 = vec_mergel (V,V);
723
 
 
724
 
    cvtyuvtoRGB (c, Y0,U0,V0,&R0,&G0,&B0);
725
 
    cvtyuvtoRGB (c, Y1,U1,V1,&R1,&G1,&B1);
726
 
 
727
 
    R  = vec_packclp (R0,R1);
728
 
    G  = vec_packclp (G0,G1);
729
 
    B  = vec_packclp (B0,B1);
730
 
 
731
 
    out_rgba (R,G,B,out);
732
 
  }
733
 
 
734
 
  if (i < dstW) {
735
 
    i -= 16;
736
 
 
737
 
    Y0 = RND;
738
 
    Y1 = RND;
739
 
    /* extract 16 coeffs from lumSrc */
740
 
    for(j=0; j<lumFilterSize; j++) {
741
 
      X0 = vec_ld (0,  &lumSrc[j][i]);
742
 
      X1 = vec_ld (16, &lumSrc[j][i]);
743
 
      Y0 = vec_mradds (X0, YCoeffs[j], Y0);
744
 
      Y1 = vec_mradds (X1, YCoeffs[j], Y1);
745
 
    }
746
 
 
747
 
    U = RND;
748
 
    V = RND;
749
 
    /* extract 8 coeffs from U,V */
750
 
    for(j=0; j<chrFilterSize; j++) {
751
 
      X  = vec_ld (0, &chrSrc[j][i/2]);
752
 
      U  = vec_mradds (X, CCoeffs[j], U);
753
 
      X  = vec_ld (0, &chrSrc[j][i/2+2048]);
754
 
      V  = vec_mradds (X, CCoeffs[j], V);
755
 
    }
756
 
 
757
 
    /* scale and clip signals */
758
 
    Y0 = vec_sra (Y0, SCL);
759
 
    Y1 = vec_sra (Y1, SCL);
760
 
    U  = vec_sra (U,  SCL);
761
 
    V  = vec_sra (V,  SCL);
762
 
 
763
 
    Y0 = vec_clip (Y0);
764
 
    Y1 = vec_clip (Y1);
765
 
    U  = vec_clip (U);
766
 
    V  = vec_clip (V);
767
 
 
768
 
    /* now we have
769
 
       Y0= y0 y1 y2 y3 y4 y5 y6 y7     Y1= y8 y9 y10 y11 y12 y13 y14 y15
770
 
       U= u0 u1 u2 u3 u4 u5 u6 u7      V= v0 v1 v2 v3 v4 v5 v6 v7
771
 
 
772
 
       Y0= y0 y1 y2 y3 y4 y5 y6 y7    Y1= y8 y9 y10 y11 y12 y13 y14 y15
773
 
       U0= u0 u0 u1 u1 u2 u2 u3 u3    U1= u4 u4 u5 u5 u6 u6 u7 u7
774
 
       V0= v0 v0 v1 v1 v2 v2 v3 v3    V1= v4 v4 v5 v5 v6 v6 v7 v7
775
 
    */
776
 
 
777
 
    U0 = vec_mergeh (U,U);
778
 
    V0 = vec_mergeh (V,V);
779
 
 
780
 
    U1 = vec_mergel (U,U);
781
 
    V1 = vec_mergel (V,V);
782
 
 
783
 
    cvtyuvtoRGB (c, Y0,U0,V0,&R0,&G0,&B0);
784
 
    cvtyuvtoRGB (c, Y1,U1,V1,&R1,&G1,&B1);
785
 
 
786
 
    R  = vec_packclp (R0,R1);
787
 
    G  = vec_packclp (G0,G1);
788
 
    B  = vec_packclp (B0,B1);
789
 
 
790
 
    nout = (vector unsigned char *)scratch;
791
 
    out_rgba (R,G,B,nout);
792
 
 
793
 
    memcpy (&((uint32_t*)dest)[i], scratch, (dstW-i)/4);
794
 
  }
795
 
 
796
 
  if (vYCoeffsBank) free (vYCoeffsBank);
797
 
  if (vCCoeffsBank) free (vCCoeffsBank);
798
 
 
799
 
}