Changeset bae04ee86f451d93afa221ae95a51d0bb424b634

Show
Ignore:
Timestamp:
31/05/07 11:56:25 (1 year ago)
Author:
Damien Fouilleul <damienf@videolan.org>
git-committer:
Damien Fouilleul <damienf@videolan.org> 1180605385 +0000
git-parent:

[9af412916f0472b37e19194b0c23db9638678d77]

git-author:
Damien Fouilleul <damienf@videolan.org> 1180605385 +0000
Message:

- video_chroma: added support for IA-32/64 SSE2 accelaration (128 bit vector integer registers), needs LOADS of testing

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • configure.ac

    r11884b8 rbae04ee  
    12701270THREEDNOW_MODULES="memcpy3dn" 
    12711271SSE_MODULES="" 
     1272SSE2_MODULES="" 
    12721273ALTIVEC_MODULES="memcpyaltivec i420_yuy2_altivec" 
    12731274#ALTIVEC_MODULES="${ALTIVEC_MODULES} idctaltivec motionaltivec" 
     
    12761277then 
    12771278  MMX_MODULES="${MMX_MODULES} i420_yuy2_mmx" 
    1278 fi 
    1279  
    1280 AC_CACHE_CHECK([if \$CC groks MMX inline assembly], 
    1281     [ac_cv_mmx_inline], 
    1282     [CFLAGS="${CFLAGS_save}" 
    1283      AC_TRY_COMPILE(,[void *p;asm volatile("packuswb %%mm1,%%mm2"::"r"(p));], 
    1284                     ac_cv_mmx_inline=yes, ac_cv_mmx_inline=no)]) 
    1285 if test "${ac_cv_mmx_inline}" != "no"; then 
    1286   AC_DEFINE(CAN_COMPILE_MMX, 1, Define if \$CC groks MMX inline assembly.) 
    1287   ACCEL_MODULES="${ACCEL_MODULES} ${MMX_MODULES}" 
     1279  SSE2_MODULES="${SSE2_MODULES} i420_yuy2_sse2" 
    12881280fi 
    12891281 
     
    13131305fi 
    13141306 
     1307dnl  Check for fully workin SSE2 intrinsics 
     1308dnl  We need support for -mmmx, we need <emmintrin.h>, and we also need a 
     1309dnl  working compiler (http://gcc.gnu.org/bugzilla/show_bug.cgi?id=23963) 
     1310AC_CACHE_CHECK([if \$CC groks SSE2 intrinsics], 
     1311    [ac_cv_c_sse2_intrinsics], 
     1312    [CFLAGS="${CFLAGS_save} -O -msse2" 
     1313     AC_TRY_COMPILE([#include <emmintrin.h> 
     1314                     #include <stdint.h> 
     1315                     uint64_t frobzor;], 
     1316                    [__m128i a, b, c; 
     1317                     a = b = c = _mm_set1_epi64((__m64)frobzor); 
     1318                     a = _mm_slli_epi16(a, 3); 
     1319                     a = _mm_adds_epi16(a, b); 
     1320                     c = _mm_srli_epi16(c, 8); 
     1321                     c = _mm_slli_epi16(c, 3); 
     1322                     b = _mm_adds_epi16(b, c); 
     1323                     a = _mm_unpacklo_epi8(a, b); 
     1324                     frobzor = (uint64_t)_mm_movepi64_pi64(a);], 
     1325                    [ac_cv_c_sse2_intrinsics=yes], 
     1326                    [ac_cv_c_sse2_intrinsics=no])]) 
     1327if test "${ac_cv_c_sse2_intrinsics}" != "no"; then 
     1328  AC_DEFINE(HAVE_SSE2_INTRINSICS, 1, Define if SSE2 intrinsics are available.) 
     1329  dnl VLC_ADD_CFLAGS([i420_rgb_sse2],[-msse2]) 
     1330fi 
     1331 
     1332AC_CACHE_CHECK([if \$CC groks MMX inline assembly], 
     1333    [ac_cv_mmx_inline], 
     1334    [CFLAGS="${CFLAGS_save}" 
     1335     AC_TRY_COMPILE(,[void *p;asm volatile("packuswb %%mm1,%%mm2"::"r"(p));], 
     1336                    ac_cv_mmx_inline=yes, ac_cv_mmx_inline=no)]) 
     1337if test "${ac_cv_mmx_inline}" != "no"; then 
     1338  AC_DEFINE(CAN_COMPILE_MMX, 1, Define if \$CC groks MMX inline assembly.) 
     1339  ACCEL_MODULES="${ACCEL_MODULES} ${MMX_MODULES}" 
     1340fi 
     1341 
    13151342AC_CACHE_CHECK([if \$CC groks MMX EXT inline assembly], 
    13161343    [ac_cv_mmxext_inline], 
     
    13411368  AC_DEFINE(CAN_COMPILE_SSE, 1, Define if \$CC groks SSE inline assembly.) 
    13421369  ACCEL_MODULES="${ACCEL_MODULES} ${SSE_MODULES}" 
     1370fi 
     1371 
     1372AC_CACHE_CHECK([if \$CC groks SSE2 inline assembly], 
     1373    [ac_cv_sse2_inline], 
     1374    [CFLAGS="${CFLAGS_save}" 
     1375     AC_TRY_COMPILE(,[void *p;asm volatile("punpckhqdq %%xmm1,%%xmm2"::"r"(p));], 
     1376                    ac_cv_sse2_inline=yes, ac_cv_sse2_inline=no)]) 
     1377if test "${ac_cv_sse2_inline}" != "no" -a "${SYS}" != "solaris"; then 
     1378  AC_DEFINE(CAN_COMPILE_SSE2, 1, Define if \$CC groks SSE2 inline assembly.) 
     1379  ACCEL_MODULES="${ACCEL_MODULES} ${SSE2_MODULES}" 
    13431380fi 
    13441381 
     
    14931530then 
    14941531    ARCH="${ARCH} mmx" 
     1532    VLC_ADD_BUILTINS([${ACCEL_MODULES}]) 
     1533fi 
     1534if test "${host_cpu}" = "i686" -o "${host_cpu}" = "x86_64" 
     1535then 
     1536    ARCH="${ARCH} sse sse2" 
    14951537    VLC_ADD_BUILTINS([${ACCEL_MODULES}]) 
    14961538fi 
  • modules/video_chroma/Modules.am

    rb3e689d rbae04ee  
    2020 
    2121SOURCES_i420_yuy2_mmx = \ 
     22    i420_yuy2.c \ 
     23    i420_yuy2.h \ 
     24    $(NULL) 
     25 
     26SOURCES_i420_yuy2_sse2 = \ 
    2227    i420_yuy2.c \ 
    2328    i420_yuy2.h \ 
  • modules/video_chroma/i420_yuy2.c

    rd3fe7f2 rbae04ee  
    66 * 
    77 * Authors: Samuel Hocevar <sam@zoy.org> 
     8 *          Damien Fouilleul <damien@videolan.org> 
    89 * 
    910 * This program is free software; you can redistribute it and/or modify 
     
    4344#elif defined (MODULE_NAME_IS_i420_yuy2_mmx) 
    4445#    define DEST_FOURCC "YUY2,YUNV,YVYU,UYVY,UYNV,Y422,IUYV,cyuv" 
     46#elif defined (MODULE_NAME_IS_i420_yuy2_sse2) 
     47#    define DEST_FOURCC "YUY2,YUNV,YVYU,UYVY,UYNV,Y422,IUYV,cyuv" 
    4548#elif defined (MODULE_NAME_IS_i420_yuy2_altivec) 
    4649#    define DEST_FOURCC "YUY2,YUNV,YVYU,UYVY,UYNV,Y422" 
     
    6467 
    6568#ifdef MODULE_NAME_IS_i420_yuy2_mmx 
    66 static uint64_t i_00ffw; 
    67 static uint64_t i_80w; 
     69/* Initialize MMX-specific constants */ 
     70static const uint64_t i_00ffw = 0x00ff00ff00ff00ffULL; 
     71static const uint64_t i_80w   = 0x0000000080808080ULL; 
    6872#endif 
    6973 
     
    7983    set_capability( "chroma", 100 ); 
    8084    add_requirement( MMX ); 
    81     /* Initialize MMX-specific constants */ 
    82     i_00ffw = 0x00ff00ff00ff00ffULL; 
    83     i_80w   = 0x0000000080808080ULL; 
     85#elif defined (MODULE_NAME_IS_i420_yuy2_sse2) 
     86    set_description( _("SSE2 conversions from " SRC_FOURCC " to " DEST_FOURCC) ); 
     87    set_capability( "chroma", 120 ); 
     88    add_requirement( SSE2 ); 
    8489#elif defined (MODULE_NAME_IS_i420_yuy2_altivec) 
    8590    set_description( 
     
    126131                    p_vout->chroma.pf_convert = I420_UYVY; 
    127132                    break; 
    128  
    129133#if !defined (MODULE_NAME_IS_i420_yuy2_altivec) 
    130134                case VLC_FOURCC('I','U','Y','V'): 
     
    257261                               - p_dest->p->i_visible_pitch; 
    258262 
     263#if !defined(MODULE_NAME_IS_i420_yuy2_sse2) 
    259264    for( i_y = p_vout->render.i_height / 2 ; i_y-- ; ) 
    260265    { 
     
    266271 
    267272#if !defined (MODULE_NAME_IS_i420_yuy2_mmx) 
    268         for( i_x = p_vout->render.i_width / 2 ; i_x-- ; ) 
    269         { 
     273        for( i_x = p_vout->render.i_width / 8; i_x-- ; ) 
     274        { 
     275            C_YUV420_YUYV( ); 
     276            C_YUV420_YUYV( ); 
     277            C_YUV420_YUYV( ); 
    270278            C_YUV420_YUYV( ); 
    271279        } 
     
    275283            MMX_CALL( MMX_YUV420_YUYV ); 
    276284        } 
     285#endif 
    277286        for( i_x = ( p_vout->render.i_width % 8 ) / 2; i_x-- ; ) 
    278287        { 
    279288            C_YUV420_YUYV( ); 
    280289        } 
    281 #endif 
    282290 
    283291        p_y1 += i_source_margin; 
     
    289297    } 
    290298 
     299#if defined (MODULE_NAME_IS_i420_yuy2_mmx) 
     300    __asm__ __volatile__("emms" :: ); 
     301#endif 
     302 
    291303#if defined (MODULE_NAME_IS_i420_yuy2_altivec) 
    292304    } 
    293305#endif 
     306 
     307#else // defined(MODULE_NAME_IS_i420_yuy2_sse2) 
     308    /* 
     309    ** SSE2 128 bytes fetch/store instructions are faster  
     310    ** if memory access is 16 bytes aligned 
     311    */ 
     312    if( 0 == (15 & (p_source->p[Y_PLANE].i_pitch|p_dest->p->i_pitch| 
     313        ((int)p_line2|(int)p_y2))) ) 
     314    { 
     315        /* use faster SSE2 aligned fetch and store */ 
     316        for( i_y = p_vout->render.i_height / 2 ; i_y-- ; ) 
     317        { 
     318            p_line1 = p_line2; 
     319            p_line2 += p_dest->p->i_pitch; 
     320 
     321            p_y1 = p_y2; 
     322            p_y2 += p_source->p[Y_PLANE].i_pitch; 
     323 
     324            for( i_x = p_vout->render.i_width / 16 ; i_x-- ; ) 
     325            { 
     326                SSE2_CALL( SSE2_YUV420_YUYV_ALIGNED ); 
     327            } 
     328            for( i_x = ( p_vout->render.i_width % 16 ) / 2; i_x-- ; ) 
     329            { 
     330                C_YUV420_YUYV( ); 
     331            } 
     332 
     333            p_y1 += i_source_margin; 
     334            p_y2 += i_source_margin; 
     335            p_u += i_source_margin_c; 
     336            p_v += i_source_margin_c; 
     337            p_line1 += i_dest_margin; 
     338            p_line2 += i_dest_margin; 
     339        } 
     340    } 
     341    else 
     342    { 
     343        /* use slower SSE2 unaligned fetch and store */ 
     344        for( i_y = p_vout->render.i_height / 2 ; i_y-- ; ) 
     345        { 
     346            p_line1 = p_line2; 
     347            p_line2 += p_dest->p->i_pitch; 
     348 
     349            p_y1 = p_y2; 
     350            p_y2 += p_source->p[Y_PLANE].i_pitch; 
     351 
     352            for( i_x = p_vout->render.i_width / 16 ; i_x-- ; ) 
     353            { 
     354                SSE2_CALL( SSE2_YUV420_YUYV_UNALIGNED ); 
     355            } 
     356            for( i_x = ( p_vout->render.i_width % 16 ) / 2; i_x-- ; ) 
     357            { 
     358                C_YUV420_YUYV( ); 
     359            } 
     360 
     361            p_y1 += i_source_margin; 
     362            p_y2 += i_source_margin; 
     363            p_u += i_source_margin_c; 
     364            p_v += i_source_margin_c; 
     365            p_line1 += i_dest_margin; 
     366            p_line2 += i_dest_margin; 
     367        } 
     368    } 
     369#endif // defined(MODULE_NAME_IS_i420_yuy2_sse2) 
    294370} 
    295371 
     
    394470                               - p_dest->p->i_visible_pitch; 
    395471 
     472#if !defined(MODULE_NAME_IS_i420_yuy2_sse2) 
    396473    for( i_y = p_vout->render.i_height / 2 ; i_y-- ; ) 
    397474    { 
     
    421498        p_line2 += i_dest_margin; 
    422499    } 
     500 
     501#if defined (MODULE_NAME_IS_i420_yuy2_mmx) 
     502    __asm__ __volatile__("emms" :: ); 
     503#endif 
     504 
    423505#if defined (MODULE_NAME_IS_i420_yuy2_altivec) 
    424506    } 
    425507#endif 
     508 
     509#else // defined(MODULE_NAME_IS_i420_yuy2_sse2) 
     510    /* 
     511    ** SSE2 128 bytes fetch/store instructions are faster  
     512    ** if memory access is 16 bytes aligned 
     513    */ 
     514    if( 0 == (15 & (p_source->p[Y_PLANE].i_pitch|p_dest->p->i_pitch| 
     515        ((int)p_line2|(int)p_y2))) ) 
     516    { 
     517        /* use faster SSE2 aligned fetch and store */ 
     518        for( i_y = p_vout->render.i_height / 2 ; i_y-- ; ) 
     519        { 
     520            p_line1 = p_line2; 
     521            p_line2 += p_dest->p->i_pitch; 
     522 
     523            p_y1 = p_y2; 
     524            p_y2 += p_source->p[Y_PLANE].i_pitch; 
     525 
     526            for( i_x = p_vout->render.i_width / 16 ; i_x-- ; ) 
     527            { 
     528                SSE2_CALL( SSE2_YUV420_YVYU_ALIGNED ); 
     529            } 
     530            for( i_x = ( p_vout->render.i_width % 16 ) / 2; i_x-- ; ) 
     531            { 
     532                C_YUV420_YVYU( ); 
     533            } 
     534 
     535            p_y1 += i_source_margin; 
     536            p_y2 += i_source_margin; 
     537            p_u += i_source_margin_c; 
     538            p_v += i_source_margin_c; 
     539            p_line1 += i_dest_margin; 
     540            p_line2 += i_dest_margin; 
     541        } 
     542    } 
     543    else 
     544    { 
     545        /* use slower SSE2 unaligned fetch and store */ 
     546        for( i_y = p_vout->render.i_height / 2 ; i_y-- ; ) 
     547        { 
     548            p_line1 = p_line2; 
     549            p_line2 += p_dest->p->i_pitch; 
     550 
     551            p_y1 = p_y2; 
     552            p_y2 += p_source->p[Y_PLANE].i_pitch; 
     553 
     554            for( i_x = p_vout->render.i_width / 16 ; i_x-- ; ) 
     555            { 
     556                SSE2_CALL( SSE2_YUV420_YVYU_UNALIGNED ); 
     557            } 
     558            for( i_x = ( p_vout->render.i_width % 16 ) / 2; i_x-- ; ) 
     559            { 
     560                C_YUV420_YVYU( ); 
     561            } 
     562 
     563            p_y1 += i_source_margin; 
     564            p_y2 += i_source_margin; 
     565            p_u += i_source_margin_c; 
     566            p_v += i_source_margin_c; 
     567            p_line1 += i_dest_margin; 
     568            p_line2 += i_dest_margin; 
     569        } 
     570    } 
     571#endif // defined(MODULE_NAME_IS_i420_yuy2_sse2) 
    426572} 
    427573 
     
    526672                               - p_dest->p->i_visible_pitch; 
    527673 
     674#if !defined(MODULE_NAME_IS_i420_yuy2_sse2) 
    528675    for( i_y = p_vout->render.i_height / 2 ; i_y-- ; ) 
    529676    { 
     
    565712    } 
    566713#endif 
     714 
     715#else // defined(MODULE_NAME_IS_i420_yuy2_sse2) 
     716    /* 
     717    ** SSE2 128 bytes fetch/store instructions are faster  
     718    ** if memory access is 16 bytes aligned 
     719    */ 
     720    if( 0 == (15 & (p_source->p[Y_PLANE].i_pitch|p_dest->p->i_pitch| 
     721        ((int)p_line2|(int)p_y2))) ) 
     722    { 
     723        /* use faster SSE2 aligned fetch and store */ 
     724        for( i_y = p_vout->render.i_height / 2 ; i_y-- ; ) 
     725        { 
     726            p_line1 = p_line2; 
     727            p_line2 += p_dest->p->i_pitch; 
     728 
     729            p_y1 = p_y2; 
     730            p_y2 += p_source->p[Y_PLANE].i_pitch; 
     731 
     732            for( i_x = p_vout->render.i_width / 16 ; i_x-- ; ) 
     733            { 
     734                SSE2_CALL( SSE2_YUV420_UYVY_ALIGNED ); 
     735            } 
     736            for( i_x = ( p_vout->render.i_width % 16 ) / 2; i_x-- ; ) 
     737            { 
     738                C_YUV420_UYVY( ); 
     739            } 
     740 
     741            p_y1 += i_source_margin; 
     742            p_y2 += i_source_margin; 
     743            p_u += i_source_margin_c; 
     744            p_v += i_source_margin_c; 
     745            p_line1 += i_dest_margin; 
     746            p_line2 += i_dest_margin; 
     747        } 
     748    } 
     749    else 
     750    { 
     751        /* use slower SSE2 unaligned fetch and store */ 
     752        for( i_y = p_vout->render.i_height / 2 ; i_y-- ; ) 
     753        { 
     754            p_line1 = p_line2; 
     755            p_line2 += p_dest->p->i_pitch; 
     756 
     757            p_y1 = p_y2; 
     758            p_y2 += p_source->p[Y_PLANE].i_pitch; 
     759 
     760            for( i_x = p_vout->render.i_width / 16 ; i_x-- ; ) 
     761            { 
     762                SSE2_CALL( SSE2_YUV420_UYVY_UNALIGNED ); 
     763            } 
     764            for( i_x = ( p_vout->render.i_width % 16 ) / 2; i_x-- ; ) 
     765            { 
     766                C_YUV420_UYVY( ); 
     767            } 
     768 
     769            p_y1 += i_source_margin; 
     770            p_y2 += i_source_margin; 
     771            p_u += i_source_margin_c; 
     772            p_v += i_source_margin_c; 
     773            p_line1 += i_dest_margin; 
     774            p_line2 += i_dest_margin; 
     775        } 
     776    } 
     777#endif // defined(MODULE_NAME_IS_i420_yuy2_sse2) 
    567778} 
    568779 
     
    602813                               - p_dest->p->i_visible_pitch; 
    603814 
     815#if !defined(MODULE_NAME_IS_i420_yuy2_sse2) 
    604816    for( i_y = p_vout->render.i_height / 2 ; i_y-- ; ) 
    605817    { 
     
    612824        for( i_x = p_vout->render.i_width / 8 ; i_x-- ; ) 
    613825        { 
    614 #if defined (MODULE_NAME_IS_i420_yuy2
     826#if !defined (MODULE_NAME_IS_i420_yuy2_mmx
    615827            C_YUV420_UYVY( ); 
    616828            C_YUV420_UYVY( ); 
     
    629841        p_line2 += i_dest_margin; 
    630842    } 
     843 
     844#if defined (MODULE_NAME_IS_i420_yuy2_mmx) 
     845    __asm__ __volatile__("emms" :: ); 
     846#endif 
     847 
     848#else // defined(MODULE_NAME_IS_i420_yuy2_sse2) 
     849    /* 
     850    ** SSE2 128 bytes fetch/store instructions are faster  
     851    ** if memory access is 16 bytes aligned 
     852    */ 
     853    if( 0 == (15 & (p_source->p[Y_PLANE].i_pitch|p_dest->p->i_pitch| 
     854        ((int)p_line2|(int)p_y2))) ) 
     855    { 
     856        /* use faster SSE2 aligned fetch and store */ 
     857        for( i_y = p_vout->render.i_height / 2 ; i_y-- ; ) 
     858        { 
     859            p_line1 = p_line2; 
     860            p_line2 += p_dest->p->i_pitch; 
     861 
     862            p_y1 = p_y2; 
     863            p_y2 += p_source->p[Y_PLANE].i_pitch; 
     864 
     865            for( i_x = p_vout->render.i_width / 16 ; i_x-- ; ) 
     866            { 
     867                SSE2_CALL( SSE2_YUV420_UYVY_ALIGNED ); 
     868            } 
     869            for( i_x = ( p_vout->render.i_width % 16 ) / 2; i_x-- ; ) 
     870            { 
     871                C_YUV420_UYVY( ); 
     872            } 
     873 
     874            p_y1 += i_source_margin; 
     875            p_y2 += i_source_margin; 
     876            p_u += i_source_margin_c; 
     877            p_v += i_source_margin_c; 
     878            p_line1 += i_dest_margin; 
     879            p_line2 += i_dest_margin; 
     880        } 
     881    } 
     882    else 
     883    { 
     884        /* use slower SSE2 unaligned fetch and store */ 
     885        for( i_y = p_vout->render.i_height / 2 ; i_y-- ; ) 
     886        { 
     887            p_line1 = p_line2; 
     888            p_line2 += p_dest->p->i_pitch; 
     889 
     890            p_y1 = p_y2; 
     891            p_y2 += p_source->p[Y_PLANE].i_pitch; 
     892 
     893            for( i_x = p_vout->render.i_width / 16 ; i_x-- ; ) 
     894            { 
     895                SSE2_CALL( SSE2_YUV420_UYVY_UNALIGNED ); 
     896            } 
     897            for( i_x = ( p_vout->render.i_width % 16 ) / 2; i_x-- ; ) 
     898            { 
     899                C_YUV420_UYVY( ); 
     900            } 
     901 
     902            p_y1 += i_source_margin; 
     903            p_y2 += i_source_margin; 
     904            p_u += i_source_margin_c; 
     905            p_v += i_source_margin_c; 
     906            p_line1 += i_dest_margin; 
     907            p_line2 += i_dest_margin; 
     908        } 
     909    } 
     910#endif // defined(MODULE_NAME_IS_i420_yuy2_sse2) 
    631911} 
    632912#endif // !defined (MODULE_NAME_IS_i420_yuy2_altivec) 
     
    676956} 
    677957#endif 
    678  
  • modules/video_chroma/i420_yuy2.h

    ra1f2a86 rbae04ee  
    66 * 
    77 * Authors: Samuel Hocevar <sam@zoy.org> 
     8 *          Damien Fouilleul <damien@videolan.org> 
    89 * 
    910 * This program is free software; you can redistribute it and/or modify 
     
    3334          "r" (p_u), "r" (p_v) );                                           \ 
    3435    p_line1 += 16; p_line2 += 16; p_y1 += 8; p_y2 += 8; p_u += 4; p_v += 4; \ 
    35     } while(0);                                                             \ 
     36    } while(0) 
    3637 
    3738#define MMX_YUV420_YUYV "                                                 \n\ 
     
    112113" 
    113114 
    114 #else 
     115#elif defined( MODULE_NAME_IS_i420_yuy2_sse2 ) 
     116 
     117/* SSE2 */ 
     118 
     119#define SSE2_CALL(SSE2_INSTRUCTIONS)   \ 
     120    do {                                                                    \ 
     121    __asm__ __volatile__(                                                   \ 
     122        ".p2align 3 \n\t"                                                   \ 
     123        SSE2_INSTRUCTIONS                                                   \ 
     124        :                                                                   \ 
     125        : "r" (p_line1),  "r" (p_line2),  "r" (p_y1),  "r" (p_y2),          \ 
     126          "r" (p_u), "r" (p_v) );                                           \ 
     127        p_line1 += 32; p_line2 += 32; p_y1 += 16; p_y2 += 16;               \ 
     128        p_u += 8; p_v += 8;                                                 \ 
     129    } while(0) 
     130 
     131#define SSE2_YUV420_YUYV_ALIGNED "                                        \n\ 
     132movdqa      (%2), %%xmm0  # Load 16 Y         y15 y14 y13 .. y2 y1 y0     \n\ 
     133movq        (%4), %%xmm1  # Load 8 Cb         u7 u6 u5 u4 u3 u2 u1 u0     \n\ 
     134movq        (%5), %%xmm2  # Load 8 Cr         v7 06 v5 v4 v3 v2 v1 v0     \n\ 
     135punpcklbw %%xmm2, %%xmm1  #                   v7 u7 v6 u6 .. u1 v0 u0     \n\ 
     136movdqa    %%xmm0, %%xmm2  #                   y15 y14 y13 .. y2 y1 y0     \n\ 
     137punpcklbw %%xmm1, %%xmm2  #                   v3 y7 u3 .. v0 y1 u0 y0     \n\ 
     138movdqa    %%xmm2, (%0)    # Store low YUYV                                \n\ 
     139punpckhbw %%xmm1, %%xmm0  #                   v3 y7 u3 y6 v2 y5 u2 y4     \n\ 
     140movdqa    %%xmm0, 16(%0)  # Store high YUYV                               \n\ 
     141movdqa      (%3), %%xmm0  # Load 8 Y          Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0     \n\ 
     142movdqa    %%xmm0, %%xmm2  #                   Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0     \n\ 
     143punpcklbw %%xmm1, %%xmm2  #                   v1 Y3 u1 Y2 v0 Y1 u0 Y0     \n\ 
     144movdqa    %%xmm2, (%1)    # Store low YUYV                                \n\ 
     145punpckhbw %%xmm1, %%xmm0  #                   v3 Y7 u3 Y6 v2 Y5 u2 Y4     \n\ 
     146movdqa    %%xmm0, 16(%1)  # Store high YUYV                               \n\ 
     147
     148 
     149#define SSE2_YUV420_YUYV_UNALIGNED "                                      \n\ 
     150movdqu      (%2), %%xmm0  # Load 16 Y         y7 y6 y5 y4 y3 y2 y1 y0     \n\ 
     151movq        (%4), %%xmm1  # Load 8 Cb         00 00 00 00 u3 u2 u1 u0     \n\ 
     152movq        (%5), %%xmm2  # Load 8 Cr         00 00 00 00 v3 v2 v1 v0     \n\ 
     153punpcklbw %%xmm2, %%xmm1  #                   v3 u3 v2 u2 v1 u1 v0 u0     \n\ 
     154movdqa    %%xmm0, %%xmm2  #                   y7 y6 y5 y4 y3 y2 y1 y0     \n\ 
     155punpcklbw %%xmm1, %%xmm2  #                   v1 y3 u1 y2 v0 y1 u0 y0     \n\ 
     156movdqu    %%xmm2, (%0)    # Store low YUYV                                \n\ 
     157punpckhbw %%xmm1, %%xmm0  #                   v3 y7 u3 y6 v2 y5 u2 y4     \n\ 
     158movdqu    %%xmm0, 16(%0)  # Store high YUYV                               \n\ 
     159movdqu      (%3), %%xmm0  # Load 16 Y         Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0     \n\ 
     160movdqa    %%xmm0, %%xmm2  #                   Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0     \n\ 
     161punpcklbw %%xmm1, %%xmm2  #                   v1 Y3 u1 Y2 v0 Y1 u0 Y0     \n\ 
     162movdqu    %%xmm2, (%1)    # Store low YUYV                                \n\ 
     163punpckhbw %%xmm1, %%xmm0  #                   v3 Y7 u3 Y6 v2 Y5 u2 Y4     \n\ 
     164movdqu    %%xmm0, 16(%1)  # Store high YUYV                               \n\ 
     165
     166 
     167#define SSE2_YUV420_YVYU_ALIGNED "                                          \n\ 
     168movdqa      (%2), %%xmm0  # Load 16 Y           y7 y6 y5 y4 y3 y2 y1 y0     \n\ 
     169movq        (%4), %%xmm2  # Load 8 Cb           00 00 00 00 u3 u2 u1 u0     \n\ 
     170movq        (%5), %%xmm1  # Load 8 Cr           00 00 00 00 v3 v2 v1 v0     \n\ 
     171punpcklbw %%xmm2, %%xmm1  #                     u3 v3 u2 v2 u1 v1 u0 v0     \n\ 
     172movdqa    %%xmm0, %%xmm2  #                     y7 y6 y5 y4 y3 y2 y1 y0     \n\ 
     173punpcklbw %%xmm1, %%xmm2  #                     u1 y3 v1 y2 u0 y1 v0 y0     \n\ 
     174movdqa    %%xmm2, (%0)    # Store low YUYV                                  \n\ 
     175punpckhbw %%xmm1, %%xmm0  #                     u3 y7 v3 y6 u2 y5 v2 y4     \n\ 
     176movdqa    %%xmm0, 16(%0)  # Store high YUYV                                 \n\ 
     177movdqa      (%3), %%xmm0  # Load 16 Y           Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0     \n\ 
     178movdqa    %%xmm0, %%xmm2  #                     Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0     \n\ 
     179punpcklbw %%xmm1, %%xmm2  #                     u1 Y3 v1 Y2 u0 Y1 v0 Y0     \n\ 
     180movdqa    %%xmm2, (%1)    # Store low YUYV                                  \n\ 
     181punpckhbw %%xmm1, %%xmm0  #                     u3 Y7 v3 Y6 u2 Y5 v2 Y4     \n\ 
     182movdqa    %%xmm0, 16(%1)  # Store high YUYV                                 \n\ 
     183
     184 
     185#define SSE2_YUV420_YVYU_UNALIGNED "                                        \n\ 
     186movdqu      (%2), %%xmm0  # Load 16 Y           y7 y6 y5 y4 y3 y2 y1 y0     \n\ 
     187movq        (%4), %%xmm2  # Load 8 Cb           00 00 00 00 u3 u2 u1 u0     \n\ 
     188movq        (%5), %%xmm1  # Load 8 Cr           00 00 00 00 v3 v2 v1 v0     \n\ 
     189punpcklbw %%xmm2, %%xmm1  #                     u3 v3 u2 v2 u1 v1 u0 v0     \n\ 
     190movdqu    %%xmm0, %%xmm2  #                     y7 y6 y5 y4 y3 y2 y1 y0     \n\ 
     191punpcklbw %%xmm1, %%xmm2  #                     u1 y3 v1 y2 u0 y1 v0 y0     \n\ 
     192movdqu    %%xmm2, (%0)    # Store low YUYV                                  \n\ 
     193punpckhbw %%xmm1, %%xmm0  #                     u3 y7 v3 y6 u2 y5 v2 y4     \n\ 
     194movdqu    %%xmm0, 16(%0)  # Store high YUYV                                 \n\ 
     195movdqu      (%3), %%xmm0  # Load 16 Y           Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0     \n\ 
     196movdqu    %%xmm0, %%xmm2  #                     Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0     \n\ 
     197punpcklbw %%xmm1, %%xmm2  #                     u1 Y3 v1 Y2 u0 Y1 v0 Y0     \n\ 
     198movdqu    %%xmm2, (%1)    # Store low YUYV                                  \n\ 
     199punpckhbw %%xmm1, %%xmm0  #                     u3 Y7 v3 Y6 u2 Y5 v2 Y4     \n\ 
     200movdqu    %%xmm0, 16(%1)  # Store high YUYV                                 \n\ 
     201
     202 
     203#define SSE2_YUV420_UYVY_ALIGNED "                                          \n\ 
     204movdqa      (%2), %%xmm0  # Load 16 Y           y7 y6 y5 y4 y3 y2 y1 y0     \n\ 
     205movdqa      (%3), %%xmm3  # Load 16 Y           Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0     \n\ 
     206movq        (%4), %%xmm1  # Load 8 Cb           00 00 00 00 u3 u2 u1 u0     \n\ 
     207movq        (%5), %%xmm2  # Load 8 Cr           00 00 00 00 v3 v2 v1 v0     \n\ 
     208punpcklbw %%xmm2, %%xmm1  #                     v3 u3 v2 u2 v1 u1 v0 u0     \n\ 
     209movdqa    %%xmm1, %%xmm2  #                     v3 u3 v2 u2 v1 u1 v0 u0     \n\ 
     210punpcklbw %%xmm0, %%xmm2  #                     y3 v1 y2 u1 y1 v0 y0 u0     \n\ 
     211movdqa    %%xmm2, (%0)    # Store low UYVY                                  \n\ 
     212movdqa    %%xmm1, %%xmm2  #                     u3 v3 u2 v2 u1 v1 u0 v0     \n\ 
     213punpckhbw %%xmm0, %%xmm2  #                     y3 v1 y2 u1 y1 v0 y0 u0     \n\ 
     214movdqa    %%xmm2, 16(%0)  # Store high UYVY                                 \n\ 
     215movdqa    %%xmm1, %%xmm2  #                     u3 v3 u2 v2 u1 v1 u0 v0     \n\ 
     216punpcklbw %%xmm3, %%xmm2  #                     Y3 v1 Y2 u1 Y1 v0 Y0 u0     \n\ 
     217movdqa    %%xmm2, (%1)    # Store low UYVY                                  \n\ 
     218punpckhbw %%xmm3, %%xmm1  #                     Y7 v3 Y6 u3 Y5 v2 Y4 u2     \n\ 
     219movdqa    %%xmm1, 16(%1)  # Store high UYVY                                 \n\ 
     220
     221 
     222#define SSE2_YUV420_UYVY_UNALIGNED "                                        \n\ 
     223movdqu      (%2), %%xmm0  # Load 16 Y           y7 y6 y5 y4 y3 y2 y1 y0     \n\ 
     224movdqu      (%3), %%xmm3  # Load 16 Y           Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0     \n\ 
     225movq        (%4), %%xmm1  # Load 8 Cb           00 00 00 00 u3 u2 u1 u0     \n\ 
     226movq        (%5), %%xmm2  # Load 8 Cr           00 00 00 00 v3 v2 v1 v0     \n\ 
     227punpcklbw %%xmm2, %%xmm1  #                     v3 u3 v2 u2 v1 u1 v0 u0     \n\ 
     228movdqu    %%xmm1, %%xmm2  #                     v3 u3 v2 u2 v1 u1 v0 u0     \n\ 
     229punpcklbw %%xmm0, %%xmm2  #                     y3 v1 y2 u1 y1 v0 y0 u0     \n\ 
     230movdqu    %%xmm2, (%0)    # Store low UYVY                                  \n\ 
     231movdqu    %%xmm1, %%xmm2  #                     u3 v3 u2 v2 u1 v1 u0 v0     \n\ 
     232punpckhbw %%xmm0, %%xmm2  #                     y3 v1 y2 u1 y1 v0 y0 u0     \n\ 
     233movdqu    %%xmm2, 16(%0)  # Store high UYVY                                 \n\ 
     234movdqu    %%xmm1, %%xmm2  #                     u3 v3 u2 v2 u1 v1 u0 v0     \n\ 
     235punpcklbw %%xmm3, %%xmm2  #                     Y3 v1 Y2 u1 Y1 v0 Y0 u0     \n\ 
     236movdqu    %%xmm2, (%1)    # Store low UYVY                                  \n\ 
     237punpckhbw %%xmm3, %%xmm1  #                     Y7 v3 Y6 u3 Y5 v2 Y4 u2     \n\ 
     238movdqu    %%xmm1, 16(%1)  # Store high UYVY                                 \n\ 
     239
     240 
     241#endif 
     242 
     243/* Used in both accelerated and C modules */ 
    115244 
    116245#define C_YUV420_YVYU( )                                                    \ 
     
    128257    *(p_line1)++ = *(p_line2)++ = *(p_v) - 0x80; p_v += 2;                  \ 
    129258 
    130 #endif 
    131  
    132 /* Used in both MMX and C modules */ 
     259 
    133260#define C_YUV420_YUYV( )                                                    \ 
    134261    *(p_line1)++ = *(p_y1)++; *(p_line2)++ = *(p_y2)++;                     \