source: trunk/ColorConversions.c @ 1038

Revision 1038, 16.3 KB checked in by astrange, 6 years ago (diff)

Add LGPL license headers to all files (or MIT where appropriate)
Get rid of "All rights reserved" which is LGPL-incompatible.

I didn't touch the Apple sample code, but they should've taken it out too...

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 - rewrite the PPC-only code to just use int instead of all the crazy types
35 - handle YUV 4:2:0 with odd width
36 */
37
38#define unlikely(x) __builtin_expect(x, 0)
39#define likely(x) __builtin_expect(x, 1)
40
41static FASTCALL void FastY420(AVFrame *picture, UInt8 *baseAddr, int outRowBytes, unsigned outWidth, unsigned outHeight)
42{
43    PlanarPixmapInfoYUV420 *planar = (PlanarPixmapInfoYUV420 *)baseAddr;       
44        /*From Docs: PixMap baseAddr points to a big-endian PlanarPixmapInfoYUV420 struct; see ImageCodec.i. */
45   
46    // if ya can't set da poiners, set da offsets
47    planar->componentInfoY.offset  =   EndianU32_NtoB(picture->data[0] - baseAddr);
48    planar->componentInfoCb.offset =   EndianU32_NtoB(picture->data[1] - baseAddr);
49    planar->componentInfoCr.offset =   EndianU32_NtoB(picture->data[2] - baseAddr);
50   
51    // for the 16/32 add look at EDGE in mpegvideo.c
52    planar->componentInfoY.rowBytes  = EndianU32_NtoB(picture->linesize[0]);
53    planar->componentInfoCb.rowBytes = EndianU32_NtoB(picture->linesize[1]);
54    planar->componentInfoCr.rowBytes = EndianU32_NtoB(picture->linesize[2]);
55}
56
57//Handles the last row for Y420 videos with an odd number of luma rows
58//FIXME odd number of luma columns is not handled and they will be lost
59static void Y420toY422_lastrow(UInt8 *o, UInt8 *yc, UInt8 *uc, UInt8 *vc, unsigned halfWidth)
60{
61        int x;
62        for(x=0; x < halfWidth; x++)
63        {
64                int x4 = x*4, x2 = x*2;
65
66                o[x4] = uc[x];
67                o[x4+1] = yc[x2];
68                o[x4+2] = vc[x];
69                o[x4+3] = yc[x2+1];
70        }
71}
72
73#define HandleLastRow(o, yc, uc, vc, halfWidth, height) if (unlikely(height & 1)) Y420toY422_lastrow(o, yc, uc, vc, halfWidth)
74
75//Y420 Planar to Y422 Packed
76//The only one anyone cares about, so implemented with SIMD
77
78#ifdef __ppc__
79//hand-unrolled code is a bad idea on modern CPUs. luckily, this does not run on modern CPUs, only G3s.
80
81static FASTCALL void Y420toY422_ppc_scalar(AVFrame *picture, UInt8 *baseAddr, int outRB, unsigned width, unsigned height)
82{
83         unsigned        y = height / 2;
84         unsigned        halfWidth = width / 2, halfHalfWidth = width / 4;
85         UInt8          *inY = picture->data[0], *inU = picture->data[1], *inV = picture->data[2];
86         int             rB = picture->linesize[0], rbU = picture->linesize[1], rbV = picture->linesize[2];
87         
88         while (y--) {
89                 UInt32         *ldst = (UInt32 *) baseAddr, *ldstr2 = (UInt32 *) (baseAddr + outRB);
90                 UInt32         *lsrc = (UInt32 *) inY, *lsrcr2 = (UInt32 *) (inY + rB);
91                 UInt16         *sU = (UInt16 *) inU, *sV = (UInt16 *) inV;
92                 ptrdiff_t              off;
93                 
94                 for (off = 0; off < halfHalfWidth; off++) {
95                         UInt16          chrU = sU[off], chrV = sV[off];
96                         UInt32          row1luma = lsrc[off], row2luma = lsrcr2[off];
97                         UInt32          chromas1 = (chrU & 0xff00) << 16 | (chrV & 0xff00), chromas2 = (chrU & 0xff) << 24 | (chrV & 0xff) << 8;
98                         int             off2 = off * 2;
99                         
100                         ldst[off2] = chromas1 | (row1luma & 0xff000000) >> 8 | (row1luma & 0xff0000) >> 16;
101                         ldstr2[off2] = chromas1 | (row2luma & 0xff000000) >> 8 | (row2luma & 0xff0000) >> 16;
102                         off2++;
103                         ldst[off2] = chromas2 | (row1luma & 0xff00) << 8 | row1luma & 0xff;
104                         ldstr2[off2] = chromas2 | (row2luma & 0xff00) << 8 | row2luma & 0xff;
105                 }
106                 
107                 if (halfWidth % 4) {
108                         UInt16         *ssrc = (UInt16 *) inY, *ssrcr2 = (UInt16 *) (inY + rB);
109                         
110                         ptrdiff_t       off = halfWidth - 2;
111                         UInt32          chromas = inV[off] << 8 | (inU[off] << 24);
112                         UInt16          row1luma = ssrc[off], row2luma = ssrcr2[off];
113                         
114                         ldst[off] = chromas | row1luma & 0xff | (row1luma & 0xff00) << 8;
115                         ldstr2[off] = chromas | row2luma & 0xff | (row2luma & 0xff00) << 8;
116                 }
117                 inY += rB * 2;
118                 inU += rbU;
119                 inV += rbV;
120                 baseAddr += outRB * 2;
121         }
122       
123        HandleLastRow(baseAddr, inY, inU, inV, halfWidth, height);
124}
125
126static FASTCALL void Y420toY422_ppc_altivec(AVFrame * picture, UInt8 * o, int outRB, unsigned width, unsigned height)
127{
128        UInt8                   *yc = picture->data[0], *uc = picture->data[1], *vc = picture->data[2];
129        unsigned                rY = picture->linesize[0], rU = picture->linesize[1], rV = picture->linesize[2];
130        unsigned                y,x,x2,x4, vWidth = width / 32, halfheight = height / 2;
131       
132        for (y = 0; y < halfheight; y ++) {
133                vUInt8 *ov = (vUInt8 *)o, *ov2 = (vUInt8 *)(o + outRB), *yv2 = (vUInt8 *)(yc + rY);
134                vUInt8 *uv  = (vUInt8 *)uc, *vv = (vUInt8 *)vc, *yv = (vUInt8 *)yc;
135               
136                for (x = 0; x < vWidth; x++) {
137                        x2 = x*2; x4 = x*4;
138                        // ldl/stl = mark data as least recently used in cache so they will be flushed out
139                        __builtin_prefetch(&yv[x+1], 0, 0); __builtin_prefetch(&yv2[x+1], 0, 0);
140                        __builtin_prefetch(&uv[x+1], 0, 0); __builtin_prefetch(&vv[x+1], 0, 0);
141                        vUInt8 tmp_u = vec_ldl(0, &uv[x]), tmp_v = vec_ldl(0, &vv[x]), chroma = vec_mergeh(tmp_u, tmp_v),
142                                        tmp_y = vec_ldl(0, &yv[x2]), tmp_y2 = vec_ldl(0, &yv2[x2]),
143                                        tmp_y3 = vec_ldl(16, &yv[x2]), tmp_y4 = vec_ldl(16, &yv2[x2]), chromal = vec_mergel(tmp_u, tmp_v);
144                       
145                        vec_stl(vec_mergeh(chroma, tmp_y), 0, &ov[x4]);
146                        vec_stl(vec_mergel(chroma, tmp_y), 16, &ov[x4]);
147                        vec_stl(vec_mergeh(chromal, tmp_y3), 32, &ov[x4]);
148                        vec_stl(vec_mergel(chromal, tmp_y3), 48, &ov[x4]);
149                       
150                        vec_stl(vec_mergeh(chroma, tmp_y2), 0, &ov2[x4]);
151                        vec_stl(vec_mergel(chroma, tmp_y2), 16, &ov2[x4]);
152                        vec_stl(vec_mergeh(chromal, tmp_y4), 32, &ov2[x4]);
153                        vec_stl(vec_mergel(chromal, tmp_y4), 48, &ov2[x4]);
154                }
155               
156                if (width % 32) { //spill to scalar for the end if the row isn't a multiple of 32
157                        UInt8 *o2 = o + outRB, *yc2 = yc + rY;
158                        for (x = vWidth * 32, x2 = x*2; x < width; x += 2, x2 += 4) {
159                                unsigned             hx = x / 2;
160                                o2[x2] = o[x2] = uc[hx];
161                                o[x2 + 1] = yc[x];
162                                o2[x2 + 1] = yc2[x];
163                                o2[x2 + 2] = o[x2 + 2] = vc[hx];
164                                o[x2 + 3] = yc[x + 1];
165                                o2[x2 + 3] = yc2[x + 1];
166                        }                       
167                }
168               
169                o += outRB; o += outRB;
170                yc += rY; yc += rY;
171                uc += rU;
172                vc += rV;
173        }
174       
175        HandleLastRow(o, yc, uc, vc, width / 2, height);
176}
177#else
178#include <emmintrin.h>
179
180static FASTCALL void Y420toY422_sse2(AVFrame * picture, UInt8 *o, int outRB, unsigned width, unsigned height)
181{
182        UInt8   *yc = picture->data[0], *uc = picture->data[1], *vc = picture->data[2];
183        int             rY = picture->linesize[0], rU = picture->linesize[1], rV = picture->linesize[2];
184        int             y, x, halfwidth = width / 2 , halfheight = height / 2;
185        int             vWidth = width / 32; 
186       
187        for (y = 0; y < halfheight; y++) {
188                UInt8   * o2 = o + outRB,   * yc2 = yc + rY;
189                __m128i * ov = (__m128i*)o, * ov2 = (__m128i*)o2, * yv = (__m128i*)yc, * yv2 = (__m128i*)yc2;
190                __m128i * uv = (__m128i*)uc,* vv  = (__m128i*)vc;
191               
192#ifdef __i386__
193                int vWidth_ = vWidth;
194
195                asm volatile(
196                        "\n0:                   \n\t"
197                        "movdqa         (%2),   %%xmm0  \n\t"
198                        "movdqa         16(%2), %%xmm2  \n\t"
199                        "movdqa         (%3),           %%xmm1  \n\t"
200                        "movdqa         16(%3), %%xmm3  \n\t"
201                        "movdqu         (%4),   %%xmm4  \n\t"
202                        "movdqu         (%5),   %%xmm5  \n\t"
203                        "addl           $32,    %2              \n\t"
204                        "addl           $32,    %3              \n\t"
205                        "addl           $16,    %4              \n\t"
206                        "addl           $16,    %5              \n\t"
207                        "movdqa         %%xmm4, %%xmm6  \n\t"
208                        "punpcklbw      %%xmm5, %%xmm4  \n\t" /*chroma_l*/
209                        "punpckhbw      %%xmm5, %%xmm6  \n\t" /*chroma_h*/
210                        "movdqa         %%xmm4, %%xmm5  \n\t"
211                        "punpcklbw      %%xmm0, %%xmm5  \n\t"
212                        "movntdq        %%xmm5, (%0)    \n\t" /*ov[x4]*/
213                        "movdqa         %%xmm4, %%xmm5  \n\t"
214                        "punpckhbw      %%xmm0, %%xmm5  \n\t"
215                        "movntdq        %%xmm5, 16(%0)  \n\t" /*ov[x4+1]*/
216                        "movdqa         %%xmm6, %%xmm5  \n\t"
217                        "punpcklbw      %%xmm2, %%xmm5  \n\t"
218                        "movntdq        %%xmm5, 32(%0)  \n\t" /*ov[x4+2]*/
219                        "movdqa         %%xmm6, %%xmm5  \n\t"
220                        "punpckhbw      %%xmm2, %%xmm5  \n\t"
221                        "movntdq        %%xmm5, 48(%0)  \n\t" /*ov[x4+3]*/
222                        "addl           $64,    %0              \n\t"
223                        "movdqa         %%xmm4, %%xmm5  \n\t"
224                        "punpcklbw      %%xmm1, %%xmm5  \n\t"
225                        "movntdq        %%xmm5, (%1)    \n\t" /*ov2[x4]*/
226                        "punpckhbw      %%xmm1, %%xmm4  \n\t"
227                        "movntdq        %%xmm4, 16(%1)  \n\t" /*ov2[x4+1]*/
228                        "movdqa         %%xmm6, %%xmm5  \n\t"
229                        "punpcklbw      %%xmm3, %%xmm5  \n\t"
230                        "movntdq        %%xmm5, 32(%1)  \n\t" /*ov2[x4+2]*/
231                        "punpckhbw      %%xmm3, %%xmm6  \n\t"
232                        "movntdq        %%xmm6, 48(%1)  \n\t" /*ov2[x4+3]*/
233                        "addl           $64,    %1              \n\t"
234                        "decl           %6                              \n\t"
235                        "jnz            0b                              \n\t"
236                        : "+r" (ov), "+r" (ov2),
237                        "+r" (yv), "+r" (yv2), "+r" (uv), "+r" (vv), "+m"(vWidth_)
238                        :
239                        : "memory", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6"
240                        );
241#else
242                for (x = 0; x < vWidth; x++) {
243                        int x2 = x*2, x4 = x*4;
244
245                        __m128i tmp_y = yv[x2], tmp_y3 = yv[x2+1],
246                                        tmp_y2 = yv2[x2], tmp_y4 = yv2[x2+1],
247                                        tmp_u = _mm_loadu_si128(&uv[x]), tmp_v = _mm_loadu_si128(&vv[x]),
248                                        chroma_l = _mm_unpacklo_epi8(tmp_u, tmp_v),
249                                        chroma_h = _mm_unpackhi_epi8(tmp_u, tmp_v);
250                       
251                        _mm_stream_si128(&ov[x4],   _mm_unpacklo_epi8(chroma_l, tmp_y)); 
252                        _mm_stream_si128(&ov[x4+1], _mm_unpackhi_epi8(chroma_l, tmp_y)); 
253                        _mm_stream_si128(&ov[x4+2], _mm_unpacklo_epi8(chroma_h, tmp_y3)); 
254                        _mm_stream_si128(&ov[x4+3], _mm_unpackhi_epi8(chroma_h, tmp_y3)); 
255                       
256                        _mm_stream_si128(&ov2[x4],  _mm_unpacklo_epi8(chroma_l, tmp_y2)); 
257                        _mm_stream_si128(&ov2[x4+1],_mm_unpackhi_epi8(chroma_l, tmp_y2));
258                        _mm_stream_si128(&ov2[x4+2],_mm_unpacklo_epi8(chroma_h, tmp_y4));
259                        _mm_stream_si128(&ov2[x4+3],_mm_unpackhi_epi8(chroma_h, tmp_y4));
260                }
261#endif
262
263                for (x=vWidth * 16; x < halfwidth; x++) {
264                        int x4 = x*4, x2 = x*2;
265                        o2[x4] = o[x4] = uc[x];
266                        o[x4 + 1] = yc[x2];
267                        o2[x4 + 1] = yc2[x2];
268                        o2[x4 + 2] = o[x4 + 2] = vc[x];
269                        o[x4 + 3] = yc[x2 + 1];
270                        o2[x4 + 3] = yc2[x2 + 1];
271                }                       
272               
273                o += outRB*2;
274                yc += rY*2;
275                uc += rU;
276                vc += rV;
277        }
278
279        HandleLastRow(o, yc, uc, vc, halfwidth, height);
280}
281
282static FASTCALL void Y420toY422_x86_scalar(AVFrame * picture, UInt8 * o, int outRB, unsigned width, unsigned height)
283{
284        UInt8   *yc = picture->data[0], *u = picture->data[1], *v = picture->data[2];
285        int             rY = picture->linesize[0], rU = picture->linesize[1], rV = picture->linesize[2];
286        int             halfheight = height / 2, halfwidth = width / 2;
287        int             y, x;
288       
289        for (y = 0; y < halfheight; y ++) {
290                UInt8 *o2 = o + outRB, *yc2 = yc + rY;
291               
292                for (x = 0; x < halfwidth; x++) {
293                        int x4 = x*4, x2 = x*2;
294                        o2[x4] = o[x4] = u[x];
295                        o[x4 + 1] = yc[x2];
296                        o2[x4 + 1] = yc2[x2];
297                        o2[x4 + 2] = o[x4 + 2] = v[x];
298                        o[x4 + 3] = yc[x2 + 1];
299                        o2[x4 + 3] = yc2[x2 + 1];
300                }
301               
302                o += outRB*2;
303                yc += rY*2;
304                u += rU;
305                v += rV;
306        }
307
308        HandleLastRow(o, yc, u, v, halfwidth, height);
309}
310#endif
311
312//Y420+Alpha Planar to V408 (YUV 4:4:4+Alpha 32-bit packed)
313//Could be fully unrolled to avoid x/2
314static FASTCALL void YA420toV408(AVFrame *picture, UInt8 *o, int outRB, unsigned width, unsigned height)
315{
316        UInt8   *yc = picture->data[0], *u = picture->data[1], *v = picture->data[2], *a = picture->data[3];
317        int             rY = picture->linesize[0], rU = picture->linesize[1], rV = picture->linesize[2], rA = picture->linesize[3];
318        unsigned y, x;
319       
320        for (y = 0; y < height; y++) {
321                for (x = 0; x < width; x++) {
322                        o[x*4] = u[x/2];
323                        o[x*4+1] = yc[x];
324                        o[x*4+2] = v[x/2];
325                        o[x*4+3] = a[x];
326                }
327               
328                o += outRB;
329                yc += rY;
330                a += rA;
331                if (y & 1) {
332                        u += rU;
333                        v += rV;
334                }
335        }
336}
337
338static FASTCALL void BGR24toRGB24(AVFrame *picture, UInt8 *baseAddr, int rowBytes, unsigned width, unsigned height)
339{
340        UInt8 *srcPtr = picture->data[0];
341        int srcRB = picture->linesize[0];
342        int x, y;
343       
344        for (y = 0; y < height; y++)
345        {
346                for (x = 0; x < width; x++)
347                {
348                        unsigned x3 = x * 3;
349                        baseAddr[x3] = srcPtr[x3+2];
350                        baseAddr[x3+1] = srcPtr[x3+1];
351                        baseAddr[x3+2] = srcPtr[x3];
352                }
353                baseAddr += rowBytes;
354                srcPtr += srcRB;
355        }
356}
357
358//Native-endian XRGB32 to big-endian XRGB32
359static FASTCALL void RGB32toRGB32(AVFrame *picture, UInt8 *baseAddr, int rowBytes, unsigned width, unsigned height)
360{
361        UInt8 *srcPtr = picture->data[0];
362        int srcRB = picture->linesize[0];
363        int y;
364
365        for (y = 0; y < height; y++) {
366#ifdef __BIG_ENDIAN__
367                memcpy(baseAddr, srcPtr, width * 4);
368#else
369                UInt32 *oRow = (UInt32 *)baseAddr, *iRow = (UInt32 *)srcPtr;
370                int x;
371                for (x = 0; x < width; x++) {oRow[x] = EndianU32_NtoB(iRow[x]);}
372#endif
373               
374                baseAddr += rowBytes;
375                srcPtr += srcRB;
376        }
377}
378
379static FASTCALL void RGB24toRGB24(AVFrame *picture, UInt8 *baseAddr, int rowBytes, unsigned width, unsigned height)
380{
381        UInt8 *srcPtr = picture->data[0];
382        int srcRB = picture->linesize[0];
383        int y;
384       
385        for (y = 0; y < height; y++) {
386                memcpy(baseAddr, srcPtr, width * 3);
387               
388                baseAddr += rowBytes;
389                srcPtr += srcRB;
390        }
391}
392
393static FASTCALL void Y422toY422(AVFrame *picture, UInt8 *o, int outRB, unsigned width, unsigned height)
394{
395        UInt8   *yc = picture->data[0], *u = picture->data[1], *v = picture->data[2];
396        int             rY = picture->linesize[0], rU = picture->linesize[1], rV = picture->linesize[2];
397        int             x, y, halfwidth = width / 2;
398       
399        for (y = 0; y < height; y++) {
400                for (x = 0; x < halfwidth; x++) {
401                        int x2 = x * 2, x4 = x * 4;
402                        o[x4] = u[x];
403                        o[x4 + 1] = yc[x2];
404                        o[x4 + 2] = v[x];
405                        o[x4 + 3] = yc[x2 + 1];
406                }
407               
408                o += outRB;
409                yc += rY;
410                u += rU;
411                v += rV;
412        }
413}
414
415static void ClearRGB(UInt8 *baseAddr, int rowBytes, unsigned width, unsigned height, int bytesPerPixel)
416{
417        int y;
418       
419        for (y = 0; y < height; y++) {
420                memset(baseAddr, 0, width * bytesPerPixel);
421               
422                baseAddr += rowBytes;
423        }
424}
425
426static FASTCALL void ClearRGB32(UInt8 *baseAddr, int rowBytes, unsigned width, unsigned height)
427{
428        ClearRGB(baseAddr, rowBytes, width, height, 4);
429}
430
431static FASTCALL void ClearRGB24(UInt8 *baseAddr, int rowBytes, unsigned width, unsigned height)
432{
433        ClearRGB(baseAddr, rowBytes, width, height, 3);
434}
435
436static FASTCALL void ClearV408(UInt8 *baseAddr, int rowBytes, unsigned width, unsigned height)
437{
438        int x, y;
439       
440        for (y = 0; y < height; y++)
441        {
442                for (x = 0; x < width; x++)
443                {
444                        unsigned x4 = x * 4;
445                        baseAddr[x4]   = 0x80; //zero chroma
446                        baseAddr[x4+1] = 0x10; //black
447                        baseAddr[x4+2] = 0x80; 
448                        baseAddr[x4+3] = 0xEB; //opaque
449                }
450                baseAddr += rowBytes;
451        }
452}
453
454static FASTCALL void ClearY422(UInt8 *baseAddr, int rowBytes, unsigned width, unsigned height)
455{
456        int x, y;
457       
458        for (y = 0; y < height; y++)
459        {
460                for (x = 0; x < width; x++)
461                {
462                        unsigned x2 = x * 2;
463                        baseAddr[x2]   = 0x80; //zero chroma
464                        baseAddr[x2+1] = 0x10; //black
465                }
466                baseAddr += rowBytes;
467        }
468}
469
470static FASTCALL void ClearNone(UInt8 *baseAddr, int rowBytes, unsigned width, unsigned height)
471{
472}
473
474int ColorConversionFindFor(ColorConversionFuncs *funcs, enum PixelFormat ffPixFmt, AVFrame *ffPicture, OSType qtPixFmt)
475{       
476        if (qtPixFmt == kYUV420CodecType && ffPixFmt == PIX_FMT_YUV420P)
477        {
478                funcs->clear = ClearNone;
479                funcs->convert = FastY420;
480        }
481        else if (qtPixFmt == k2vuyPixelFormat && ffPixFmt == PIX_FMT_YUV420P)
482        {
483                funcs->clear = ClearY422;
484
485#ifdef __ppc__
486                if (IsAltivecSupported())
487                        funcs->convert = Y420toY422_ppc_altivec;
488                else
489                        funcs->convert = Y420toY422_ppc_scalar;
490#else
491                //can't set this without the first real frame
492                if (ffPicture) {
493                        if (ffPicture->linesize[0] % 16)
494                                funcs->convert = Y420toY422_x86_scalar;
495                        else
496                                funcs->convert = Y420toY422_sse2;
497                }
498#endif         
499        }
500        else if (qtPixFmt == k24RGBPixelFormat && ffPixFmt == PIX_FMT_BGR24)
501        {
502                funcs->clear = ClearRGB24;
503                funcs->convert = BGR24toRGB24;
504        }
505        else if (qtPixFmt == k32ARGBPixelFormat && ffPixFmt == PIX_FMT_RGB32)
506        {
507                funcs->clear = ClearRGB32;
508                funcs->convert = RGB32toRGB32;
509        }
510        else if (qtPixFmt == k24RGBPixelFormat && ffPixFmt == PIX_FMT_RGB24)
511        {
512                funcs->clear = ClearRGB24;
513                funcs->convert = RGB24toRGB24;
514        }
515        else if (qtPixFmt == k2vuyPixelFormat && ffPixFmt == PIX_FMT_YUV422P)
516        {
517                funcs->clear = ClearY422;
518                funcs->convert = Y422toY422;
519        }
520        else if (qtPixFmt == k4444YpCbCrA8PixelFormat && ffPixFmt == PIX_FMT_YUVA420P)
521        {
522                funcs->clear = ClearV408;
523                funcs->convert = YA420toV408;
524        }
525        else
526        {
527                return paramErr;
528        }
529       
530        return noErr;
531}
Note: See TracBrowser for help on using the repository browser.