source: trunk/ColorConversions.c @ 1424

Revision 1424, 17.3 KB checked in by astrange, 3 years ago (diff)

Map PIX_FMT_YUVJ420P to 2vuy

Fixes fraps v0/3/4.

Note this is wrong - the full-range YUV format is kComponentVideoCodecType.
Follow up later.

Refs #566

Line 
1/*
2 * ColorConversions.c
3 * Created by Alexander Strange on 1/10/07.
4 *
5 * This file is part of Perian.
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22#include <QuickTime/QuickTime.h>
23#include <Accelerate/Accelerate.h>
24#include "ColorConversions.h"
25#include "Codecprintf.h"
26#include "CommonUtils.h"
27
28/*
29 Converts (without resampling) from ffmpeg pixel formats to the ones QT accepts
30 
31 Todo:
32 - rewrite everything in asm (or C with all loop optimization opportunities removed)
33 - add a version with bilinear resampling
34 - handle YUV 4:2:0 with odd width
35 */
36
37#define unlikely(x) __builtin_expect(x, 0)
38#define likely(x) __builtin_expect(x, 1)
39
40//Handles the last row for Y420 videos with an odd number of luma rows
41//FIXME: odd number of luma columns is not handled and they will be lost
42static void Y420toY422_lastrow(UInt8 *o, UInt8 *yc, UInt8 *uc, UInt8 *vc, int halfWidth)
43{
44        int x;
45        for(x=0; x < halfWidth; x++)
46        {
47                int x4 = x*4, x2 = x*2;
48
49                o[x4]   = uc[x];
50                o[x4+1] = yc[x2];
51                o[x4+2] = vc[x];
52                o[x4+3] = yc[x2+1];
53        }
54}
55
56#define HandleLastRow(o, yc, uc, vc, halfWidth, height) if (unlikely(height & 1)) Y420toY422_lastrow(o, yc, uc, vc, halfWidth)
57
58//Y420 Planar to Y422 Packed
59//The only one anyone cares about, so implemented with SIMD
60
61#ifdef __ppc__
62//hand-unrolled code is a bad idea on modern CPUs. luckily, this does not run on modern CPUs, only G3s.
63
64static FASTCALL void Y420toY422_ppc_scalar(AVPicture *picture, UInt8 *baseAddr, int outRB, int width, int height)
65{
66        int     y = height >> 1, halfWidth = width >> 1, halfHalfWidth = width >> 2;
67        UInt8 *inY = picture->data[0], *inU = picture->data[1], *inV = picture->data[2];
68        int     rB = picture->linesize[0], rbUV = picture->linesize[1];
69         
70         while (y--) {
71                 UInt32         *ldst = (UInt32 *) baseAddr, *ldstr2 = (UInt32 *) (baseAddr + outRB);
72                 UInt32         *lsrc = (UInt32 *) inY, *lsrcr2 = (UInt32 *) (inY + rB);
73                 UInt16         *sU = (UInt16 *) inU, *sV = (UInt16 *) inV;
74                 ptrdiff_t              off;
75                 
76                 for (off = 0; off < halfHalfWidth; off++) {
77                         UInt16          chrU = sU[off], chrV = sV[off];
78                         UInt32          row1luma = lsrc[off], row2luma = lsrcr2[off];
79                         UInt32          chromas1 = (chrU & 0xff00) << 16 | (chrV & 0xff00), chromas2 = (chrU & 0xff) << 24 | (chrV & 0xff) << 8;
80                         int             off2 = off * 2;
81                         
82                         ldst[off2] = chromas1 | (row1luma & 0xff000000) >> 8 | (row1luma & 0xff0000) >> 16;
83                         ldstr2[off2] = chromas1 | (row2luma & 0xff000000) >> 8 | (row2luma & 0xff0000) >> 16;
84                         off2++;
85                         ldst[off2] = chromas2 | (row1luma & 0xff00) << 8 | row1luma & 0xff;
86                         ldstr2[off2] = chromas2 | (row2luma & 0xff00) << 8 | row2luma & 0xff;
87                 }
88                 
89                 if (halfWidth & 3) {
90                         UInt16         *ssrc = (UInt16 *) inY, *ssrcr2 = (UInt16 *) (inY + rB);
91                         
92                         ptrdiff_t       off = halfWidth - 2;
93                         UInt32          chromas = inV[off] << 8 | (inU[off] << 24);
94                         UInt16          row1luma = ssrc[off], row2luma = ssrcr2[off];
95                         
96                         ldst[off] = chromas | row1luma & 0xff | (row1luma & 0xff00) << 8;
97                         ldstr2[off] = chromas | row2luma & 0xff | (row2luma & 0xff00) << 8;
98                 }
99                 
100                 inY += rB * 2;
101                 inU += rbUV;
102                 inV += rbUV;
103                 baseAddr += outRB * 2;
104         }
105       
106        HandleLastRow(baseAddr, inY, inU, inV, halfWidth, height);
107}
108
109static FASTCALL void Y420toY422_ppc_altivec(AVPicture *picture, UInt8 *o, int outRB, int width, int height)
110{
111        UInt8   *yc = picture->data[0], *uc = picture->data[1], *vc = picture->data[2];
112        int             rY = picture->linesize[0], rUV = picture->linesize[1];
113        int             y, x, x2, x4, vWidth = width >> 5, halfheight = height >> 1;
114       
115        for (y = 0; y < halfheight; y ++) {
116                vUInt8 *ov = (vUInt8 *)o, *ov2 = (vUInt8 *)(o + outRB), *yv2 = (vUInt8 *)(yc + rY);
117                vUInt8 *uv  = (vUInt8 *)uc, *vv = (vUInt8 *)vc, *yv = (vUInt8 *)yc;
118               
119                for (x = 0; x < vWidth; x++) {
120                        x2 = x*2; x4 = x*4;
121                        // ldl/stl = mark data as least recently used in cache so they will be flushed out
122                        __builtin_prefetch(&yv[x+1], 0, 0); __builtin_prefetch(&yv2[x+1], 0, 0);
123                        __builtin_prefetch(&uv[x+1], 0, 0); __builtin_prefetch(&vv[x+1], 0, 0);
124                        vUInt8 tmp_u = vec_ldl(0, &uv[x]), tmp_v = vec_ldl(0, &vv[x]), chroma = vec_mergeh(tmp_u, tmp_v),
125                                        tmp_y = vec_ldl(0, &yv[x2]), tmp_y2 = vec_ldl(0, &yv2[x2]),
126                                        tmp_y3 = vec_ldl(16, &yv[x2]), tmp_y4 = vec_ldl(16, &yv2[x2]), chromal = vec_mergel(tmp_u, tmp_v);
127                       
128                        vec_stl(vec_mergeh(chroma, tmp_y), 0, &ov[x4]);
129                        vec_stl(vec_mergel(chroma, tmp_y), 16, &ov[x4]);
130                        vec_stl(vec_mergeh(chromal, tmp_y3), 32, &ov[x4]);
131                        vec_stl(vec_mergel(chromal, tmp_y3), 48, &ov[x4]);
132                       
133                        vec_stl(vec_mergeh(chroma, tmp_y2), 0, &ov2[x4]);
134                        vec_stl(vec_mergel(chroma, tmp_y2), 16, &ov2[x4]);
135                        vec_stl(vec_mergeh(chromal, tmp_y4), 32, &ov2[x4]);
136                        vec_stl(vec_mergel(chromal, tmp_y4), 48, &ov2[x4]);
137                }
138               
139                if (width & 31) { //spill to scalar for the end if the row isn't a multiple of 32
140                        UInt8 *o2 = o + outRB, *yc2 = yc + rY;
141                        for (x = vWidth * 32, x2 = x*2; x < width; x += 2, x2 += 4) {
142                                int hx = x >> 1;
143                                o2[x2]     = o[x2] = uc[hx];
144                                o [x2 + 1] = yc[x];
145                                o2[x2 + 1] = yc2[x];
146                                o2[x2 + 2] = o[x2 + 2] = vc[hx];
147                                o [x2 + 3] = yc[x + 1];
148                                o2[x2 + 3] = yc2[x + 1];
149                        }                       
150                }
151               
152                o  += outRB * 2;
153                yc += rY * 2;
154                uc += rUV;
155                vc += rUV;
156        }
157       
158        HandleLastRow(o, yc, uc, vc, width >> 1, height);
159}
160#else
161#include <emmintrin.h>
162
163static FASTCALL void Y420toY422_sse2(AVPicture *picture, UInt8 *o, int outRB, int width, int height)
164{
165        UInt8   *yc = picture->data[0], *uc = picture->data[1], *vc = picture->data[2];
166        int             rY = picture->linesize[0], rUV = picture->linesize[1];
167        int             y, x, halfwidth = width >> 1, halfheight = height >> 1;
168        int             vWidth = width >> 5;
169       
170        for (y = 0; y < halfheight; y++) {
171                UInt8   *o2 = o + outRB,   *yc2 = yc + rY;
172                __m128i *ov = (__m128i*)o, *ov2 = (__m128i*)o2, *yv = (__m128i*)yc, *yv2 = (__m128i*)yc2;
173                __m128i *uv = (__m128i*)uc,*vv  = (__m128i*)vc;
174               
175#ifdef __i386__
176                int vWidth_ = vWidth;
177
178                asm volatile(
179                        "\n0:                   \n\t"
180                        "movdqa         (%2),   %%xmm0  \n\t"
181                        "movdqa         16(%2), %%xmm2  \n\t"
182                        "movdqa         (%3),           %%xmm1  \n\t"
183                        "movdqa         16(%3), %%xmm3  \n\t"
184                        "movdqu         (%4),   %%xmm4  \n\t"
185                        "movdqu         (%5),   %%xmm5  \n\t"
186                        "addl           $32,    %2              \n\t"
187                        "addl           $32,    %3              \n\t"
188                        "addl           $16,    %4              \n\t"
189                        "addl           $16,    %5              \n\t"
190                        "movdqa         %%xmm4, %%xmm6  \n\t"
191                        "punpcklbw      %%xmm5, %%xmm4  \n\t" /*chroma_l*/
192                        "punpckhbw      %%xmm5, %%xmm6  \n\t" /*chroma_h*/
193                        "movdqa         %%xmm4, %%xmm5  \n\t"
194                        "punpcklbw      %%xmm0, %%xmm5  \n\t"
195                        "movntdq        %%xmm5, (%0)    \n\t" /*ov[x4]*/
196                        "movdqa         %%xmm4, %%xmm5  \n\t"
197                        "punpckhbw      %%xmm0, %%xmm5  \n\t"
198                        "movntdq        %%xmm5, 16(%0)  \n\t" /*ov[x4+1]*/
199                        "movdqa         %%xmm6, %%xmm5  \n\t"
200                        "punpcklbw      %%xmm2, %%xmm5  \n\t"
201                        "movntdq        %%xmm5, 32(%0)  \n\t" /*ov[x4+2]*/
202                        "movdqa         %%xmm6, %%xmm5  \n\t"
203                        "punpckhbw      %%xmm2, %%xmm5  \n\t"
204                        "movntdq        %%xmm5, 48(%0)  \n\t" /*ov[x4+3]*/
205                        "addl           $64,    %0              \n\t"
206                        "movdqa         %%xmm4, %%xmm5  \n\t"
207                        "punpcklbw      %%xmm1, %%xmm5  \n\t"
208                        "movntdq        %%xmm5, (%1)    \n\t" /*ov2[x4]*/
209                        "punpckhbw      %%xmm1, %%xmm4  \n\t"
210                        "movntdq        %%xmm4, 16(%1)  \n\t" /*ov2[x4+1]*/
211                        "movdqa         %%xmm6, %%xmm5  \n\t"
212                        "punpcklbw      %%xmm3, %%xmm5  \n\t"
213                        "movntdq        %%xmm5, 32(%1)  \n\t" /*ov2[x4+2]*/
214                        "punpckhbw      %%xmm3, %%xmm6  \n\t"
215                        "movntdq        %%xmm6, 48(%1)  \n\t" /*ov2[x4+3]*/
216                        "addl           $64,    %1              \n\t"
217                        "decl           %6                              \n\t"
218                        "jnz            0b                              \n\t"
219                        : "+r" (ov), "+r" (ov2), "+r" (yv),
220                          "+r" (yv2), "+r" (uv), "+r" (vv), "+m"(vWidth_)
221                        :
222                        : "memory", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6"
223                        );
224#else
225                for (x = 0; x < vWidth; x++) {
226                        int x2 = x*2, x4 = x*4;
227
228                        __m128i tmp_y = yv[x2], tmp_y3 = yv[x2+1],
229                                        tmp_y2 = yv2[x2], tmp_y4 = yv2[x2+1],
230                                        tmp_u = _mm_loadu_si128(&uv[x]), tmp_v = _mm_loadu_si128(&vv[x]),
231                                        chroma_l = _mm_unpacklo_epi8(tmp_u, tmp_v),
232                                        chroma_h = _mm_unpackhi_epi8(tmp_u, tmp_v);
233                       
234                        _mm_stream_si128(&ov[x4],   _mm_unpacklo_epi8(chroma_l, tmp_y)); 
235                        _mm_stream_si128(&ov[x4+1], _mm_unpackhi_epi8(chroma_l, tmp_y)); 
236                        _mm_stream_si128(&ov[x4+2], _mm_unpacklo_epi8(chroma_h, tmp_y3)); 
237                        _mm_stream_si128(&ov[x4+3], _mm_unpackhi_epi8(chroma_h, tmp_y3)); 
238                       
239                        _mm_stream_si128(&ov2[x4],  _mm_unpacklo_epi8(chroma_l, tmp_y2)); 
240                        _mm_stream_si128(&ov2[x4+1],_mm_unpackhi_epi8(chroma_l, tmp_y2));
241                        _mm_stream_si128(&ov2[x4+2],_mm_unpacklo_epi8(chroma_h, tmp_y4));
242                        _mm_stream_si128(&ov2[x4+3],_mm_unpackhi_epi8(chroma_h, tmp_y4));
243                }
244#endif
245
246                for (x=vWidth * 16; x < halfwidth; x++) {
247                        int x4 = x*4, x2 = x*2;
248                        o2[x4]     = o[x4] = uc[x];
249                        o [x4 + 1] = yc[x2];
250                        o2[x4 + 1] = yc2[x2];
251                        o2[x4 + 2] = o[x4 + 2] = vc[x];
252                        o [x4 + 3] = yc[x2 + 1];
253                        o2[x4 + 3] = yc2[x2 + 1];
254                }                       
255               
256                o  += outRB*2;
257                yc += rY*2;
258                uc += rUV;
259                vc += rUV;
260        }
261
262        HandleLastRow(o, yc, uc, vc, halfwidth, height);
263}
264
265static FASTCALL void Y420toY422_x86_scalar(AVPicture *picture, UInt8 *o, int outRB, int width, int height)
266{
267        UInt8   *yc = picture->data[0], *u = picture->data[1], *v = picture->data[2];
268        int             rY = picture->linesize[0], rUV = picture->linesize[1];
269        int             halfheight = height >> 1, halfwidth = width >> 1;
270        int             y, x;
271       
272        for (y = 0; y < halfheight; y ++) {
273                UInt8 *o2 = o + outRB, *yc2 = yc + rY;
274               
275                for (x = 0; x < halfwidth; x++) {
276                        int x4 = x*4, x2 = x*2;
277                        o2[x4]     = o[x4] = u[x];
278                        o [x4 + 1] = yc[x2];
279                        o2[x4 + 1] = yc2[x2];
280                        o2[x4 + 2] = o[x4 + 2] = v[x];
281                        o [x4 + 3] = yc[x2 + 1];
282                        o2[x4 + 3] = yc2[x2 + 1];
283                }
284               
285                o  += outRB*2;
286                yc += rY*2;
287                u  += rUV;
288                v  += rUV;
289        }
290
291        HandleLastRow(o, yc, u, v, halfwidth, height);
292}
293#endif
294
295//Y420+Alpha Planar to V408 (YUV 4:4:4+Alpha 32-bit packed)
296//Could be fully unrolled to avoid x/2
297static FASTCALL void YA420toV408(AVPicture *picture, UInt8 *o, int outRB, int width, int height)
298{
299        UInt8   *yc = picture->data[0], *u = picture->data[1], *v = picture->data[2], *a = picture->data[3];
300        int             rYA = picture->linesize[0], rUV = picture->linesize[1];
301        int y, x;
302       
303        for (y = 0; y < height; y++) {
304                for (x = 0; x < width; x++) {
305                        o[x*4]   = u[x>>1];
306                        o[x*4+1] = yc[x];
307                        o[x*4+2] = v[x>>1];
308                        o[x*4+3] = a[x];
309                }
310               
311                o  += outRB;
312                yc += rYA;
313                a  += rYA;
314                if (y & 1) {
315                        u += rUV;
316                        v += rUV;
317                }
318        }
319}
320
321static FASTCALL void BGR24toRGB24(AVPicture *picture, UInt8 *baseAddr, int rowBytes, int width, int height)
322{
323        UInt8 *srcPtr = picture->data[0];
324        int srcRB = picture->linesize[0];
325        int x, y;
326       
327        for (y = 0; y < height; y++)
328        {
329                for (x = 0; x < width; x++)
330                {
331                        int x3 = x * 3;
332                        baseAddr[x3] = srcPtr[x3+2];
333                        baseAddr[x3+1] = srcPtr[x3+1];
334                        baseAddr[x3+2] = srcPtr[x3];
335                }
336                baseAddr += rowBytes;
337                srcPtr += srcRB;
338        }
339}
340
341static FASTCALL void RGBtoRGB(AVPicture *picture, UInt8 *baseAddr, int rowBytes, int width, int height, int bytesPerPixel)
342{
343        UInt8 *srcPtr = picture->data[0];
344        int srcRB = picture->linesize[0];
345        int y;
346       
347        for (y = 0; y < height; y++) {
348                memcpy(baseAddr, srcPtr, width * bytesPerPixel);
349               
350                baseAddr += rowBytes;
351                srcPtr += srcRB;
352        }
353}
354
355//Big-endian XRGB32 to big-endian XRGB32
356static FASTCALL void RGB32toRGB32Copy(AVPicture *picture, UInt8 *baseAddr, int rowBytes, int width, int height)
357{
358        RGBtoRGB(picture, baseAddr, rowBytes, width, height, 4);
359}
360
361static FASTCALL void RGB24toRGB24(AVPicture *picture, UInt8 *baseAddr, int rowBytes, int width, int height)
362{
363        RGBtoRGB(picture, baseAddr, rowBytes, width, height, 3);
364}
365
366static FASTCALL void RGB16toRGB16(AVPicture *picture, UInt8 *baseAddr, int rowBytes, int width, int height)
367{
368        RGBtoRGB(picture, baseAddr, rowBytes, width, height, 2);
369}
370
371//Little-endian XRGB32 to big-endian XRGB32
372static FASTCALL void RGB32toRGB32Swap(AVPicture *picture, UInt8 *baseAddr, int rowBytes, int width, int height)
373{
374        UInt8 *srcPtr = picture->data[0];
375        int srcRB = picture->linesize[0];
376        int x, y;
377       
378        for (y = 0; y < height; y++) {
379                UInt32 *oRow = (UInt32 *)baseAddr, *iRow = (UInt32 *)srcPtr;
380                for (x = 0; x < width; x++) oRow[x] = EndianU32_LtoB(iRow[x]);
381               
382                baseAddr += rowBytes;
383                srcPtr += srcRB;
384        }
385}
386
387static FASTCALL void RGB16toRGB16Swap(AVPicture *picture, UInt8 *baseAddr, int rowBytes, int width, int height)
388{
389        UInt8 *srcPtr = picture->data[0];
390        int srcRB = picture->linesize[0];
391        int x, y;
392       
393        for (y = 0; y < height; y++) {
394                UInt16 *oRow = (UInt16 *)baseAddr, *iRow = (UInt16 *)srcPtr;
395                for (x = 0; x < width; x++) oRow[x] = EndianU16_LtoB(iRow[x]);
396               
397                baseAddr += rowBytes;
398                srcPtr += srcRB;
399        }
400}
401
402static FASTCALL void Y422toY422(AVPicture *picture, UInt8 *o, int outRB, int width, int height)
403{
404        UInt8   *yc = picture->data[0], *u = picture->data[1], *v = picture->data[2];
405        int             rY = picture->linesize[0], rUV = picture->linesize[1];
406        int             x, y, halfwidth = width >> 1;
407       
408        for (y = 0; y < height; y++) {
409                for (x = 0; x < halfwidth; x++) {
410                        int x2 = x * 2, x4 = x * 4;
411                        o[x4] = u[x];
412                        o[x4 + 1] = yc[x2];
413                        o[x4 + 2] = v[x];
414                        o[x4 + 3] = yc[x2 + 1];
415                }
416               
417                o  += outRB;
418                yc += rY;
419                u  += rUV;
420                v  += rUV;
421        }
422}
423
424static FASTCALL void Y410toY422(AVPicture *picture, UInt8 *o, int outRB, int width, int height)
425{
426        UInt8   *yc = picture->data[0], *u = picture->data[1], *v = picture->data[2];
427        int             rY = picture->linesize[0], rUV = picture->linesize[1];
428        int             x, y, halfwidth = width >> 1;
429       
430        for (y = 0; y < height; y++) {
431                for (x = 0; x < halfwidth; x++) {
432                        int x2 = x * 2, x4 = x * 4;
433                        o[x4] = u[x>>1];
434                        o[x4 + 1] = yc[x2];
435                        o[x4 + 2] = v[x>>1];
436                        o[x4 + 3] = yc[x2 + 1];
437                }
438               
439                o  += outRB;
440                yc += rY;
441               
442                if ((y & 3) == 3) {
443                        u += rUV;
444                        v += rUV;
445                }
446        }
447}
448
449static void ClearRGB(UInt8 *baseAddr, int rowBytes, int width, int height, int bytesPerPixel)
450{
451        int y;
452       
453        for (y = 0; y < height; y++) {
454                memset(baseAddr, 0, width * bytesPerPixel);
455               
456                baseAddr += rowBytes;
457        }
458}
459
460static FASTCALL void ClearRGB32(UInt8 *baseAddr, int rowBytes, int width, int height)
461{
462        ClearRGB(baseAddr, rowBytes, width, height, 4);
463}
464
465static FASTCALL void ClearRGB24(UInt8 *baseAddr, int rowBytes, int width, int height)
466{
467        ClearRGB(baseAddr, rowBytes, width, height, 3);
468}
469
470static FASTCALL void ClearRGB16(UInt8 *baseAddr, int rowBytes, int width, int height)
471{
472        ClearRGB(baseAddr, rowBytes, width, height, 2);
473}
474
475static FASTCALL void ClearV408(UInt8 *baseAddr, int rowBytes, int width, int height)
476{
477        int x, y;
478       
479        for (y = 0; y < height; y++)
480        {
481                for (x = 0; x < width; x++)
482                {
483                        int x4 = x * 4;
484                        baseAddr[x4]   = 0x80; //zero chroma
485                        baseAddr[x4+1] = 0x10; //black
486                        baseAddr[x4+2] = 0x80; 
487                        baseAddr[x4+3] = 0xEB; //opaque
488                }
489                baseAddr += rowBytes;
490        }
491}
492
493static FASTCALL void ClearY422(UInt8 *baseAddr, int rowBytes, int width, int height)
494{
495        int x, y;
496       
497        for (y = 0; y < height; y++)
498        {
499                for (x = 0; x < width; x++)
500                {
501                        int x2 = x * 2;
502                        baseAddr[x2]   = 0x80; //zero chroma
503                        baseAddr[x2+1] = 0x10; //black
504                }
505                baseAddr += rowBytes;
506        }
507}
508
509OSType ColorConversionDstForPixFmt(enum PixelFormat ffPixFmt)
510{
511        switch (ffPixFmt) {
512                case PIX_FMT_RGB555LE:
513                case PIX_FMT_RGB555BE:
514                        return k16BE555PixelFormat;
515                case PIX_FMT_BGR24:
516                        return k24RGBPixelFormat; //FIXME: try k24BGRPixelFormat
517                case PIX_FMT_RGB24:
518                        return k24RGBPixelFormat;
519                case PIX_FMT_ARGB:
520                case PIX_FMT_BGRA:
521                        return k32ARGBPixelFormat;
522                case PIX_FMT_YUV410P:
523                        return k2vuyPixelFormat;
524                case PIX_FMT_YUVJ420P:
525                case PIX_FMT_YUV420P:
526                        return k2vuyPixelFormat; //disables "fast YUV" path
527                case PIX_FMT_YUV422P:
528                        return k2vuyPixelFormat;
529                case PIX_FMT_YUVA420P:
530                        return k4444YpCbCrA8PixelFormat;
531                default:
532                        return 0; // error
533        }
534}
535
536int ColorConversionFindFor(ColorConversionFuncs *funcs, enum PixelFormat ffPixFmt, AVPicture *ffPicture, OSType qtPixFmt)
537{
538        switch (ffPixFmt) {
539                case PIX_FMT_YUV420P:
540                        funcs->clear = ClearY422;
541                       
542#ifdef __ppc__
543                        if (IsAltivecSupported())
544                                funcs->convert = Y420toY422_ppc_altivec;
545                        else
546                                funcs->convert = Y420toY422_ppc_scalar;
547#else
548                        //can't set this without the first real frame
549                        if (ffPicture) {
550                                if (ffPicture->linesize[0] & 15)
551                                        funcs->convert = Y420toY422_x86_scalar;
552                                else
553                                        funcs->convert = Y420toY422_sse2;
554                        }
555#endif
556                        break;
557                case PIX_FMT_BGR24:
558                        funcs->clear = ClearRGB24;
559                        funcs->convert = BGR24toRGB24;
560                        break;
561                case PIX_FMT_ARGB:
562                        funcs->clear = ClearRGB32;
563#ifdef __ppc__
564                        funcs->convert = RGB32toRGB32Swap;
565#else
566                        funcs->convert = RGB32toRGB32Copy;
567#endif
568                        break;
569                case PIX_FMT_BGRA:
570                        funcs->clear = ClearRGB32;
571#ifdef __ppc__
572                        funcs->convert = RGB32toRGB32Copy;
573#else
574                        funcs->convert = RGB32toRGB32Swap;
575#endif
576                        break;
577                case PIX_FMT_RGB24:
578                        funcs->clear = ClearRGB24;
579                        funcs->convert = RGB24toRGB24;
580                        break;
581                case PIX_FMT_RGB555LE:
582                        funcs->clear = ClearRGB16;
583                        funcs->convert = RGB16toRGB16Swap;
584                        break;
585                case PIX_FMT_RGB555BE:
586                        funcs->clear = ClearRGB16;
587                        funcs->convert = RGB16toRGB16;
588                        break;
589                case PIX_FMT_YUV410P:
590                        funcs->clear = ClearY422;
591                        funcs->convert = Y410toY422;
592                        break;
593                case PIX_FMT_YUV422P:
594                        funcs->clear = ClearY422;
595                        funcs->convert = Y422toY422;
596                        break;
597                case PIX_FMT_YUVA420P:
598                        funcs->clear = ClearV408;
599                        funcs->convert = YA420toV408;
600                        break;
601                default:
602                        return paramErr;
603        }
604       
605        return noErr;
606}
Note: See TracBrowser for help on using the repository browser.