source: trunk/ColorConversions.c @ 1249

Revision 1249, 17.9 KB checked in by astrange, 4 years ago (diff)

Fix compilation with ffmpeg trunk.

Two patches no longer apply, but are fixed upstream or
aren't important to need updating.

PIX_FMT_RGB32 is no longer visible outside ffmpeg.
We could include its config.h but this is actually
more correct already.

Not properly tested, Huffyuv on PPC might display wrong.

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