Changeset 278

Show
Ignore:
Timestamp:
01/09/07 21:00:17 (2 years ago)
Author:
astrange
Message:

Endian-swap RGB32 on x86. Optimize YUV 4:2:2 very slightly (untested on PPC).

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/FFusionCodec.c

    r243 r278  
    104104static OSErr FFusionDecompress(AVCodecContext *context, UInt8 *dataPtr, ICMDataProcRecordPtr dataProc, long width, long height, AVFrame *picture, long length, int useFirstFrameHack, int failSilently); 
    105105static void FastY420(UInt8 *baseAddr, AVFrame *picture); 
    106 static void SlowY420(UInt8 *baseAddr, long rowBump, long width, long height, AVFrame *picture); 
     106static void SlowY420(UInt8* baseAddr, int outRB, int width, int height, AVFrame * picture); 
     107static void EndianSwapRow32(UInt32 *d, UInt32 *s, size_t n); 
    107108static void BGR24toRGB24(UInt8 *baseAddr, long rowBump, long width, long height, AVFrame *picture); 
    108109static int FFusionGetBuffer(AVCodecContext *s, AVFrame *pic); 
     
    936937                Ptr src = (Ptr) picture->data[0]; 
    937938                for (i = 0; i < myDrp->height; i++) { 
     939#ifdef __BIG_ENDIAN__ 
    938940                        memcpy(dest, src, FFMIN(drp->rowBytes, picture->linesize[0])); 
     941#else 
     942                        EndianSwapRow32(dest, src, myDrp->width); 
     943#endif 
    939944                        dest += drp->rowBytes; 
    940945                        src += picture->linesize[0]; 
     
    13371342//----------------------------------------------------------------- 
    13381343 
    1339 static void SlowY420(UInt8 *baseAddr, long rowBump, long width, long height, AVFrame *picture) 
    1340 
    1341     unsigned int i, j; 
    1342     char *yuvPtr; 
    1343     char *py,*pu,*pv; 
    1344          
    1345     // now let's do some yuv420/vuy2 conversion 
    1346      
    1347     yuvPtr = (char *)baseAddr; 
    1348     py = (char *)picture->data[0]; 
    1349     pu = (char *)picture->data[1]; 
    1350     pv = (char *)picture->data[2]; 
    1351          
    1352     for(i = 0 ;  i < height; i++) 
    1353     { 
    1354         for(j = 0; j < width; j+= 2) 
    1355         { 
    1356             yuvPtr[2*j] = pu[j>>1]; 
    1357             yuvPtr[2*j+1] = py[j]; 
    1358             yuvPtr[2*j+2] = pv[j>>1]; 
    1359             yuvPtr[2*j+3] = py[j+1]; 
    1360         } 
    1361          
    1362         yuvPtr += rowBump; 
    1363         py += picture->linesize[0]; 
    1364          
    1365         if (i & 1) 
    1366         { 
    1367             pu += picture->linesize[1]; 
    1368             pv += picture->linesize[2]; 
    1369         } 
    1370     } 
    1371 
     1344#ifdef __BIG_ENDIAN__ 
     1345//hand-unrolled code is a bad idea on modern CPUs. luckily, this does not run on modern CPUs, only G3s. 
     1346//also, big-endian only 
     1347static void  
     1348SlowY420(UInt8* baseAddr, int outRB, int width, int height, AVFrame * picture) 
     1349
     1350        int             y = height >> 1; 
     1351        int             halfWidth = width >> 1, halfHalfWidth = halfWidth >> 1; 
     1352        UInt8          *inY = picture->data[0], *inU = picture->data[1], *inV = picture->data[2]; 
     1353        int             rB = picture->linesize[0], rbU = picture->linesize[1], rbV = picture->linesize[2]; 
     1354         
     1355        while (y--) { 
     1356                UInt32         *ldst = (UInt32 *) baseAddr, *ldstr2 = (UInt32 *) (baseAddr + outRB); 
     1357                UInt32         *lsrc = (UInt32 *) inY, *lsrcr2 = (UInt32 *) (inY + rB); 
     1358                UInt16         *sU = (UInt16 *) inU, *sV = (UInt16 *) inV; 
     1359                ptrdiff_t               off; 
     1360                 
     1361                for (off = 0; off < halfHalfWidth; off++) { 
     1362                        UInt16          chrU = sU[off], chrV = sV[off]; 
     1363                        UInt32          row1luma = lsrc[off], row2luma = lsrcr2[off]; 
     1364                        UInt32          chromas1 = (chrU & 0xff00) << 16 | (chrV & 0xff00), 
     1365                                chromas2 = (chrU & 0xff) << 24 | (chrV & 0xff) << 8; 
     1366                        int             off2 = off * 2; 
     1367                         
     1368                        ldst[off2] = chromas1 | (row1luma & 0xff000000) >> 8 | (row1luma & 0xff0000) >> 16; 
     1369                        ldstr2[off2] = chromas1 | (row2luma & 0xff000000) >> 8 | (row2luma & 0xff0000) >> 16; 
     1370                        off2++; 
     1371                        ldst[off2] = chromas2 | (row1luma & 0xff00) << 8 | row1luma & 0xff; 
     1372                        ldstr2[off2] = chromas2 | (row2luma & 0xff00) << 8 | row2luma & 0xff; 
     1373                } 
     1374                 
     1375                if (halfWidth % 4) { 
     1376                        UInt16         *ssrc = (UInt16 *) inY, *ssrcr2 = (UInt16 *) (inY + rB); 
     1377                         
     1378                        ptrdiff_t       off = halfWidth - 2; 
     1379                        UInt32          chromas = inV[off] << 8 | (inU[off] << 24); 
     1380                        UInt16          row1luma = ssrc[off], row2luma = ssrcr2[off]; 
     1381                         
     1382                        ldst[off] = chromas | row1luma & 0xff | (row1luma & 0xff00) << 8; 
     1383                        ldstr2[off] = chromas | row2luma & 0xff | (row2luma & 0xff00) << 8; 
     1384                } 
     1385                inY += rB * 2; 
     1386                inU += rbU; 
     1387                inV += rbV; 
     1388                baseAddr += outRB * 2; 
     1389        } 
     1390
     1391#else 
     1392static void  
     1393SlowY420(UInt8* o, int outRB, int width, int height, AVFrame * picture) 
     1394
     1395        UInt8          *yc = picture->data[0], *u = picture->data[1], *v = picture->data[2]; 
     1396        int             rY = picture->linesize[0], rU = picture->linesize[1], rV = picture->linesize[2], y = 0, x, x2; 
     1397         
     1398        for (; y < height; y++) { 
     1399                for (x = 0, x2 = 0; x < width; x += 2, x2 += 4) { 
     1400                        int             hx = x >> 1; 
     1401                        o[x2] = u[hx]; 
     1402                        o[x2 + 1] = yc[x]; 
     1403                        o[x2 + 2] = v[hx]; 
     1404                        o[x2 + 3] = yc[x + 1]; 
     1405                } 
     1406                 
     1407                o += outRB; 
     1408                yc += rY; 
     1409                if (y % 2) { 
     1410                        u += rU; 
     1411                        v += rV; 
     1412                } 
     1413        } 
     1414
     1415#endif 
    13721416 
    13731417static void BGR24toRGB24(UInt8 *baseAddr, long rowBump, long width, long height, AVFrame *picture) 
     
    13891433} 
    13901434 
     1435static void EndianSwapRow32(UInt32 *d, UInt32 *s, size_t n) 
     1436{ 
     1437        while (n--) {*d++ = EndianU32_NtoB(*s); s++;} 
     1438}