From: Christophe Massiot Date: Wed, 22 Aug 2001 17:21:46 +0000 (+0000) Subject: * Totally rewrote the video decoder (inspired by walken's mpeg2dec), implying : X-Git-Tag: 0.2.91~142 X-Git-Url: https://git.sesse.net/?a=commitdiff_plain;h=45f3f2825f878822ca99b07b3eb9a6134e0224ea;p=vlc * Totally rewrote the video decoder (inspired by walken's mpeg2dec), implying : - performance boost ; - fixed the "Dual Prime Arithmetic" bug ; - 3DNow! motion compensation module ; * BTW, fixed numerous bugs ; * AC3dec statistics do not show up with --enable-stats, because I doubt they're understandable by a normal human being, and they pollute the output. --- diff --git a/AUTHORS b/AUTHORS index 79f44e3a4b..5e68a03ec2 100644 --- a/AUTHORS +++ b/AUTHORS @@ -117,6 +117,11 @@ D: playlist and modules system D: Gnome and Gtk+ interfaces, Glide and fb video outputs, Esound audio output D: DVD subtitles decoder +N: Aaron Holtzman +E: aholtzma@ess.engr.uvic.ca +D: AC3 decoder +D: MPEG video decoder + N: Eugenio Jarosiewicz E: ej0@cise.ufl.edu C: ej diff --git a/configure b/configure index e1abbc3967..6a34731762 100755 --- a/configure +++ b/configure @@ -639,7 +639,7 @@ echo "$ac_t""$host" 1>&6 HAVE_VLC=0 if test -r src/interface/main.c; then HAVE_VLC=1 - VLC_VERSION=0.2.82 + VLC_VERSION=0.2.83 VLC_CODENAME=Ourumov @@ -2136,12 +2136,15 @@ else #include #include #include +#include +#include + +#ifdef HAVE_UNISTD_H +# include +#endif /* This mess was copied from the GNU getpagesize.h. */ #ifndef HAVE_GETPAGESIZE -# ifdef HAVE_UNISTD_H -# include -# endif /* Assume that all systems that can run configure have sys/param.h. */ # ifndef HAVE_SYS_PARAM_H @@ -2196,7 +2199,7 @@ main() /* * First, make a file with some known garbage in it. */ - data = malloc(pagesize); + data = (char*)malloc(pagesize); if (!data) exit(1); for (i = 0; i < pagesize; ++i) @@ -2217,7 +2220,7 @@ main() fd = open("conftestmmap", O_RDWR); if (fd < 0) exit(1); - data2 = malloc(2 * pagesize); + data2 = (char*)malloc(2 * pagesize); if (!data2) exit(1); data2 += (pagesize - ((int) data2 & (pagesize - 1))) & (pagesize - 1); @@ -2235,7 +2238,7 @@ main() */ for (i = 0; i < pagesize; ++i) *(data2 + i) = *(data2 + i) + 1; - data3 = malloc(pagesize); + data3 = (char*)malloc(pagesize); if (!data3) exit(1); if (read(fd, data3, pagesize) != pagesize) @@ -2249,7 +2252,7 @@ main() } EOF -if { (eval echo configure:2253: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:2256: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_func_mmap_fixed_mapped=yes else @@ -2272,12 +2275,12 @@ EOF fi echo $ac_n "checking return type of signal handlers""... $ac_c" 1>&6 -echo "configure:2276: checking return type of signal handlers" >&5 +echo "configure:2279: checking return type of signal handlers" >&5 if eval "test \"`echo '$''{'ac_cv_type_signal'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -2294,7 +2297,7 @@ int main() { int i; ; return 0; } EOF -if { (eval echo configure:2298: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:2301: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_type_signal=void else @@ -2313,7 +2316,7 @@ EOF echo $ac_n "checking for dlopen in -ldl""... $ac_c" 1>&6 -echo "configure:2317: checking for dlopen in -ldl" >&5 +echo "configure:2320: checking for dlopen in -ldl" >&5 ac_lib_var=`echo dl'_'dlopen | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -2321,7 +2324,7 @@ else ac_save_LIBS="$LIBS" LIBS="-ldl $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:2339: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -2353,7 +2356,7 @@ else fi echo $ac_n "checking for pow in -lm""... $ac_c" 1>&6 -echo "configure:2357: checking for pow in -lm" >&5 +echo "configure:2360: checking for pow in -lm" >&5 ac_lib_var=`echo m'_'pow | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -2361,7 +2364,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lm $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:2379: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -2399,7 +2402,7 @@ CFLAGS="${CFLAGS} -I/usr/local/include" THREAD_LIB=error if test "x${THREAD_LIB}" = xerror; then echo $ac_n "checking for pthread_attr_init in -lpthread""... $ac_c" 1>&6 -echo "configure:2403: checking for pthread_attr_init in -lpthread" >&5 +echo "configure:2406: checking for pthread_attr_init in -lpthread" >&5 ac_lib_var=`echo pthread'_'pthread_attr_init | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -2407,7 +2410,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lpthread $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:2425: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -2441,7 +2444,7 @@ fi fi if test "x${THREAD_LIB}" = xerror; then echo $ac_n "checking for pthread_attr_init in -lpthreads""... $ac_c" 1>&6 -echo "configure:2445: checking for pthread_attr_init in -lpthreads" >&5 +echo "configure:2448: checking for pthread_attr_init in -lpthreads" >&5 ac_lib_var=`echo pthreads'_'pthread_attr_init | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -2449,7 +2452,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lpthreads $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:2467: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -2483,7 +2486,7 @@ fi fi if test "x${THREAD_LIB}" = xerror; then echo $ac_n "checking for pthread_attr_init in -lc_r""... $ac_c" 1>&6 -echo "configure:2487: checking for pthread_attr_init in -lc_r" >&5 +echo "configure:2490: checking for pthread_attr_init in -lc_r" >&5 ac_lib_var=`echo c_r'_'pthread_attr_init | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -2491,7 +2494,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lc_r $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:2509: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -2525,12 +2528,12 @@ fi fi if test "x${THREAD_LIB}" = xerror; then echo $ac_n "checking for pthread_attr_init""... $ac_c" 1>&6 -echo "configure:2529: checking for pthread_attr_init" >&5 +echo "configure:2532: checking for pthread_attr_init" >&5 if eval "test \"`echo '$''{'ac_cv_func_pthread_attr_init'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:2560: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_pthread_attr_init=yes" else @@ -2576,7 +2579,7 @@ fi fi echo $ac_n "checking for cthread_fork in -lthreads""... $ac_c" 1>&6 -echo "configure:2580: checking for cthread_fork in -lthreads" >&5 +echo "configure:2583: checking for cthread_fork in -lthreads" >&5 ac_lib_var=`echo threads'_'cthread_fork | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -2584,7 +2587,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lthreads $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:2602: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -2617,7 +2620,7 @@ fi cat > conftest.$ac_ext < EOF @@ -2633,7 +2636,7 @@ fi rm -f conftest* cat > conftest.$ac_ext < EOF @@ -2653,17 +2656,17 @@ for ac_hdr in stddef.h getopt.h strings.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:2657: checking for $ac_hdr" >&5 +echo "configure:2660: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:2667: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:2670: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -2693,17 +2696,17 @@ for ac_hdr in sys/sockio.h fcntl.h sys/time.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:2697: checking for $ac_hdr" >&5 +echo "configure:2700: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:2707: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:2710: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -2733,17 +2736,17 @@ for ac_hdr in sys/soundcard.h machine/soundcard.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:2737: checking for $ac_hdr" >&5 +echo "configure:2740: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:2747: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:2750: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -2773,17 +2776,17 @@ for ac_hdr in dlfcn.h image.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:2777: checking for $ac_hdr" >&5 +echo "configure:2780: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:2787: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:2790: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -2813,17 +2816,17 @@ for ac_hdr in arpa/inet.h net/if.h netinet/in.h sys/socket.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:2817: checking for $ac_hdr" >&5 +echo "configure:2820: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:2827: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:2830: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -2853,17 +2856,17 @@ for ac_hdr in machine/param.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:2857: checking for $ac_hdr" >&5 +echo "configure:2860: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:2867: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:2870: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -2894,17 +2897,17 @@ for ac_hdr in cthreads.h pthread.h kernel/scheduler.h kernel/OS.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:2898: checking for $ac_hdr" >&5 +echo "configure:2901: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:2908: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:2911: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -2933,9 +2936,9 @@ done CFLAGS="${save_CFLAGS} -Wall -Werror" echo $ac_n "checking for ntohl in sys/param.h""... $ac_c" 1>&6 -echo "configure:2937: checking for ntohl in sys/param.h" >&5 +echo "configure:2940: checking for ntohl in sys/param.h" >&5 cat > conftest.$ac_ext < void foo() { int meuh; ntohl(meuh); } @@ -2943,7 +2946,7 @@ int main() { ; return 0; } EOF -if { (eval echo configure:2947: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:2950: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* cat >> confdefs.h <<\EOF #define NTOHL_IN_SYS_PARAM_H 1 @@ -2958,20 +2961,20 @@ else fi rm -f conftest* -CFLAGS="${save_CFLAGS} -finline-limit=31337" +CFLAGS="${save_CFLAGS} -finline-limit-20000" echo $ac_n "checking if \$CC accepts -finline-limit""... $ac_c" 1>&6 -echo "configure:2964: checking if \$CC accepts -finline-limit" >&5 +echo "configure:2967: checking if \$CC accepts -finline-limit" >&5 cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:2976: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* - save_CFLAGS="${save_CFLAGS} -finline-limit=31337"; echo "$ac_t""yes" 1>&6 + save_CFLAGS="${save_CFLAGS} -finline-limit-20000"; echo "$ac_t""yes" 1>&6 else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 @@ -2982,16 +2985,16 @@ rm -f conftest* CFLAGS="${save_CFLAGS} -bundle -undefined suppress" echo $ac_n "checking if \$CC accepts -bundle -undefined suppress""... $ac_c" 1>&6 -echo "configure:2986: checking if \$CC accepts -bundle -undefined suppress" >&5 +echo "configure:2989: checking if \$CC accepts -bundle -undefined suppress" >&5 cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:2998: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* PLCFLAGS="${PLCFLAGS} -bundle -undefined suppress"; echo "$ac_t""yes" 1>&6 else @@ -3004,16 +3007,16 @@ rm -f conftest* CFLAGS="${save_CFLAGS} -shared" echo $ac_n "checking if \$CC accepts -shared""... $ac_c" 1>&6 -echo "configure:3008: checking if \$CC accepts -shared" >&5 +echo "configure:3011: checking if \$CC accepts -shared" >&5 cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3020: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* PLCFLAGS="${PLCFLAGS} -shared"; echo "$ac_t""yes" 1>&6 else @@ -3028,16 +3031,16 @@ if test x"${SOFLAGS}" = x; then try_SOFLAGS="-Wl,-soname -Wl," LDFLAGS="${save_LDFLAGS} ${try_SOFLAGS}foo.so.0" echo $ac_n "checking if linker accepts ${try_SOFLAGS}foo.so.0""... $ac_c" 1>&6 -echo "configure:3032: checking if linker accepts ${try_SOFLAGS}foo.so.0" >&5 +echo "configure:3035: checking if linker accepts ${try_SOFLAGS}foo.so.0" >&5 cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:3044: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* SOFLAGS="${try_SOFLAGS}"; echo "$ac_t""yes" 1>&6 else @@ -3053,16 +3056,16 @@ if test x"${SOFLAGS}" = x; then try_SOFLAGS="-Wl,-h -Wl," LDFLAGS="${save_LDFLAGS} ${try_SOFLAGS}foo.so.0" echo $ac_n "checking if linker accepts ${try_SOFLAGS}foo.so.0""... $ac_c" 1>&6 -echo "configure:3057: checking if linker accepts ${try_SOFLAGS}foo.so.0" >&5 +echo "configure:3060: checking if linker accepts ${try_SOFLAGS}foo.so.0" >&5 cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:3069: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* SOFLAGS="${try_SOFLAGS}"; echo "$ac_t""yes" 1>&6 else @@ -3078,9 +3081,9 @@ CFLAGS="${save_CFLAGS}" LDFLAGS="${save_LDFLAGS}" echo $ac_n "checking for boolean_t in sys/types.h""... $ac_c" 1>&6 -echo "configure:3082: checking for boolean_t in sys/types.h" >&5 +echo "configure:3085: checking for boolean_t in sys/types.h" >&5 cat > conftest.$ac_ext < void quux() { boolean_t foo; } @@ -3088,7 +3091,7 @@ int main() { ; return 0; } EOF -if { (eval echo configure:3092: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3095: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* cat >> confdefs.h <<\EOF #define BOOLEAN_T_IN_SYS_TYPES_H 1 @@ -3103,9 +3106,9 @@ else fi rm -f conftest* echo $ac_n "checking for boolean_t in pthread.h""... $ac_c" 1>&6 -echo "configure:3107: checking for boolean_t in pthread.h" >&5 +echo "configure:3110: checking for boolean_t in pthread.h" >&5 cat > conftest.$ac_ext < void quux() { boolean_t foo; } @@ -3113,7 +3116,7 @@ int main() { ; return 0; } EOF -if { (eval echo configure:3117: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3120: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* cat >> confdefs.h <<\EOF #define BOOLEAN_T_IN_PTHREAD_H 1 @@ -3128,9 +3131,9 @@ else fi rm -f conftest* echo $ac_n "checking for boolean_t in cthreads.h""... $ac_c" 1>&6 -echo "configure:3132: checking for boolean_t in cthreads.h" >&5 +echo "configure:3135: checking for boolean_t in cthreads.h" >&5 cat > conftest.$ac_ext < void quux() { boolean_t foo; } @@ -3138,7 +3141,7 @@ int main() { ; return 0; } EOF -if { (eval echo configure:3142: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3145: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* cat >> confdefs.h <<\EOF #define BOOLEAN_T_IN_CTHREADS_H 1 @@ -3154,18 +3157,18 @@ fi rm -f conftest* echo $ac_n "checking for working const""... $ac_c" 1>&6 -echo "configure:3158: checking for working const" >&5 +echo "configure:3161: checking for working const" >&5 if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3215: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_c_const=yes else @@ -3229,12 +3232,12 @@ EOF fi echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6 -echo "configure:3233: checking for ANSI C header files" >&5 +echo "configure:3236: checking for ANSI C header files" >&5 if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -3242,7 +3245,7 @@ else #include EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:3246: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:3249: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -3259,7 +3262,7 @@ rm -f conftest* if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat > conftest.$ac_ext < EOF @@ -3277,7 +3280,7 @@ fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat > conftest.$ac_ext < EOF @@ -3298,7 +3301,7 @@ if test "$cross_compiling" = yes; then : else cat > conftest.$ac_ext < #define ISLOWER(c) ('a' <= (c) && (c) <= 'z') @@ -3309,7 +3312,7 @@ if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2); exit (0); } EOF -if { (eval echo configure:3313: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:3316: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then : else @@ -3333,12 +3336,12 @@ EOF fi echo $ac_n "checking for size_t""... $ac_c" 1>&6 -echo "configure:3337: checking for size_t" >&5 +echo "configure:3340: checking for size_t" >&5 if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #if STDC_HEADERS @@ -3366,12 +3369,12 @@ EOF fi echo $ac_n "checking whether time.h and sys/time.h may both be included""... $ac_c" 1>&6 -echo "configure:3370: checking whether time.h and sys/time.h may both be included" >&5 +echo "configure:3373: checking whether time.h and sys/time.h may both be included" >&5 if eval "test \"`echo '$''{'ac_cv_header_time'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -3380,7 +3383,7 @@ int main() { struct tm *tp; ; return 0; } EOF -if { (eval echo configure:3384: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3387: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_header_time=yes else @@ -3401,6 +3404,42 @@ EOF fi +echo $ac_n "checking __attribute__ ((aligned ())) support""... $ac_c" 1>&6 +echo "configure:3409: checking __attribute__ ((aligned ())) support" >&5 +if eval "test \"`echo '$''{'ac_cv_c_attribute_aligned'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_cv_c_attribute_aligned=0 + for ac_cv_c_attr_align_try in 2 4 8 16 32 64; do + cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_c_attribute_aligned=$ac_cv_c_attr_align_try +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 +fi +rm -f conftest* + done +fi + +echo "$ac_t""$ac_cv_c_attribute_aligned" 1>&6 +if test x"$ac_cv_c_attribute_aligned" != x"0"; then + cat >> confdefs.h <&6 -echo "configure:3416: checking if \$CC groks MMX inline assembly" >&5 +echo "configure:3455: checking if \$CC groks MMX inline assembly" >&5 cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3464: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ACCEL_MODULES="${ACCEL_MODULES} ${MMX_MODULES}" echo "$ac_t""yes" 1>&6 @@ -3434,16 +3473,16 @@ fi rm -f conftest* echo $ac_n "checking if \$CC groks MMX EXT inline assembly""... $ac_c" 1>&6 -echo "configure:3438: checking if \$CC groks MMX EXT inline assembly" >&5 +echo "configure:3477: checking if \$CC groks MMX EXT inline assembly" >&5 cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3486: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ACCEL_MODULES="${ACCEL_MODULES} ${MMXEXT_MODULES}" echo "$ac_t""yes" 1>&6 @@ -3456,16 +3495,16 @@ fi rm -f conftest* echo $ac_n "checking if \$CC groks 3D Now! inline assembly""... $ac_c" 1>&6 -echo "configure:3460: checking if \$CC groks 3D Now! inline assembly" >&5 +echo "configure:3499: checking if \$CC groks 3D Now! inline assembly" >&5 cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3508: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ACCEL_MODULES="${ACCEL_MODULES} ${THREEDNOW_MODULES}" echo "$ac_t""yes" 1>&6 @@ -3478,16 +3517,16 @@ fi rm -f conftest* echo $ac_n "checking if \$CC groks SSE inline assembly""... $ac_c" 1>&6 -echo "configure:3482: checking if \$CC groks SSE inline assembly" >&5 +echo "configure:3521: checking if \$CC groks SSE inline assembly" >&5 cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3530: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ACCEL_MODULES="${ACCEL_MODULES} ${SSE_MODULES}" echo "$ac_t""yes" 1>&6 @@ -3506,17 +3545,17 @@ for ac_hdr in winioctl.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:3510: checking for $ac_hdr" >&5 +echo "configure:3549: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:3520: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:3559: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -3549,17 +3588,17 @@ for ac_hdr in sys/ioctl.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:3553: checking for $ac_hdr" >&5 +echo "configure:3592: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:3563: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:3602: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -3585,17 +3624,17 @@ EOF do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:3589: checking for $ac_hdr" >&5 +echo "configure:3628: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:3599: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:3638: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -3624,7 +3663,7 @@ done BSD_DVD_STRUCT=0 LINUX_DVD_STRUCT=0 cat > conftest.$ac_ext < EOF @@ -3642,7 +3681,7 @@ fi rm -f conftest* cat > conftest.$ac_ext < EOF @@ -3660,7 +3699,7 @@ fi rm -f conftest* cat > conftest.$ac_ext < EOF @@ -3679,7 +3718,7 @@ rm -f conftest* NEED_BSDI_LIBDVD=0 cat > conftest.$ac_ext < EOF @@ -3701,17 +3740,17 @@ else do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:3705: checking for $ac_hdr" >&5 +echo "configure:3744: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:3715: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:3754: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -3751,17 +3790,17 @@ rm -f conftest* ac_safe=`echo "sys/scsi/scsi_types.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for sys/scsi/scsi_types.h""... $ac_c" 1>&6 -echo "configure:3755: checking for sys/scsi/scsi_types.h" >&5 +echo "configure:3794: checking for sys/scsi/scsi_types.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:3765: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:3804: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -3780,17 +3819,17 @@ if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then ac_safe=`echo "sys/scsi/impl/uscsi.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for sys/scsi/impl/uscsi.h""... $ac_c" 1>&6 -echo "configure:3784: checking for sys/scsi/impl/uscsi.h" >&5 +echo "configure:3823: checking for sys/scsi/impl/uscsi.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:3794: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:3833: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -3944,7 +3983,7 @@ if test "${enable_pth+set}" = set; then enableval="$enable_pth" if test x$enableval = xyes; then echo $ac_n "checking for pth_init in -lpth""... $ac_c" 1>&6 -echo "configure:3948: checking for pth_init in -lpth" >&5 +echo "configure:3987: checking for pth_init in -lpth" >&5 ac_lib_var=`echo pth'_'pth_init | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -3952,7 +3991,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lpth $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:4006: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -3991,7 +4030,7 @@ else fi cat > conftest.$ac_ext < EOF @@ -4155,7 +4194,7 @@ if test "${enable_esd+set}" = set; then # Extract the first word of "esd-config", so it can be a program name with args. set dummy esd-config; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:4159: checking for $ac_word" >&5 +echo "configure:4198: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_ESD_CONFIG'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -4222,17 +4261,17 @@ else do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:4226: checking for $ac_hdr" >&5 +echo "configure:4265: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:4236: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:4275: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -4277,17 +4316,17 @@ fi do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:4281: checking for $ac_hdr" >&5 +echo "configure:4320: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:4291: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:4330: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -4365,7 +4404,7 @@ fi # Extract the first word of "sdl12-config", so it can be a program name with args. set dummy sdl12-config; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:4369: checking for $ac_word" >&5 +echo "configure:4408: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_SDL12_CONFIG'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -4405,7 +4444,7 @@ fi # Extract the first word of "sdl11-config", so it can be a program name with args. set dummy sdl11-config; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:4409: checking for $ac_word" >&5 +echo "configure:4448: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_SDL11_CONFIG'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -4446,7 +4485,7 @@ fi # Extract the first word of "sdl-config", so it can be a program name with args. set dummy sdl-config; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:4450: checking for $ac_word" >&5 +echo "configure:4489: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_SDL_CONFIG'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -4492,17 +4531,17 @@ fi do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:4496: checking for $ac_hdr" >&5 +echo "configure:4535: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:4506: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:4545: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -4565,17 +4604,17 @@ if test "${with_directx+set}" = set; then do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:4569: checking for $ac_hdr" >&5 +echo "configure:4608: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:4579: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:4618: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -4613,17 +4652,17 @@ fi do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:4617: checking for $ac_hdr" >&5 +echo "configure:4656: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:4627: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:4666: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -4735,7 +4774,7 @@ then # Extract the first word of "gtk-config", so it can be a program name with args. set dummy gtk-config; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:4739: checking for $ac_word" >&5 +echo "configure:4778: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_GTK_CONFIG'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -4780,17 +4819,17 @@ fi do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:4784: checking for $ac_hdr" >&5 +echo "configure:4823: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:4794: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:4833: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -4841,17 +4880,17 @@ if test x$enable_x11 != xno; then do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:4845: checking for $ac_hdr" >&5 +echo "configure:4884: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:4855: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:4894: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -4903,17 +4942,17 @@ if test x$enable_xvideo != xno; then do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:4907: checking for $ac_hdr" >&5 +echo "configure:4946: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:4917: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:4956: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -4953,17 +4992,17 @@ if test "${enable_alsa+set}" = set; then then ac_safe=`echo "sys/asoundlib.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for sys/asoundlib.h""... $ac_c" 1>&6 -echo "configure:4957: checking for sys/asoundlib.h" >&5 +echo "configure:4996: checking for sys/asoundlib.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:4967: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:5006: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -4980,7 +5019,7 @@ fi if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then echo "$ac_t""yes" 1>&6 echo $ac_n "checking for main in -lasound""... $ac_c" 1>&6 -echo "configure:4984: checking for main in -lasound" >&5 +echo "configure:5023: checking for main in -lasound" >&5 ac_lib_var=`echo asound'_'main | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -4988,14 +5027,14 @@ else ac_save_LIBS="$LIBS" LIBS="-lasound $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5038: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else diff --git a/configure.in b/configure.in index 2666421e5a..5ddc6423c8 100644 --- a/configure.in +++ b/configure.in @@ -124,10 +124,10 @@ void foo() { int meuh; ntohl(meuh); }],, AC_MSG_RESULT(yes), AC_MSG_RESULT(no)) dnl Check for inline function size limit -CFLAGS="${save_CFLAGS} -finline-limit=31337" +CFLAGS="${save_CFLAGS} -finline-limit-20000" AC_MSG_CHECKING([if \$CC accepts -finline-limit]) AC_TRY_COMPILE([],, - save_CFLAGS="${save_CFLAGS} -finline-limit=31337"; AC_MSG_RESULT(yes), + save_CFLAGS="${save_CFLAGS} -finline-limit-20000"; AC_MSG_RESULT(yes), AC_MSG_RESULT(no)) dnl Check for Darwin plugin linking flags @@ -190,6 +190,22 @@ AC_C_CONST AC_TYPE_SIZE_T AC_HEADER_TIME +dnl Checks for __attribute__(aligned()) directive +AC_CACHE_CHECK([__attribute__ ((aligned ())) support], + [ac_cv_c_attribute_aligned], + [ac_cv_c_attribute_aligned=0 + for ac_cv_c_attr_align_try in 2 4 8 16 32 64; do + AC_TRY_COMPILE([], + [static char c __attribute__ ((aligned($ac_cv_c_attr_align_try))) = 0; return c;], + [ac_cv_c_attribute_aligned=$ac_cv_c_attr_align_try]) + done]) +if test x"$ac_cv_c_attribute_aligned" != x"0"; then + AC_DEFINE_UNQUOTED([ATTRIBUTE_ALIGNED_MAX], + [$ac_cv_c_attribute_aligned],[Maximum supported data alignment]) +fi + + + ARCH=${host_cpu} dnl diff --git a/include/attributes.h b/include/attributes.h deleted file mode 100644 index 8ed7aef9e3..0000000000 --- a/include/attributes.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * attributes.h - * Copyright (C) 1999-2000 Aaron Holtzman - * - * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. - * - * mpeg2dec is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * mpeg2dec is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -//use gcc attribs to align critical data structures -#ifdef ATTRIBUTE_ALIGNED_MAX -#define ATTR_ALIGN(align) __attribute__ ((__aligned__ ((ATTRIBUTE_ALIGNED_MAX < align) ? ATTRIBUTE_ALIGNED_MAX : align))) -#else -#define ATTR_ALIGN(align) -#endif diff --git a/include/common.h b/include/common.h index 437e4c46d9..74d005a0db 100644 --- a/include/common.h +++ b/include/common.h @@ -3,7 +3,7 @@ * Collection of useful common types and macros definitions ***************************************************************************** * Copyright (C) 1998, 1999, 2000 VideoLAN - * $Id: common.h,v 1.38 2001/08/14 04:52:39 sam Exp $ + * $Id: common.h,v 1.39 2001/08/22 17:21:45 massiot Exp $ * * Authors: Samuel Hocevar * Vincent Seguin @@ -66,11 +66,10 @@ typedef int ptrdiff_t; typedef unsigned long count_t; /* DCT elements types */ -#ifndef VDEC_DFT -typedef short dctelem_t; -#else -typedef int dctelem_t; -#endif +typedef s16 dctelem_t; + +/* Video buffer types */ +typedef u8 yuv_data_t; /***************************************************************************** * Classes declaration @@ -193,6 +192,13 @@ struct pgrm_descriptor_s; #define U32_AT(p) ( ntoh32 ( *( (u32 *)(p) ) ) ) #define U16_AT(p) ( ntoh16 ( *( (u16 *)(p) ) ) ) +/* Alignment of critical static data structures */ +#ifdef ATTRIBUTE_ALIGNED_MAX +# define ATTR_ALIGN(align) __attribute__ ((__aligned__ ((ATTRIBUTE_ALIGNED_MAX < align) ? ATTRIBUTE_ALIGNED_MAX : align))) +#else +# define ATTR_ALIGN(align) +#endif + /* win32, cl and icl support */ #if defined( _MSC_VER ) # define __attribute__(x) diff --git a/include/defs.h.in b/include/defs.h.in index c88aae1b08..46e445f87d 100644 --- a/include/defs.h.in +++ b/include/defs.h.in @@ -1,4 +1,4 @@ -/* include/defs.h.in. Generated automatically from configure.in by autoheader 2.13. */ +/* include/defs.h.in. Generated automatically from configure.in by autoheader. */ /* Define to empty if the keyword does not work. */ #undef const @@ -184,6 +184,9 @@ /* Define if defines boolean_t. */ #undef BOOLEAN_T_IN_CTHREADS_H +/* Maximum supported data alignment */ +#undef ATTRIBUTE_ALIGNED_MAX + /* Define if defines dvd_struct. */ #undef DVD_STRUCT_IN_SYS_DVDIO_H diff --git a/include/input_ext-dec.h b/include/input_ext-dec.h index 131cad9daf..30e0a2c641 100644 --- a/include/input_ext-dec.h +++ b/include/input_ext-dec.h @@ -2,7 +2,7 @@ * input_ext-dec.h: structures exported to the VideoLAN decoders ***************************************************************************** * Copyright (C) 1999, 2000 VideoLAN - * $Id: input_ext-dec.h,v 1.33 2001/07/16 12:10:32 massiot Exp $ + * $Id: input_ext-dec.h,v 1.34 2001/08/22 17:21:45 massiot Exp $ * * Authors: Christophe Massiot * Michel Kaempf @@ -192,8 +192,10 @@ typedef struct bit_stream_s #if (WORD_TYPE == u32) # define WORD_AT U32_AT +# define WORD_SIGNED s32 #elif (WORD_TYPE == u64) # define WORD_AT U64_AT +# define WORD_SIGNED s64 #else # error Unsupported WORD_TYPE #endif @@ -201,7 +203,7 @@ typedef struct bit_stream_s /***************************************************************************** * Protoypes from input_ext-dec.c *****************************************************************************/ -u32 UnalignedShowBits( struct bit_stream_s *, unsigned int ); +void UnalignedShowBits( struct bit_stream_s *, unsigned int ); void UnalignedRemoveBits( struct bit_stream_s * ); u32 UnalignedGetBits( struct bit_stream_s *, unsigned int ); @@ -252,7 +254,26 @@ static __inline__ u32 ShowBits( bit_stream_t * p_bit_stream, >> (8 * sizeof(WORD_TYPE) - i_bits) ); } - return UnalignedShowBits( p_bit_stream, i_bits ); + UnalignedShowBits( p_bit_stream, i_bits ); + return( p_bit_stream->fifo.buffer >> (8 * sizeof(WORD_TYPE) - i_bits) ); +} + +/***************************************************************************** + * ShowSignedBits : return i_bits bits from the bit stream, using signed + * arithmetic + *****************************************************************************/ +static __inline__ s32 ShowSignedBits( bit_stream_t * p_bit_stream, + unsigned int i_bits ) +{ + if( p_bit_stream->fifo.i_available >= i_bits ) + { + return( (WORD_SIGNED)p_bit_stream->fifo.buffer + >> (8 * sizeof(WORD_TYPE) - i_bits) ); + } + + /* You can probably do something a little faster, but now I'm tired. */ + return( (WORD_SIGNED)(ShowBits( p_bit_stream, i_bits ) << (32 - i_bits)) + >> (32 - i_bits) ); } /***************************************************************************** @@ -346,6 +367,30 @@ static __inline__ u32 GetBits( bit_stream_t * p_bit_stream, return UnalignedGetBits( p_bit_stream, i_bits ); } +/***************************************************************************** + * GetSignedBits : returns i_bits bits from the bit stream and removes them, + * using signed arithmetic + * XXX: do not use for 32 bits + *****************************************************************************/ +static __inline__ s32 GetSignedBits( bit_stream_t * p_bit_stream, + unsigned int i_bits ) +{ + if( p_bit_stream->fifo.i_available >= i_bits ) + { + s32 i_result; + + p_bit_stream->fifo.i_available -= i_bits; + i_result = (WORD_SIGNED)p_bit_stream->fifo.buffer + >> (8 * sizeof(WORD_TYPE) - i_bits); + p_bit_stream->fifo.buffer <<= i_bits; + return( i_result ); + } + + /* You can probably do something a little faster, but now I'm tired. */ + return( (WORD_SIGNED)(GetBits( p_bit_stream, i_bits ) << (32 - i_bits)) + >> (32 - i_bits) ); +} + /***************************************************************************** * GetBits32 : returns 32 bits from the bit stream and removes them *****************************************************************************/ diff --git a/include/modules.h b/include/modules.h index 46290afd8a..1b707c4d42 100644 --- a/include/modules.h +++ b/include/modules.h @@ -2,7 +2,7 @@ * modules.h : Module management functions. ***************************************************************************** * Copyright (C) 2001 VideoLAN - * $Id: modules.h,v 1.27 2001/07/17 09:48:07 massiot Exp $ + * $Id: modules.h,v 1.28 2001/08/22 17:21:45 massiot Exp $ * * Authors: Samuel Hocevar * @@ -162,32 +162,21 @@ typedef struct function_list_s /* Motion compensation plugin */ struct { -#define motion_functions( yuv ) \ - void ( * pf_field_field_##yuv ) ( struct macroblock_s * ); \ - void ( * pf_field_16x8_##yuv ) ( struct macroblock_s * ); \ - void ( * pf_field_dmv_##yuv ) ( struct macroblock_s * ); \ - void ( * pf_frame_field_##yuv ) ( struct macroblock_s * ); \ - void ( * pf_frame_frame_##yuv ) ( struct macroblock_s * ); \ - void ( * pf_frame_dmv_##yuv ) ( struct macroblock_s * ); - motion_functions( 420 ) - motion_functions( 422 ) - motion_functions( 444 ) -#undef motion_functions + void ( * ppppf_motion[2][2][4] ) ( yuv_data_t *, yuv_data_t *, + int, int ); } motion; /* IDCT plugin */ struct { - void ( * pf_idct_init ) ( struct vdec_thread_s * ); + void ( * pf_idct_init ) ( void ** ); void ( * pf_sparse_idct ) ( void *, dctelem_t *, int ); void ( * pf_idct ) ( void *, dctelem_t *, int ); void ( * pf_norm_scan ) ( u8 ppi_scan[2][64] ); - void ( * pf_decode_init ) ( struct vdec_thread_s * ); - void ( * pf_decode_mb_c ) ( struct vdec_thread_s *, - struct macroblock_s * ); - void ( * pf_decode_mb_bw ) ( struct vdec_thread_s *, - struct macroblock_s * ); + void ( * pf_decode_init ) ( ); + void ( * pf_addblock ) ( dctelem_t *, yuv_data_t *, int ); + void ( * pf_copyblock ) ( dctelem_t *, yuv_data_t *, int ); } idct; /* YUV transformation plugin */ diff --git a/include/vdec_ext-plugins.h b/include/vdec_ext-plugins.h index bcd01e50dd..d6ee8f11ae 100644 --- a/include/vdec_ext-plugins.h +++ b/include/vdec_ext-plugins.h @@ -1,8 +1,8 @@ /***************************************************************************** - * vdec_common.h : structures from the video decoder exported to plug-ins + * vdec_ext-plugins.h : structures from the video decoder exported to plug-ins ***************************************************************************** * Copyright (C) 1999, 2000 VideoLAN - * $Id: vdec_ext-plugins.h,v 1.2 2001/07/18 14:21:00 massiot Exp $ + * $Id: vdec_ext-plugins.h,v 1.3 2001/08/22 17:21:45 massiot Exp $ * * Authors: Christophe Massiot * @@ -21,77 +21,55 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. *****************************************************************************/ -/***************************************************************************** - * Function pointers - *****************************************************************************/ -typedef void (*f_motion_t)( struct macroblock_s * ); - /***************************************************************************** * macroblock_t : information on a macroblock passed to the video_decoder * thread *****************************************************************************/ +typedef struct idct_inner_s +{ + dctelem_t pi_block[64]; /* block */ + void ( * pf_idct ) ( void *, dctelem_t*, int ); + /* sparse IDCT or not ? */ + int i_sparse_pos; /* position of the + * non-NULL coeff */ + yuv_data_t * p_dct_data; /* pointer to the position + * in the final picture */ +} idct_inner_t; + +typedef struct motion_inner_s +{ + boolean_t b_average; /* 0 == copy */ + int i_x_pred, i_y_pred; /* motion vectors */ + yuv_data_t * pp_source[3]; + int i_dest_offset, i_src_offset; + int i_stride, i_height; + boolean_t b_second_half; +} motion_inner_t; + typedef struct macroblock_s { - picture_t * p_picture; /* current frame in progress */ + int i_mb_modes; - int i_mb_type; /* macroblock type */ + /* IDCT information */ + idct_inner_t p_idcts[6]; int i_coded_block_pattern; /* which blocks are coded ? */ - int i_chroma_nb_blocks; /* number of blocks for - * chroma components */ - - /* IDCT information */ - dctelem_t ppi_blocks[12][64]; /* blocks */ - void ( * pf_idct[12] ) ( void *, dctelem_t*, int ); - /* sparse IDCT or not ? */ - int pi_sparse_pos[12]; /* position of the - * non-NULL coeff */ + int i_lum_dct_stride, i_chrom_dct_stride; + /* nb of coeffs to jump when changing lines */ /* Motion compensation information */ - f_motion_t pf_motion; /* function to use for motion comp */ - picture_t * p_backward; /* backward reference frame */ - picture_t * p_forward; /* forward reference frame */ - int ppi_field_select[2][2]; /* field to use to - * form predictions */ - int pppi_motion_vectors[2][2][2]; /* motion vectors */ - int ppi_dmv[2][2]; /* differential motion vectors */ - /* coordinates of the block in the picture */ - int i_l_x, i_c_x; - int i_motion_l_y; - int i_motion_c_y; - int i_l_stride; /* number of yuv_data_t to - * ignore when changing line */ - int i_c_stride; /* idem, for chroma */ - boolean_t b_P_second; /* Second field of a P picture ? - * (used to determine the predicting - * frame) */ - boolean_t b_motion_field; /* Field we are predicting - * (top field or bottom field) */ - - /* AddBlock information */ - yuv_data_t * p_data[12]; /* pointer to the position - * in the final picture */ - int i_addb_l_stride, i_addb_c_stride; - /* nb of coeffs to jump when changing lines */ + motion_inner_t p_motions[8]; + int i_nb_motions; + yuv_data_t * pp_dest[3]; } macroblock_t; -/* Macroblock types */ +/* Macroblock Modes */ #define MB_INTRA 1 #define MB_PATTERN 2 #define MB_MOTION_BACKWARD 4 #define MB_MOTION_FORWARD 8 #define MB_QUANT 16 - -/* Motion types */ -#define MOTION_FIELD 1 -#define MOTION_FRAME 2 -#define MOTION_16X8 2 -#define MOTION_DMV 3 - -/* Structures */ -#define TOP_FIELD 1 -#define BOTTOM_FIELD 2 -#define FRAME_STRUCTURE 3 +#define DCT_TYPE_INTERLACED 32 /***************************************************************************** * vdec_thread_t: video decoder thread descriptor diff --git a/include/video.h b/include/video.h index e90a0d9ecd..2e5e50a159 100644 --- a/include/video.h +++ b/include/video.h @@ -4,7 +4,7 @@ * includes all common video types and constants. ***************************************************************************** * Copyright (C) 1999, 2000 VideoLAN - * $Id: video.h,v 1.31 2001/07/18 14:21:00 massiot Exp $ + * $Id: video.h,v 1.32 2001/08/22 17:21:45 massiot Exp $ * * Authors: Vincent Seguin * @@ -30,11 +30,6 @@ * "mtime.h" *****************************************************************************/ -/***************************************************************************** - * yuv_data_t: type for storing one Y, U or V sample. - *****************************************************************************/ -typedef u8 yuv_data_t; - /***************************************************************************** * picture_t: video picture ***************************************************************************** diff --git a/plugins/idct/idct.c b/plugins/idct/idct.c index 5ff0b93cbe..2eafe3b79e 100644 --- a/plugins/idct/idct.c +++ b/plugins/idct/idct.c @@ -2,7 +2,7 @@ * idct.c : IDCT module ***************************************************************************** * Copyright (C) 1999, 2000 VideoLAN - * $Id: idct.c,v 1.13 2001/07/17 09:48:07 massiot Exp $ + * $Id: idct.c,v 1.14 2001/08/22 17:21:45 massiot Exp $ * * Authors: Gaël Hendryckx * @@ -37,12 +37,6 @@ #include "mtime.h" #include "tests.h" -#include "video.h" -#include "video_output.h" - -#include "vdec_ext-plugins.h" - -#include "vdec_block.h" #include "vdec_idct.h" #include "modules.h" @@ -91,8 +85,8 @@ static void idct_getfunctions( function_list_t * p_function_list ) F.pf_idct = _M( vdec_IDCT ); F.pf_norm_scan = vdec_NormScan; F.pf_decode_init = _M( vdec_InitDecode ); - F.pf_decode_mb_c = _M( vdec_DecodeMacroblockC ); - F.pf_decode_mb_bw = _M( vdec_DecodeMacroblockBW ); + F.pf_addblock = _M( vdec_AddBlock ); + F.pf_copyblock = _M( vdec_CopyBlock ); #undef F } @@ -121,7 +115,8 @@ static void vdec_NormScan( u8 ppi_scan[2][64] ) /***************************************************************************** * vdec_IDCT : IDCT function for normal matrices *****************************************************************************/ -void _M( vdec_IDCT )( void * p_idct_data, dctelem_t * p_block, int i_idontcare ) +void _M( vdec_IDCT )( void * p_unused_data, dctelem_t * p_block, + int i_idontcare ) { s32 tmp0, tmp1, tmp2, tmp3; s32 tmp10, tmp11, tmp12, tmp13; diff --git a/plugins/idct/idctaltivec.c b/plugins/idct/idctaltivec.c index 1114f01152..22b33f0cac 100644 --- a/plugins/idct/idctaltivec.c +++ b/plugins/idct/idctaltivec.c @@ -2,7 +2,7 @@ * idctaltivec.c : Altivec IDCT module ***************************************************************************** * Copyright (C) 1999, 2000 VideoLAN - * $Id: idctaltivec.c,v 1.10 2001/07/17 09:48:07 massiot Exp $ + * $Id: idctaltivec.c,v 1.11 2001/08/22 17:21:45 massiot Exp $ * * Authors: Christophe Massiot * @@ -22,6 +22,7 @@ *****************************************************************************/ #define MODULE_NAME idctaltivec +#include "modules_inner.h" /***************************************************************************** * Preamble @@ -36,19 +37,11 @@ #include "mtime.h" #include "tests.h" /* TestCPU() */ -#include "video.h" -#include "video_output.h" - -#include "modules.h" -#include "modules_inner.h" - -#include "vdec_ext-plugins.h" - -#include "vdec_block.h" #include "vdec_idct.h" #include "idctaltivec.h" +#include "modules.h" #include "modules_export.h" /***************************************************************************** @@ -93,8 +86,8 @@ static void idct_getfunctions( function_list_t * p_function_list ) F.pf_idct = _M( vdec_IDCT ); F.pf_norm_scan = vdec_NormScan; F.pf_decode_init = _M( vdec_InitDecode ); - F.pf_decode_mb_c = _M( vdec_DecodeMacroblockC ); - F.pf_decode_mb_bw = _M( vdec_DecodeMacroblockBW ); + F.pf_addblock = _M( vdec_AddBlock ); + F.pf_copyblock = _M( vdec_CopyBlock ); #undef F } @@ -128,7 +121,8 @@ static void vdec_NormScan( u8 ppi_scan[2][64] ) /***************************************************************************** * vdec_IDCT : *****************************************************************************/ -void _M( vdec_IDCT )( void * p_idct_data, dctelem_t * p_block, int i_idontcare ) +void _M( vdec_IDCT )( void * p_unused_data, dctelem_t * p_block, + int i_idontcare ) { IDCT( p_block, p_block ); } diff --git a/plugins/idct/idctclassic.c b/plugins/idct/idctclassic.c index c6bcb8b72b..b47fcaf31f 100644 --- a/plugins/idct/idctclassic.c +++ b/plugins/idct/idctclassic.c @@ -2,7 +2,7 @@ * idctclassic.c : Classic IDCT module ***************************************************************************** * Copyright (C) 1999, 2000 VideoLAN - * $Id: idctclassic.c,v 1.13 2001/07/17 09:48:07 massiot Exp $ + * $Id: idctclassic.c,v 1.14 2001/08/22 17:21:45 massiot Exp $ * * Authors: Gaël Hendryckx * @@ -22,6 +22,7 @@ *****************************************************************************/ #define MODULE_NAME idctclassic +#include "modules_inner.h" /***************************************************************************** * Preamble @@ -36,17 +37,9 @@ #include "mtime.h" #include "tests.h" -#include "video.h" -#include "video_output.h" - -#include "vdec_ext-plugins.h" - -#include "modules.h" -#include "modules_inner.h" - -#include "vdec_block.h" #include "vdec_idct.h" +#include "modules.h" #include "modules_export.h" /***************************************************************************** @@ -93,8 +86,8 @@ static void idct_getfunctions( function_list_t * p_function_list ) F.pf_idct = _M( vdec_IDCT ); F.pf_norm_scan = vdec_NormScan; F.pf_decode_init = _M( vdec_InitDecode ); - F.pf_decode_mb_c = _M( vdec_DecodeMacroblockC ); - F.pf_decode_mb_bw = _M( vdec_DecodeMacroblockBW ); + F.pf_addblock = _M( vdec_AddBlock ); + F.pf_copyblock = _M( vdec_CopyBlock ); #undef F } @@ -123,7 +116,8 @@ static void vdec_NormScan( u8 ppi_scan[2][64] ) /***************************************************************************** * vdec_IDCT : IDCT function for normal matrices *****************************************************************************/ -void _M( vdec_IDCT )( void * p_idct_data, dctelem_t * p_block, int i_idontcare ) +void _M( vdec_IDCT )( void * p_unused_data, dctelem_t * p_block, + int i_idontcare ) { /* dct classique: pour tester la meilleure entre la classique et la */ /* no classique */ @@ -248,7 +242,7 @@ void _M( vdec_IDCT )( void * p_idct_data, dctelem_t * p_block, int i_idontcare ) * may be commented out. */ -#ifndef NO_ZERO_COLUMN_TEST /*ajoute un test mais evite des calculs */ +#ifndef NO_ZERO_COLUMN_TEST /* Adds a test but avoids calculus */ if ((dataptr[DCTSIZE*1] | dataptr[DCTSIZE*2] | dataptr[DCTSIZE*3] | dataptr[DCTSIZE*4] | dataptr[DCTSIZE*5] | dataptr[DCTSIZE*6] | dataptr[DCTSIZE*7]) == 0) diff --git a/plugins/idct/idctmmx.c b/plugins/idct/idctmmx.c index 86f90053cc..020d0c14ec 100644 --- a/plugins/idct/idctmmx.c +++ b/plugins/idct/idctmmx.c @@ -2,7 +2,7 @@ * idctmmx.c : MMX IDCT module ***************************************************************************** * Copyright (C) 1999, 2000 VideoLAN - * $Id: idctmmx.c,v 1.15 2001/07/17 09:48:07 massiot Exp $ + * $Id: idctmmx.c,v 1.16 2001/08/22 17:21:45 massiot Exp $ * * Authors: Aaron Holtzman * Michel Lespinasse @@ -26,6 +26,7 @@ *****************************************************************************/ #define MODULE_NAME idctmmx +#include "modules_inner.h" /***************************************************************************** * Preamble @@ -40,20 +41,11 @@ #include "mtime.h" #include "tests.h" /* TestCPU() */ -#include "video.h" -#include "video_output.h" - -#include "modules.h" -#include "modules_inner.h" - -#include "vdec_ext-plugins.h" - -#include "vdec_block.h" #include "vdec_idct.h" -#include "attributes.h" #include "mmx.h" +#include "modules.h" #include "modules_export.h" /***************************************************************************** @@ -98,8 +90,8 @@ static void idct_getfunctions( function_list_t * p_function_list ) F.pf_idct = _M( vdec_IDCT ); F.pf_norm_scan = vdec_NormScan; F.pf_decode_init = _M( vdec_InitDecode ); - F.pf_decode_mb_c = _M( vdec_DecodeMacroblockC ); - F.pf_decode_mb_bw = _M( vdec_DecodeMacroblockBW ); + F.pf_addblock = _M( vdec_AddBlock ); + F.pf_copyblock = _M( vdec_CopyBlock ); #undef F } @@ -434,7 +426,8 @@ static s32 rounder3[] ATTR_ALIGN(8) = static s32 rounder5[] ATTR_ALIGN(8) = rounder (-0.441341716183); // C3*(-C5/C4+C5-C3)/2 -void _M( vdec_IDCT )( void * p_idct_data, dctelem_t * p_block, int i_idontcare ) +void _M( vdec_IDCT )( void * p_unused_data, dctelem_t * p_block, + int i_idontcare ) { static dctelem_t table04[] ATTR_ALIGN(16) = table (22725, 21407, 19266, 16384, 12873, 8867, 4520); diff --git a/plugins/idct/idctmmxext.c b/plugins/idct/idctmmxext.c index 6b3da57a53..97ab2eba7e 100644 --- a/plugins/idct/idctmmxext.c +++ b/plugins/idct/idctmmxext.c @@ -2,7 +2,7 @@ * idctmmxext.c : MMX EXT IDCT module ***************************************************************************** * Copyright (C) 1999, 2000 VideoLAN - * $Id: idctmmxext.c,v 1.12 2001/07/17 09:48:07 massiot Exp $ + * $Id: idctmmxext.c,v 1.13 2001/08/22 17:21:45 massiot Exp $ * * Authors: Aaron Holtzman * Michel Lespinasse @@ -26,6 +26,7 @@ *****************************************************************************/ #define MODULE_NAME idctmmxext +#include "modules_inner.h" /***************************************************************************** * Preamble @@ -40,20 +41,11 @@ #include "mtime.h" #include "tests.h" /* TestCPU() */ -#include "video.h" -#include "video_output.h" - -#include "modules.h" -#include "modules_inner.h" - -#include "vdec_ext-plugins.h" - -#include "vdec_block.h" #include "vdec_idct.h" -#include "attributes.h" #include "mmx.h" +#include "modules.h" #include "modules_export.h" /***************************************************************************** @@ -98,8 +90,8 @@ static void idct_getfunctions( function_list_t * p_function_list ) F.pf_idct = _M( vdec_IDCT ); F.pf_norm_scan = vdec_NormScan; F.pf_decode_init = _M( vdec_InitDecode ); - F.pf_decode_mb_c = _M( vdec_DecodeMacroblockC ); - F.pf_decode_mb_bw = _M( vdec_DecodeMacroblockBW ); + F.pf_addblock = _M( vdec_AddBlock ); + F.pf_copyblock = _M( vdec_CopyBlock ); #undef F } @@ -418,7 +410,8 @@ static s32 rounder3[] ATTR_ALIGN(8) = static s32 rounder5[] ATTR_ALIGN(8) = rounder (-0.441341716183); // C3*(-C5/C4+C5-C3)/2 -void _M( vdec_IDCT )( void * p_idct_data, dctelem_t * p_block, int i_idontcare ) +void _M( vdec_IDCT )( void * p_unused_data, dctelem_t * p_block, + int i_idontcare ) { static dctelem_t table04[] ATTR_ALIGN(16) = table (22725, 21407, 19266, 16384, 12873, 8867, 4520); diff --git a/plugins/idct/vdec_block.h b/plugins/idct/vdec_block.h deleted file mode 100644 index 1c6c10bbaf..0000000000 --- a/plugins/idct/vdec_block.h +++ /dev/null @@ -1,113 +0,0 @@ -/***************************************************************************** - * vdec_block_h: Macroblock copy functions - ***************************************************************************** - * Copyright (C) 1999, 2000, 2001 VideoLAN - * $Id: vdec_block.h,v 1.3 2001/07/17 09:48:07 massiot Exp $ - * - * Authors: Christophe Massiot - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. - *****************************************************************************/ - -/***************************************************************************** - * Prototypes - *****************************************************************************/ -void _M( vdec_InitDecode ) ( struct vdec_thread_s *p_vdec ); -void _M( vdec_DecodeMacroblockC ) ( struct vdec_thread_s *p_vdec, - struct macroblock_s * p_mb ); -void _M( vdec_DecodeMacroblockBW ) ( struct vdec_thread_s *p_vdec, - struct macroblock_s * p_mb ); - -/***************************************************************************** - * vdec_DecodeMacroblock : decode a macroblock of a picture - *****************************************************************************/ -#define DECODEBLOCKSC( OPBLOCK ) \ -{ \ - int i_b, i_mask; \ - \ - i_mask = 1 << (3 + p_mb->i_chroma_nb_blocks); \ - \ - /* luminance */ \ - for( i_b = 0; i_b < 4; i_b++, i_mask >>= 1 ) \ - { \ - if( p_mb->i_coded_block_pattern & i_mask ) \ - { \ - /* \ - * Inverse DCT (ISO/IEC 13818-2 section Annex A) \ - */ \ - (p_mb->pf_idct[i_b])( p_vdec->p_idct_data, \ - p_mb->ppi_blocks[i_b], \ - p_mb->pi_sparse_pos[i_b] ); \ - \ - /* \ - * Adding prediction and coefficient data (ISO/IEC 13818-2 \ - * section 7.6.8) \ - */ \ - OPBLOCK( p_vdec, p_mb->ppi_blocks[i_b], \ - p_mb->p_data[i_b], p_mb->i_addb_l_stride ); \ - } \ - } \ - \ - /* chrominance */ \ - for( i_b = 4; i_b < 4 + p_mb->i_chroma_nb_blocks; \ - i_b++, i_mask >>= 1 ) \ - { \ - if( p_mb->i_coded_block_pattern & i_mask ) \ - { \ - /* \ - * Inverse DCT (ISO/IEC 13818-2 section Annex A) \ - */ \ - (p_mb->pf_idct[i_b])( p_vdec->p_idct_data, \ - p_mb->ppi_blocks[i_b], \ - p_mb->pi_sparse_pos[i_b] ); \ - \ - /* \ - * Adding prediction and coefficient data (ISO/IEC 13818-2 \ - * section 7.6.8) \ - */ \ - OPBLOCK( p_vdec, p_mb->ppi_blocks[i_b], \ - p_mb->p_data[i_b], p_mb->i_addb_c_stride ); \ - } \ - } \ -} - -#define DECODEBLOCKSBW( OPBLOCK ) \ -{ \ - int i_b, i_mask; \ - \ - i_mask = 1 << (3 + p_mb->i_chroma_nb_blocks); \ - \ - /* luminance */ \ - for( i_b = 0; i_b < 4; i_b++, i_mask >>= 1 ) \ - { \ - if( p_mb->i_coded_block_pattern & i_mask ) \ - { \ - /* \ - * Inverse DCT (ISO/IEC 13818-2 section Annex A) \ - */ \ - (p_mb->pf_idct[i_b])( p_vdec->p_idct_data, \ - p_mb->ppi_blocks[i_b], \ - p_mb->pi_sparse_pos[i_b] ); \ - \ - /* \ - * Adding prediction and coefficient data (ISO/IEC 13818-2 \ - * section 7.6.8) \ - */ \ - OPBLOCK( p_vdec, p_mb->ppi_blocks[i_b], \ - p_mb->p_data[i_b], p_mb->i_addb_l_stride ); \ - } \ - } \ -} - diff --git a/plugins/idct/vdec_block_c.c b/plugins/idct/vdec_block_c.c index 20ab131f7d..db50d13909 100644 --- a/plugins/idct/vdec_block_c.c +++ b/plugins/idct/vdec_block_c.c @@ -2,7 +2,7 @@ * vdec_block_c.c: Macroblock copy functions in C ***************************************************************************** * Copyright (C) 1999, 2000, 2001 VideoLAN - * $Id: vdec_block_c.c,v 1.5 2001/07/17 09:48:07 massiot Exp $ + * $Id: vdec_block_c.c,v 1.6 2001/08/22 17:21:45 massiot Exp $ * * Authors: Christophe Massiot * @@ -42,14 +42,7 @@ #include "intf_msg.h" -#include "input_ext-dec.h" - -#include "video.h" -#include "video_output.h" - -#include "vdec_ext-plugins.h" - -#include "vdec_block.h" +#include "vdec_idct.h" #include "modules.h" #include "modules_export.h" @@ -65,7 +58,7 @@ static u8 *pi_crop; /***************************************************************************** * vdec_InitDecode: initialize video decoder thread *****************************************************************************/ -void _M( vdec_InitDecode ) ( vdec_thread_t *p_vdec ) +void _M( vdec_InitDecode ) ( ) { int i_dummy; @@ -89,88 +82,48 @@ void _M( vdec_InitDecode ) ( vdec_thread_t *p_vdec ) } /***************************************************************************** - * AddBlock : add a block + * vdec_AddBlock : add a block *****************************************************************************/ -static __inline__ void AddBlock( vdec_thread_t * p_vdec, dctelem_t * p_block, - yuv_data_t * p_data, int i_incr ) +void _M( vdec_AddBlock ) ( dctelem_t * p_block, yuv_data_t * p_data, + int i_incr ) { - int i_x, i_y; + int i = 8; + + do { + p_data[0] = pi_crop[ p_data[0] + p_block[0] ]; + p_data[1] = pi_crop[ p_data[1] + p_block[1] ]; + p_data[2] = pi_crop[ p_data[2] + p_block[2] ]; + p_data[3] = pi_crop[ p_data[3] + p_block[3] ]; + p_data[4] = pi_crop[ p_data[4] + p_block[4] ]; + p_data[5] = pi_crop[ p_data[5] + p_block[5] ]; + p_data[6] = pi_crop[ p_data[6] + p_block[6] ]; + p_data[7] = pi_crop[ p_data[7] + p_block[7] ]; - for( i_y = 0; i_y < 8; i_y++ ) - { - for( i_x = 0; i_x < 8; i_x++ ) - { - *p_data = pi_crop[*p_data + *p_block++]; - p_data++; - } p_data += i_incr; - } + p_block += 8; + } while( --i ); } /***************************************************************************** - * CopyBlock : copy a block + * vdec_CopyBlock : copy a block *****************************************************************************/ -static __inline__ void CopyBlock( vdec_thread_t * p_vdec, dctelem_t * p_block, - yuv_data_t * p_data, int i_incr ) +void _M( vdec_CopyBlock )( dctelem_t * p_block, yuv_data_t * p_data, + int i_incr ) { - int i_x, i_y; + int i = 8; + + do { + p_data[0] = pi_crop[ p_block[0] ]; + p_data[1] = pi_crop[ p_block[1] ]; + p_data[2] = pi_crop[ p_block[2] ]; + p_data[3] = pi_crop[ p_block[3] ]; + p_data[4] = pi_crop[ p_block[4] ]; + p_data[5] = pi_crop[ p_block[5] ]; + p_data[6] = pi_crop[ p_block[6] ]; + p_data[7] = pi_crop[ p_block[7] ]; - for( i_y = 0; i_y < 8; i_y++ ) - { - for( i_x = 0; i_x < 8; i_x++ ) - { - *p_data++ = pi_crop[*p_block++]; - } p_data += i_incr; - } -} - -void _M( vdec_DecodeMacroblockC ) ( vdec_thread_t *p_vdec, macroblock_t * p_mb ) -{ - if( !(p_mb->i_mb_type & MB_INTRA) ) - { - /* - * Motion Compensation (ISO/IEC 13818-2 section 7.6) - */ - if( p_mb->pf_motion == 0 ) - { - intf_WarnMsg( 2, "pf_motion set to NULL" ); - } - else - { - p_mb->pf_motion( p_mb ); - } - - DECODEBLOCKSC( AddBlock ) - } - else - { - DECODEBLOCKSC( CopyBlock ) - } -} - -void _M( vdec_DecodeMacroblockBW ) ( vdec_thread_t *p_vdec, - macroblock_t * p_mb ) -{ - if( !(p_mb->i_mb_type & MB_INTRA) ) - { - /* - * Motion Compensation (ISO/IEC 13818-2 section 7.6) - */ - if( p_mb->pf_motion == 0 ) - { - intf_WarnMsg( 2, "pf_motion set to NULL" ); - } - else - { - p_mb->pf_motion( p_mb ); - } - - DECODEBLOCKSBW( AddBlock ) - } - else - { - DECODEBLOCKSBW( CopyBlock ) - } + p_block += 8; + } while( --i ); } diff --git a/plugins/idct/vdec_block_mmx.c b/plugins/idct/vdec_block_mmx.c index d6e36cc5bc..3bc2d172c3 100644 --- a/plugins/idct/vdec_block_mmx.c +++ b/plugins/idct/vdec_block_mmx.c @@ -2,9 +2,10 @@ * vdec_block_mmx.c: Macroblock copy functions in MMX assembly ***************************************************************************** * Copyright (C) 1999, 2000, 2001 VideoLAN - * $Id: vdec_block_mmx.c,v 1.5 2001/07/17 09:48:07 massiot Exp $ + * $Id: vdec_block_mmx.c,v 1.6 2001/08/22 17:21:45 massiot Exp $ * - * Authors: Gaël Hendryckx + * Authors: Michel Lespinasse + * Aaron Holtzman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -47,212 +48,89 @@ #include "video.h" #include "video_output.h" -#include "vdec_ext-plugins.h" - -#include "vdec_block.h" +#include "vdec_idct.h" #include "modules.h" #include "modules_export.h" +#include "mmx.h" + /***************************************************************************** * vdec_InitDecode: initialize video decoder thread *****************************************************************************/ -void _M( vdec_InitDecode ) ( vdec_thread_t *p_vdec ) +void _M( vdec_InitDecode ) ( ) { ; } /***************************************************************************** - * AddBlock : add a block + * vdec_AddBlock : add a block *****************************************************************************/ -static __inline__ void AddBlock( vdec_thread_t * p_vdec, dctelem_t * p_block, - yuv_data_t * p_data, int i_incr ) +#define ADD_MMX(offset,r1,r2,r3,r4) \ + movq_m2r (*(p_data+2*i_incr), r1); \ + packuswb_r2r (r4, r3); \ + movq_r2r (r1, r2); \ + p_data += i_incr; \ + movq_r2m (r3, *p_data); \ + punpcklbw_r2r (mm0, r1); \ + paddsw_m2r (*(p_block+offset), r1); \ + punpckhbw_r2r (mm0, r2); \ + paddsw_m2r (*(p_block+offset+4), r2); + +void _M( vdec_AddBlock ) ( dctelem_t * p_block, yuv_data_t * p_data, + int i_incr ) { - asm __volatile__ ( - "pxor %%mm7,%%mm7\n\t" - - "movq (%0),%%mm1\n\t" - "movq %%mm1,%%mm2\n\t" - "punpckhbw %%mm7,%%mm1\n\t" - "punpcklbw %%mm7,%%mm2\n\t" - "paddw (%2),%%mm2\n\t" - "paddw 8(%2),%%mm1\n\t" - "packuswb %%mm1,%%mm2\n\t" - "movq %%mm2,(%0)\n\t" - "addl %3,%0\n\t" - - "movq (%0),%%mm1\n\t" - "movq %%mm1,%%mm2\n\t" - "punpckhbw %%mm7,%%mm1\n\t" - "punpcklbw %%mm7,%%mm2\n\t" - "paddw 16(%2),%%mm2\n\t" - "paddw 24(%2),%%mm1\n\t" - "packuswb %%mm1,%%mm2\n\t" - "movq %%mm2,(%0)\n\t" - "addl %3,%0\n\t" - - "movq (%0),%%mm1\n\t" - "movq %%mm1,%%mm2\n\t" - "punpckhbw %%mm7,%%mm1\n\t" - "punpcklbw %%mm7,%%mm2\n\t" - "paddw 32(%2),%%mm2\n\t" - "paddw 40(%2),%%mm1\n\t" - "packuswb %%mm1,%%mm2\n\t" - "movq %%mm2,(%0)\n\t" - "addl %3,%0\n\t" - - "movq (%0),%%mm1\n\t" - "movq %%mm1,%%mm2\n\t" - "punpckhbw %%mm7,%%mm1\n\t" - "punpcklbw %%mm7,%%mm2\n\t" - "paddw 48(%2),%%mm2\n\t" - "paddw 56(%2),%%mm1\n\t" - "packuswb %%mm1,%%mm2\n\t" - "movq %%mm2,(%0)\n\t" - "addl %3,%0\n\t" - - "movq (%0),%%mm1\n\t" - "movq %%mm1,%%mm2\n\t" - "punpckhbw %%mm7,%%mm1\n\t" - "punpcklbw %%mm7,%%mm2\n\t" - "paddw 64(%2),%%mm2\n\t" - "paddw 72(%2),%%mm1\n\t" - "packuswb %%mm1,%%mm2\n\t" - "movq %%mm2,(%0)\n\t" - "addl %3,%0\n\t" - - "movq (%0),%%mm1\n\t" - "movq %%mm1,%%mm2\n\t" - "punpckhbw %%mm7,%%mm1\n\t" - "punpcklbw %%mm7,%%mm2\n\t" - "paddw 80(%2),%%mm2\n\t" - "paddw 88(%2),%%mm1\n\t" - "packuswb %%mm1,%%mm2\n\t" - "movq %%mm2,(%0)\n\t" - "addl %3,%0\n\t" - - "movq (%0),%%mm1\n\t" - "movq %%mm1,%%mm2\n\t" - "punpckhbw %%mm7,%%mm1\n\t" - "punpcklbw %%mm7,%%mm2\n\t" - "paddw 96(%2),%%mm2\n\t" - "paddw 104(%2),%%mm1\n\t" - "packuswb %%mm1,%%mm2\n\t" - "movq %%mm2,(%0)\n\t" - "addl %3,%0\n\t" - - "movq (%0),%%mm1\n\t" - "movq %%mm1,%%mm2\n\t" - "punpckhbw %%mm7,%%mm1\n\t" - "punpcklbw %%mm7,%%mm2\n\t" - "paddw 112(%2),%%mm2\n\t" - "paddw 120(%2),%%mm1\n\t" - "packuswb %%mm1,%%mm2\n\t" - "movq %%mm2,(%0)\n\t" - - //"emms" - : "=r" (p_data) - : "0" (p_data), "r" (p_block), "r" (i_incr + 8) ); + movq_m2r (*p_data, mm1); + pxor_r2r (mm0, mm0); + movq_m2r (*(p_data + i_incr), mm3); + movq_r2r (mm1, mm2); + punpcklbw_r2r (mm0, mm1); + movq_r2r (mm3, mm4); + paddsw_m2r (*(p_block+0*8), mm1); + punpckhbw_r2r (mm0, mm2); + paddsw_m2r (*(p_block+0*8+4), mm2); + punpcklbw_r2r (mm0, mm3); + paddsw_m2r (*(p_block+1*8), mm3); + packuswb_r2r (mm2, mm1); + punpckhbw_r2r (mm0, mm4); + movq_r2m (mm1, *p_data); + paddsw_m2r (*(p_block+1*8+4), mm4); + ADD_MMX (2*8, mm1, mm2, mm3, mm4); + ADD_MMX (3*8, mm3, mm4, mm1, mm2); + ADD_MMX (4*8, mm1, mm2, mm3, mm4); + ADD_MMX (5*8, mm3, mm4, mm1, mm2); + ADD_MMX (6*8, mm1, mm2, mm3, mm4); + ADD_MMX (7*8, mm3, mm4, mm1, mm2); + packuswb_r2r (mm4, mm3); + movq_r2m (mm3, *(p_data + i_incr)); } /***************************************************************************** - * CopyBlock : copy a block + * vdec_CopyBlock : copy a block *****************************************************************************/ -static __inline__ void CopyBlock( vdec_thread_t * p_vdec, dctelem_t * p_block, - yuv_data_t * p_data, int i_incr ) +#define COPY_MMX(offset,r0,r1,r2) \ + movq_m2r (*(p_block+offset), r0); \ + p_data += i_incr; \ + movq_m2r (*(p_block+offset+4), r1); \ + movq_r2m (r2, *p_data); \ + packuswb_r2r (r1, r0); + +void _M( vdec_CopyBlock ) ( dctelem_t * p_block, yuv_data_t * p_data, + int i_incr ) { - asm __volatile__ ( - "movq (%2),%%mm0\n\t" - "packuswb 8(%2),%%mm0\n\t" - "movq %%mm0,(%0)\n\t" - "addl %3,%0\n\t" - - "movq 16(%2),%%mm0\n\t" - "packuswb 24(%2),%%mm0\n\t" - "movq %%mm0,(%0)\n\t" - "addl %3,%0\n\t" - - "movq 32(%2),%%mm0\n\t" - "packuswb 40(%2),%%mm0\n\t" - "movq %%mm0,(%0)\n\t" - "addl %3,%0\n\t" - - "movq 48(%2),%%mm0\n\t" - "packuswb 56(%2),%%mm0\n\t" - "movq %%mm0,(%0)\n\t" - "addl %3,%0\n\t" - - "movq 64(%2),%%mm0\n\t" - "packuswb 72(%2),%%mm0\n\t" - "movq %%mm0,(%0)\n\t" - "addl %3,%0\n\t" - - "movq 80(%2),%%mm0\n\t" - "packuswb 88(%2),%%mm0\n\t" - "movq %%mm0,(%0)\n\t" - "addl %3,%0\n\t" - - "movq 96(%2),%%mm0\n\t" - "packuswb 104(%2),%%mm0\n\t" - "movq %%mm0,(%0)\n\t" - "addl %3,%0\n\t" - - "movq 112(%2),%%mm0\n\t" - "packuswb 120(%2),%%mm0\n\t" - "movq %%mm0,(%0)\n\t" - - //"emms" - : "=r" (p_data) - : "0" (p_data), "r" (p_block), "r" (i_incr + 8) ); -} - -void _M( vdec_DecodeMacroblockC ) ( vdec_thread_t *p_vdec, - macroblock_t * p_mb ) -{ - if( !(p_mb->i_mb_type & MB_INTRA) ) - { - /* - * Motion Compensation (ISO/IEC 13818-2 section 7.6) - */ - if( p_mb->pf_motion == 0 ) - { - intf_WarnMsg( 2, "pf_motion set to NULL" ); - } - else - { - p_mb->pf_motion( p_mb ); - } - - DECODEBLOCKSC( AddBlock ) - } - else - { - DECODEBLOCKSC( CopyBlock ) - } -} - -void _M( vdec_DecodeMacroblockBW ) ( vdec_thread_t *p_vdec, - macroblock_t * p_mb ) -{ - if( !(p_mb->i_mb_type & MB_INTRA) ) - { - /* - * Motion Compensation (ISO/IEC 13818-2 section 7.6) - */ - if( p_mb->pf_motion == 0 ) - { - intf_WarnMsg( 2, "pf_motion set to NULL" ); - } - else - { - p_mb->pf_motion( p_mb ); - } - - DECODEBLOCKSBW( AddBlock ) - } - else - { - DECODEBLOCKSBW( CopyBlock ) - } + movq_m2r (*(p_block+0*8), mm0); + movq_m2r (*(p_block+0*8+4), mm1); + movq_m2r (*(p_block+1*8), mm2); + packuswb_r2r (mm1, mm0); + movq_m2r (*(p_block+1*8+4), mm3); + movq_r2m (mm0, *p_data); + packuswb_r2r (mm3, mm2); + COPY_MMX (2*8, mm0, mm1, mm2); + COPY_MMX (3*8, mm2, mm3, mm0); + COPY_MMX (4*8, mm0, mm1, mm2); + COPY_MMX (5*8, mm2, mm3, mm0); + COPY_MMX (6*8, mm0, mm1, mm2); + COPY_MMX (7*8, mm2, mm3, mm0); + movq_r2m (mm2, *(p_data + i_incr)); } diff --git a/plugins/idct/vdec_idct.c b/plugins/idct/vdec_idct.c index 278e7f2ea5..b8ad5fc129 100644 --- a/plugins/idct/vdec_idct.c +++ b/plugins/idct/vdec_idct.c @@ -2,7 +2,7 @@ * vdec_idct.c : common IDCT functions ***************************************************************************** * Copyright (C) 1999, 2000 VideoLAN - * $Id: vdec_idct.c,v 1.3 2001/07/25 08:41:21 gbazin Exp $ + * $Id: vdec_idct.c,v 1.4 2001/08/22 17:21:45 massiot Exp $ * * Authors: Gaël Hendryckx * @@ -46,25 +46,24 @@ #include "modules.h" -#include "vdec_ext-plugins.h" #include "vdec_idct.h" /***************************************************************************** * vdec_InitIDCT : initialize datas for vdec_SparseIDCT *****************************************************************************/ -void _M( vdec_InitIDCT ) ( vdec_thread_t * p_vdec ) +void _M( vdec_InitIDCT ) ( void ** pp_idct_data ) { int i; dctelem_t * p_pre; - p_vdec->p_idct_data = malloc( sizeof(dctelem_t) * 64 * 64 ); - p_pre = (dctelem_t *) p_vdec->p_idct_data; + *pp_idct_data = malloc( sizeof(dctelem_t) * 64 * 64 ); + p_pre = (dctelem_t *) *pp_idct_data; memset( p_pre, 0, 64 * 64 * sizeof(dctelem_t) ); - for( i=0 ; i < 64 ; i++ ) + for( i = 0 ; i < 64 ; i++ ) { p_pre[i*64+i] = 1 << SPARSE_SCALE_FACTOR; - _M( vdec_IDCT )( p_vdec, &p_pre[i*64], 0) ; + _M( vdec_IDCT )( NULL, &p_pre[i*64], 0) ; } return; } diff --git a/plugins/idct/vdec_idct.h b/plugins/idct/vdec_idct.h index da519658fe..de73718f74 100644 --- a/plugins/idct/vdec_idct.h +++ b/plugins/idct/vdec_idct.h @@ -2,7 +2,7 @@ * vdec_idct.h : macros for the inverse discrete cosine transform ***************************************************************************** * Copyright (C) 1999, 2000 VideoLAN - * $Id: vdec_idct.h,v 1.2 2001/07/17 09:48:07 massiot Exp $ + * $Id: vdec_idct.h,v 1.3 2001/08/22 17:21:45 massiot Exp $ * * Authors: Gaël Hendryckx * Christophe Massiot @@ -143,7 +143,11 @@ /***************************************************************************** * Protoypes *****************************************************************************/ -void _M( vdec_SparseIDCT ) ( void *, dctelem_t * p_block, int i_sparse_pos); -void _M( vdec_InitIDCT ) ( struct vdec_thread_s * ); +void _M( vdec_SparseIDCT ) ( void *, dctelem_t * p_block, int i_sparse_pos ); +void _M( vdec_InitIDCT ) ( void ** ); void _M( vdec_IDCT ) ( void *, dctelem_t * p_block, int i_idontcare ); - +void _M( vdec_InitDecode ) ( ); +void _M( vdec_AddBlock ) ( dctelem_t * p_block, yuv_data_t * p_data, + int i_incr ); +void _M( vdec_CopyBlock ) ( dctelem_t * p_block, yuv_data_t * p_data, + int i_incr ); diff --git a/plugins/motion/Makefile b/plugins/motion/Makefile index c03c2f9318..31bbd5f145 100644 --- a/plugins/motion/Makefile +++ b/plugins/motion/Makefile @@ -7,20 +7,18 @@ # Objects # -PLUGIN_MOTION = motion.o vdec_motion_inner.o -PLUGIN_MOTIONMMX = motionmmx.o vdec_motion_inner_mmx.o -PLUGIN_MOTIONMMXEXT = motionmmxext.o vdec_motion_inner_mmxext.o -PLUGIN_MOTIONCOMMON = vdec_motion_common.o +PLUGIN_MOTION = motion.o +PLUGIN_MOTIONMMX = motionmmx.o +PLUGIN_MOTIONMMXEXT = motionmmxext.o +PLUGIN_MOTION3DNOW = motion3dnow.o -BUILTIN_MOTION = $(PLUGIN_MOTION:%.o=BUILTIN_MOTION_%.o) \ - $(PLUGIN_MOTIONCOMMON:%.o=BUILTIN_MOTION_%.o) -BUILTIN_MOTIONMMX = $(PLUGIN_MOTIONMMX:%.o=BUILTIN_MOTIONMMX_%.o) \ - $(PLUGIN_MOTIONCOMMON:%.o=BUILTIN_MOTIONMMX_%.o) -BUILTIN_MOTIONMMXEXT = $(PLUGIN_MOTIONMMXEXT:%.o=BUILTIN_MOTIONMMXEXT_%.o) \ - $(PLUGIN_MOTIONCOMMON:%.o=BUILTIN_MOTIONMMXEXT_%.o) +BUILTIN_MOTION = $(PLUGIN_MOTION:%.o=BUILTIN_MOTION_%.o) +BUILTIN_MOTIONMMX = $(PLUGIN_MOTIONMMX:%.o=BUILTIN_MOTIONMMX_%.o) +BUILTIN_MOTIONMMXEXT = $(PLUGIN_MOTIONMMXEXT:%.o=BUILTIN_MOTIONMMXEXT_%.o) +BUILTIN_MOTION3DNOW = $(PLUGIN_MOTION3DNOW:%.o=BUILTIN_MOTION3DNOW_%.o) -PLUGIN_C = $(PLUGIN_MOTION) $(PLUGIN_MOTIONMMX) $(PLUGIN_MOTIONMMXEXT) $(PLUGIN_MOTIONCOMMON) -ALL_OBJ = $(PLUGIN_C) $(BUILTIN_MOTION) $(BUILTIN_MOTIONMMX) $(BUILTIN_MOTIONMMXEXT) +PLUGIN_C = $(PLUGIN_MOTION) $(PLUGIN_MOTIONMMX) $(PLUGIN_MOTIONMMXEXT) $(PLUGIN_MOTION3DNOW) +ALL_OBJ = $(PLUGIN_C) $(BUILTIN_MOTION) $(BUILTIN_MOTIONMMX) $(BUILTIN_MOTIONMMXEXT) $(BUILTIN_MOTION3DNOW) # # Virtual targets @@ -40,35 +38,46 @@ $(BUILTIN_MOTIONMMXEXT): BUILTIN_MOTIONMMXEXT_%.o: .dep/%.d $(BUILTIN_MOTIONMMXEXT): BUILTIN_MOTIONMMXEXT_%.o: %.c $(CC) $(CFLAGS) -DBUILTIN -DMODULE_NAME=motionmmxext -c -o $@ $< +$(BUILTIN_MOTION3DNOW): BUILTIN_MOTION3DNOW_%.o: .dep/%.d +$(BUILTIN_MOTION3DNOW): BUILTIN_MOTION3DNOW_%.o: %.c + $(CC) $(CFLAGS) -DBUILTIN -DMODULE_NAME=motion3dnow -c -o $@ $< + # # Real targets # -../motion.so: $(PLUGIN_MOTION) $(PLUGIN_MOTIONCOMMON) +../motion.so: $(PLUGIN_MOTION) $(CC) $(PCFLAGS) -o $@ $^ $(PLCFLAGS) ../motion.a: $(BUILTIN_MOTION) ar r $@ $^ $(RANLIB) $@ -../motionclassic.so: $(PLUGIN_MOTIONCLASSIC) $(PLUGIN_MOTIONCOMMON) +../motionclassic.so: $(PLUGIN_MOTIONCLASSIC) $(CC) $(PCFLAGS) -o $@ $^ $(PLCFLAGS) ../motionclassic.a: $(BUILTIN_MOTIONCLASSIC) ar r $@ $^ $(RANLIB) $@ -../motionmmx.so: $(PLUGIN_MOTIONMMX) $(PLUGIN_MOTIONCOMMON) +../motionmmx.so: $(PLUGIN_MOTIONMMX) $(CC) $(PCFLAGS) -o $@ $^ $(PLCFLAGS) ../motionmmx.a: $(BUILTIN_MOTIONMMX) ar r $@ $^ $(RANLIB) $@ -../motionmmxext.so: $(PLUGIN_MOTIONMMXEXT) $(PLUGIN_MOTIONCOMMON) +../motionmmxext.so: $(PLUGIN_MOTIONMMXEXT) $(CC) $(PCFLAGS) -o $@ $^ $(PLCFLAGS) ../motionmmxext.a: $(BUILTIN_MOTIONMMXEXT) ar r $@ $^ $(RANLIB) $@ +../motion3dnow.so: $(PLUGIN_MOTION3DNOW) + $(CC) $(PCFLAGS) -o $@ $^ $(PLCFLAGS) + +../motionm3dnow.a: $(BUILTIN_MOTION3DNOW) + ar r $@ $^ + $(RANLIB) $@ + diff --git a/plugins/motion/motion.c b/plugins/motion/motion.c index ffc6522f4d..4f7e90e17e 100644 --- a/plugins/motion/motion.c +++ b/plugins/motion/motion.c @@ -1,16 +1,17 @@ /***************************************************************************** * motion.c : C motion compensation module for vlc ***************************************************************************** - * Copyright (C) 2000 VideoLAN - * $Id: motion.c,v 1.8 2001/07/11 02:01:05 sam Exp $ + * Copyright (C) 2001 VideoLAN + * $Id: motion.c,v 1.9 2001/08/22 17:21:45 massiot Exp $ * - * Authors: Christophe Massiot + * Authors: Aaron Holtzman + * Michel Lespinasse * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the @@ -37,15 +38,13 @@ #include "mtime.h" #include "tests.h" -#include "video.h" - #include "modules.h" #include "modules_export.h" /***************************************************************************** * Local and extern prototypes. *****************************************************************************/ -void _M( motion_getfunctions )( function_list_t * p_function_list ); +static void motion_getfunctions( function_list_t * p_function_list ); /***************************************************************************** * Build configuration tree. @@ -62,7 +61,7 @@ MODULE_INIT_START MODULE_INIT_STOP MODULE_ACTIVATE_START - _M( motion_getfunctions )( &p_module->p_functions->motion ); + motion_getfunctions( &p_module->p_functions->motion ); MODULE_ACTIVATE_STOP MODULE_DEACTIVATE_START @@ -71,7 +70,7 @@ MODULE_DEACTIVATE_STOP /***************************************************************************** * motion_Probe: tests probe the CPU and return a score *****************************************************************************/ -int _M( motion_Probe )( probedata_t *p_data ) +static int motion_Probe( probedata_t *p_data ) { if( TestMethod( MOTION_METHOD_VAR, "motion" ) || TestMethod( MOTION_METHOD_VAR, "c" ) ) @@ -83,3 +82,114 @@ int _M( motion_Probe )( probedata_t *p_data ) return( 50 ); } +/***************************************************************************** + * Simple motion compensation in C + *****************************************************************************/ + +#define avg2(a,b) ((a+b+1)>>1) +#define avg4(a,b,c,d) ((a+b+c+d+2)>>2) + +#define predict_(i) (ref[i]) +#define predict_x(i) (avg2 (ref[i], ref[i+1])) +#define predict_y(i) (avg2 (ref[i], (ref+stride)[i])) +#define predict_xy(i) (avg4 (ref[i], ref[i+1], (ref+stride)[i], (ref+stride)[i+1])) + +#define put(predictor,i) dest[i] = predictor (i) +#define avg(predictor,i) dest[i] = avg2 (predictor (i), dest[i]) + +// mc function template + +#define MC_FUNC(op,xy) \ +static void MC_##op##_##xy##16_c (yuv_data_t * dest, yuv_data_t * ref, \ + int stride, int height) \ +{ \ + do { \ + op (predict_##xy, 0); \ + op (predict_##xy, 1); \ + op (predict_##xy, 2); \ + op (predict_##xy, 3); \ + op (predict_##xy, 4); \ + op (predict_##xy, 5); \ + op (predict_##xy, 6); \ + op (predict_##xy, 7); \ + op (predict_##xy, 8); \ + op (predict_##xy, 9); \ + op (predict_##xy, 10); \ + op (predict_##xy, 11); \ + op (predict_##xy, 12); \ + op (predict_##xy, 13); \ + op (predict_##xy, 14); \ + op (predict_##xy, 15); \ + ref += stride; \ + dest += stride; \ + } while (--height); \ +} \ +static void MC_##op##_##xy##8_c (yuv_data_t * dest, yuv_data_t * ref, \ + int stride, int height) \ +{ \ + do { \ + op (predict_##xy, 0); \ + op (predict_##xy, 1); \ + op (predict_##xy, 2); \ + op (predict_##xy, 3); \ + op (predict_##xy, 4); \ + op (predict_##xy, 5); \ + op (predict_##xy, 6); \ + op (predict_##xy, 7); \ + ref += stride; \ + dest += stride; \ + } while (--height); \ +} + +// definitions of the actual mc functions + +MC_FUNC (put,) +MC_FUNC (avg,) +MC_FUNC (put,x) +MC_FUNC (avg,x) +MC_FUNC (put,y) +MC_FUNC (avg,y) +MC_FUNC (put,xy) +MC_FUNC (avg,xy) + +/***************************************************************************** + * Functions exported as capabilities. They are declared as static so that + * we don't pollute the namespace too much. + *****************************************************************************/ +static void motion_getfunctions( function_list_t * p_function_list ) +{ + static void (* ppppf_motion[2][2][4])( yuv_data_t *, yuv_data_t *, + int, int ) = + { + { + /* Copying functions */ + { + /* Width == 16 */ + MC_put_16_c, MC_put_x16_c, MC_put_y16_c, MC_put_xy16_c + }, + { + /* Width == 8 */ + MC_put_8_c, MC_put_x8_c, MC_put_y8_c, MC_put_xy8_c + } + }, + { + /* Averaging functions */ + { + /* Width == 16 */ + MC_avg_16_c, MC_avg_x16_c, MC_avg_y16_c, MC_avg_xy16_c + }, + { + /* Width == 8 */ + MC_avg_8_c, MC_avg_x8_c, MC_avg_y8_c, MC_avg_xy8_c + } + } + }; + + p_function_list->pf_probe = motion_Probe; + +#define list p_function_list->functions.motion + memcpy( list.ppppf_motion, ppppf_motion, sizeof( void * ) * 16 ); +#undef list + + return; +} diff --git a/plugins/motion/motion3dnow.c b/plugins/motion/motion3dnow.c new file mode 100644 index 0000000000..2a1f916094 --- /dev/null +++ b/plugins/motion/motion3dnow.c @@ -0,0 +1,629 @@ +/***************************************************************************** + * motion3dnow.c : 3DNow! motion compensation module for vlc + ***************************************************************************** + * Copyright (C) 2001 VideoLAN + * $Id: motion3dnow.c,v 1.1 2001/08/22 17:21:45 massiot Exp $ + * + * Authors: Aaron Holtzman + * Michel Lespinasse + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. + *****************************************************************************/ + +#define MODULE_NAME motion3dnow +#include "modules_inner.h" + +/***************************************************************************** + * Preamble + *****************************************************************************/ +#include "defs.h" + +#include /* malloc(), free() */ + +#include "config.h" +#include "common.h" /* boolean_t, byte_t */ +#include "threads.h" +#include "mtime.h" +#include "tests.h" + +#include "mmx.h" + +#include "modules.h" +#include "modules_export.h" + +/***************************************************************************** + * Local and extern prototypes. + *****************************************************************************/ +static void motion_getfunctions( function_list_t * p_function_list ); + +/***************************************************************************** + * Build configuration tree. + *****************************************************************************/ +MODULE_CONFIG_START +ADD_WINDOW( "Configuration for 3DNow! motion compensation module" ) + ADD_COMMENT( "Ha, ha -- nothing to configure yet" ) +MODULE_CONFIG_STOP + +MODULE_INIT_START + p_module->i_capabilities = MODULE_CAPABILITY_NULL + | MODULE_CAPABILITY_MOTION; + p_module->psz_longname = "3DNow! motion compensation module"; +MODULE_INIT_STOP + +MODULE_ACTIVATE_START + motion_getfunctions( &p_module->p_functions->motion ); +MODULE_ACTIVATE_STOP + +MODULE_DEACTIVATE_START +MODULE_DEACTIVATE_STOP + +/***************************************************************************** + * motion_Probe: tests probe the CPU and return a score + *****************************************************************************/ +static int motion_Probe( probedata_t *p_data ) +{ + if( !TestCPU( CPU_CAPABILITY_3DNOW ) ) + { + return( 0 ); + } + + if( TestMethod( MOTION_METHOD_VAR, "motion3dnow" ) + || TestMethod( MOTION_METHOD_VAR, "3dnow" ) ) + { + return( 999 ); + } + + return( 200 ); +} + +/***************************************************************************** + * Motion compensation in 3DNow (OK I know this does MMXEXT too and it's ugly) + *****************************************************************************/ + +#define CPU_MMXEXT 0 +#define CPU_3DNOW 1 + + +//CPU_MMXEXT/CPU_3DNOW adaptation layer + +#define pavg_r2r(src,dest) \ +do { \ + if (cpu == CPU_MMXEXT) \ + pavgb_r2r (src, dest); \ + else \ + pavgusb_r2r (src, dest); \ +} while (0) + +#define pavg_m2r(src,dest) \ +do { \ + if (cpu == CPU_MMXEXT) \ + pavgb_m2r (src, dest); \ + else \ + pavgusb_m2r (src, dest); \ +} while (0) + + +//CPU_MMXEXT code + + +static __inline__ void MC_put1_8 (int height, yuv_data_t * dest, yuv_data_t * ref, + int stride) +{ + do { + movq_m2r (*ref, mm0); + movq_r2m (mm0, *dest); + ref += stride; + dest += stride; + } while (--height); +} + +static __inline__ void MC_put1_16 (int height, yuv_data_t * dest, yuv_data_t * ref, + int stride) +{ + do { + movq_m2r (*ref, mm0); + movq_m2r (*(ref+8), mm1); + ref += stride; + movq_r2m (mm0, *dest); + movq_r2m (mm1, *(dest+8)); + dest += stride; + } while (--height); +} + +static __inline__ void MC_avg1_8 (int height, yuv_data_t * dest, yuv_data_t * ref, + int stride, int cpu) +{ + do { + movq_m2r (*ref, mm0); + pavg_m2r (*dest, mm0); + ref += stride; + movq_r2m (mm0, *dest); + dest += stride; + } while (--height); +} + +static __inline__ void MC_avg1_16 (int height, yuv_data_t * dest, yuv_data_t * ref, + int stride, int cpu) +{ + do { + movq_m2r (*ref, mm0); + movq_m2r (*(ref+8), mm1); + pavg_m2r (*dest, mm0); + pavg_m2r (*(dest+8), mm1); + movq_r2m (mm0, *dest); + ref += stride; + movq_r2m (mm1, *(dest+8)); + dest += stride; + } while (--height); +} + +static __inline__ void MC_put2_8 (int height, yuv_data_t * dest, yuv_data_t * ref, + int stride, int offset, int cpu) +{ + do { + movq_m2r (*ref, mm0); + pavg_m2r (*(ref+offset), mm0); + ref += stride; + movq_r2m (mm0, *dest); + dest += stride; + } while (--height); +} + +static __inline__ void MC_put2_16 (int height, yuv_data_t * dest, yuv_data_t * ref, + int stride, int offset, int cpu) +{ + do { + movq_m2r (*ref, mm0); + movq_m2r (*(ref+8), mm1); + pavg_m2r (*(ref+offset), mm0); + pavg_m2r (*(ref+offset+8), mm1); + movq_r2m (mm0, *dest); + ref += stride; + movq_r2m (mm1, *(dest+8)); + dest += stride; + } while (--height); +} + +static __inline__ void MC_avg2_8 (int height, yuv_data_t * dest, yuv_data_t * ref, + int stride, int offset, int cpu) +{ + do { + movq_m2r (*ref, mm0); + pavg_m2r (*(ref+offset), mm0); + pavg_m2r (*dest, mm0); + ref += stride; + movq_r2m (mm0, *dest); + dest += stride; + } while (--height); +} + +static __inline__ void MC_avg2_16 (int height, yuv_data_t * dest, yuv_data_t * ref, + int stride, int offset, int cpu) +{ + do { + movq_m2r (*ref, mm0); + movq_m2r (*(ref+8), mm1); + pavg_m2r (*(ref+offset), mm0); + pavg_m2r (*(ref+offset+8), mm1); + pavg_m2r (*dest, mm0); + pavg_m2r (*(dest+8), mm1); + ref += stride; + movq_r2m (mm0, *dest); + movq_r2m (mm1, *(dest+8)); + dest += stride; + } while (--height); +} + +static mmx_t mask_one = {0x0101010101010101LL}; + +static __inline__ void MC_put4_8 (int height, yuv_data_t * dest, yuv_data_t * ref, + int stride, int cpu) +{ + movq_m2r (*ref, mm0); + movq_m2r (*(ref+1), mm1); + movq_r2r (mm0, mm7); + pxor_r2r (mm1, mm7); + pavg_r2r (mm1, mm0); + ref += stride; + + do { + movq_m2r (*ref, mm2); + movq_r2r (mm0, mm5); + + movq_m2r (*(ref+1), mm3); + movq_r2r (mm2, mm6); + + pxor_r2r (mm3, mm6); + pavg_r2r (mm3, mm2); + + por_r2r (mm6, mm7); + pxor_r2r (mm2, mm5); + + pand_r2r (mm5, mm7); + pavg_r2r (mm2, mm0); + + pand_m2r (mask_one, mm7); + + psubusb_r2r (mm7, mm0); + + ref += stride; + movq_r2m (mm0, *dest); + dest += stride; + + movq_r2r (mm6, mm7); // unroll ! + movq_r2r (mm2, mm0); // unroll ! + } while (--height); +} + +static __inline__ void MC_put4_16 (int height, yuv_data_t * dest, yuv_data_t * ref, + int stride, int cpu) +{ + do { + movq_m2r (*ref, mm0); + movq_m2r (*(ref+stride+1), mm1); + movq_r2r (mm0, mm7); + movq_m2r (*(ref+1), mm2); + pxor_r2r (mm1, mm7); + movq_m2r (*(ref+stride), mm3); + movq_r2r (mm2, mm6); + pxor_r2r (mm3, mm6); + pavg_r2r (mm1, mm0); + pavg_r2r (mm3, mm2); + por_r2r (mm6, mm7); + movq_r2r (mm0, mm6); + pxor_r2r (mm2, mm6); + pand_r2r (mm6, mm7); + pand_m2r (mask_one, mm7); + pavg_r2r (mm2, mm0); + psubusb_r2r (mm7, mm0); + movq_r2m (mm0, *dest); + + movq_m2r (*(ref+8), mm0); + movq_m2r (*(ref+stride+9), mm1); + movq_r2r (mm0, mm7); + movq_m2r (*(ref+9), mm2); + pxor_r2r (mm1, mm7); + movq_m2r (*(ref+stride+8), mm3); + movq_r2r (mm2, mm6); + pxor_r2r (mm3, mm6); + pavg_r2r (mm1, mm0); + pavg_r2r (mm3, mm2); + por_r2r (mm6, mm7); + movq_r2r (mm0, mm6); + pxor_r2r (mm2, mm6); + pand_r2r (mm6, mm7); + pand_m2r (mask_one, mm7); + pavg_r2r (mm2, mm0); + psubusb_r2r (mm7, mm0); + ref += stride; + movq_r2m (mm0, *(dest+8)); + dest += stride; + } while (--height); +} + +static __inline__ void MC_avg4_8 (int height, yuv_data_t * dest, yuv_data_t * ref, + int stride, int cpu) +{ + do { + movq_m2r (*ref, mm0); + movq_m2r (*(ref+stride+1), mm1); + movq_r2r (mm0, mm7); + movq_m2r (*(ref+1), mm2); + pxor_r2r (mm1, mm7); + movq_m2r (*(ref+stride), mm3); + movq_r2r (mm2, mm6); + pxor_r2r (mm3, mm6); + pavg_r2r (mm1, mm0); + pavg_r2r (mm3, mm2); + por_r2r (mm6, mm7); + movq_r2r (mm0, mm6); + pxor_r2r (mm2, mm6); + pand_r2r (mm6, mm7); + pand_m2r (mask_one, mm7); + pavg_r2r (mm2, mm0); + psubusb_r2r (mm7, mm0); + movq_m2r (*dest, mm1); + pavg_r2r (mm1, mm0); + ref += stride; + movq_r2m (mm0, *dest); + dest += stride; + } while (--height); +} + +static __inline__ void MC_avg4_16 (int height, yuv_data_t * dest, yuv_data_t * ref, + int stride, int cpu) +{ + do { + movq_m2r (*ref, mm0); + movq_m2r (*(ref+stride+1), mm1); + movq_r2r (mm0, mm7); + movq_m2r (*(ref+1), mm2); + pxor_r2r (mm1, mm7); + movq_m2r (*(ref+stride), mm3); + movq_r2r (mm2, mm6); + pxor_r2r (mm3, mm6); + pavg_r2r (mm1, mm0); + pavg_r2r (mm3, mm2); + por_r2r (mm6, mm7); + movq_r2r (mm0, mm6); + pxor_r2r (mm2, mm6); + pand_r2r (mm6, mm7); + pand_m2r (mask_one, mm7); + pavg_r2r (mm2, mm0); + psubusb_r2r (mm7, mm0); + movq_m2r (*dest, mm1); + pavg_r2r (mm1, mm0); + movq_r2m (mm0, *dest); + + movq_m2r (*(ref+8), mm0); + movq_m2r (*(ref+stride+9), mm1); + movq_r2r (mm0, mm7); + movq_m2r (*(ref+9), mm2); + pxor_r2r (mm1, mm7); + movq_m2r (*(ref+stride+8), mm3); + movq_r2r (mm2, mm6); + pxor_r2r (mm3, mm6); + pavg_r2r (mm1, mm0); + pavg_r2r (mm3, mm2); + por_r2r (mm6, mm7); + movq_r2r (mm0, mm6); + pxor_r2r (mm2, mm6); + pand_r2r (mm6, mm7); + pand_m2r (mask_one, mm7); + pavg_r2r (mm2, mm0); + psubusb_r2r (mm7, mm0); + movq_m2r (*(dest+8), mm1); + pavg_r2r (mm1, mm0); + ref += stride; + movq_r2m (mm0, *(dest+8)); + dest += stride; + } while (--height); +} + +static void MC_avg_16_mmxext (yuv_data_t * dest, yuv_data_t * ref, + int stride, int height) +{ + MC_avg1_16 (height, dest, ref, stride, CPU_MMXEXT); +} + +static void MC_avg_8_mmxext (yuv_data_t * dest, yuv_data_t * ref, + int stride, int height) +{ + MC_avg1_8 (height, dest, ref, stride, CPU_MMXEXT); +} + +static void MC_put_16_mmxext (yuv_data_t * dest, yuv_data_t * ref, + int stride, int height) +{ + MC_put1_16 (height, dest, ref, stride); +} + +static void MC_put_8_mmxext (yuv_data_t * dest, yuv_data_t * ref, + int stride, int height) +{ + MC_put1_8 (height, dest, ref, stride); +} + +static void MC_avg_x16_mmxext (yuv_data_t * dest, yuv_data_t * ref, + int stride, int height) +{ + MC_avg2_16 (height, dest, ref, stride, 1, CPU_MMXEXT); +} + +static void MC_avg_x8_mmxext (yuv_data_t * dest, yuv_data_t * ref, + int stride, int height) +{ + MC_avg2_8 (height, dest, ref, stride, 1, CPU_MMXEXT); +} + +static void MC_put_x16_mmxext (yuv_data_t * dest, yuv_data_t * ref, + int stride, int height) +{ + MC_put2_16 (height, dest, ref, stride, 1, CPU_MMXEXT); +} + +static void MC_put_x8_mmxext (yuv_data_t * dest, yuv_data_t * ref, + int stride, int height) +{ + MC_put2_8 (height, dest, ref, stride, 1, CPU_MMXEXT); +} + +static void MC_avg_y16_mmxext (yuv_data_t * dest, yuv_data_t * ref, + int stride, int height) +{ + MC_avg2_16 (height, dest, ref, stride, stride, CPU_MMXEXT); +} + +static void MC_avg_y8_mmxext (yuv_data_t * dest, yuv_data_t * ref, + int stride, int height) +{ + MC_avg2_8 (height, dest, ref, stride, stride, CPU_MMXEXT); +} + +static void MC_put_y16_mmxext (yuv_data_t * dest, yuv_data_t * ref, + int stride, int height) +{ + MC_put2_16 (height, dest, ref, stride, stride, CPU_MMXEXT); +} + +static void MC_put_y8_mmxext (yuv_data_t * dest, yuv_data_t * ref, + int stride, int height) +{ + MC_put2_8 (height, dest, ref, stride, stride, CPU_MMXEXT); +} + +static void MC_avg_xy16_mmxext (yuv_data_t * dest, yuv_data_t * ref, + int stride, int height) +{ + MC_avg4_16 (height, dest, ref, stride, CPU_MMXEXT); +} + +static void MC_avg_xy8_mmxext (yuv_data_t * dest, yuv_data_t * ref, + int stride, int height) +{ + MC_avg4_8 (height, dest, ref, stride, CPU_MMXEXT); +} + +static void MC_put_xy16_mmxext (yuv_data_t * dest, yuv_data_t * ref, + int stride, int height) +{ + MC_put4_16 (height, dest, ref, stride, CPU_MMXEXT); +} + +static void MC_put_xy8_mmxext (yuv_data_t * dest, yuv_data_t * ref, + int stride, int height) +{ + MC_put4_8 (height, dest, ref, stride, CPU_MMXEXT); +} + + +static void MC_avg_16_3dnow (yuv_data_t * dest, yuv_data_t * ref, + int stride, int height) +{ + MC_avg1_16 (height, dest, ref, stride, CPU_3DNOW); +} + +static void MC_avg_8_3dnow (yuv_data_t * dest, yuv_data_t * ref, + int stride, int height) +{ + MC_avg1_8 (height, dest, ref, stride, CPU_3DNOW); +} + +static void MC_put_16_3dnow (yuv_data_t * dest, yuv_data_t * ref, + int stride, int height) +{ + MC_put1_16 (height, dest, ref, stride); +} + +static void MC_put_8_3dnow (yuv_data_t * dest, yuv_data_t * ref, + int stride, int height) +{ + MC_put1_8 (height, dest, ref, stride); +} + +static void MC_avg_x16_3dnow (yuv_data_t * dest, yuv_data_t * ref, + int stride, int height) +{ + MC_avg2_16 (height, dest, ref, stride, 1, CPU_3DNOW); +} + +static void MC_avg_x8_3dnow (yuv_data_t * dest, yuv_data_t * ref, + int stride, int height) +{ + MC_avg2_8 (height, dest, ref, stride, 1, CPU_3DNOW); +} + +static void MC_put_x16_3dnow (yuv_data_t * dest, yuv_data_t * ref, + int stride, int height) +{ + MC_put2_16 (height, dest, ref, stride, 1, CPU_3DNOW); +} + +static void MC_put_x8_3dnow (yuv_data_t * dest, yuv_data_t * ref, + int stride, int height) +{ + MC_put2_8 (height, dest, ref, stride, 1, CPU_3DNOW); +} + +static void MC_avg_y16_3dnow (yuv_data_t * dest, yuv_data_t * ref, + int stride, int height) +{ + MC_avg2_16 (height, dest, ref, stride, stride, CPU_3DNOW); +} + +static void MC_avg_y8_3dnow (yuv_data_t * dest, yuv_data_t * ref, + int stride, int height) +{ + MC_avg2_8 (height, dest, ref, stride, stride, CPU_3DNOW); +} + +static void MC_put_y16_3dnow (yuv_data_t * dest, yuv_data_t * ref, + int stride, int height) +{ + MC_put2_16 (height, dest, ref, stride, stride, CPU_3DNOW); +} + +static void MC_put_y8_3dnow (yuv_data_t * dest, yuv_data_t * ref, + int stride, int height) +{ + MC_put2_8 (height, dest, ref, stride, stride, CPU_3DNOW); +} + +static void MC_avg_xy16_3dnow (yuv_data_t * dest, yuv_data_t * ref, + int stride, int height) +{ + MC_avg4_16 (height, dest, ref, stride, CPU_3DNOW); +} + +static void MC_avg_xy8_3dnow (yuv_data_t * dest, yuv_data_t * ref, + int stride, int height) +{ + MC_avg4_8 (height, dest, ref, stride, CPU_3DNOW); +} + +static void MC_put_xy16_3dnow (yuv_data_t * dest, yuv_data_t * ref, + int stride, int height) +{ + MC_put4_16 (height, dest, ref, stride, CPU_3DNOW); +} + +static void MC_put_xy8_3dnow (yuv_data_t * dest, yuv_data_t * ref, + int stride, int height) +{ + MC_put4_8 (height, dest, ref, stride, CPU_3DNOW); +} + +/***************************************************************************** + * Functions exported as capabilities. They are declared as static so that + * we don't pollute the namespace too much. + *****************************************************************************/ +static void motion_getfunctions( function_list_t * p_function_list ) +{ + static void (* ppppf_motion[2][2][4])( yuv_data_t *, yuv_data_t *, + int, int ) = + { + { + /* Copying functions */ + { + /* Width == 16 */ + MC_put_16_3dnow, MC_put_x16_3dnow, MC_put_y16_3dnow, MC_put_xy16_3dnow + }, + { + /* Width == 8 */ + MC_put_8_3dnow, MC_put_x8_3dnow, MC_put_y8_3dnow, MC_put_xy8_3dnow + } + }, + { + /* Averaging functions */ + { + /* Width == 16 */ + MC_avg_16_3dnow, MC_avg_x16_3dnow, MC_avg_y16_3dnow, MC_avg_xy16_3dnow + }, + { + /* Width == 8 */ + MC_avg_8_3dnow, MC_avg_x8_3dnow, MC_avg_y8_3dnow, MC_avg_xy8_3dnow + } + } + }; + + p_function_list->pf_probe = motion_Probe; + +#define list p_function_list->functions.motion + memcpy( list.ppppf_motion, ppppf_motion, sizeof( void * ) * 16 ); +#undef list + + return; +} + diff --git a/plugins/motion/motionmmx.c b/plugins/motion/motionmmx.c index f821877844..338402ba89 100644 --- a/plugins/motion/motionmmx.c +++ b/plugins/motion/motionmmx.c @@ -1,16 +1,17 @@ /***************************************************************************** * motionmmx.c : MMX motion compensation module for vlc ***************************************************************************** - * Copyright (C) 2000 VideoLAN - * $Id: motionmmx.c,v 1.9 2001/07/11 02:01:05 sam Exp $ + * Copyright (C) 2001 VideoLAN + * $Id: motionmmx.c,v 1.10 2001/08/22 17:21:45 massiot Exp $ * - * Authors: Christophe Massiot + * Authors: Aaron Holtzman + * Michel Lespinasse * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the @@ -37,7 +38,7 @@ #include "mtime.h" #include "tests.h" -#include "video.h" +#include "mmx.h" #include "modules.h" #include "modules_export.h" @@ -45,7 +46,7 @@ /***************************************************************************** * Local and extern prototypes. *****************************************************************************/ -void _M( motion_getfunctions )( function_list_t * p_function_list ); +static void motion_getfunctions( function_list_t * p_function_list ); /***************************************************************************** * Build configuration tree. @@ -62,7 +63,7 @@ MODULE_INIT_START MODULE_INIT_STOP MODULE_ACTIVATE_START - _M( motion_getfunctions )( &p_module->p_functions->motion ); + motion_getfunctions( &p_module->p_functions->motion ); MODULE_ACTIVATE_STOP MODULE_DEACTIVATE_START @@ -71,7 +72,7 @@ MODULE_DEACTIVATE_STOP /***************************************************************************** * motion_Probe: tests probe the CPU and return a score *****************************************************************************/ -int _M( motion_Probe )( probedata_t *p_data ) +static int motion_Probe( probedata_t *p_data ) { if( !TestCPU( CPU_CAPABILITY_MMX ) ) { @@ -87,3 +88,526 @@ int _M( motion_Probe )( probedata_t *p_data ) return( 150 ); } +/***************************************************************************** + * Motion compensation in MMX + *****************************************************************************/ + +// some rounding constants +mmx_t round1 = {0x0001000100010001LL}; +mmx_t round4 = {0x0002000200020002LL}; + +/* + * This code should probably be compiled with loop unrolling + * (ie, -funroll-loops in gcc)becuase some of the loops + * use a small static number of iterations. This was written + * with the assumption the compiler knows best about when + * unrolling will help + */ + +static __inline__ void mmx_zero_reg () +{ + // load 0 into mm0 + pxor_r2r (mm0, mm0); +} + +static __inline__ void mmx_average_2_U8 (yuv_data_t * dest, + yuv_data_t * src1, yuv_data_t * src2) +{ + // + // *dest = (*src1 + *src2 + 1)/ 2; + // + + movq_m2r (*src1, mm1); // load 8 src1 bytes + movq_r2r (mm1, mm2); // copy 8 src1 bytes + + movq_m2r (*src2, mm3); // load 8 src2 bytes + movq_r2r (mm3, mm4); // copy 8 src2 bytes + + punpcklbw_r2r (mm0, mm1); // unpack low src1 bytes + punpckhbw_r2r (mm0, mm2); // unpack high src1 bytes + + punpcklbw_r2r (mm0, mm3); // unpack low src2 bytes + punpckhbw_r2r (mm0, mm4); // unpack high src2 bytes + + paddw_r2r (mm3, mm1); // add lows to mm1 + paddw_m2r (round1, mm1); + psraw_i2r (1, mm1); // /2 + + paddw_r2r (mm4, mm2); // add highs to mm2 + paddw_m2r (round1, mm2); + psraw_i2r (1, mm2); // /2 + + packuswb_r2r (mm2, mm1); // pack (w/ saturation) + movq_r2m (mm1, *dest); // store result in dest +} + +static __inline__ void mmx_interp_average_2_U8 (yuv_data_t * dest, + yuv_data_t * src1, yuv_data_t * src2) +{ + // + // *dest = (*dest + (*src1 + *src2 + 1)/ 2 + 1)/ 2; + // + + movq_m2r (*dest, mm1); // load 8 dest bytes + movq_r2r (mm1, mm2); // copy 8 dest bytes + + movq_m2r (*src1, mm3); // load 8 src1 bytes + movq_r2r (mm3, mm4); // copy 8 src1 bytes + + movq_m2r (*src2, mm5); // load 8 src2 bytes + movq_r2r (mm5, mm6); // copy 8 src2 bytes + + punpcklbw_r2r (mm0, mm1); // unpack low dest bytes + punpckhbw_r2r (mm0, mm2); // unpack high dest bytes + + punpcklbw_r2r (mm0, mm3); // unpack low src1 bytes + punpckhbw_r2r (mm0, mm4); // unpack high src1 bytes + + punpcklbw_r2r (mm0, mm5); // unpack low src2 bytes + punpckhbw_r2r (mm0, mm6); // unpack high src2 bytes + + paddw_r2r (mm5, mm3); // add lows + paddw_m2r (round1, mm3); + psraw_i2r (1, mm3); // /2 + + paddw_r2r (mm6, mm4); // add highs + paddw_m2r (round1, mm4); + psraw_i2r (1, mm4); // /2 + + paddw_r2r (mm3, mm1); // add lows + paddw_m2r (round1, mm1); + psraw_i2r (1, mm1); // /2 + + paddw_r2r (mm4, mm2); // add highs + paddw_m2r (round1, mm2); + psraw_i2r (1, mm2); // /2 + + packuswb_r2r (mm2, mm1); // pack (w/ saturation) + movq_r2m (mm1, *dest); // store result in dest +} + +static __inline__ void mmx_average_4_U8 (yuv_data_t * dest, + yuv_data_t * src1, yuv_data_t * src2, + yuv_data_t * src3, yuv_data_t * src4) +{ + // + // *dest = (*src1 + *src2 + *src3 + *src4 + 2)/ 4; + // + + movq_m2r (*src1, mm1); // load 8 src1 bytes + movq_r2r (mm1, mm2); // copy 8 src1 bytes + + punpcklbw_r2r (mm0, mm1); // unpack low src1 bytes + punpckhbw_r2r (mm0, mm2); // unpack high src1 bytes + + movq_m2r (*src2, mm3); // load 8 src2 bytes + movq_r2r (mm3, mm4); // copy 8 src2 bytes + + punpcklbw_r2r (mm0, mm3); // unpack low src2 bytes + punpckhbw_r2r (mm0, mm4); // unpack high src2 bytes + + paddw_r2r (mm3, mm1); // add lows + paddw_r2r (mm4, mm2); // add highs + + // now have partials in mm1 and mm2 + + movq_m2r (*src3, mm3); // load 8 src3 bytes + movq_r2r (mm3, mm4); // copy 8 src3 bytes + + punpcklbw_r2r (mm0, mm3); // unpack low src3 bytes + punpckhbw_r2r (mm0, mm4); // unpack high src3 bytes + + paddw_r2r (mm3, mm1); // add lows + paddw_r2r (mm4, mm2); // add highs + + movq_m2r (*src4, mm5); // load 8 src4 bytes + movq_r2r (mm5, mm6); // copy 8 src4 bytes + + punpcklbw_r2r (mm0, mm5); // unpack low src4 bytes + punpckhbw_r2r (mm0, mm6); // unpack high src4 bytes + + paddw_r2r (mm5, mm1); // add lows + paddw_r2r (mm6, mm2); // add highs + + // now have subtotal in mm1 and mm2 + + paddw_m2r (round4, mm1); + psraw_i2r (2, mm1); // /4 + paddw_m2r (round4, mm2); + psraw_i2r (2, mm2); // /4 + + packuswb_r2r (mm2, mm1); // pack (w/ saturation) + movq_r2m (mm1, *dest); // store result in dest +} + +static __inline__ void mmx_interp_average_4_U8 (yuv_data_t * dest, + yuv_data_t * src1, yuv_data_t * src2, + yuv_data_t * src3, yuv_data_t * src4) +{ + // + // *dest = (*dest + (*src1 + *src2 + *src3 + *src4 + 2)/ 4 + 1)/ 2; + // + + movq_m2r (*src1, mm1); // load 8 src1 bytes + movq_r2r (mm1, mm2); // copy 8 src1 bytes + + punpcklbw_r2r (mm0, mm1); // unpack low src1 bytes + punpckhbw_r2r (mm0, mm2); // unpack high src1 bytes + + movq_m2r (*src2, mm3); // load 8 src2 bytes + movq_r2r (mm3, mm4); // copy 8 src2 bytes + + punpcklbw_r2r (mm0, mm3); // unpack low src2 bytes + punpckhbw_r2r (mm0, mm4); // unpack high src2 bytes + + paddw_r2r (mm3, mm1); // add lows + paddw_r2r (mm4, mm2); // add highs + + // now have partials in mm1 and mm2 + + movq_m2r (*src3, mm3); // load 8 src3 bytes + movq_r2r (mm3, mm4); // copy 8 src3 bytes + + punpcklbw_r2r (mm0, mm3); // unpack low src3 bytes + punpckhbw_r2r (mm0, mm4); // unpack high src3 bytes + + paddw_r2r (mm3, mm1); // add lows + paddw_r2r (mm4, mm2); // add highs + + movq_m2r (*src4, mm5); // load 8 src4 bytes + movq_r2r (mm5, mm6); // copy 8 src4 bytes + + punpcklbw_r2r (mm0, mm5); // unpack low src4 bytes + punpckhbw_r2r (mm0, mm6); // unpack high src4 bytes + + paddw_r2r (mm5, mm1); // add lows + paddw_r2r (mm6, mm2); // add highs + + paddw_m2r (round4, mm1); + psraw_i2r (2, mm1); // /4 + paddw_m2r (round4, mm2); + psraw_i2r (2, mm2); // /4 + + // now have subtotal/4 in mm1 and mm2 + + movq_m2r (*dest, mm3); // load 8 dest bytes + movq_r2r (mm3, mm4); // copy 8 dest bytes + + punpcklbw_r2r (mm0, mm3); // unpack low dest bytes + punpckhbw_r2r (mm0, mm4); // unpack high dest bytes + + paddw_r2r (mm3, mm1); // add lows + paddw_r2r (mm4, mm2); // add highs + + paddw_m2r (round1, mm1); + psraw_i2r (1, mm1); // /2 + paddw_m2r (round1, mm2); + psraw_i2r (1, mm2); // /2 + + // now have end value in mm1 and mm2 + + packuswb_r2r (mm2, mm1); // pack (w/ saturation) + movq_r2m (mm1,*dest); // store result in dest +} + +//----------------------------------------------------------------------- + +static __inline__ void MC_avg_mmx (int width, int height, + yuv_data_t * dest, yuv_data_t * ref, int stride) +{ + mmx_zero_reg (); + + do { + mmx_average_2_U8 (dest, dest, ref); + + if (width == 16) + mmx_average_2_U8 (dest+8, dest+8, ref+8); + + dest += stride; + ref += stride; + } while (--height); +} + +static void MC_avg_16_mmx (yuv_data_t * dest, yuv_data_t * ref, + int stride, int height) +{ + MC_avg_mmx (16, height, dest, ref, stride); +} + +static void MC_avg_8_mmx (yuv_data_t * dest, yuv_data_t * ref, + int stride, int height) +{ + MC_avg_mmx (8, height, dest, ref, stride); +} + +//----------------------------------------------------------------------- + +static __inline__ void MC_put_mmx (int width, int height, + yuv_data_t * dest, yuv_data_t * ref, int stride) +{ + mmx_zero_reg (); + + do { + movq_m2r (* ref, mm1); // load 8 ref bytes + movq_r2m (mm1,* dest); // store 8 bytes at curr + + if (width == 16) + { + movq_m2r (* (ref+8), mm1); // load 8 ref bytes + movq_r2m (mm1,* (dest+8)); // store 8 bytes at curr + } + + dest += stride; + ref += stride; + } while (--height); +} + +static void MC_put_16_mmx (yuv_data_t * dest, yuv_data_t * ref, + int stride, int height) +{ + MC_put_mmx (16, height, dest, ref, stride); +} + +static void MC_put_8_mmx (yuv_data_t * dest, yuv_data_t * ref, + int stride, int height) +{ + MC_put_mmx (8, height, dest, ref, stride); +} + +//----------------------------------------------------------------------- + +// Half pixel interpolation in the x direction +static __inline__ void MC_avg_x_mmx (int width, int height, + yuv_data_t * dest, yuv_data_t * ref, int stride) +{ + mmx_zero_reg (); + + do { + mmx_interp_average_2_U8 (dest, ref, ref+1); + + if (width == 16) + mmx_interp_average_2_U8 (dest+8, ref+8, ref+9); + + dest += stride; + ref += stride; + } while (--height); +} + +static void MC_avg_x16_mmx (yuv_data_t * dest, yuv_data_t * ref, + int stride, int height) +{ + MC_avg_x_mmx (16, height, dest, ref, stride); +} + +static void MC_avg_x8_mmx (yuv_data_t * dest, yuv_data_t * ref, + int stride, int height) +{ + MC_avg_x_mmx (8, height, dest, ref, stride); +} + +//----------------------------------------------------------------------- + +static __inline__ void MC_put_x_mmx (int width, int height, + yuv_data_t * dest, yuv_data_t * ref, int stride) +{ + mmx_zero_reg (); + + do { + mmx_average_2_U8 (dest, ref, ref+1); + + if (width == 16) + mmx_average_2_U8 (dest+8, ref+8, ref+9); + + dest += stride; + ref += stride; + } while (--height); +} + +static void MC_put_x16_mmx (yuv_data_t * dest, yuv_data_t * ref, + int stride, int height) +{ + MC_put_x_mmx (16, height, dest, ref, stride); +} + +static void MC_put_x8_mmx (yuv_data_t * dest, yuv_data_t * ref, + int stride, int height) +{ + MC_put_x_mmx (8, height, dest, ref, stride); +} + +//----------------------------------------------------------------------- + +static __inline__ void MC_avg_xy_mmx (int width, int height, + yuv_data_t * dest, yuv_data_t * ref, int stride) +{ + yuv_data_t * ref_next = ref+stride; + + mmx_zero_reg (); + + do { + mmx_interp_average_4_U8 (dest, ref, ref+1, ref_next, ref_next+1); + + if (width == 16) + mmx_interp_average_4_U8 (dest+8, ref+8, ref+9, + ref_next+8, ref_next+9); + + dest += stride; + ref += stride; + ref_next += stride; + } while (--height); +} + +static void MC_avg_xy16_mmx (yuv_data_t * dest, yuv_data_t * ref, + int stride, int height) +{ + MC_avg_xy_mmx (16, height, dest, ref, stride); +} + +static void MC_avg_xy8_mmx (yuv_data_t * dest, yuv_data_t * ref, + int stride, int height) +{ + MC_avg_xy_mmx (8, height, dest, ref, stride); +} + +//----------------------------------------------------------------------- + +static __inline__ void MC_put_xy_mmx (int width, int height, + yuv_data_t * dest, yuv_data_t * ref, int stride) +{ + yuv_data_t * ref_next = ref+stride; + + mmx_zero_reg (); + + do { + mmx_average_4_U8 (dest, ref, ref+1, ref_next, ref_next+1); + + if (width == 16) + mmx_average_4_U8 (dest+8, ref+8, ref+9, ref_next+8, ref_next+9); + + dest += stride; + ref += stride; + ref_next += stride; + } while (--height); +} + +static void MC_put_xy16_mmx (yuv_data_t * dest, yuv_data_t * ref, + int stride, int height) +{ + MC_put_xy_mmx (16, height, dest, ref, stride); +} + +static void MC_put_xy8_mmx (yuv_data_t * dest, yuv_data_t * ref, + int stride, int height) +{ + MC_put_xy_mmx (8, height, dest, ref, stride); +} + +//----------------------------------------------------------------------- + +static __inline__ void MC_avg_y_mmx (int width, int height, + yuv_data_t * dest, yuv_data_t * ref, int stride) +{ + yuv_data_t * ref_next = ref+stride; + + mmx_zero_reg (); + + do { + mmx_interp_average_2_U8 (dest, ref, ref_next); + + if (width == 16) + mmx_interp_average_2_U8 (dest+8, ref+8, ref_next+8); + + dest += stride; + ref += stride; + ref_next += stride; + } while (--height); +} + +static void MC_avg_y16_mmx (yuv_data_t * dest, yuv_data_t * ref, + int stride, int height) +{ + MC_avg_y_mmx (16, height, dest, ref, stride); +} + +static void MC_avg_y8_mmx (yuv_data_t * dest, yuv_data_t * ref, + int stride, int height) +{ + MC_avg_y_mmx (8, height, dest, ref, stride); +} + +//----------------------------------------------------------------------- + +static __inline__ void MC_put_y_mmx (int width, int height, + yuv_data_t * dest, yuv_data_t * ref, int stride) +{ + yuv_data_t * ref_next = ref+stride; + + mmx_zero_reg (); + + do { + mmx_average_2_U8 (dest, ref, ref_next); + + if (width == 16) + mmx_average_2_U8 (dest+8, ref+8, ref_next+8); + + dest += stride; + ref += stride; + ref_next += stride; + } while (--height); +} + +static void MC_put_y16_mmx (yuv_data_t * dest, yuv_data_t * ref, + int stride, int height) +{ + MC_put_y_mmx (16, height, dest, ref, stride); +} + +static void MC_put_y8_mmx (yuv_data_t * dest, yuv_data_t * ref, + int stride, int height) +{ + MC_put_y_mmx (8, height, dest, ref, stride); +} + + +/***************************************************************************** + * Functions exported as capabilities. They are declared as static so that + * we don't pollute the namespace too much. + *****************************************************************************/ +static void motion_getfunctions( function_list_t * p_function_list ) +{ + static void (* ppppf_motion[2][2][4])( yuv_data_t *, yuv_data_t *, + int, int ) = + { + { + /* Copying functions */ + { + /* Width == 16 */ + MC_put_16_mmx, MC_put_x16_mmx, MC_put_y16_mmx, MC_put_xy16_mmx + }, + { + /* Width == 8 */ + MC_put_8_mmx, MC_put_x8_mmx, MC_put_y8_mmx, MC_put_xy8_mmx + } + }, + { + /* Averaging functions */ + { + /* Width == 16 */ + MC_avg_16_mmx, MC_avg_x16_mmx, MC_avg_y16_mmx, MC_avg_xy16_mmx + }, + { + /* Width == 8 */ + MC_avg_8_mmx, MC_avg_x8_mmx, MC_avg_y8_mmx, MC_avg_xy8_mmx + } + } + }; + + p_function_list->pf_probe = motion_Probe; + +#define list p_function_list->functions.motion + memcpy( list.ppppf_motion, ppppf_motion, sizeof( void * ) * 16 ); +#undef list + + return; +} + diff --git a/plugins/motion/motionmmxext.c b/plugins/motion/motionmmxext.c index 4163fa785c..738ce1c2d9 100644 --- a/plugins/motion/motionmmxext.c +++ b/plugins/motion/motionmmxext.c @@ -1,16 +1,17 @@ /***************************************************************************** * motionmmxext.c : MMX EXT motion compensation module for vlc ***************************************************************************** - * Copyright (C) 2000 VideoLAN - * $Id: motionmmxext.c,v 1.9 2001/07/11 02:01:05 sam Exp $ + * Copyright (C) 2001 VideoLAN + * $Id: motionmmxext.c,v 1.10 2001/08/22 17:21:45 massiot Exp $ * - * Authors: Christophe Massiot + * Authors: Aaron Holtzman + * Michel Lespinasse * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the @@ -37,7 +38,7 @@ #include "mtime.h" #include "tests.h" -#include "video.h" +#include "mmx.h" #include "modules.h" #include "modules_export.h" @@ -45,24 +46,24 @@ /***************************************************************************** * Local and extern prototypes. *****************************************************************************/ -void _M( motion_getfunctions )( function_list_t * p_function_list ); +static void motion_getfunctions( function_list_t * p_function_list ); /***************************************************************************** * Build configuration tree. *****************************************************************************/ MODULE_CONFIG_START -ADD_WINDOW( "Configuration for motion compensation module" ) +ADD_WINDOW( "Configuration for MMXEXT motion compensation module" ) ADD_COMMENT( "Ha, ha -- nothing to configure yet" ) MODULE_CONFIG_STOP MODULE_INIT_START p_module->i_capabilities = MODULE_CAPABILITY_NULL | MODULE_CAPABILITY_MOTION; - p_module->psz_longname = "MMX EXT motion compensation module"; + p_module->psz_longname = "MMXEXT motion compensation module"; MODULE_INIT_STOP MODULE_ACTIVATE_START - _M( motion_getfunctions )( &p_module->p_functions->motion ); + motion_getfunctions( &p_module->p_functions->motion ); MODULE_ACTIVATE_STOP MODULE_DEACTIVATE_START @@ -71,7 +72,7 @@ MODULE_DEACTIVATE_STOP /***************************************************************************** * motion_Probe: tests probe the CPU and return a score *****************************************************************************/ -int _M( motion_Probe )( probedata_t *p_data ) +static int motion_Probe( probedata_t *p_data ) { if( !TestCPU( CPU_CAPABILITY_MMXEXT ) ) { @@ -87,3 +88,542 @@ int _M( motion_Probe )( probedata_t *p_data ) return( 200 ); } +/***************************************************************************** + * Motion compensation in MMXEXT (OK I know this does 3DNow too and it's ugly) + *****************************************************************************/ + +#define CPU_MMXEXT 0 +#define CPU_3DNOW 1 + + +//CPU_MMXEXT/CPU_3DNOW adaptation layer + +#define pavg_r2r(src,dest) \ +do { \ + if (cpu == CPU_MMXEXT) \ + pavgb_r2r (src, dest); \ + else \ + pavgusb_r2r (src, dest); \ +} while (0) + +#define pavg_m2r(src,dest) \ +do { \ + if (cpu == CPU_MMXEXT) \ + pavgb_m2r (src, dest); \ + else \ + pavgusb_m2r (src, dest); \ +} while (0) + + +//CPU_MMXEXT code + + +static __inline__ void MC_put1_8 (int height, yuv_data_t * dest, yuv_data_t * ref, + int stride) +{ + do { + movq_m2r (*ref, mm0); + movq_r2m (mm0, *dest); + ref += stride; + dest += stride; + } while (--height); +} + +static __inline__ void MC_put1_16 (int height, yuv_data_t * dest, yuv_data_t * ref, + int stride) +{ + do { + movq_m2r (*ref, mm0); + movq_m2r (*(ref+8), mm1); + ref += stride; + movq_r2m (mm0, *dest); + movq_r2m (mm1, *(dest+8)); + dest += stride; + } while (--height); +} + +static __inline__ void MC_avg1_8 (int height, yuv_data_t * dest, yuv_data_t * ref, + int stride, int cpu) +{ + do { + movq_m2r (*ref, mm0); + pavg_m2r (*dest, mm0); + ref += stride; + movq_r2m (mm0, *dest); + dest += stride; + } while (--height); +} + +static __inline__ void MC_avg1_16 (int height, yuv_data_t * dest, yuv_data_t * ref, + int stride, int cpu) +{ + do { + movq_m2r (*ref, mm0); + movq_m2r (*(ref+8), mm1); + pavg_m2r (*dest, mm0); + pavg_m2r (*(dest+8), mm1); + movq_r2m (mm0, *dest); + ref += stride; + movq_r2m (mm1, *(dest+8)); + dest += stride; + } while (--height); +} + +static __inline__ void MC_put2_8 (int height, yuv_data_t * dest, yuv_data_t * ref, + int stride, int offset, int cpu) +{ + do { + movq_m2r (*ref, mm0); + pavg_m2r (*(ref+offset), mm0); + ref += stride; + movq_r2m (mm0, *dest); + dest += stride; + } while (--height); +} + +static __inline__ void MC_put2_16 (int height, yuv_data_t * dest, yuv_data_t * ref, + int stride, int offset, int cpu) +{ + do { + movq_m2r (*ref, mm0); + movq_m2r (*(ref+8), mm1); + pavg_m2r (*(ref+offset), mm0); + pavg_m2r (*(ref+offset+8), mm1); + movq_r2m (mm0, *dest); + ref += stride; + movq_r2m (mm1, *(dest+8)); + dest += stride; + } while (--height); +} + +static __inline__ void MC_avg2_8 (int height, yuv_data_t * dest, yuv_data_t * ref, + int stride, int offset, int cpu) +{ + do { + movq_m2r (*ref, mm0); + pavg_m2r (*(ref+offset), mm0); + pavg_m2r (*dest, mm0); + ref += stride; + movq_r2m (mm0, *dest); + dest += stride; + } while (--height); +} + +static __inline__ void MC_avg2_16 (int height, yuv_data_t * dest, yuv_data_t * ref, + int stride, int offset, int cpu) +{ + do { + movq_m2r (*ref, mm0); + movq_m2r (*(ref+8), mm1); + pavg_m2r (*(ref+offset), mm0); + pavg_m2r (*(ref+offset+8), mm1); + pavg_m2r (*dest, mm0); + pavg_m2r (*(dest+8), mm1); + ref += stride; + movq_r2m (mm0, *dest); + movq_r2m (mm1, *(dest+8)); + dest += stride; + } while (--height); +} + +static mmx_t mask_one = {0x0101010101010101LL}; + +static __inline__ void MC_put4_8 (int height, yuv_data_t * dest, yuv_data_t * ref, + int stride, int cpu) +{ + movq_m2r (*ref, mm0); + movq_m2r (*(ref+1), mm1); + movq_r2r (mm0, mm7); + pxor_r2r (mm1, mm7); + pavg_r2r (mm1, mm0); + ref += stride; + + do { + movq_m2r (*ref, mm2); + movq_r2r (mm0, mm5); + + movq_m2r (*(ref+1), mm3); + movq_r2r (mm2, mm6); + + pxor_r2r (mm3, mm6); + pavg_r2r (mm3, mm2); + + por_r2r (mm6, mm7); + pxor_r2r (mm2, mm5); + + pand_r2r (mm5, mm7); + pavg_r2r (mm2, mm0); + + pand_m2r (mask_one, mm7); + + psubusb_r2r (mm7, mm0); + + ref += stride; + movq_r2m (mm0, *dest); + dest += stride; + + movq_r2r (mm6, mm7); // unroll ! + movq_r2r (mm2, mm0); // unroll ! + } while (--height); +} + +static __inline__ void MC_put4_16 (int height, yuv_data_t * dest, yuv_data_t * ref, + int stride, int cpu) +{ + do { + movq_m2r (*ref, mm0); + movq_m2r (*(ref+stride+1), mm1); + movq_r2r (mm0, mm7); + movq_m2r (*(ref+1), mm2); + pxor_r2r (mm1, mm7); + movq_m2r (*(ref+stride), mm3); + movq_r2r (mm2, mm6); + pxor_r2r (mm3, mm6); + pavg_r2r (mm1, mm0); + pavg_r2r (mm3, mm2); + por_r2r (mm6, mm7); + movq_r2r (mm0, mm6); + pxor_r2r (mm2, mm6); + pand_r2r (mm6, mm7); + pand_m2r (mask_one, mm7); + pavg_r2r (mm2, mm0); + psubusb_r2r (mm7, mm0); + movq_r2m (mm0, *dest); + + movq_m2r (*(ref+8), mm0); + movq_m2r (*(ref+stride+9), mm1); + movq_r2r (mm0, mm7); + movq_m2r (*(ref+9), mm2); + pxor_r2r (mm1, mm7); + movq_m2r (*(ref+stride+8), mm3); + movq_r2r (mm2, mm6); + pxor_r2r (mm3, mm6); + pavg_r2r (mm1, mm0); + pavg_r2r (mm3, mm2); + por_r2r (mm6, mm7); + movq_r2r (mm0, mm6); + pxor_r2r (mm2, mm6); + pand_r2r (mm6, mm7); + pand_m2r (mask_one, mm7); + pavg_r2r (mm2, mm0); + psubusb_r2r (mm7, mm0); + ref += stride; + movq_r2m (mm0, *(dest+8)); + dest += stride; + } while (--height); +} + +static __inline__ void MC_avg4_8 (int height, yuv_data_t * dest, yuv_data_t * ref, + int stride, int cpu) +{ + do { + movq_m2r (*ref, mm0); + movq_m2r (*(ref+stride+1), mm1); + movq_r2r (mm0, mm7); + movq_m2r (*(ref+1), mm2); + pxor_r2r (mm1, mm7); + movq_m2r (*(ref+stride), mm3); + movq_r2r (mm2, mm6); + pxor_r2r (mm3, mm6); + pavg_r2r (mm1, mm0); + pavg_r2r (mm3, mm2); + por_r2r (mm6, mm7); + movq_r2r (mm0, mm6); + pxor_r2r (mm2, mm6); + pand_r2r (mm6, mm7); + pand_m2r (mask_one, mm7); + pavg_r2r (mm2, mm0); + psubusb_r2r (mm7, mm0); + movq_m2r (*dest, mm1); + pavg_r2r (mm1, mm0); + ref += stride; + movq_r2m (mm0, *dest); + dest += stride; + } while (--height); +} + +static __inline__ void MC_avg4_16 (int height, yuv_data_t * dest, yuv_data_t * ref, + int stride, int cpu) +{ + do { + movq_m2r (*ref, mm0); + movq_m2r (*(ref+stride+1), mm1); + movq_r2r (mm0, mm7); + movq_m2r (*(ref+1), mm2); + pxor_r2r (mm1, mm7); + movq_m2r (*(ref+stride), mm3); + movq_r2r (mm2, mm6); + pxor_r2r (mm3, mm6); + pavg_r2r (mm1, mm0); + pavg_r2r (mm3, mm2); + por_r2r (mm6, mm7); + movq_r2r (mm0, mm6); + pxor_r2r (mm2, mm6); + pand_r2r (mm6, mm7); + pand_m2r (mask_one, mm7); + pavg_r2r (mm2, mm0); + psubusb_r2r (mm7, mm0); + movq_m2r (*dest, mm1); + pavg_r2r (mm1, mm0); + movq_r2m (mm0, *dest); + + movq_m2r (*(ref+8), mm0); + movq_m2r (*(ref+stride+9), mm1); + movq_r2r (mm0, mm7); + movq_m2r (*(ref+9), mm2); + pxor_r2r (mm1, mm7); + movq_m2r (*(ref+stride+8), mm3); + movq_r2r (mm2, mm6); + pxor_r2r (mm3, mm6); + pavg_r2r (mm1, mm0); + pavg_r2r (mm3, mm2); + por_r2r (mm6, mm7); + movq_r2r (mm0, mm6); + pxor_r2r (mm2, mm6); + pand_r2r (mm6, mm7); + pand_m2r (mask_one, mm7); + pavg_r2r (mm2, mm0); + psubusb_r2r (mm7, mm0); + movq_m2r (*(dest+8), mm1); + pavg_r2r (mm1, mm0); + ref += stride; + movq_r2m (mm0, *(dest+8)); + dest += stride; + } while (--height); +} + +static void MC_avg_16_mmxext (yuv_data_t * dest, yuv_data_t * ref, + int stride, int height) +{ + MC_avg1_16 (height, dest, ref, stride, CPU_MMXEXT); +} + +static void MC_avg_8_mmxext (yuv_data_t * dest, yuv_data_t * ref, + int stride, int height) +{ + MC_avg1_8 (height, dest, ref, stride, CPU_MMXEXT); +} + +static void MC_put_16_mmxext (yuv_data_t * dest, yuv_data_t * ref, + int stride, int height) +{ + MC_put1_16 (height, dest, ref, stride); +} + +static void MC_put_8_mmxext (yuv_data_t * dest, yuv_data_t * ref, + int stride, int height) +{ + MC_put1_8 (height, dest, ref, stride); +} + +static void MC_avg_x16_mmxext (yuv_data_t * dest, yuv_data_t * ref, + int stride, int height) +{ + MC_avg2_16 (height, dest, ref, stride, 1, CPU_MMXEXT); +} + +static void MC_avg_x8_mmxext (yuv_data_t * dest, yuv_data_t * ref, + int stride, int height) +{ + MC_avg2_8 (height, dest, ref, stride, 1, CPU_MMXEXT); +} + +static void MC_put_x16_mmxext (yuv_data_t * dest, yuv_data_t * ref, + int stride, int height) +{ + MC_put2_16 (height, dest, ref, stride, 1, CPU_MMXEXT); +} + +static void MC_put_x8_mmxext (yuv_data_t * dest, yuv_data_t * ref, + int stride, int height) +{ + MC_put2_8 (height, dest, ref, stride, 1, CPU_MMXEXT); +} + +static void MC_avg_y16_mmxext (yuv_data_t * dest, yuv_data_t * ref, + int stride, int height) +{ + MC_avg2_16 (height, dest, ref, stride, stride, CPU_MMXEXT); +} + +static void MC_avg_y8_mmxext (yuv_data_t * dest, yuv_data_t * ref, + int stride, int height) +{ + MC_avg2_8 (height, dest, ref, stride, stride, CPU_MMXEXT); +} + +static void MC_put_y16_mmxext (yuv_data_t * dest, yuv_data_t * ref, + int stride, int height) +{ + MC_put2_16 (height, dest, ref, stride, stride, CPU_MMXEXT); +} + +static void MC_put_y8_mmxext (yuv_data_t * dest, yuv_data_t * ref, + int stride, int height) +{ + MC_put2_8 (height, dest, ref, stride, stride, CPU_MMXEXT); +} + +static void MC_avg_xy16_mmxext (yuv_data_t * dest, yuv_data_t * ref, + int stride, int height) +{ + MC_avg4_16 (height, dest, ref, stride, CPU_MMXEXT); +} + +static void MC_avg_xy8_mmxext (yuv_data_t * dest, yuv_data_t * ref, + int stride, int height) +{ + MC_avg4_8 (height, dest, ref, stride, CPU_MMXEXT); +} + +static void MC_put_xy16_mmxext (yuv_data_t * dest, yuv_data_t * ref, + int stride, int height) +{ + MC_put4_16 (height, dest, ref, stride, CPU_MMXEXT); +} + +static void MC_put_xy8_mmxext (yuv_data_t * dest, yuv_data_t * ref, + int stride, int height) +{ + MC_put4_8 (height, dest, ref, stride, CPU_MMXEXT); +} + + +static void MC_avg_16_3dnow (yuv_data_t * dest, yuv_data_t * ref, + int stride, int height) +{ + MC_avg1_16 (height, dest, ref, stride, CPU_3DNOW); +} + +static void MC_avg_8_3dnow (yuv_data_t * dest, yuv_data_t * ref, + int stride, int height) +{ + MC_avg1_8 (height, dest, ref, stride, CPU_3DNOW); +} + +static void MC_put_16_3dnow (yuv_data_t * dest, yuv_data_t * ref, + int stride, int height) +{ + MC_put1_16 (height, dest, ref, stride); +} + +static void MC_put_8_3dnow (yuv_data_t * dest, yuv_data_t * ref, + int stride, int height) +{ + MC_put1_8 (height, dest, ref, stride); +} + +static void MC_avg_x16_3dnow (yuv_data_t * dest, yuv_data_t * ref, + int stride, int height) +{ + MC_avg2_16 (height, dest, ref, stride, 1, CPU_3DNOW); +} + +static void MC_avg_x8_3dnow (yuv_data_t * dest, yuv_data_t * ref, + int stride, int height) +{ + MC_avg2_8 (height, dest, ref, stride, 1, CPU_3DNOW); +} + +static void MC_put_x16_3dnow (yuv_data_t * dest, yuv_data_t * ref, + int stride, int height) +{ + MC_put2_16 (height, dest, ref, stride, 1, CPU_3DNOW); +} + +static void MC_put_x8_3dnow (yuv_data_t * dest, yuv_data_t * ref, + int stride, int height) +{ + MC_put2_8 (height, dest, ref, stride, 1, CPU_3DNOW); +} + +static void MC_avg_y16_3dnow (yuv_data_t * dest, yuv_data_t * ref, + int stride, int height) +{ + MC_avg2_16 (height, dest, ref, stride, stride, CPU_3DNOW); +} + +static void MC_avg_y8_3dnow (yuv_data_t * dest, yuv_data_t * ref, + int stride, int height) +{ + MC_avg2_8 (height, dest, ref, stride, stride, CPU_3DNOW); +} + +static void MC_put_y16_3dnow (yuv_data_t * dest, yuv_data_t * ref, + int stride, int height) +{ + MC_put2_16 (height, dest, ref, stride, stride, CPU_3DNOW); +} + +static void MC_put_y8_3dnow (yuv_data_t * dest, yuv_data_t * ref, + int stride, int height) +{ + MC_put2_8 (height, dest, ref, stride, stride, CPU_3DNOW); +} + +static void MC_avg_xy16_3dnow (yuv_data_t * dest, yuv_data_t * ref, + int stride, int height) +{ + MC_avg4_16 (height, dest, ref, stride, CPU_3DNOW); +} + +static void MC_avg_xy8_3dnow (yuv_data_t * dest, yuv_data_t * ref, + int stride, int height) +{ + MC_avg4_8 (height, dest, ref, stride, CPU_3DNOW); +} + +static void MC_put_xy16_3dnow (yuv_data_t * dest, yuv_data_t * ref, + int stride, int height) +{ + MC_put4_16 (height, dest, ref, stride, CPU_3DNOW); +} + +static void MC_put_xy8_3dnow (yuv_data_t * dest, yuv_data_t * ref, + int stride, int height) +{ + MC_put4_8 (height, dest, ref, stride, CPU_3DNOW); +} + +/***************************************************************************** + * Functions exported as capabilities. They are declared as static so that + * we don't pollute the namespace too much. + *****************************************************************************/ +static void motion_getfunctions( function_list_t * p_function_list ) +{ + static void (* ppppf_motion[2][2][4])( yuv_data_t *, yuv_data_t *, + int, int ) = + { + { + /* Copying functions */ + { + /* Width == 16 */ + MC_put_16_mmxext, MC_put_x16_mmxext, MC_put_y16_mmxext, MC_put_xy16_mmxext + }, + { + /* Width == 8 */ + MC_put_8_mmxext, MC_put_x8_mmxext, MC_put_y8_mmxext, MC_put_xy8_mmxext + } + }, + { + /* Averaging functions */ + { + /* Width == 16 */ + MC_avg_16_mmxext, MC_avg_x16_mmxext, MC_avg_y16_mmxext, MC_avg_xy16_mmxext + }, + { + /* Width == 8 */ + MC_avg_8_mmxext, MC_avg_x8_mmxext, MC_avg_y8_mmxext, MC_avg_xy8_mmxext + } + } + }; + + p_function_list->pf_probe = motion_Probe; + +#define list p_function_list->functions.motion + memcpy( list.ppppf_motion, ppppf_motion, sizeof( void * ) * 16 ); +#undef list + + return; +} + diff --git a/plugins/motion/vdec_motion_common.c b/plugins/motion/vdec_motion_common.c deleted file mode 100644 index 102323af17..0000000000 --- a/plugins/motion/vdec_motion_common.c +++ /dev/null @@ -1,751 +0,0 @@ -/***************************************************************************** - * vdec_motion_common.c : common motion compensation routines common - ***************************************************************************** - * Copyright (C) 1999, 2000 VideoLAN - * $Id: vdec_motion_common.c,v 1.9 2001/07/17 09:48:07 massiot Exp $ - * - * Authors: Christophe Massiot - * Jean-Marc Dressler - * Michel Lespinasse - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. - *****************************************************************************/ - -/* MODULE_NAME defined in Makefile together with -DBUILTIN */ -#ifdef BUILTIN -# include "modules_inner.h" -#else -# define _M( foo ) foo -#endif - -/***************************************************************************** - * Preamble - *****************************************************************************/ -#include "defs.h" - -#include "config.h" -#include "common.h" -#include "threads.h" -#include "mtime.h" - -#include "intf_msg.h" - -#include "video.h" - -#include "vdec_ext-plugins.h" - -#include "modules.h" -#include "modules_export.h" - -extern int _M( motion_Probe )( probedata_t *p_data ); - -static void vdec_MotionFieldField420 ( macroblock_t * p_mb ); -static void vdec_MotionFieldField422 ( macroblock_t * p_mb ); -static void vdec_MotionFieldField444 ( macroblock_t * p_mb ); -static void vdec_MotionField16x8420 ( macroblock_t * p_mb ); -static void vdec_MotionField16x8422 ( macroblock_t * p_mb ); -static void vdec_MotionField16x8444 ( macroblock_t * p_mb ); -static void vdec_MotionFieldDMV420 ( macroblock_t * p_mb ); -static void vdec_MotionFieldDMV422 ( macroblock_t * p_mb ); -static void vdec_MotionFieldDMV444 ( macroblock_t * p_mb ); -static void vdec_MotionFrameFrame420 ( macroblock_t * p_mb ); -static void vdec_MotionFrameFrame422 ( macroblock_t * p_mb ); -static void vdec_MotionFrameFrame444 ( macroblock_t * p_mb ); -static void vdec_MotionFrameField420 ( macroblock_t * p_mb ); -static void vdec_MotionFrameField422 ( macroblock_t * p_mb ); -static void vdec_MotionFrameField444 ( macroblock_t * p_mb ); -static void vdec_MotionFrameDMV420 ( macroblock_t * p_mb ); -static void vdec_MotionFrameDMV422 ( macroblock_t * p_mb ); -static void vdec_MotionFrameDMV444 ( macroblock_t * p_mb ); - -/***************************************************************************** - * Functions exported as capabilities. They are declared as static so that - * we don't pollute the namespace too much. - *****************************************************************************/ -void _M( motion_getfunctions )( function_list_t * p_function_list ) -{ - p_function_list->pf_probe = _M( motion_Probe ); - -#define list p_function_list->functions.motion -#define motion_functions( yuv ) \ - list.pf_field_field_##yuv = vdec_MotionFieldField##yuv; \ - list.pf_field_16x8_##yuv = vdec_MotionField16x8##yuv; \ - list.pf_field_dmv_##yuv = vdec_MotionFieldDMV##yuv; \ - list.pf_frame_field_##yuv = vdec_MotionFrameField##yuv; \ - list.pf_frame_frame_##yuv = vdec_MotionFrameFrame##yuv; \ - list.pf_frame_dmv_##yuv = vdec_MotionFrameDMV##yuv; - motion_functions( 420 ) - motion_functions( 422 ) - motion_functions( 444 ) -#undef motion_functions -#undef list - - return; -} - -#define __MotionComponents(width,height) \ -void _M( MotionComponent_x_y_copy_##width##_##height )(); \ -void _M( MotionComponent_X_y_copy_##width##_##height )(); \ -void _M( MotionComponent_x_Y_copy_##width##_##height )(); \ -void _M( MotionComponent_X_Y_copy_##width##_##height )(); \ -void _M( MotionComponent_x_y_avg_##width##_##height )(); \ -void _M( MotionComponent_X_y_avg_##width##_##height )(); \ -void _M( MotionComponent_x_Y_avg_##width##_##height )(); \ -void _M( MotionComponent_X_Y_avg_##width##_##height )(); - -__MotionComponents (16,16) /* 444, 422, 420 */ -__MotionComponents (16,8) /* 444, 422, 420 */ -__MotionComponents (8,8) /* 422, 420 */ -__MotionComponents (8,4) /* 420 */ -#if 0 -__MotionComponents (8,16) /* 422 */ -#endif - -#define ___callTheRightOne(width,height) \ - if ((i_width == width) && (i_height == height)) \ - { \ - if (!b_average) \ - { \ - switch (i_select) \ - { \ - case 0: \ - _M( MotionComponent_x_y_copy_##width##_##height )(p_src, \ - p_dest, i_stride); \ - break; \ - case 1: \ - _M( MotionComponent_X_y_copy_##width##_##height )(p_src, \ - p_dest, i_stride); \ - break; \ - case 2: \ - _M( MotionComponent_x_Y_copy_##width##_##height )(p_src, \ - p_dest, i_stride); \ - break; \ - case 3: \ - _M( MotionComponent_X_Y_copy_##width##_##height )(p_src, \ - p_dest, i_stride); \ - break; \ - } \ - } \ - else \ - { \ - switch (i_select) \ - { \ - case 0: \ - _M( MotionComponent_x_y_avg_##width##_##height )(p_src, \ - p_dest, i_stride); \ - break; \ - case 1: \ - _M( MotionComponent_X_y_avg_##width##_##height )(p_src, \ - p_dest, i_stride); \ - break; \ - case 2: \ - _M( MotionComponent_x_Y_avg_##width##_##height )(p_src, \ - p_dest, i_stride); \ - break; \ - case 3: \ - _M( MotionComponent_X_Y_avg_##width##_##height )(p_src, \ - p_dest, i_stride); \ - break; \ - } \ - } \ - } - -/***************************************************************************** - * vdec_MotionComponent : last stage of motion compensation - *****************************************************************************/ -static __inline__ void MotionComponent( - yuv_data_t * p_src, /* source block */ - yuv_data_t * p_dest, /* dest block */ - int i_width, /* (explicit) width of block */ - int i_height, /* (explicit) height of block */ - int i_stride, /* number of coeffs to jump - * between each predicted line */ - int i_select, /* half-pel vectors */ - boolean_t b_average /* (explicit) averaging of several - * predictions */ ) -{ - ___callTheRightOne (16,16) - ___callTheRightOne (16,8) - ___callTheRightOne (8,8) - ___callTheRightOne (8,4) -#if 0 - ___callTheRightOne (8,16) -#endif -} - -/***************************************************************************** - * Motion420 : motion compensation for a 4:2:0 macroblock - *****************************************************************************/ -static __inline__ void Motion420( - macroblock_t * p_mb, /* destination macroblock */ - picture_t * p_source, /* source picture */ - boolean_t b_source_field, /* source field */ - boolean_t b_dest_field, /* destination field */ - int i_mv_x, int i_mv_y, /* motion vector coordinates, - * in half pels */ - int i_l_stride, /* number of coeffs to jump to - * go to the next predicted - * line */ - int i_c_stride, - int i_height, /* height of the block to - * predict, in luminance - * (explicit) */ - int i_offset, /* position of the first - * predicted line (explicit) */ - boolean_t b_average /* (explicit) averaging of - * several predictions */ ) -{ - /* Temporary variables to avoid recalculating things twice */ - int i_source_offset, i_dest_offset, i_c_height, i_c_select; - - i_source_offset = (p_mb->i_l_x + (i_mv_x >> 1)) - + (p_mb->i_motion_l_y + i_offset - + b_source_field) - * p_mb->p_picture->i_width - + (i_mv_y >> 1) * i_l_stride; - - if( i_source_offset >= p_source->i_size ) - { - intf_WarnMsg( 2, "Bad motion vector (lum)" ); - return; - } - - /* Luminance */ - MotionComponent( /* source */ - p_source->p_y + i_source_offset, - /* destination */ - p_mb->p_picture->p_y - + (p_mb->i_l_x) - + (p_mb->i_motion_l_y + b_dest_field + i_offset) - * p_mb->p_picture->i_width, - /* prediction width and height */ - 16, i_height, - /* stride */ - i_l_stride, - /* select */ - ((i_mv_y & 1) << 1) | (i_mv_x & 1), - b_average ); - - i_source_offset = (p_mb->i_c_x + ((i_mv_x/2) >> 1)) - + (p_mb->i_motion_c_y + (i_offset >> 1) - + b_source_field) - * p_mb->p_picture->i_chroma_width - + ((i_mv_y/2) >> 1) * i_c_stride; - - if( i_source_offset >= p_source->i_chroma_size ) - { - intf_WarnMsg( 2, "Bad motion vector (chroma)" ); - return; - } - - i_dest_offset = (p_mb->i_c_x) - + (p_mb->i_motion_c_y + b_dest_field - + (i_offset >> 1)) - * p_mb->p_picture->i_chroma_width; - i_c_height = i_height >> 1; - i_c_select = (((i_mv_y/2) & 1) << 1) | ((i_mv_x/2) & 1); - - /* Chrominance Cr */ - MotionComponent( p_source->p_u - + i_source_offset, - p_mb->p_picture->p_u - + i_dest_offset, - 8, i_c_height, i_c_stride, - i_c_select, b_average ); - - /* Chrominance Cb */ - MotionComponent( p_source->p_v - + i_source_offset, - p_mb->p_picture->p_v - + i_dest_offset, - 8, i_c_height, i_c_stride, - i_c_select, b_average ); -} - -/***************************************************************************** - * Motion422 : motion compensation for a 4:2:2 macroblock - *****************************************************************************/ -static __inline__ void Motion422( - macroblock_t * p_mb, /* destination macroblock */ - picture_t * p_source, /* source picture */ - boolean_t b_source_field, /* source field */ - boolean_t b_dest_field, /* destination field */ - int i_mv_x, int i_mv_y, /* motion vector coordinates, - * in half pels */ - int i_l_stride, /* number of coeffs to jump to - * go to the next predicted - * line */ - int i_c_stride, - int i_height, /* height of the block to - * predict, in luminance - * (explicit) */ - int i_offset, /* position of the first - * predicted line (explicit) */ - boolean_t b_average /* (explicit) averaging of - * several predictions */ ) -{ -#if 0 - int i_source_offset, i_dest_offset, i_c_select; - - /* Luminance */ - MotionComponent( /* source */ - p_source->p_y - + (p_mb->i_l_x + (i_mv_x >> 1)) - + (p_mb->i_motion_l_y + i_offset - + b_source_field) - * p_mb->p_picture->i_width - + (i_mv_y >> 1) * p_mb->i_l_stride, - /* destination */ - p_mb->p_picture->p_y - + (p_mb->i_l_x) - + (p_mb->i_motion_l_y + b_dest_field) - * p_mb->p_picture->i_width, - /* prediction width and height */ - 16, i_height, - /* stride */ - i_l_stride, - /* select */ - ((i_mv_y & 1) << 1) | (i_mv_x & 1), - b_average ); - - i_source_offset = (p_mb->i_c_x + ((i_mv_x/2) >> 1)) - + (p_mb->i_motion_c_y + i_offset - + b_source_field) - * p_mb->p_picture->i_chroma_width - + (i_mv_y) >> 1) * p_mb->i_c_stride; - i_dest_offset = (p_mb->i_c_x) - + (p_mb->i_motion_c_y + b_dest_field) - * p_mb->p_picture->i_chroma_width; - i_c_select = ((i_mv_y & 1) << 1) | ((i_mv_x/2) & 1); - - /* Chrominance Cr */ - MotionComponent( p_source->p_u - + i_source_offset, - p_mb->p_picture->p_u - + i_dest_offset, - 8, i_height, i_c_stride, - i_c_select, b_average ); - - /* Chrominance Cb */ - MotionComponent( p_source->p_v - + i_source_offset, - p_mb->p_picture->p_u - + i_dest_offset, - 8, i_height, i_c_stride, - i_c_select, b_average ); -#endif -} - -/***************************************************************************** - * Motion444 : motion compensation for a 4:4:4 macroblock - *****************************************************************************/ -static __inline__ void Motion444( - macroblock_t * p_mb, /* destination macroblock */ - picture_t * p_source, /* source picture */ - boolean_t b_source_field, /* source field */ - boolean_t b_dest_field, /* destination field */ - int i_mv_x, int i_mv_y, /* motion vector coordinates, - * in half pels */ - int i_l_stride, /* number of coeffs to jump to - * go to the next predicted - * line */ - int i_c_stride, - int i_height, /* height of the block to - * predict, in luminance - * (explicit) */ - int i_offset, /* position of the first - * predicted line (explicit) */ - boolean_t b_average /* (explicit) averaging of - * several predictions */ ) -{ -#if 0 - int i_source_offset, i_dest_offset, i_select; - - i_source_offset = (p_mb->i_l_x + (i_mv_x >> 1)) - + (p_mb->i_motion_l_y + i_offset - + b_source_field) - * p_mb->p_picture->i_width - + (i_mv_y >> 1) * p_mb->i_l_stride; - i_dest_offset = (p_mb->i_l_x) - + (p_mb->i_motion_l_y + b_dest_field) - * p_mb->p_picture->i_width; - i_select = ((i_mv_y & 1) << 1) | (i_mv_x & 1); - - - /* Luminance */ - MotionComponent( p_source->p_y - + i_source_offset, - p_mb->p_picture->p_y - + i_dest_offset, - 16, i_height, i_l_stride, - i_select, b_average ); - - /* Chrominance Cr */ - MotionComponent( p_source->p_u - + i_source_offset, - p_mb->p_picture->p_u - + i_dest_offset, - 16, i_height, i_l_stride, - i_select, b_average ); - - /* Chrominance Cb */ - MotionComponent( p_source->p_v - + i_source_offset, - p_mb->p_picture->p_v - + i_dest_offset, - 16, i_height, i_l_stride, - i_select, b_average ); -#endif -} - -/***************************************************************************** - * vdec_MotionFieldField : motion compensation for field motion type (field) - *****************************************************************************/ -#define FIELDFIELD( MOTION ) \ -{ \ - picture_t * p_pred; \ - \ - if( p_mb->i_mb_type & MB_MOTION_FORWARD ) \ - { \ - if( p_mb->b_P_second \ - && (p_mb->b_motion_field != p_mb->ppi_field_select[0][0]) )\ - p_pred = p_mb->p_picture; \ - else \ - p_pred = p_mb->p_forward; \ - \ - MOTION( p_mb, p_pred, p_mb->ppi_field_select[0][0], \ - p_mb->b_motion_field, \ - p_mb->pppi_motion_vectors[0][0][0], \ - p_mb->pppi_motion_vectors[0][0][1], \ - p_mb->i_l_stride, p_mb->i_c_stride, 16, 0, 0 ); \ - \ - if( p_mb->i_mb_type & MB_MOTION_BACKWARD ) \ - { \ - MOTION( p_mb, p_mb->p_backward, \ - p_mb->ppi_field_select[0][1], \ - p_mb->b_motion_field, \ - p_mb->pppi_motion_vectors[0][1][0], \ - p_mb->pppi_motion_vectors[0][1][1], \ - p_mb->i_l_stride, p_mb->i_c_stride, 16, 0, 1 ); \ - } \ - } \ - \ - else /* MB_MOTION_BACKWARD */ \ - { \ - MOTION( p_mb, p_mb->p_backward, p_mb->ppi_field_select[0][1], \ - p_mb->b_motion_field, \ - p_mb->pppi_motion_vectors[0][1][0], \ - p_mb->pppi_motion_vectors[0][1][1], \ - p_mb->i_l_stride, p_mb->i_c_stride, 16, 0, 0 ); \ - } \ -} - -static void vdec_MotionFieldField420( macroblock_t * p_mb ) -{ - FIELDFIELD( Motion420 ) -} - -static void vdec_MotionFieldField422( macroblock_t * p_mb ) -{ - //FIELDFIELD( Motion422 ) -} - -static void vdec_MotionFieldField444( macroblock_t * p_mb ) -{ - //FIELDFIELD( Motion444 ) -} - -/***************************************************************************** - * vdec_MotionField16x8XXX: motion compensation for 16x8 motion type (field) - *****************************************************************************/ -#define FIELD16X8( MOTION ) \ -{ \ - picture_t * p_pred; \ - \ - if( p_mb->i_mb_type & MB_MOTION_FORWARD ) \ - { \ - if( p_mb->b_P_second \ - && (p_mb->b_motion_field != p_mb->ppi_field_select[0][0]) )\ - p_pred = p_mb->p_picture; \ - else \ - p_pred = p_mb->p_forward; \ - \ - MOTION( p_mb, p_pred, p_mb->ppi_field_select[0][0], \ - p_mb->b_motion_field, \ - p_mb->pppi_motion_vectors[0][0][0], \ - p_mb->pppi_motion_vectors[0][0][1], \ - p_mb->i_l_stride, p_mb->i_c_stride, 8, 0, 0 ); \ - \ - if( p_mb->b_P_second \ - && (p_mb->b_motion_field != p_mb->ppi_field_select[1][0]) )\ - p_pred = p_mb->p_picture; \ - else \ - p_pred = p_mb->p_forward; \ - \ - MOTION( p_mb, p_pred, p_mb->ppi_field_select[1][0], \ - p_mb->b_motion_field, \ - p_mb->pppi_motion_vectors[1][0][0], \ - p_mb->pppi_motion_vectors[1][0][1], \ - p_mb->i_l_stride, p_mb->i_c_stride, 8, 8, 0 ); \ - \ - if( p_mb->i_mb_type & MB_MOTION_BACKWARD ) \ - { \ - MOTION( p_mb, p_mb->p_backward, \ - p_mb->ppi_field_select[0][1], \ - p_mb->b_motion_field, \ - p_mb->pppi_motion_vectors[0][1][0], \ - p_mb->pppi_motion_vectors[0][1][1], \ - p_mb->i_l_stride, p_mb->i_c_stride, 8, 0, 1 ); \ - \ - MOTION( p_mb, p_mb->p_backward, \ - p_mb->ppi_field_select[1][1], \ - p_mb->b_motion_field, \ - p_mb->pppi_motion_vectors[1][1][0], \ - p_mb->pppi_motion_vectors[1][1][1], \ - p_mb->i_l_stride, p_mb->i_c_stride, 8, 8, 1 ); \ - } \ - } \ - \ - else /* MB_MOTION_BACKWARD */ \ - { \ - MOTION( p_mb, p_mb->p_backward, p_mb->ppi_field_select[0][1], \ - p_mb->b_motion_field, \ - p_mb->pppi_motion_vectors[0][1][0], \ - p_mb->pppi_motion_vectors[0][1][1], \ - p_mb->i_l_stride, p_mb->i_c_stride, 8, 0, 0 ); \ - \ - MOTION( p_mb, p_mb->p_backward, p_mb->ppi_field_select[1][1], \ - p_mb->b_motion_field, \ - p_mb->pppi_motion_vectors[1][1][0], \ - p_mb->pppi_motion_vectors[1][1][1], \ - p_mb->i_l_stride, p_mb->i_c_stride, 8, 8, 0 ); \ - } \ -} - -static void vdec_MotionField16x8420( macroblock_t * p_mb ) -{ - FIELD16X8( Motion420 ) -} - -static void vdec_MotionField16x8422( macroblock_t * p_mb ) -{ - //FIELD16X8( Motion422 ) -} - -static void vdec_MotionField16x8444( macroblock_t * p_mb ) -{ - //FIELD16X8( Motion444 ) -} - -/***************************************************************************** - * vdec_MotionFieldDMVXXX : motion compensation for dmv motion type (field) - *****************************************************************************/ -#define FIELDDMV( MOTION ) \ -{ \ - /* This is necessarily a MOTION_FORWARD only macroblock, in a P \ - * picture. */ \ - picture_t * p_pred; \ - \ - /* predict from field of same parity */ \ - MOTION( p_mb, p_mb->p_forward, \ - p_mb->b_motion_field, p_mb->b_motion_field, \ - p_mb->pppi_motion_vectors[0][0][0], \ - p_mb->pppi_motion_vectors[0][0][1], \ - p_mb->i_l_stride, p_mb->i_c_stride, 16, 0, 0 ); \ - \ - if( p_mb->b_P_second ) \ - p_pred = p_mb->p_picture; \ - else \ - p_pred = p_mb->p_forward; \ - \ - /* predict from field of opposite parity */ \ - MOTION( p_mb, p_pred, !p_mb->b_motion_field, p_mb->b_motion_field, \ - p_mb->ppi_dmv[0][0], p_mb->ppi_dmv[0][1], \ - p_mb->i_l_stride, p_mb->i_c_stride, 16, 0, 1 ); \ -} /* FIELDDMV */ - -static void vdec_MotionFieldDMV420( macroblock_t * p_mb ) -{ - FIELDDMV( Motion420 ) -} - -static void vdec_MotionFieldDMV422( macroblock_t * p_mb ) -{ - //FIELDDMV( Motion422 ) -} - -static void vdec_MotionFieldDMV444( macroblock_t * p_mb ) -{ - //FIELDDMV( Motion444 ) -} - -/***************************************************************************** - * vdec_MotionFrameFrameXXX?? : motion compensation for frame motion type (frame) - *****************************************************************************/ -#define FRAMEFRAME( MOTION ) \ -{ \ - if( p_mb->i_mb_type & MB_MOTION_FORWARD ) \ - { \ - MOTION( p_mb, p_mb->p_forward, 0, 0, \ - p_mb->pppi_motion_vectors[0][0][0], \ - p_mb->pppi_motion_vectors[0][0][1], \ - p_mb->i_l_stride, p_mb->i_c_stride, 16, 0, 0 ); \ - \ - if( p_mb->i_mb_type & MB_MOTION_BACKWARD ) \ - { \ - MOTION( p_mb, p_mb->p_backward, 0, 0, \ - p_mb->pppi_motion_vectors[0][1][0], \ - p_mb->pppi_motion_vectors[0][1][1], \ - p_mb->i_l_stride, p_mb->i_c_stride, 16, 0, 1 ); \ - } \ - } \ - \ - else /* MB_MOTION_BACKWARD */ \ - { \ - MOTION( p_mb, p_mb->p_backward, 0, 0, \ - p_mb->pppi_motion_vectors[0][1][0], \ - p_mb->pppi_motion_vectors[0][1][1], \ - p_mb->i_l_stride, p_mb->i_c_stride, 16, 0, 0 ); \ - } \ -} /* FRAMEFRAME */ - -static void vdec_MotionFrameFrame420( macroblock_t * p_mb ) -{ - FRAMEFRAME( Motion420 ) -} - -static void vdec_MotionFrameFrame422( macroblock_t * p_mb ) -{ - //FRAMEFRAME( Motion422 ) -} - -static void vdec_MotionFrameFrame444( macroblock_t * p_mb ) -{ - //FRAMEFRAME( Motion444 ) -} - -/***************************************************************************** - * vdec_MotionFrameFieldXXX?? : motion compensation for field motion type (frame) - *****************************************************************************/ -#define FRAMEFIELD( MOTION ) \ -{ \ - int i_l_stride = p_mb->i_l_stride << 1; \ - int i_c_stride = p_mb->i_c_stride << 1; \ - \ - if( p_mb->i_mb_type & MB_MOTION_FORWARD ) \ - { \ - MOTION( p_mb, p_mb->p_forward, p_mb->ppi_field_select[0][0], 0, \ - p_mb->pppi_motion_vectors[0][0][0], \ - p_mb->pppi_motion_vectors[0][0][1] >> 1, \ - i_l_stride, i_c_stride, 8, 0, 0 ); \ - \ - MOTION( p_mb, p_mb->p_forward, p_mb->ppi_field_select[1][0], 1, \ - p_mb->pppi_motion_vectors[1][0][0], \ - p_mb->pppi_motion_vectors[1][0][1] >> 1, \ - i_l_stride, i_c_stride, 8, 0, 0 ); \ - \ - if( p_mb->i_mb_type & MB_MOTION_BACKWARD ) \ - { \ - MOTION( p_mb, p_mb->p_backward, \ - p_mb->ppi_field_select[0][1], 0, \ - p_mb->pppi_motion_vectors[0][1][0], \ - p_mb->pppi_motion_vectors[0][1][1] >> 1, \ - i_l_stride, i_c_stride, 8, 0, 1 ); \ - \ - MOTION( p_mb, p_mb->p_backward, \ - p_mb->ppi_field_select[1][1], 1, \ - p_mb->pppi_motion_vectors[1][1][0], \ - p_mb->pppi_motion_vectors[1][1][1] >> 1, \ - i_l_stride, i_c_stride, 8, 0, 1 ); \ - } \ - } \ - \ - else /* MB_MOTION_BACKWARD only */ \ - { \ - MOTION( p_mb, p_mb->p_backward, p_mb->ppi_field_select[0][1], 0,\ - p_mb->pppi_motion_vectors[0][1][0], \ - p_mb->pppi_motion_vectors[0][1][1] >> 1, \ - i_l_stride, i_c_stride, 8, 0, 0 ); \ - \ - MOTION( p_mb, p_mb->p_backward, p_mb->ppi_field_select[1][1], 1,\ - p_mb->pppi_motion_vectors[1][1][0], \ - p_mb->pppi_motion_vectors[1][1][1] >> 1, \ - i_l_stride, i_c_stride, 8, 0, 0 ); \ - } \ -} /* FRAMEFIELD */ - -static void vdec_MotionFrameField420( macroblock_t * p_mb ) -{ - FRAMEFIELD( Motion420 ) -} - -static void vdec_MotionFrameField422( macroblock_t * p_mb ) -{ - //FRAMEFIELD( Motion422 ) -} - -static void vdec_MotionFrameField444( macroblock_t * p_mb ) -{ - //FRAMEFIELD( Motion444 ) -} - -/***************************************************************************** - * vdec_MotionFrameDMVXXX?? : motion compensation for dmv motion type (frame) - *****************************************************************************/ -#define FRAMEDMV( MOTION ) \ -{ \ - /* This is necessarily a MOTION_FORWARD only macroblock, in a P \ - * picture. */ \ - \ - /* predict top field from top field */ \ - MOTION( p_mb, p_mb->p_forward, 0, 0, \ - p_mb->pppi_motion_vectors[0][0][0], \ - p_mb->pppi_motion_vectors[0][0][1], \ - /* XXX?? XXX?? >> 1 ? */ \ - p_mb->i_l_stride << 1, p_mb->i_c_stride << 1, 8, 0, 0 ); \ - \ - /* predict and add to top field from bottom field */ \ - MOTION( p_mb, p_mb->p_forward, 1, 0, \ - p_mb->ppi_dmv[0][0], p_mb->ppi_dmv[0][1], \ - p_mb->i_l_stride << 1, p_mb->i_c_stride << 1, 8, 0, 1 ); \ - \ - /* predict bottom field from bottom field */ \ - MOTION( p_mb, p_mb->p_forward, 1, 1, \ - p_mb->pppi_motion_vectors[0][0][0], \ - p_mb->pppi_motion_vectors[0][0][1], \ - /* XXX?? XXX?? >> 1 ? */ \ - p_mb->i_l_stride << 1, p_mb->i_c_stride << 1, 8, 0, 0 ); \ - \ - /* predict and add to bottom field from top field */ \ - MOTION( p_mb, p_mb->p_forward, 1, 0, \ - p_mb->ppi_dmv[1][0], p_mb->ppi_dmv[1][1], \ - p_mb->i_l_stride << 1, p_mb->i_c_stride << 1, 8, 0, 1 ); \ -} /* FRAMEDMV */ - -static void vdec_MotionFrameDMV420( macroblock_t * p_mb ) -{ - FRAMEDMV( Motion420 ) -} - -static void vdec_MotionFrameDMV422( macroblock_t * p_mb ) -{ - //FRAMEDMV( Motion422 ) -} - -static void vdec_MotionFrameDMV444( macroblock_t * p_mb ) -{ - //FRAMEDMV( Motion444 ) -} - diff --git a/plugins/motion/vdec_motion_inner.c b/plugins/motion/vdec_motion_inner.c deleted file mode 100644 index ee6dbde39c..0000000000 --- a/plugins/motion/vdec_motion_inner.c +++ /dev/null @@ -1,227 +0,0 @@ -/***************************************************************************** - * vdec_motion_inner.c : motion compensation inner routines - ***************************************************************************** - * Copyright (C) 1999, 2000 VideoLAN - * $Id: vdec_motion_inner.c,v 1.3 2001/06/07 22:14:55 sam Exp $ - * - * Authors: Christophe Massiot - * Jean-Marc Dressler - * Michel Lespinasse - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. - *****************************************************************************/ - -#define MODULE_NAME motion -#include "modules_inner.h" - -/***************************************************************************** - * Preamble - *****************************************************************************/ -#include "defs.h" - -#include "config.h" -#include "common.h" -#include "threads.h" -#include "mtime.h" - -#include "video.h" - -#define __MotionComponent_x_y_copy(width,height) \ -void _M(MotionComponent_x_y_copy_##width##_##height)(yuv_data_t *p_src, \ - yuv_data_t *p_dest, \ - int i_stride) \ -{ \ - int i_x, i_y; \ - \ - for( i_y = 0; i_y < height; i_y ++ ) \ - { \ - for( i_x = 0; i_x < width; i_x++ ) \ - { \ - p_dest[i_x] = p_src[i_x]; \ - } \ - p_dest += i_stride; \ - p_src += i_stride; \ - } \ -} - -#define __MotionComponent_X_y_copy(width,height) \ -void _M(MotionComponent_X_y_copy_##width##_##height)(yuv_data_t *p_src, \ - yuv_data_t * p_dest, \ - int i_stride) \ -{ \ - int i_x, i_y; \ - \ - for( i_y = 0; i_y < height; i_y ++ ) \ - { \ - for( i_x = 0; i_x < width; i_x++ ) \ - { \ - p_dest[i_x] = (unsigned int)(p_src[i_x] \ - + p_src[i_x + 1] \ - + 1) >> 1; \ - } \ - p_dest += i_stride; \ - p_src += i_stride; \ - } \ -} - -#define __MotionComponent_x_Y_copy(width,height) \ -void _M(MotionComponent_x_Y_copy_##width##_##height)(yuv_data_t *p_src, \ - yuv_data_t * p_dest, \ - int i_stride) \ -{ \ - int i_x, i_y; \ - \ - for( i_y = 0; i_y < height; i_y ++ ) \ - { \ - for( i_x = 0; i_x < width; i_x++ ) \ - { \ - p_dest[i_x] = (unsigned int)(p_src[i_x] \ - + p_src[i_x + i_stride] \ - + 1) >> 1; \ - } \ - p_dest += i_stride; \ - p_src += i_stride; \ - } \ -} - -#define __MotionComponent_X_Y_copy(width,height) \ -void _M(MotionComponent_X_Y_copy_##width##_##height)(yuv_data_t *p_src, \ - yuv_data_t * p_dest, \ - int i_stride) \ -{ \ - int i_x, i_y; \ - \ - for( i_y = 0; i_y < height; i_y ++ ) \ - { \ - for( i_x = 0; i_x < width; i_x++ ) \ - { \ - p_dest[i_x] = (unsigned int)(p_src[i_x] \ - + p_src[i_x + 1] \ - + p_src[i_x + i_stride] \ - + p_src[i_x + i_stride + 1] \ - + 2) >> 2; \ - } \ - p_dest += i_stride; \ - p_src += i_stride; \ - } \ -} - -#define __MotionComponent_x_y_avg(width,height) \ -void _M(MotionComponent_x_y_avg_##width##_##height)(yuv_data_t * p_src, \ - yuv_data_t * p_dest, \ - int i_stride) \ -{ \ - int i_x, i_y; \ - unsigned int i_dummy; \ - \ - for( i_y = 0; i_y < height; i_y ++ ) \ - { \ - for( i_x = 0; i_x < width; i_x++ ) \ - { \ - i_dummy = p_dest[i_x] + p_src[i_x]; \ - p_dest[i_x] = (i_dummy + 1) >> 1; \ - } \ - p_dest += i_stride; \ - p_src += i_stride; \ - } \ -} - -#define __MotionComponent_X_y_avg(width,height) \ -void _M(MotionComponent_X_y_avg_##width##_##height)(yuv_data_t * p_src, \ - yuv_data_t * p_dest, \ - int i_stride) \ -{ \ - int i_x, i_y; \ - unsigned int i_dummy; \ - \ - for( i_y = 0; i_y < height; i_y ++ ) \ - { \ - for( i_x = 0; i_x < width; i_x++ ) \ - { \ - i_dummy = p_dest[i_x] + ((unsigned int)(p_src[i_x] \ - + p_src[i_x + 1] \ - + 1) >> 1); \ - p_dest[i_x] = (i_dummy + 1) >> 1; \ - } \ - p_dest += i_stride; \ - p_src += i_stride; \ - } \ -} - -#define __MotionComponent_x_Y_avg(width,height) \ -void _M(MotionComponent_x_Y_avg_##width##_##height)(yuv_data_t * p_src, \ - yuv_data_t * p_dest, \ - int i_stride) \ -{ \ - int i_x, i_y; \ - unsigned int i_dummy; \ - \ - for( i_y = 0; i_y < height; i_y ++ ) \ - { \ - for( i_x = 0; i_x < width; i_x++ ) \ - { \ - i_dummy = \ - p_dest[i_x] + ((unsigned int)(p_src[i_x] \ - + p_src[i_x + i_stride] \ - + 1) >> 1); \ - p_dest[i_x] = (i_dummy + 1) >> 1; \ - } \ - p_dest += i_stride; \ - p_src += i_stride; \ - } \ -} - -#define __MotionComponent_X_Y_avg(width,height) \ -void _M(MotionComponent_X_Y_avg_##width##_##height)(yuv_data_t * p_src, \ - yuv_data_t * p_dest, \ - int i_stride) \ -{ \ - int i_x, i_y; \ - unsigned int i_dummy; \ - \ - for( i_y = 0; i_y < height; i_y ++ ) \ - { \ - for( i_x = 0; i_x < width; i_x++ ) \ - { \ - i_dummy = \ - p_dest[i_x] + ((unsigned int)(p_src[i_x] \ - + p_src[i_x + 1] \ - + p_src[i_x + i_stride] \ - + p_src[i_x + i_stride + 1] \ - + 2) >> 2); \ - p_dest[i_x] = (i_dummy + 1) >> 1; \ - } \ - p_dest += i_stride; \ - p_src += i_stride; \ - } \ -} - -#define __MotionComponents(width,height) \ -__MotionComponent_x_y_copy(width,height) \ -__MotionComponent_X_y_copy(width,height) \ -__MotionComponent_x_Y_copy(width,height) \ -__MotionComponent_X_Y_copy(width,height) \ -__MotionComponent_x_y_avg(width,height) \ -__MotionComponent_X_y_avg(width,height) \ -__MotionComponent_x_Y_avg(width,height) \ -__MotionComponent_X_Y_avg(width,height) - -__MotionComponents (16,16) /* 444, 422, 420 */ -__MotionComponents (16,8) /* 444, 422, 420 */ -__MotionComponents (8,8) /* 422, 420 */ -__MotionComponents (8,4) /* 420 */ -#if 0 -__MotionComponents (8,16) /* 422 */ -#endif diff --git a/plugins/motion/vdec_motion_inner_mmx.c b/plugins/motion/vdec_motion_inner_mmx.c deleted file mode 100644 index ac31682aaf..0000000000 --- a/plugins/motion/vdec_motion_inner_mmx.c +++ /dev/null @@ -1,474 +0,0 @@ -/***************************************************************************** - * vdec_motion_inner_mmx.c : motion compensation inner routines optimized in - * MMX - ***************************************************************************** - * Copyright (C) 1999, 2000 VideoLAN - * $Id: vdec_motion_inner_mmx.c,v 1.3 2001/06/07 22:14:55 sam Exp $ - * - * Authors: Christophe Massiot , largerly inspired by the - * work done by the livid project - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. - *****************************************************************************/ - -#define MODULE_NAME motionmmx -#include "modules_inner.h" - -/***************************************************************************** - * Preamble - *****************************************************************************/ -#include "defs.h" - -#include "config.h" -#include "common.h" -#include "threads.h" -#include "mtime.h" - -#include "video.h" - -#include "attributes.h" -#include "mmx.h" - -/* OK, I know, this code has been taken from livid's mpeg2dec --Meuuh */ - -/* Some rounding constants */ -mmx_t round1 = {0x0001000100010001LL}; -mmx_t round4 = {0x0002000200020002LL}; - -/* - * Useful functions - */ - -static __inline__ void MMXZeroReg() -{ - /* load 0 into mm0 */ - pxor_r2r(mm0,mm0); -} - -static __inline__ void MMXAverage2( u8 *dst, u8 *src1, u8 *src2 ) -{ - // - // *dst = clip_to_u8((*src1 + *src2 + 1)/2); - // - - movq_m2r(*src1,mm1); // load 8 src1 bytes - movq_r2r(mm1,mm2); // copy 8 src1 bytes - - movq_m2r(*src2,mm3); // load 8 src2 bytes - movq_r2r(mm3,mm4); // copy 8 src2 bytes - - punpcklbw_r2r(mm0,mm1); // unpack low src1 bytes - punpckhbw_r2r(mm0,mm2); // unpack high src1 bytes - - punpcklbw_r2r(mm0,mm3); // unpack low src2 bytes - punpckhbw_r2r(mm0,mm4); // unpack high src2 bytes - - paddw_r2r(mm3,mm1); // add lows to mm1 - paddw_m2r(round1,mm1); - psraw_i2r(1,mm1); // /2 - - paddw_r2r(mm4,mm2); // add highs to mm2 - paddw_m2r(round1,mm2); - psraw_i2r(1,mm2); // /2 - - packuswb_r2r(mm2,mm1); // pack (w/ saturation) - movq_r2m(mm1,*dst); // store result in dst -} - -static __inline__ void MMXInterpAverage2( u8 *dst, u8 *src1, u8 *src2 ) -{ - // - // *dst = clip_to_u8((*dst + (*src1 + *src2 + 1)/2 + 1)/2); - // - - movq_m2r(*dst,mm1); // load 8 dst bytes - movq_r2r(mm1,mm2); // copy 8 dst bytes - - movq_m2r(*src1,mm3); // load 8 src1 bytes - movq_r2r(mm3,mm4); // copy 8 src1 bytes - - movq_m2r(*src2,mm5); // load 8 src2 bytes - movq_r2r(mm5,mm6); // copy 8 src2 bytes - - punpcklbw_r2r(mm0,mm1); // unpack low dst bytes - punpckhbw_r2r(mm0,mm2); // unpack high dst bytes - - punpcklbw_r2r(mm0,mm3); // unpack low src1 bytes - punpckhbw_r2r(mm0,mm4); // unpack high src1 bytes - - punpcklbw_r2r(mm0,mm5); // unpack low src2 bytes - punpckhbw_r2r(mm0,mm6); // unpack high src2 bytes - - paddw_r2r(mm5,mm3); // add lows - paddw_m2r(round1,mm3); - psraw_i2r(1,mm3); // /2 - - paddw_r2r(mm6,mm4); // add highs - paddw_m2r(round1,mm4); - psraw_i2r(1,mm4); // /2 - - paddw_r2r(mm3,mm1); // add lows - paddw_m2r(round1,mm1); - psraw_i2r(1,mm1); // /2 - - paddw_r2r(mm4,mm2); // add highs - paddw_m2r(round1,mm2); - psraw_i2r(1,mm2); // /2 - - packuswb_r2r(mm2,mm1); // pack (w/ saturation) - movq_r2m(mm1,*dst); // store result in dst -} - -static __inline__ void MMXAverage4( u8 *dst, u8 *src1, u8 *src2, u8 *src3, - u8 *src4 ) -{ - // - // *dst = (*src1 + *src2 + *src3 + *src4 + 2) / 4; - // - - movq_m2r(*src1,mm1); // load 8 src1 bytes - movq_r2r(mm1,mm2); // copy 8 src1 bytes - - punpcklbw_r2r(mm0,mm1); // unpack low src1 bytes - punpckhbw_r2r(mm0,mm2); // unpack high src1 bytes - - movq_m2r(*src2,mm3); // load 8 src2 bytes - movq_r2r(mm3,mm4); // copy 8 src2 bytes - - punpcklbw_r2r(mm0,mm3); // unpack low src2 bytes - punpckhbw_r2r(mm0,mm4); // unpack high src2 bytes - - paddw_r2r(mm3,mm1); // add lows - paddw_r2r(mm4,mm2); // add highs - - // now have partials in mm1 and mm2 - - movq_m2r(*src3,mm3); // load 8 src3 bytes - movq_r2r(mm3,mm4); // copy 8 src3 bytes - - punpcklbw_r2r(mm0,mm3); // unpack low src3 bytes - punpckhbw_r2r(mm0,mm4); // unpack high src3 bytes - - paddw_r2r(mm3,mm1); // add lows - paddw_r2r(mm4,mm2); // add highs - - movq_m2r(*src4,mm5); // load 8 src4 bytes - movq_r2r(mm5,mm6); // copy 8 src4 bytes - - punpcklbw_r2r(mm0,mm5); // unpack low src4 bytes - punpckhbw_r2r(mm0,mm6); // unpack high src4 bytes - - paddw_r2r(mm5,mm1); // add lows - paddw_r2r(mm6,mm2); // add highs - - // now have subtotal in mm1 and mm2 - - paddw_m2r(round4,mm1); - psraw_i2r(2,mm1); // /4 - paddw_m2r(round4,mm2); - psraw_i2r(2,mm2); // /4 - - packuswb_r2r(mm2,mm1); // pack (w/ saturation) - movq_r2m(mm1,*dst); // store result in dst -} - -static __inline__ void MMXInterpAverage4( u8 *dst, u8 *src1, u8 *src2, - u8 *src3, u8 *src4 ) -{ - // - // *dst = clip_to_u8((*dst + (*src1 + *src2 + *src3 + *src4 + 2)/4 + 1)/2); - // - - movq_m2r(*src1,mm1); // load 8 src1 bytes - movq_r2r(mm1,mm2); // copy 8 src1 bytes - - punpcklbw_r2r(mm0,mm1); // unpack low src1 bytes - punpckhbw_r2r(mm0,mm2); // unpack high src1 bytes - - movq_m2r(*src2,mm3); // load 8 src2 bytes - movq_r2r(mm3,mm4); // copy 8 src2 bytes - - punpcklbw_r2r(mm0,mm3); // unpack low src2 bytes - punpckhbw_r2r(mm0,mm4); // unpack high src2 bytes - - paddw_r2r(mm3,mm1); // add lows - paddw_r2r(mm4,mm2); // add highs - - // now have partials in mm1 and mm2 - - movq_m2r(*src3,mm3); // load 8 src3 bytes - movq_r2r(mm3,mm4); // copy 8 src3 bytes - - punpcklbw_r2r(mm0,mm3); // unpack low src3 bytes - punpckhbw_r2r(mm0,mm4); // unpack high src3 bytes - - paddw_r2r(mm3,mm1); // add lows - paddw_r2r(mm4,mm2); // add highs - - movq_m2r(*src4,mm5); // load 8 src4 bytes - movq_r2r(mm5,mm6); // copy 8 src4 bytes - - punpcklbw_r2r(mm0,mm5); // unpack low src4 bytes - punpckhbw_r2r(mm0,mm6); // unpack high src4 bytes - - paddw_r2r(mm5,mm1); // add lows - paddw_r2r(mm6,mm2); // add highs - - paddw_m2r(round4,mm1); - psraw_i2r(2,mm1); // /4 - paddw_m2r(round4,mm2); - psraw_i2r(2,mm2); // /4 - - // now have subtotal/4 in mm1 and mm2 - - movq_m2r(*dst,mm3); // load 8 dst bytes - movq_r2r(mm3,mm4); // copy 8 dst bytes - - punpcklbw_r2r(mm0,mm3); // unpack low dst bytes - punpckhbw_r2r(mm0,mm4); // unpack high dst bytes - - paddw_r2r(mm3,mm1); // add lows - paddw_r2r(mm4,mm2); // add highs - - paddw_m2r(round1,mm1); - psraw_i2r(1,mm1); // /2 - paddw_m2r(round1,mm2); - psraw_i2r(1,mm2); // /2 - - // now have end value in mm1 and mm2 - - packuswb_r2r(mm2,mm1); // pack (w/ saturation) - movq_r2m(mm1,*dst); // store result in dst -} - - -/* - * Actual Motion compensation - */ - -#define pavg_r2r(src,dest) pavgusb_r2r (src, dest); -#define pavg_m2r(src,dest) pavgusb_m2r (src, dest); - -#define __MotionComponent_x_y_copy(width,height) \ -void _M(MotionComponent_x_y_copy_##width##_##height)(yuv_data_t * p_src, \ - yuv_data_t * p_dest, \ - int i_stride) \ -{ \ - int i_y; \ - \ - MMXZeroReg(); \ - \ - for( i_y = 0; i_y < height; i_y ++ ) \ - { \ - movq_m2r( *p_src, mm0 ); /* load 8 ref bytes */ \ - if( width == 16 ) \ - movq_m2r( *(p_src + 8), mm1 ); \ - p_src += i_stride; \ - \ - movq_r2m( mm0, *p_dest ); /* store 8 bytes at curr */ \ - if( width == 16 ) \ - movq_r2m( mm1, *(p_dest + 8) ); \ - p_dest += i_stride; \ - } \ -} - -#define __MotionComponent_X_y_copy(width,height) \ -void _M(MotionComponent_X_y_copy_##width##_##height)(yuv_data_t * p_src, \ - yuv_data_t * p_dest, \ - int i_stride) \ -{ \ - int i_y; \ - \ - MMXZeroReg(); \ - \ - for( i_y = 0; i_y < height; i_y ++ ) \ - { \ - MMXAverage2( p_dest, p_src, p_src + 1 ); \ - \ - if( width == 16 ) \ - { \ - MMXAverage2( p_dest + 8, p_src + 8, p_src + 9 ); \ - } \ - \ - p_dest += i_stride; \ - p_src += i_stride; \ - } \ -} - -#define __MotionComponent_x_Y_copy(width,height) \ -void _M(MotionComponent_x_Y_copy_##width##_##height)(yuv_data_t * p_src, \ - yuv_data_t * p_dest, \ - int i_stride) \ -{ \ - int i_y; \ - yuv_data_t * p_next_src = p_src + i_stride; \ - \ - MMXZeroReg(); \ - \ - for( i_y = 0; i_y < height; i_y ++ ) \ - { \ - MMXAverage2( p_dest, p_src, p_next_src ); \ - \ - if( width == 16 ) \ - { \ - MMXAverage2( p_dest + 8, p_src + 8, p_next_src + 8 ); \ - } \ - \ - p_dest += i_stride; \ - p_src += i_stride; \ - p_next_src += i_stride; \ - } \ -} - -#define __MotionComponent_X_Y_copy(width,height) \ -void _M(MotionComponent_X_Y_copy_##width##_##height)(yuv_data_t * p_src, \ - yuv_data_t * p_dest, \ - int i_stride) \ -{ \ - int i_y; \ - yuv_data_t * p_next_src = p_src + i_stride; \ - \ - MMXZeroReg(); \ - \ - for( i_y = 0; i_y < height; i_y ++ ) \ - { \ - MMXAverage4( p_dest, p_src, p_src + 1, p_next_src, p_next_src + 1 );\ - \ - if( width == 16 ) \ - { \ - MMXAverage4( p_dest + 8, p_src + 8, p_src + 9, \ - p_next_src + 8, p_next_src + 9 ); \ - } \ - \ - p_dest += i_stride; \ - p_src += i_stride; \ - p_next_src += i_stride; \ - } \ -} - -#define __MotionComponent_x_y_avg(width,height) \ -void _M(MotionComponent_x_y_avg_##width##_##height)(yuv_data_t * p_src, \ - yuv_data_t * p_dest, \ - int i_stride) \ -{ \ - int i_y; \ - \ - MMXZeroReg(); \ - \ - for( i_y = 0; i_y < height; i_y ++ ) \ - { \ - MMXAverage2( p_dest, p_dest, p_src ); \ - \ - if( width == 16 ) \ - { \ - MMXAverage2( p_dest + 8, p_dest + 8, p_src + 8 ); \ - } \ - \ - p_dest += i_stride; \ - p_src += i_stride; \ - } \ -} - -#define __MotionComponent_X_y_avg(width,height) \ -void _M(MotionComponent_X_y_avg_##width##_##height)(yuv_data_t * p_src, \ - yuv_data_t * p_dest, \ - int i_stride) \ -{ \ - int i_y; \ - \ - MMXZeroReg(); \ - \ - for( i_y = 0; i_y < height; i_y ++ ) \ - { \ - MMXInterpAverage2( p_dest, p_src, p_src + 1 ); \ - \ - if( width == 16 ) \ - { \ - MMXInterpAverage2( p_dest + 8, p_src + 8, p_src + 9 ); \ - } \ - \ - p_dest += i_stride; \ - p_src += i_stride; \ - } \ -} - -#define __MotionComponent_x_Y_avg(width,height) \ -void _M(MotionComponent_x_Y_avg_##width##_##height)(yuv_data_t * p_src, \ - yuv_data_t * p_dest, \ - int i_stride) \ -{ \ - int i_y; \ - yuv_data_t * p_next_src = p_src + i_stride; \ - \ - MMXZeroReg(); \ - \ - for( i_y = 0; i_y < height; i_y ++ ) \ - { \ - MMXInterpAverage2( p_dest, p_src, p_next_src ); \ - \ - if( width == 16 ) \ - { \ - MMXInterpAverage2( p_dest + 8, p_src + 8, p_next_src + 8 ); \ - } \ - p_dest += i_stride; \ - p_src += i_stride; \ - p_next_src += i_stride; \ - } \ -} - -#define __MotionComponent_X_Y_avg(width,height) \ -void _M(MotionComponent_X_Y_avg_##width##_##height)(yuv_data_t * p_src, \ - yuv_data_t * p_dest, \ - int i_stride) \ -{ \ - int i_y; \ - yuv_data_t * p_next_src = p_src + i_stride; \ - \ - MMXZeroReg(); \ - \ - for( i_y = 0; i_y < height; i_y ++ ) \ - { \ - MMXInterpAverage4( p_dest, p_src, p_src + 1, p_next_src, \ - p_next_src + 1 ); \ - \ - if( width == 16 ) \ - { \ - MMXInterpAverage4( p_dest + 8, p_src + 8, p_src + 9, \ - p_next_src + 8, p_next_src + 9 ); \ - } \ - \ - p_dest += i_stride; \ - p_src += i_stride; \ - p_next_src += i_stride; \ - } \ -} - -#define __MotionComponents(width,height) \ -__MotionComponent_x_y_copy(width,height) \ -__MotionComponent_X_y_copy(width,height) \ -__MotionComponent_x_Y_copy(width,height) \ -__MotionComponent_X_Y_copy(width,height) \ -__MotionComponent_x_y_avg(width,height) \ -__MotionComponent_X_y_avg(width,height) \ -__MotionComponent_x_Y_avg(width,height) \ -__MotionComponent_X_Y_avg(width,height) - -__MotionComponents (16,16) /* 444, 422, 420 */ -__MotionComponents (16,8) /* 444, 422, 420 */ -__MotionComponents (8,8) /* 422, 420 */ -__MotionComponents (8,4) /* 420 */ -#if 0 -__MotionComponents (8,16) /* 422 */ -#endif diff --git a/plugins/motion/vdec_motion_inner_mmxext.c b/plugins/motion/vdec_motion_inner_mmxext.c deleted file mode 100644 index 2d6df9ffc3..0000000000 --- a/plugins/motion/vdec_motion_inner_mmxext.c +++ /dev/null @@ -1,396 +0,0 @@ -/***************************************************************************** - * vdec_motion_inner_mmxext.c : motion compensation inner routines optimized - * in MMX EXT - ***************************************************************************** - * Copyright (C) 1999, 2000 VideoLAN - * $Id: vdec_motion_inner_mmxext.c,v 1.3 2001/06/07 22:14:55 sam Exp $ - * - * Authors: Christophe Massiot , largerly inspired by the - * work done by the livid project - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. - *****************************************************************************/ - -#define MODULE_NAME motionmmxext -#include "modules_inner.h" - -/***************************************************************************** - * Preamble - *****************************************************************************/ -#include "defs.h" - -#include "config.h" -#include "common.h" -#include "threads.h" -#include "mtime.h" - -#include "video.h" - -#include "attributes.h" -#include "mmx.h" - -/* OK, I know, this code has been taken from livid's mpeg2dec --Meuuh */ - -static mmx_t mask_one = {0x0101010101010101LL}; - -/* - * Useful functions - */ - -#define pavg_r2r(src,dest) pavgb_r2r (src, dest); -#define pavg_m2r(src,dest) pavgb_m2r (src, dest); - -#define __MotionComponent_x_y_copy(width,height) \ -void _M(MotionComponent_x_y_copy_##width##_##height)(yuv_data_t * p_src, \ - yuv_data_t * p_dest, \ - int i_stride) \ -{ \ - int i_y; \ - \ - pxor_r2r (mm0, mm0); \ - pxor_r2r (mm1, mm1); \ - pxor_r2r (mm2, mm2); \ - pxor_r2r (mm3, mm3); \ - pxor_r2r (mm4, mm4); \ - pxor_r2r (mm5, mm5); \ - pxor_r2r (mm6, mm6); \ - pxor_r2r (mm7, mm7); \ - \ - for( i_y = 0; i_y < height; i_y ++ ) \ - { \ - movq_m2r( *p_src, mm0 ); /* load 8 ref bytes */ \ - if( width == 16 ) \ - movq_m2r( *(p_src + 8), mm1 ); \ - p_src += i_stride; \ - \ - movq_r2m( mm0, *p_dest ); /* store 8 bytes at curr */ \ - if( width == 16 ) \ - movq_r2m( mm1, *(p_dest + 8) ); \ - p_dest += i_stride; \ - } \ -} - -#define __MotionComponent_X_y_copy(width,height) \ -void _M(MotionComponent_X_y_copy_##width##_##height)(yuv_data_t * p_src, \ - yuv_data_t * p_dest, \ - int i_stride) \ -{ \ - int i_y; \ - \ - for( i_y = 0; i_y < height; i_y ++ ) \ - { \ - movq_m2r (*p_src, mm0); \ - if( width == 16 ) \ - movq_m2r (*(p_src + 8), mm1); \ - pavg_m2r (*(p_src + 1), mm0); \ - if( width == 16 ) \ - pavg_m2r (*(p_src + 9), mm1); \ - movq_r2m (mm0, *p_dest); \ - p_src += i_stride; \ - if( width == 16 ) \ - movq_r2m (mm1, *(p_dest + 8)); \ - p_dest += i_stride; \ - } \ -} - -#define __MotionComponent_x_Y_copy(width,height) \ -void _M(MotionComponent_x_Y_copy_##width##_##height)(yuv_data_t * p_src, \ - yuv_data_t * p_dest, \ - int i_stride) \ -{ \ - int i_y; \ - yuv_data_t * p_next_src = p_src + i_stride; \ - \ - for( i_y = 0; i_y < height; i_y ++ ) \ - { \ - movq_m2r (*p_src, mm0); \ - if( width == 16 ) \ - movq_m2r (*(p_src + 8), mm1); \ - pavg_m2r (*(p_next_src), mm0); \ - if( width == 16 ) \ - pavg_m2r (*(p_next_src + 8), mm1); \ - movq_r2m (mm0, *p_dest); \ - p_src += i_stride; \ - p_next_src += i_stride; \ - if( width == 16 ) \ - movq_r2m (mm1, *(p_dest + 8)); \ - p_dest += i_stride; \ - } \ -} - -#define __MotionComponent_X_Y_copy(width,height) \ -void _M(MotionComponent_X_Y_copy_##width##_##height)(yuv_data_t * p_src, \ - yuv_data_t * p_dest, \ - int i_stride) \ -{ \ - int i_y; \ - \ - if( width == 16 ) \ - { \ - for( i_y = 0; i_y < height; i_y ++ ) \ - { \ - movq_m2r (*p_src, mm0); \ - movq_m2r (*(p_src+i_stride+1), mm1); \ - movq_r2r (mm0, mm7); \ - movq_m2r (*(p_src+1), mm2); \ - pxor_r2r (mm1, mm7); \ - movq_m2r (*(p_src + i_stride), mm3); \ - movq_r2r (mm2, mm6); \ - pxor_r2r (mm3, mm6); \ - pavg_r2r (mm1, mm0); \ - pavg_r2r (mm3, mm2); \ - por_r2r (mm6, mm7); \ - movq_r2r (mm0, mm6); \ - pxor_r2r (mm2, mm6); \ - pand_r2r (mm6, mm7); \ - pand_m2r (mask_one, mm7); \ - pavg_r2r (mm2, mm0); \ - psubusb_r2r (mm7, mm0); \ - movq_r2m (mm0, *p_dest); \ - \ - movq_m2r (*(p_src+8), mm0); \ - movq_m2r (*(p_src+i_stride+9), mm1); \ - movq_r2r (mm0, mm7); \ - movq_m2r (*(p_src+9), mm2); \ - pxor_r2r (mm1, mm7); \ - movq_m2r (*(p_src+i_stride+8), mm3); \ - movq_r2r (mm2, mm6); \ - pxor_r2r (mm3, mm6); \ - pavg_r2r (mm1, mm0); \ - pavg_r2r (mm3, mm2); \ - por_r2r (mm6, mm7); \ - movq_r2r (mm0, mm6); \ - pxor_r2r (mm2, mm6); \ - pand_r2r (mm6, mm7); \ - pand_m2r (mask_one, mm7); \ - pavg_r2r (mm2, mm0); \ - psubusb_r2r (mm7, mm0); \ - p_src += i_stride; \ - movq_r2m (mm0, *(p_dest+8)); \ - p_dest += i_stride; \ - } \ - } \ - else \ - { \ - movq_m2r (*p_src, mm0); \ - movq_m2r (*(p_src+1), mm1); \ - movq_r2r (mm0, mm7); \ - pxor_r2r (mm1, mm7); \ - pavg_r2r (mm1, mm0); \ - p_src += i_stride; \ - \ - for( i_y = 0; i_y < height; i_y ++ ) \ - { \ - movq_m2r (*p_src, mm2); \ - movq_r2r (mm0, mm5); \ - movq_m2r (*(p_src+1), mm3); \ - movq_r2r (mm2, mm6); \ - pxor_r2r (mm3, mm6); \ - pavg_r2r (mm3, mm2); \ - por_r2r (mm6, mm7); \ - pxor_r2r (mm2, mm5); \ - pand_r2r (mm5, mm7); \ - pavg_r2r (mm2, mm0); \ - pand_m2r (mask_one, mm7); \ - psubusb_r2r (mm7, mm0); \ - p_src += i_stride; \ - movq_r2m (mm0, *p_dest); \ - p_dest += i_stride; \ - movq_r2r (mm6, mm7); \ - movq_r2r (mm2, mm0); \ - } \ - } \ -} - -#define __MotionComponent_x_y_avg(width,height) \ -void _M(MotionComponent_x_y_avg_##width##_##height)(yuv_data_t * p_src, \ - yuv_data_t * p_dest, \ - int i_stride) \ -{ \ - int i_y; \ - \ - for( i_y = 0; i_y < height; i_y ++ ) \ - { \ - movq_m2r( *p_src, mm0 ); \ - if( width == 16 ) \ - movq_m2r( *(p_src + 8), mm1 ); \ - pavg_m2r( *p_dest, mm0 ); \ - if( width == 16 ) \ - pavg_m2r( *(p_dest + 8), mm1 ); \ - movq_r2m( mm0, *p_dest ); \ - p_src += i_stride; \ - if( width == 16 ) \ - movq_r2m( mm1, *(p_dest + 8) ); \ - p_dest += i_stride; \ - } \ -} - -#define __MotionComponent_X_y_avg(width,height) \ -void _M(MotionComponent_X_y_avg_##width##_##height)(yuv_data_t * p_src, \ - yuv_data_t * p_dest, \ - int i_stride) \ -{ \ - int i_y; \ - \ - for( i_y = 0; i_y < height; i_y ++ ) \ - { \ - movq_m2r (*p_src, mm0); \ - if( width == 16 ) \ - movq_m2r (*(p_src + 8), mm1); \ - pavg_m2r (*(p_src + 1), mm0); \ - if( width == 16 ) \ - pavg_m2r (*(p_src + 9), mm1); \ - pavg_m2r (*p_dest, mm0); \ - if( width == 16 ) \ - pavg_m2r (*(p_dest + 8), mm1); \ - p_src += i_stride; \ - movq_r2m (mm0, *p_dest); \ - if( width == 16 ) \ - movq_r2m (mm1, *(p_dest + 8)); \ - p_dest += i_stride; \ - } \ -} - -#define __MotionComponent_x_Y_avg(width,height) \ -void _M(MotionComponent_x_Y_avg_##width##_##height)(yuv_data_t * p_src, \ - yuv_data_t * p_dest, \ - int i_stride) \ -{ \ - int i_y; \ - yuv_data_t * p_next_src = p_src + i_stride; \ - \ - for( i_y = 0; i_y < height; i_y ++ ) \ - { \ - movq_m2r (*p_src, mm0); \ - if( width == 16 ) \ - movq_m2r (*(p_src + 8), mm1); \ - pavg_m2r (*(p_next_src), mm0); \ - if( width == 16 ) \ - pavg_m2r (*(p_next_src + 8), mm1); \ - pavg_m2r (*p_dest, mm0); \ - if( width == 16 ) \ - pavg_m2r (*(p_dest + 8), mm1); \ - p_src += i_stride; \ - p_next_src += i_stride; \ - movq_r2m (mm0, *p_dest); \ - if( width == 16 ) \ - movq_r2m (mm1, *(p_dest + 8)); \ - p_dest += i_stride; \ - } \ -} - -#define __MotionComponent_X_Y_avg(width,height) \ -void _M(MotionComponent_X_Y_avg_##width##_##height)(yuv_data_t * p_src, \ - yuv_data_t * p_dest, \ - int i_stride) \ -{ \ - int i_y; \ - \ - if( width == 16 ) \ - { \ - for( i_y = 0; i_y < height; i_y ++ ) \ - { \ - movq_m2r (*p_src, mm0); \ - movq_m2r (*(p_src+i_stride+1), mm1); \ - movq_r2r (mm0, mm7); \ - movq_m2r (*(p_src+1), mm2); \ - pxor_r2r (mm1, mm7); \ - movq_m2r (*(p_src+i_stride), mm3); \ - movq_r2r (mm2, mm6); \ - pxor_r2r (mm3, mm6); \ - pavg_r2r (mm1, mm0); \ - pavg_r2r (mm3, mm2); \ - por_r2r (mm6, mm7); \ - movq_r2r (mm0, mm6); \ - pxor_r2r (mm2, mm6); \ - pand_r2r (mm6, mm7); \ - pand_m2r (mask_one, mm7); \ - pavg_r2r (mm2, mm0); \ - psubusb_r2r (mm7, mm0); \ - movq_m2r (*p_dest, mm1); \ - pavg_r2r (mm1, mm0); \ - movq_r2m (mm0, *p_dest); \ - \ - movq_m2r (*(p_src+8), mm0); \ - movq_m2r (*(p_src+i_stride+9), mm1); \ - movq_r2r (mm0, mm7); \ - movq_m2r (*(p_src+9), mm2); \ - pxor_r2r (mm1, mm7); \ - movq_m2r (*(p_src+i_stride+8), mm3); \ - movq_r2r (mm2, mm6); \ - pxor_r2r (mm3, mm6); \ - pavg_r2r (mm1, mm0); \ - pavg_r2r (mm3, mm2); \ - por_r2r (mm6, mm7); \ - movq_r2r (mm0, mm6); \ - pxor_r2r (mm2, mm6); \ - pand_r2r (mm6, mm7); \ - pand_m2r (mask_one, mm7); \ - pavg_r2r (mm2, mm0); \ - psubusb_r2r (mm7, mm0); \ - movq_m2r (*(p_dest+8), mm1); \ - pavg_r2r (mm1, mm0); \ - p_src += i_stride; \ - movq_r2m (mm0, *(p_dest+8)); \ - p_dest += i_stride; \ - } \ - } \ - else \ - { \ - for( i_y = 0; i_y < height; i_y ++ ) \ - { \ - movq_m2r (*p_src, mm0); \ - movq_m2r (*(p_src+i_stride+1), mm1); \ - movq_r2r (mm0, mm7); \ - movq_m2r (*(p_src+1), mm2); \ - pxor_r2r (mm1, mm7); \ - movq_m2r (*(p_src+i_stride), mm3); \ - movq_r2r (mm2, mm6); \ - pxor_r2r (mm3, mm6); \ - pavg_r2r (mm1, mm0); \ - pavg_r2r (mm3, mm2); \ - por_r2r (mm6, mm7); \ - movq_r2r (mm0, mm6); \ - pxor_r2r (mm2, mm6); \ - pand_r2r (mm6, mm7); \ - pand_m2r (mask_one, mm7); \ - pavg_r2r (mm2, mm0); \ - psubusb_r2r (mm7, mm0); \ - movq_m2r (*p_dest, mm1); \ - pavg_r2r (mm1, mm0); \ - p_src += i_stride; \ - movq_r2m (mm0, *p_dest); \ - p_dest += i_stride; \ - } \ - } \ -} - -#define __MotionComponents(width,height) \ -__MotionComponent_x_y_copy(width,height) \ -__MotionComponent_X_y_copy(width,height) \ -__MotionComponent_x_Y_copy(width,height) \ -__MotionComponent_X_Y_copy(width,height) \ -__MotionComponent_x_y_avg(width,height) \ -__MotionComponent_X_y_avg(width,height) \ -__MotionComponent_x_Y_avg(width,height) \ -__MotionComponent_X_Y_avg(width,height) - -__MotionComponents (16,16) /* 444, 422, 420 */ -__MotionComponents (16,8) /* 444, 422, 420 */ -__MotionComponents (8,8) /* 422, 420 */ -__MotionComponents (8,4) /* 420 */ -#if 0 -__MotionComponents (8,16) /* 422 */ -#endif diff --git a/src/ac3_decoder/ac3_parse.c b/src/ac3_decoder/ac3_parse.c index 0903da5804..e6d1c06d13 100644 --- a/src/ac3_decoder/ac3_parse.c +++ b/src/ac3_decoder/ac3_parse.c @@ -2,7 +2,7 @@ * ac3_parse.c: ac3 parsing procedures ***************************************************************************** * Copyright (C) 1999, 2000, 2001 VideoLAN - * $Id: ac3_parse.c,v 1.23 2001/05/15 16:19:42 sam Exp $ + * $Id: ac3_parse.c,v 1.24 2001/08/22 17:21:45 massiot Exp $ * * Authors: Michel Kaempf * Aaron Holtzman @@ -103,7 +103,7 @@ static const struct frmsize_s frmsizecod_tbl[] = static const int fscod_tbl[] = {48000, 44100, 32000}; /* Some internal functions */ -#ifdef STATS +#ifdef TRACE static void parse_bsi_stats (ac3dec_t * p_ac3dec); static void parse_audblk_stats (ac3dec_t * p_ac3dec); #endif @@ -308,7 +308,7 @@ int parse_bsi (ac3dec_t * p_ac3dec) } p_ac3dec->total_bits_read += 25; -#ifdef STATS +#ifdef TRACE parse_bsi_stats (p_ac3dec); #endif @@ -785,7 +785,7 @@ int parse_audblk (ac3dec_t * p_ac3dec, int blknum) p_ac3dec->total_bits_read += 8 * p_ac3dec->audblk.skipl + 9; } -#ifdef STATS +#ifdef TRACE parse_audblk_stats(p_ac3dec); #endif @@ -814,7 +814,7 @@ void parse_auxdata (ac3dec_t * p_ac3dec) RemoveBits (&p_ac3dec->bit_stream,16); } -#ifdef STATS +#ifdef TRACE static void parse_bsi_stats (ac3dec_t * p_ac3dec) /* Some stats */ { struct mixlev_s diff --git a/src/audio_decoder/audio_decoder.c b/src/audio_decoder/audio_decoder.c index 4b6c7848f1..e06f6c2d21 100644 --- a/src/audio_decoder/audio_decoder.c +++ b/src/audio_decoder/audio_decoder.c @@ -2,7 +2,7 @@ * audio_decoder.c: MPEG audio decoder thread ***************************************************************************** * Copyright (C) 1999, 2000 VideoLAN - * $Id: audio_decoder.c,v 1.51 2001/05/31 01:37:08 sam Exp $ + * $Id: audio_decoder.c,v 1.52 2001/08/22 17:21:45 massiot Exp $ * * Authors: Michel Kaempf * Michel Lespinasse @@ -170,18 +170,6 @@ static void RunThread (adec_thread_t * p_adec) s16 * buffer; adec_sync_info_t sync_info; - if( DECODER_FIFO_START( *p_adec->p_fifo)->i_pts ) - { - p_adec->p_aout_fifo->date[p_adec->p_aout_fifo->l_end_frame] = - DECODER_FIFO_START( *p_adec->p_fifo )->i_pts; - DECODER_FIFO_START(*p_adec->p_fifo)->i_pts = 0; - } - else - { - p_adec->p_aout_fifo->date[p_adec->p_aout_fifo->l_end_frame] = - LAST_MDATE; - } - if( ! adec_SyncFrame (p_adec, &sync_info) ) { sync = 1; @@ -191,6 +179,18 @@ static void RunThread (adec_thread_t * p_adec) buffer = ((s16 *)p_adec->p_aout_fifo->buffer) + (p_adec->p_aout_fifo->l_end_frame * ADEC_FRAME_SIZE); + if( DECODER_FIFO_START( *p_adec->p_fifo)->i_pts ) + { + p_adec->p_aout_fifo->date[p_adec->p_aout_fifo->l_end_frame] = + DECODER_FIFO_START( *p_adec->p_fifo )->i_pts; + DECODER_FIFO_START(*p_adec->p_fifo)->i_pts = 0; + } + else + { + p_adec->p_aout_fifo->date[p_adec->p_aout_fifo->l_end_frame] = + LAST_MDATE; + } + if( adec_DecodeFrame (p_adec, buffer) ) { /* Ouch, failed decoding... We'll have to resync */ diff --git a/src/input/input_ext-dec.c b/src/input/input_ext-dec.c index 7c88025fe1..33e2f50ba8 100644 --- a/src/input/input_ext-dec.c +++ b/src/input/input_ext-dec.c @@ -2,7 +2,7 @@ * input_ext-dec.c: services to the decoders ***************************************************************************** * Copyright (C) 1998, 1999, 2000 VideoLAN - * $Id: input_ext-dec.c,v 1.17 2001/07/17 09:48:08 massiot Exp $ + * $Id: input_ext-dec.c,v 1.18 2001/08/22 17:21:45 massiot Exp $ * * Authors: Christophe Massiot * @@ -150,10 +150,10 @@ void NextDataPacket( bit_stream_t * p_bit_stream ) } /***************************************************************************** - * UnalignedShowBits : return i_bits bits from the bit stream, even when + * UnalignedShowBits : places i_bits bits into the bit buffer, even when * not aligned on a word boundary *****************************************************************************/ -u32 UnalignedShowBits( bit_stream_t * p_bit_stream, unsigned int i_bits ) +void UnalignedShowBits( bit_stream_t * p_bit_stream, unsigned int i_bits ) { /* We just fill in the bit buffer. */ while( p_bit_stream->fifo.i_available < i_bits ) @@ -216,11 +216,8 @@ u32 UnalignedShowBits( bit_stream_t * p_bit_stream, unsigned int i_bits ) AlignWord( p_bit_stream ); } } - - return( ShowBits( p_bit_stream, i_bits ) ); } } - return( p_bit_stream->fifo.buffer >> (8 * sizeof(WORD_TYPE) - i_bits) ); } /***************************************************************************** @@ -283,7 +280,7 @@ u32 UnalignedGetBits( bit_stream_t * p_bit_stream, unsigned int i_bits ) { /* Get aligned on a word boundary. Otherwise it is safer * to do it the next time. - * NB : we _will_ get aligned, because we have at most + * NB : we _will_ get aligned, because we have at most * sizeof(WORD_TYPE) - 1 bytes to store, and at least * sizeof(WORD_TYPE) - 1 empty bytes in the bit buffer. */ AlignWord( p_bit_stream ); diff --git a/src/video_decoder/video_decoder.c b/src/video_decoder/video_decoder.c index 2323aaaf72..94a60c5839 100644 --- a/src/video_decoder/video_decoder.c +++ b/src/video_decoder/video_decoder.c @@ -2,10 +2,10 @@ * video_decoder.c : video decoder thread ***************************************************************************** * Copyright (C) 1999, 2000 VideoLAN - * $Id: video_decoder.c,v 1.56 2001/07/31 21:13:30 gbazin Exp $ + * $Id: video_decoder.c,v 1.57 2001/08/22 17:21:45 massiot Exp $ * * Authors: Christophe Massiot - * Gaël Hendryckx + * Michel Lespinasse * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -51,6 +51,7 @@ #include "vdec_ext-plugins.h" #include "video_decoder.h" #include "vpar_pool.h" +#include "video_parser.h" /* * Local prototypes @@ -126,7 +127,7 @@ void vdec_DestroyThread( vdec_thread_t *p_vdec ) * This function is called from RunThread and performs the second step of the * initialization. *****************************************************************************/ -void vdec_InitThread( vdec_thread_t *p_vdec ) +void vdec_InitThread( vdec_thread_t * p_vdec ) { intf_DbgMsg("vdec debug: initializing video decoder thread %p", p_vdec); @@ -134,12 +135,12 @@ void vdec_InitThread( vdec_thread_t *p_vdec ) # if VDEC_NICE /* Re-nice ourself - otherwise we would steal CPU time from the video * output, which would make a poor display. */ -#if !defined(WIN32) +# if !defined(WIN32) if( nice(VDEC_NICE) == -1 ) -#else +# else if( !SetThreadPriority( GetCurrentThread(), THREAD_PRIORITY_BELOW_NORMAL ) ) -#endif +# endif { intf_WarnMsg( 2, "vpar warning : couldn't nice() (%s)", strerror(errno) ); @@ -150,7 +151,7 @@ void vdec_InitThread( vdec_thread_t *p_vdec ) p_vdec->p_idct_data = NULL; p_vdec->p_pool->pf_decode_init( p_vdec ); - p_vdec->p_pool->pf_idct_init( p_vdec ); + p_vdec->p_pool->pf_idct_init( &p_vdec->p_idct_data ); /* Mark thread as running and return */ intf_DbgMsg("vdec debug: InitThread(%p) succeeded", p_vdec); @@ -162,7 +163,7 @@ void vdec_InitThread( vdec_thread_t *p_vdec ) * This function is called when the thread ends after a sucessful * initialization. *****************************************************************************/ -void vdec_EndThread( vdec_thread_t *p_vdec ) +void vdec_EndThread( vdec_thread_t * p_vdec ) { intf_DbgMsg("vdec debug: EndThread(%p)", p_vdec); @@ -174,6 +175,125 @@ void vdec_EndThread( vdec_thread_t *p_vdec ) free( p_vdec ); } +/***************************************************************************** + * MotionBlock: does one component of the motion compensation + *****************************************************************************/ +static __inline__ void MotionBlock( vdec_pool_t * p_pool, + boolean_t b_average, + int i_x_pred, int i_y_pred, + yuv_data_t * pp_dest[3], int i_dest_offset, + yuv_data_t * pp_src[3], int i_src_offset, + int i_stride, int i_height, + boolean_t b_second_half, boolean_t b_color ) +{ + int i_xy_half; + yuv_data_t * p_src1; + yuv_data_t * p_src2; + + i_xy_half = ((i_y_pred & 1) << 1) | (i_x_pred & 1); + + p_src1 = pp_src[0] + i_src_offset + + (i_x_pred >> 1) + (i_y_pred >> 1) * i_stride + + b_second_half * (i_stride << 3); + + p_pool->ppppf_motion[b_average][0][i_xy_half] + ( pp_dest[0] + i_dest_offset + b_second_half * (i_stride << 3), + p_src1, i_stride, i_height ); + + if( b_color ) + { + /* Expanded at compile-time. */ + i_x_pred /= 2; + i_y_pred /= 2; + + i_xy_half = ((i_y_pred & 1) << 1) | (i_x_pred & 1); + i_stride >>= 1; + i_height >>= 1; + i_src_offset >>= 1; + i_src_offset += b_second_half * (i_stride << 2); + i_dest_offset >>= 1; + i_dest_offset += b_second_half * (i_stride << 2); + + p_src1 = pp_src[1] + i_src_offset + + (i_x_pred >> 1) + (i_y_pred >> 1) * i_stride; + p_src2 = pp_src[2] + i_src_offset + + (i_x_pred >> 1) + (i_y_pred >> 1) * i_stride; + + p_pool->ppppf_motion[b_average][1][i_xy_half] + ( pp_dest[1] + i_dest_offset, p_src1, i_stride, i_height ); + p_pool->ppppf_motion[b_average][1][i_xy_half] + ( pp_dest[2] + i_dest_offset, p_src2, i_stride, i_height ); + } +} + + +/***************************************************************************** + * DecodeMacroblock: decode a macroblock + *****************************************************************************/ +#define DECLARE_DECODEMB( PSZ_NAME, B_COLOR ) \ +void PSZ_NAME ( vdec_thread_t *p_vdec, macroblock_t * p_mb ) \ +{ \ + int i; \ + idct_inner_t * p_idct; \ + vdec_pool_t * p_pool = p_vdec->p_pool; \ + \ + if( !(p_mb->i_mb_modes & MB_INTRA) ) \ + { \ + /* \ + * Motion Compensation (ISO/IEC 13818-2 section 7.6) \ + */ \ + for( i = 0; i < p_mb->i_nb_motions; i++ ) \ + { \ + motion_inner_t * p_motion = &p_mb->p_motions[i]; \ + MotionBlock( p_pool, p_motion->b_average, \ + p_motion->i_x_pred, p_motion->i_y_pred, \ + p_mb->pp_dest, p_motion->i_dest_offset, \ + p_motion->pp_source, p_motion->i_src_offset, \ + p_motion->i_stride, p_motion->i_height, \ + p_motion->b_second_half, B_COLOR ); \ + } \ + \ + for( i = 0, p_idct = p_mb->p_idcts; i < 4 + 2 * B_COLOR; \ + i++, p_idct++ ) \ + { \ + if( p_mb->i_coded_block_pattern & (1 << (5 - i)) ) \ + { \ + /* \ + * Inverse DCT (ISO/IEC 13818-2 section Annex A) \ + */ \ + p_idct->pf_idct( p_vdec->p_idct_data, p_idct->pi_block, \ + p_idct->i_sparse_pos ); \ + \ + /* \ + * Adding prediction and coefficient data (ISO/IEC \ + * 13818-2 section 7.6.8) \ + */ \ + p_pool->pf_addblock( p_idct->pi_block, p_idct->p_dct_data, \ + i < 4 ? p_mb->i_lum_dct_stride : \ + p_mb->i_chrom_dct_stride ); \ + } \ + } \ + } \ + else \ + { \ + /* Intra macroblock */ \ + for( i = 0, p_idct = p_mb->p_idcts; i < 4 + 2 * B_COLOR; \ + i++, p_idct++ ) \ + { \ + p_idct->pf_idct( p_vdec->p_idct_data, p_idct->pi_block, \ + p_idct->i_sparse_pos ); \ + p_pool->pf_copyblock( p_idct->pi_block, p_idct->p_dct_data, \ + i < 4 ? p_mb->i_lum_dct_stride : \ + p_mb->i_chrom_dct_stride ); \ + } \ + } \ +} + +DECLARE_DECODEMB( vdec_DecodeMacroblockC, 1 ); +DECLARE_DECODEMB( vdec_DecodeMacroblockBW, 0 ); + +#undef DECLARE_DECODEMB + /***************************************************************************** * RunThread: video decoder thread ***************************************************************************** diff --git a/src/video_decoder/video_decoder.h b/src/video_decoder/video_decoder.h index b7b33e0355..e30dbf6bae 100644 --- a/src/video_decoder/video_decoder.h +++ b/src/video_decoder/video_decoder.h @@ -2,7 +2,7 @@ * video_decoder.h : video decoder thread ***************************************************************************** * Copyright (C) 1999, 2000 VideoLAN - * $Id: video_decoder.h,v 1.4 2001/07/18 14:21:00 massiot Exp $ + * $Id: video_decoder.h,v 1.5 2001/08/22 17:21:45 massiot Exp $ * * Authors: Christophe Massiot * @@ -24,18 +24,12 @@ /***************************************************************************** * Prototypes *****************************************************************************/ -struct vpar_thread_s; -struct macroblock_s; - -/* Thread management functions */ -void vdec_InitThread ( struct vdec_thread_s *p_vdec ); -void vdec_EndThread ( struct vdec_thread_s *p_vdec ); -void vdec_DecodeMacroblock ( struct vdec_thread_s *p_vdec, - struct macroblock_s *p_mb ); -void vdec_DecodeMacroblockC ( struct vdec_thread_s *p_vdec, - struct macroblock_s *p_mb ); -void vdec_DecodeMacroblockBW ( struct vdec_thread_s *p_vdec, - struct macroblock_s *p_mb ); +void vdec_InitThread ( struct vdec_thread_s * ); +void vdec_EndThread ( struct vdec_thread_s * ); +void vdec_DecodeMacroblockC ( struct vdec_thread_s *, + struct macroblock_s * ); +void vdec_DecodeMacroblockBW ( struct vdec_thread_s *, + struct macroblock_s * ); struct vdec_thread_s * vdec_CreateThread( struct vdec_pool_s * ); -void vdec_DestroyThread ( struct vdec_thread_s *p_vdec ); +void vdec_DestroyThread ( struct vdec_thread_s * ); diff --git a/src/video_decoder/video_parser.c b/src/video_decoder/video_parser.c index e74239add7..e843960a5a 100644 --- a/src/video_decoder/video_parser.c +++ b/src/video_decoder/video_parser.c @@ -2,7 +2,7 @@ * video_parser.c : video parser thread ***************************************************************************** * Copyright (C) 1999, 2000 VideoLAN - * $Id: video_parser.c,v 1.3 2001/07/18 14:21:00 massiot Exp $ + * $Id: video_parser.c,v 1.4 2001/08/22 17:21:45 massiot Exp $ * * Authors: Christophe Massiot * Samuel Hocevar @@ -134,58 +134,9 @@ static int InitThread( vpar_thread_t *p_vpar ) return( 0 ); } -#define M ( p_vpar->pppf_motion ) -#define S ( p_vpar->ppf_motion_skipped ) -#define F ( p_vpar->p_motion_module->p_functions->motion.functions.motion ) - M[0][0][0] = M[0][0][1] = M[0][0][2] = M[0][0][3] = NULL; - M[0][1][0] = M[0][1][1] = M[0][1][2] = M[0][1][3] = NULL; - M[1][0][0] = NULL; - M[1][1][0] = NULL; - M[2][0][0] = NULL; - M[2][1][0] = NULL; - M[3][0][0] = NULL; - M[3][1][0] = NULL; - - M[1][0][1] = F.pf_field_field_420; - M[1][1][1] = F.pf_frame_field_420; - M[2][0][1] = F.pf_field_field_422; - M[2][1][1] = F.pf_frame_field_422; - M[3][0][1] = F.pf_field_field_444; - M[3][1][1] = F.pf_frame_field_444; - - M[1][0][2] = F.pf_field_16x8_420; - M[1][1][2] = F.pf_frame_frame_420; - M[2][0][2] = F.pf_field_16x8_422; - M[2][1][2] = F.pf_frame_frame_422; - M[3][0][2] = F.pf_field_16x8_444; - M[3][1][2] = F.pf_frame_frame_444; - - M[1][0][3] = F.pf_field_dmv_420; - M[1][1][3] = F.pf_frame_dmv_420; - M[2][0][3] = F.pf_field_dmv_422; - M[2][1][3] = F.pf_frame_dmv_422; - M[3][0][3] = F.pf_field_dmv_444; - M[3][1][3] = F.pf_frame_dmv_444; - - S[0][0] = S[0][1] = S[0][2] = S[0][3] = NULL; - S[1][0] = NULL; - S[2][0] = NULL; - S[3][0] = NULL; - - S[1][1] = F.pf_field_field_420; - S[2][1] = F.pf_field_field_422; - S[3][1] = F.pf_field_field_444; - - S[1][2] = F.pf_field_field_420; - S[2][2] = F.pf_field_field_422; - S[3][2] = F.pf_field_field_444; - - S[1][3] = F.pf_frame_frame_420; - S[2][3] = F.pf_frame_frame_422; - S[3][3] = F.pf_frame_frame_444; -#undef F -#undef S -#undef M +#define f ( p_vpar->p_motion_module->p_functions->motion.functions.motion ) + memcpy( p_vpar->pool.ppppf_motion, f.ppppf_motion, sizeof(void *) * 16 ); +#undef f /* * Choose the best IDCT module @@ -201,13 +152,13 @@ static int InitThread( vpar_thread_t *p_vpar ) } #define f p_vpar->p_idct_module->p_functions->idct.functions.idct - p_vpar->pool.pf_idct_init = f.pf_idct_init; - p_vpar->pf_sparse_idct = f.pf_sparse_idct; - p_vpar->pf_idct = f.pf_idct; - p_vpar->pf_norm_scan = f.pf_norm_scan; - p_vpar->pool.pf_decode_init = f.pf_decode_init; - p_vpar->pf_decode_mb_c = f.pf_decode_mb_c; - p_vpar->pf_decode_mb_bw = f.pf_decode_mb_bw; + p_vpar->pool.pf_idct_init = f.pf_idct_init; + p_vpar->pf_sparse_idct = f.pf_sparse_idct; + p_vpar->pf_idct = f.pf_idct; + p_vpar->pf_norm_scan = f.pf_norm_scan; + p_vpar->pool.pf_decode_init = f.pf_decode_init; + p_vpar->pool.pf_addblock = f.pf_addblock; + p_vpar->pool.pf_copyblock = f.pf_copyblock; #undef f /* Initialize input bitstream */ @@ -244,13 +195,6 @@ static int InitThread( vpar_thread_t *p_vpar ) memset(p_vpar->pc_malformed_pictures, 0, sizeof(p_vpar->pc_malformed_pictures)); #endif - - /* Initialize lookup tables */ - vpar_InitMbAddrInc( p_vpar ); - vpar_InitDCTTables( p_vpar ); - vpar_InitPMBType( p_vpar ); - vpar_InitBMBType( p_vpar ); - vpar_InitDCTTables( p_vpar ); vpar_InitScanTable( p_vpar ); /* diff --git a/src/video_decoder/video_parser.h b/src/video_decoder/video_parser.h index 1def8f68df..be23b69189 100644 --- a/src/video_decoder/video_parser.h +++ b/src/video_decoder/video_parser.h @@ -2,7 +2,7 @@ * video_parser.h : video parser thread ***************************************************************************** * Copyright (C) 1999, 2000 VideoLAN - * $Id: video_parser.h,v 1.11 2001/07/18 14:21:00 massiot Exp $ + * $Id: video_parser.h,v 1.12 2001/08/22 17:21:45 massiot Exp $ * * Authors: Christophe Massiot * Jean-Marc Dressler @@ -30,60 +30,25 @@ /***************************************************************************** * macroblock_parsing_t : macroblock context & predictors *****************************************************************************/ -typedef struct +typedef struct motion_s { - unsigned char i_quantizer_scale; /* scale of the quantization - * matrices */ - int pi_dc_dct_pred[3]; /* ISO/IEC 13818-2 7.2.1 */ - int pppi_pmv[2][2][2]; /* Motion vect predictors, 7.6.3 */ - int i_motion_dir;/* Used for the next skipped macroblock */ - - /* Context used to optimize block parsing */ - int i_motion_type, i_mv_count, i_mv_format; - boolean_t b_dmv, b_dct_type; - - /* Coordinates of the upper-left pixel of the macroblock, in lum and - * chroma */ - int i_l_x, i_l_y, i_c_x, i_c_y; -} macroblock_parsing_t; - -/***************************************************************************** - * lookup_t : entry type for lookup tables * - *****************************************************************************/ -typedef struct lookup_s -{ - int i_value; - int i_length; -} lookup_t; + u8 * pppi_ref[2][3]; + int ppi_pmv[2][2]; + int pi_f_code[2]; +} motion_t; -/***************************************************************************** - * ac_lookup_t : special entry type for lookup tables about ac coefficients - *****************************************************************************/ -typedef struct dct_lookup_s +typedef struct macroblock_parsing_s { - char i_run; - char i_level; - char i_length; -} dct_lookup_t; - -/***************************************************************************** - * Standard codes - *****************************************************************************/ - -/* Macroblock Address Increment types */ -#define MB_ADDRINC_ESCAPE 8 -#define MB_ADDRINC_STUFFING 15 - -/* Error constant for lookup tables */ -#define MB_ERROR (-1) + int i_offset; -/* Scan */ -#define SCAN_ZIGZAG 0 -#define SCAN_ALT 1 + motion_t b_motion; + motion_t f_motion; -/* Constant for block decoding */ -#define DCT_EOB 64 -#define DCT_ESCAPE 65 + /* Predictor for DC coefficients in intra blocks */ + u16 pi_dc_dct_pred[3]; + u8 i_quantizer_scale; /* scale of the quantization + * matrices */ +} macroblock_parsing_t; /***************************************************************************** * Constants @@ -95,18 +60,11 @@ extern u8 pi_scan[2][64]; /***************************************************************************** * Prototypes *****************************************************************************/ -void vpar_InitCrop( struct vpar_thread_s* p_vpar ); -void vpar_InitMbAddrInc( struct vpar_thread_s * p_vpar ); -void vpar_InitPMBType( struct vpar_thread_s * p_vpar ); -void vpar_InitBMBType( struct vpar_thread_s * p_vpar ); -void vpar_InitCodedPattern( struct vpar_thread_s * p_vpar ); -void vpar_InitDCTTables( struct vpar_thread_s * p_vpar ); void vpar_InitScanTable( struct vpar_thread_s * p_vpar ); -typedef void (*f_picture_data_t)( struct vpar_thread_s * p_vpar, - int i_mb_base ); +typedef void (*f_picture_data_t)( struct vpar_thread_s * p_vpar ); #define PROTO_PICD( FUNCNAME ) \ -void FUNCNAME( struct vpar_thread_s * p_vpar, int i_mb_base ); +void FUNCNAME( struct vpar_thread_s * p_vpar ); PROTO_PICD( vpar_PictureDataGENERIC ) #if (VPAR_OPTIM_LEVEL > 0) @@ -157,25 +115,15 @@ typedef struct sequence_s /* the same, in macroblock units */ unsigned int i_aspect_ratio; /* height/width display ratio */ unsigned int i_matrix_coefficients;/* coeffs of the YUV transform */ + int i_chroma_format, i_scalable_mode; int i_frame_rate; /* theoritical frame rate in fps*1001 */ boolean_t b_mpeg2; /* guess */ boolean_t b_progressive; /* progressive (ie. * non-interlaced) frame */ - unsigned int i_scalable_mode; /* scalability ; unsupported, but - * modifies the syntax of the binary - * stream. */ quant_matrix_t intra_quant, nonintra_quant; quant_matrix_t chroma_intra_quant, chroma_nonintra_quant; /* current quantization matrices */ - /* Chromatic information */ - unsigned int i_chroma_format; /* see CHROMA_* below */ - int i_chroma_nb_blocks; /* number of chroma blocks */ - u32 i_chroma_width;/* width of a line of the chroma comp */ - u32 i_chroma_mb_width, i_chroma_mb_height; - /* size of a macroblock in the chroma buffer - * (eg. 8x8 or 8x16 or 16x16) */ - /* Parser context */ picture_t * p_forward; /* current forward reference frame */ picture_t * p_backward; /* current backward reference frame */ @@ -200,31 +148,26 @@ typedef struct sequence_s *****************************************************************************/ typedef struct picture_parsing_s { - /* ISO/CEI 11172-2 backward compatibility */ - boolean_t pb_full_pel_vector[2]; - int i_forward_f_code, i_backward_f_code; - - /* Values from the picture_coding_extension. Please refer to ISO/IEC - * 13818-2. */ + /* Values from the picture_coding_extension. */ int ppi_f_code[2][2]; int i_intra_dc_precision; boolean_t b_frame_pred_frame_dct, b_q_scale_type; boolean_t b_intra_vlc_format; - boolean_t b_alternate_scan, b_progressive; + boolean_t b_progressive; + u8 * pi_scan; boolean_t b_top_field_first, b_concealment_mv; boolean_t b_repeat_first_field; /* Relative to the current field */ int i_coding_type, i_structure; boolean_t b_frame_structure; /* i_structure == FRAME_STRUCTURE */ + boolean_t b_current_field; /* i_structure == TOP_FIELD */ + boolean_t b_second_field; picture_t * p_picture; /* picture buffer from vout */ int i_current_structure; /* current parsed structure of * p_picture (second field ?) */ + int i_field_width; boolean_t b_error; /* parsing error, try to recover */ - - int i_l_stride, i_c_stride; - /* number of coeffs to jump when changing - * lines (different with field pictures) */ } picture_parsing_t; /***************************************************************************** @@ -270,6 +213,11 @@ typedef struct picture_parsing_s #define D_CODING_TYPE 4 /* MPEG-1 ONLY */ /* other values are reserved */ +/* Structures */ +#define TOP_FIELD 1 +#define BOTTOM_FIELD 2 +#define FRAME_STRUCTURE 3 + /***************************************************************************** * Prototypes *****************************************************************************/ @@ -373,19 +321,6 @@ typedef struct vpar_thread_s macroblock_parsing_t mb; video_synchro_t synchro; - /* - * Lookup tables - */ - /* table for macroblock address increment */ - lookup_t pl_mb_addr_inc[2048]; - /* tables for macroblock types 0=P 1=B */ - lookup_t ppl_mb_type[2][64]; - /* table for coded_block_pattern */ - lookup_t * pl_coded_pattern; - /* variable length codes for the structure dct_dc_size for intra blocks */ - lookup_t * pppl_dct_dc_size[2][2]; - /* Structure to store the tables B14 & B15 (ISO/IEC 13818-2 B.4) */ - dct_lookup_t ppl_dct_coef[2][16384]; /* Scan table */ u8 ppi_scan[2][64]; /* Default quantization matrices */ @@ -394,16 +329,12 @@ typedef struct vpar_thread_s /* Motion compensation plug-in used and shortcuts */ struct module_s * p_motion_module; - void ( * pppf_motion[4][2][4] ) ( struct macroblock_s * ); - void ( * ppf_motion_skipped[4][4] ) ( struct macroblock_s * ); /* IDCT plugin used and shortcuts */ - struct module_s * p_idct_module; + struct module_s * p_idct_module; void ( * pf_sparse_idct ) ( void *, dctelem_t*, int ); void ( * pf_idct ) ( void *, dctelem_t*, int ); void ( * pf_norm_scan ) ( u8 ppi_scan[2][64] ); - void ( * pf_decode_mb_c ) ( struct vdec_thread_s *, struct macroblock_s * ); - void ( * pf_decode_mb_bw )( struct vdec_thread_s *, struct macroblock_s * ); #ifdef STATS /* Statistics */ @@ -417,13 +348,6 @@ typedef struct vpar_thread_s #endif } vpar_thread_t; -/***************************************************************************** - * Prototypes - *****************************************************************************/ - -/* Thread management functions - temporary ! */ -vlc_thread_t vpar_CreateThread ( vdec_config_t * ); - /***************************************************************************** * NextStartCode : Find the next start code *****************************************************************************/ @@ -447,29 +371,21 @@ static __inline__ void NextStartCode( bit_stream_t * p_bit_stream ) static __inline__ void LoadQuantizerScale( struct vpar_thread_s * p_vpar ) { /* Quantization coefficient table */ - static u8 ppi_quantizer_scale[3][32] = + static u8 pi_non_linear_quantizer_scale[32] = { - /* MPEG-2 */ - { - /* q_scale_type */ - /* linear */ - 0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30, - 32,34,36,38,40,42,44,46,48,50,52,54,56,58,60,62 - }, - { - /* non-linear */ - 0, 1, 2, 3, 4, 5, 6, 7, 8, 10,12,14,16,18,20, 22, - 24,28,32,36,40,44,48,52,56,64,72,80,88,96,104,112 - }, - /* MPEG-1 */ - { - 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, - 16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31 - } + 0, 1, 2, 3, 4, 5, 6, 7, 8, 10,12,14,16,18,20, 22, + 24,28,32,36,40,44,48,52,56,64,72,80,88,96,104,112 }; + int i_q_scale_code = GetBits( &p_vpar->bit_stream, 5 ); - p_vpar->mb.i_quantizer_scale = ppi_quantizer_scale - [(!p_vpar->sequence.b_mpeg2 << 1) | p_vpar->picture.b_q_scale_type] - [GetBits( &p_vpar->bit_stream, 5 )]; + if( p_vpar->picture.b_q_scale_type ) + { + p_vpar->mb.i_quantizer_scale = + pi_non_linear_quantizer_scale[i_q_scale_code]; + } + else + { + p_vpar->mb.i_quantizer_scale = i_q_scale_code << 1; + } } diff --git a/src/video_decoder/vpar_blocks.c b/src/video_decoder/vpar_blocks.c index 7c0f81e319..2c92f8b9a1 100644 --- a/src/video_decoder/vpar_blocks.c +++ b/src/video_decoder/vpar_blocks.c @@ -2,11 +2,11 @@ * vpar_blocks.c : blocks parsing ***************************************************************************** * Copyright (C) 1999, 2000 VideoLAN - * $Id: vpar_blocks.c,v 1.5 2001/07/27 09:17:38 massiot Exp $ + * $Id: vpar_blocks.c,v 1.6 2001/08/22 17:21:45 massiot Exp $ * - * Authors: Christophe Massiot - * Jean-Marc Dressler - * Stéphane Borel + * Authors: Michel Lespinasse + * Aaron Holtzman + * Christophe Massiot * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -47,10 +47,11 @@ #include "vpar_pool.h" #include "video_parser.h" +#include "vpar_blocks.h" + /* * Welcome to vpar_blocks.c ! Here's where the heavy processor-critical parsing * task is done. This file is divided in several parts : - * - Initialization of the lookup tables * - Decoding of coded blocks * - Decoding of motion vectors * - Decoding of the other macroblock structures @@ -59,1150 +60,1003 @@ */ -/* - * Initialization tables - */ +/***************************************************************************** + * vpar_InitScanTable : Initialize scan table + *****************************************************************************/ +void vpar_InitScanTable( vpar_thread_t * p_vpar ) +{ + int i; - /* Table for coded_block_pattern resolution */ -static lookup_t pl_coded_pattern[512] = - { {MB_ERROR, 0}, {0, 9}, {39, 9}, {27, 9}, {59, 9}, {55, 9}, {47, 9}, {31, 9}, - {58, 8}, {58, 8}, {54, 8}, {54, 8}, {46, 8}, {46, 8}, {30, 8}, {30, 8}, - {57, 8}, {57, 8}, {53, 8}, {53, 8}, {45, 8}, {45, 8}, {29, 8}, {29, 8}, - {38, 8}, {38, 8}, {26, 8}, {26, 8}, {37, 8}, {37, 8}, {25, 8}, {25, 8}, - {43, 8}, {43, 8}, {23, 8}, {23, 8}, {51, 8}, {51, 8}, {15, 8}, {15, 8}, - {42, 8}, {42, 8}, {22, 8}, {22, 8}, {50, 8}, {50, 8}, {14, 8}, {14, 8}, - {41, 8}, {41, 8}, {21, 8}, {21, 8}, {49, 8}, {49, 8}, {13, 8}, {13, 8}, - {35, 8}, {35, 8}, {19, 8}, {19, 8}, {11, 8}, {11, 8}, {7, 8}, {7, 8}, - {34, 7}, {34, 7}, {34, 7}, {34, 7}, {18, 7}, {18, 7}, {18, 7}, {18, 7}, - {10, 7}, {10, 7}, {10, 7}, {10, 7}, {6, 7}, {6, 7}, {6, 7}, {6, 7}, - {33, 7}, {33, 7}, {33, 7}, {33, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, - {9, 7}, {9, 7}, {9, 7}, {9, 7}, {5, 7}, {5, 7}, {5, 7}, {5, 7}, - {63, 6}, {63, 6}, {63, 6}, {63, 6}, {63, 6}, {63, 6}, {63, 6}, {63, 6}, - {3, 6}, {3, 6}, {3, 6}, {3, 6}, {3, 6}, {3, 6}, {3, 6}, {3, 6}, - {36, 6}, {36, 6}, {36, 6}, {36, 6}, {36, 6}, {36, 6}, {36, 6}, {36, 6}, - {24, 6}, {24, 6}, {24, 6}, {24, 6}, {24, 6}, {24, 6}, {24, 6}, {24, 6}, - {62, 5}, {62, 5}, {62, 5}, {62, 5}, {62, 5}, {62, 5}, {62, 5}, {62, 5}, - {62, 5}, {62, 5}, {62, 5}, {62, 5}, {62, 5}, {62, 5}, {62, 5}, {62, 5}, - {2, 5}, {2, 5}, {2, 5}, {2, 5}, {2, 5}, {2, 5}, {2, 5}, {2, 5}, - {2, 5}, {2, 5}, {2, 5}, {2, 5}, {2, 5}, {2, 5}, {2, 5}, {2, 5}, - {61, 5}, {61, 5}, {61, 5}, {61, 5}, {61, 5}, {61, 5}, {61, 5}, {61, 5}, - {61, 5}, {61, 5}, {61, 5}, {61, 5}, {61, 5}, {61, 5}, {61, 5}, {61, 5}, - {1, 5}, {1, 5}, {1, 5}, {1, 5}, {1, 5}, {1, 5}, {1, 5}, {1, 5}, - {1, 5}, {1, 5}, {1, 5}, {1, 5}, {1, 5}, {1, 5}, {1, 5}, {1, 5}, - {56, 5}, {56, 5}, {56, 5}, {56, 5}, {56, 5}, {56, 5}, {56, 5}, {56, 5}, - {56, 5}, {56, 5}, {56, 5}, {56, 5}, {56, 5}, {56, 5}, {56, 5}, {56, 5}, - {52, 5}, {52, 5}, {52, 5}, {52, 5}, {52, 5}, {52, 5}, {52, 5}, {52, 5}, - {52, 5}, {52, 5}, {52, 5}, {52, 5}, {52, 5}, {52, 5}, {52, 5}, {52, 5}, - {44, 5}, {44, 5}, {44, 5}, {44, 5}, {44, 5}, {44, 5}, {44, 5}, {44, 5}, - {44, 5}, {44, 5}, {44, 5}, {44, 5}, {44, 5}, {44, 5}, {44, 5}, {44, 5}, - {28, 5}, {28, 5}, {28, 5}, {28, 5}, {28, 5}, {28, 5}, {28, 5}, {28, 5}, - {28, 5}, {28, 5}, {28, 5}, {28, 5}, {28, 5}, {28, 5}, {28, 5}, {28, 5}, - {40, 5}, {40, 5}, {40, 5}, {40, 5}, {40, 5}, {40, 5}, {40, 5}, {40, 5}, - {40, 5}, {40, 5}, {40, 5}, {40, 5}, {40, 5}, {40, 5}, {40, 5}, {40, 5}, - {20, 5}, {20, 5}, {20, 5}, {20, 5}, {20, 5}, {20, 5}, {20, 5}, {20, 5}, - {20, 5}, {20, 5}, {20, 5}, {20, 5}, {20, 5}, {20, 5}, {20, 5}, {20, 5}, - {48, 5}, {48, 5}, {48, 5}, {48, 5}, {48, 5}, {48, 5}, {48, 5}, {48, 5}, - {48, 5}, {48, 5}, {48, 5}, {48, 5}, {48, 5}, {48, 5}, {48, 5}, {48, 5}, - {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, - {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, - {32, 4}, {32, 4}, {32, 4}, {32, 4}, {32, 4}, {32, 4}, {32, 4}, {32, 4}, - {32, 4}, {32, 4}, {32, 4}, {32, 4}, {32, 4}, {32, 4}, {32, 4}, {32, 4}, - {32, 4}, {32, 4}, {32, 4}, {32, 4}, {32, 4}, {32, 4}, {32, 4}, {32, 4}, - {32, 4}, {32, 4}, {32, 4}, {32, 4}, {32, 4}, {32, 4}, {32, 4}, {32, 4}, - {16, 4}, {16, 4}, {16, 4}, {16, 4}, {16, 4}, {16, 4}, {16, 4}, {16, 4}, - {16, 4}, {16, 4}, {16, 4}, {16, 4}, {16, 4}, {16, 4}, {16, 4}, {16, 4}, - {16, 4}, {16, 4}, {16, 4}, {16, 4}, {16, 4}, {16, 4}, {16, 4}, {16, 4}, - {16, 4}, {16, 4}, {16, 4}, {16, 4}, {16, 4}, {16, 4}, {16, 4}, {16, 4}, - {8, 4}, {8, 4}, {8, 4}, {8, 4}, {8, 4}, {8, 4}, {8, 4}, {8, 4}, - {8, 4}, {8, 4}, {8, 4}, {8, 4}, {8, 4}, {8, 4}, {8, 4}, {8, 4}, - {8, 4}, {8, 4}, {8, 4}, {8, 4}, {8, 4}, {8, 4}, {8, 4}, {8, 4}, - {8, 4}, {8, 4}, {8, 4}, {8, 4}, {8, 4}, {8, 4}, {8, 4}, {8, 4}, - {4, 4}, {4, 4}, {4, 4}, {4, 4}, {4, 4}, {4, 4}, {4, 4}, {4, 4}, - {4, 4}, {4, 4}, {4, 4}, {4, 4}, {4, 4}, {4, 4}, {4, 4}, {4, 4}, - {4, 4}, {4, 4}, {4, 4}, {4, 4}, {4, 4}, {4, 4}, {4, 4}, {4, 4}, - {4, 4}, {4, 4}, {4, 4}, {4, 4}, {4, 4}, {4, 4}, {4, 4}, {4, 4}, - {60, 3}, {60, 3}, {60, 3}, {60, 3}, {60, 3}, {60, 3}, {60, 3}, {60, 3}, - {60, 3}, {60, 3}, {60, 3}, {60, 3}, {60, 3}, {60, 3}, {60, 3}, {60, 3}, - {60, 3}, {60, 3}, {60, 3}, {60, 3}, {60, 3}, {60, 3}, {60, 3}, {60, 3}, - {60, 3}, {60, 3}, {60, 3}, {60, 3}, {60, 3}, {60, 3}, {60, 3}, {60, 3}, - {60, 3}, {60, 3}, {60, 3}, {60, 3}, {60, 3}, {60, 3}, {60, 3}, {60, 3}, - {60, 3}, {60, 3}, {60, 3}, {60, 3}, {60, 3}, {60, 3}, {60, 3}, {60, 3}, - {60, 3}, {60, 3}, {60, 3}, {60, 3}, {60, 3}, {60, 3}, {60, 3}, {60, 3}, - {60, 3}, {60, 3}, {60, 3}, {60, 3}, {60, 3}, {60, 3}, {60, 3}, {60, 3} }; - - /* Tables for dc DCT coefficients - * Tables are cut in two parts to reduce memory occupation - */ - - /* Table B-12, dct_dc_size_luminance, codes 00XXX ... 11110 */ - -static lookup_t pl_dct_dc_lum_init_table_1[32] = - { {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, - {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, - {0, 3}, {0, 3}, {0, 3}, {0, 3}, {3, 3}, {3, 3}, {3, 3}, {3, 3}, - {4, 3}, {4, 3}, {4, 3}, {4, 3}, {5, 4}, {5, 4}, {6, 5}, {MB_ERROR, 0} - }; - -static lookup_t ppl_dct_dc_init_table_1[2][32] = -{ { {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, - {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, - {0, 3}, {0, 3}, {0, 3}, {0, 3}, {3, 3}, {3, 3}, {3, 3}, {3, 3}, - {4, 3}, {4, 3}, {4, 3}, {4, 3}, {5, 4}, {5, 4}, {6, 5}, {MB_ERROR, 0}}, -{ {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, - {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, - {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, - {3, 3}, {3, 3}, {3, 3}, {3, 3}, {4, 4}, {4, 4}, {5, 5}, {MB_ERROR, 0} - } - }; - - /* Table B-12, dct_dc_size_luminance, codes 111110xxx ... 111111111 */ - -static lookup_t pl_dct_dc_lum_init_table_2[32] = - { {7, 6}, {7, 6}, {7, 6}, {7, 6}, {7, 6}, {7, 6}, {7, 6}, {7, 6}, - {8, 7}, {8, 7}, {8, 7}, {8, 7}, {9, 8}, {9, 8}, {10,9}, {11,9}, - {MB_ERROR, 0}, {MB_ERROR, 0}, {MB_ERROR, 0}, {MB_ERROR, 0}, - {MB_ERROR, 0}, {MB_ERROR, 0}, {MB_ERROR, 0}, {MB_ERROR, 0}, - {MB_ERROR, 0}, {MB_ERROR, 0}, {MB_ERROR, 0}, {MB_ERROR, 0}, - {MB_ERROR, 0}, {MB_ERROR, 0}, {MB_ERROR, 0}, {MB_ERROR, 0} - }; - -static lookup_t ppl_dct_dc_init_table_2[2][32] = -{ { {7, 6}, {7, 6}, {7, 6}, {7, 6}, {7, 6}, {7, 6}, {7, 6}, {7, 6}, - {8, 7}, {8, 7}, {8, 7}, {8, 7}, {9, 8}, {9, 8}, {10,9}, {11,9}, - {MB_ERROR, 0}, {MB_ERROR, 0}, {MB_ERROR, 0}, {MB_ERROR, 0}, - {MB_ERROR, 0}, {MB_ERROR, 0}, {MB_ERROR, 0}, {MB_ERROR, 0}, - {MB_ERROR, 0}, {MB_ERROR, 0}, {MB_ERROR, 0}, {MB_ERROR, 0}, - {MB_ERROR, 0}, {MB_ERROR, 0}, {MB_ERROR, 0}, {MB_ERROR, 0}}, - { {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, - {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, - {7, 7}, {7, 7}, {7, 7}, {7, 7}, {7, 7}, {7, 7}, {7, 7}, {7, 7}, - {8, 8}, {8, 8}, {8, 8}, {8, 8}, {9, 9}, {9, 9}, {10,10}, {11,10} - } - }; - - /* Table B-13, dct_dc_size_chrominance, codes 00xxx ... 11110 */ -static lookup_t pl_dct_dc_chrom_init_table_1[32] = - { {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, - {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, - {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, - {3, 3}, {3, 3}, {3, 3}, {3, 3}, {4, 4}, {4, 4}, {5, 5}, {MB_ERROR, 0} - }; - + memcpy( p_vpar->ppi_scan, pi_scan, sizeof(pi_scan) ); + p_vpar->pf_norm_scan( p_vpar->ppi_scan ); - /* Table B-13, dct_dc_size_chrominance, codes 111110xxxx ... 1111111111 */ -static lookup_t pl_dct_dc_chrom_init_table_2[32] = - { {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, - {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, - {7, 7}, {7, 7}, {7, 7}, {7, 7}, {7, 7}, {7, 7}, {7, 7}, {7, 7}, - {8, 8}, {8, 8}, {8, 8}, {8, 8}, {9, 9}, {9, 9}, {10,10}, {11,10} - }; - - - /* Tables for ac DCT coefficients. There are cut in many parts to - * save space */ - /* Table B-14, DCT coefficients table zero, - * codes 0100 ... 1xxx (used for first (DC) coefficient) - */ -static dct_lookup_t pl_DCT_tab_dc[12] = - { - {0,2,4}, {2,1,4}, {1,1,3}, {1,1,3}, - {0,1,1}, {0,1,1}, {0,1,1}, {0,1,1}, - {0,1,1}, {0,1,1}, {0,1,1}, {0,1,1} - }; - - /* Table B-14, DCT coefficients table zero, - * codes 0100 ... 1xxx (used for all other coefficients) - */ -static dct_lookup_t pl_DCT_tab_ac[12] = - { - {0,2,4}, {2,1,4}, {1,1,3}, {1,1,3}, - {DCT_EOB,0,2}, {DCT_EOB,0,2}, {DCT_EOB,0,2}, {DCT_EOB,0,2}, /* EOB */ - {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2} - }; - - /* Table B-14, DCT coefficients table zero, - * codes 000001xx ... 00111xxx - */ -static dct_lookup_t pl_DCT_tab0[60] = - { - {DCT_ESCAPE,0,6}, {DCT_ESCAPE,0,6}, {DCT_ESCAPE,0,6}, {DCT_ESCAPE,0,6}, - /* Escape */ - {2,2,7}, {2,2,7}, {9,1,7}, {9,1,7}, - {0,4,7}, {0,4,7}, {8,1,7}, {8,1,7}, - {7,1,6}, {7,1,6}, {7,1,6}, {7,1,6}, - {6,1,6}, {6,1,6}, {6,1,6}, {6,1,6}, - {1,2,6}, {1,2,6}, {1,2,6}, {1,2,6}, - {5,1,6}, {5,1,6}, {5,1,6}, {5,1,6}, - {13,1,8}, {0,6,8}, {12,1,8}, {11,1,8}, - {3,2,8}, {1,3,8}, {0,5,8}, {10,1,8}, - {0,3,5}, {0,3,5}, {0,3,5}, {0,3,5}, - {0,3,5}, {0,3,5}, {0,3,5}, {0,3,5}, - {4,1,5}, {4,1,5}, {4,1,5}, {4,1,5}, - {4,1,5}, {4,1,5}, {4,1,5}, {4,1,5}, - {3,1,5}, {3,1,5}, {3,1,5}, {3,1,5}, - {3,1,5}, {3,1,5}, {3,1,5}, {3,1,5} - }; - - /* Table B-15, DCT coefficients table one, - * codes 000001xx ... 11111111 - */ -static dct_lookup_t pl_DCT_tab0a[252] = - { - {65,0,6}, {65,0,6}, {65,0,6}, {65,0,6}, /* Escape */ - {7,1,7}, {7,1,7}, {8,1,7}, {8,1,7}, - {6,1,7}, {6,1,7}, {2,2,7}, {2,2,7}, - {0,7,6}, {0,7,6}, {0,7,6}, {0,7,6}, - {0,6,6}, {0,6,6}, {0,6,6}, {0,6,6}, - {4,1,6}, {4,1,6}, {4,1,6}, {4,1,6}, - {5,1,6}, {5,1,6}, {5,1,6}, {5,1,6}, - {1,5,8}, {11,1,8}, {0,11,8}, {0,10,8}, - {13,1,8}, {12,1,8}, {3,2,8}, {1,4,8}, - {2,1,5}, {2,1,5}, {2,1,5}, {2,1,5}, - {2,1,5}, {2,1,5}, {2,1,5}, {2,1,5}, - {1,2,5}, {1,2,5}, {1,2,5}, {1,2,5}, - {1,2,5}, {1,2,5}, {1,2,5}, {1,2,5}, - {3,1,5}, {3,1,5}, {3,1,5}, {3,1,5}, - {3,1,5}, {3,1,5}, {3,1,5}, {3,1,5}, - {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3}, - {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3}, - {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3}, - {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3}, - {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3}, - {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3}, - {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3}, - {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3}, - {64,0,4}, {64,0,4}, {64,0,4}, {64,0,4}, /* EOB */ - {64,0,4}, {64,0,4}, {64,0,4}, {64,0,4}, - {64,0,4}, {64,0,4}, {64,0,4}, {64,0,4}, - {64,0,4}, {64,0,4}, {64,0,4}, {64,0,4}, - {0,3,4}, {0,3,4}, {0,3,4}, {0,3,4}, - {0,3,4}, {0,3,4}, {0,3,4}, {0,3,4}, - {0,3,4}, {0,3,4}, {0,3,4}, {0,3,4}, - {0,3,4}, {0,3,4}, {0,3,4}, {0,3,4}, - {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, - {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, - {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, - {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, - {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, - {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, - {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, - {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, - {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, - {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, - {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, - {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, - {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, - {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, - {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, - {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, - {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3}, - {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3}, - {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3}, - {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3}, - {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3}, - {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3}, - {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3}, - {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3}, - {0,4,5}, {0,4,5}, {0,4,5}, {0,4,5}, - {0,4,5}, {0,4,5}, {0,4,5}, {0,4,5}, - {0,5,5}, {0,5,5}, {0,5,5}, {0,5,5}, - {0,5,5}, {0,5,5}, {0,5,5}, {0,5,5}, - {9,1,7}, {9,1,7}, {1,3,7}, {1,3,7}, - {10,1,7}, {10,1,7}, {0,8,7}, {0,8,7}, - {0,9,7}, {0,9,7}, {0,12,8}, {0,13,8}, - {2,3,8}, {4,2,8}, {0,14,8}, {0,15,8} - }; - - /* Table B-14, DCT coefficients table zero, - * codes 0000001000 ... 0000001111 - */ -static dct_lookup_t pl_DCT_tab1[8] = - { - {16,1,10}, {5,2,10}, {0,7,10}, {2,3,10}, - {1,4,10}, {15,1,10}, {14,1,10}, {4,2,10} - }; - - /* Table B-15, DCT coefficients table one, - * codes 000000100x ... 000000111x - */ -static dct_lookup_t pl_DCT_tab1a[8] = - { - {5,2,9}, {5,2,9}, {14,1,9}, {14,1,9}, - {2,4,10}, {16,1,10}, {15,1,9}, {15,1,9} - }; - - /* Table B-14/15, DCT coefficients table zero / one, - * codes 000000010000 ... 000000011111 - */ -static dct_lookup_t pl_DCT_tab2[16] = - { - {0,11,12}, {8,2,12}, {4,3,12}, {0,10,12}, - {2,4,12}, {7,2,12}, {21,1,12}, {20,1,12}, - {0,9,12}, {19,1,12}, {18,1,12}, {1,5,12}, - {3,3,12}, {0,8,12}, {6,2,12}, {17,1,12} - }; - - /* Table B-14/15, DCT coefficients table zero / one, - * codes 0000000010000 ... 0000000011111 - */ -static dct_lookup_t pl_DCT_tab3[16] = - { - {10,2,13}, {9,2,13}, {5,3,13}, {3,4,13}, - {2,5,13}, {1,7,13}, {1,6,13}, {0,15,13}, - {0,14,13}, {0,13,13}, {0,12,13}, {26,1,13}, - {25,1,13}, {24,1,13}, {23,1,13}, {22,1,13} - }; - - /* Table B-14/15, DCT coefficients table zero / one, - * codes 00000000010000 ... 00000000011111 - */ -static dct_lookup_t pl_DCT_tab4[16] = - { - {0,31,14}, {0,30,14}, {0,29,14}, {0,28,14}, - {0,27,14}, {0,26,14}, {0,25,14}, {0,24,14}, - {0,23,14}, {0,22,14}, {0,21,14}, {0,20,14}, - {0,19,14}, {0,18,14}, {0,17,14}, {0,16,14} - }; - - /* Table B-14/15, DCT coefficients table zero / one, - * codes 000000000010000 ... 000000000011111 - */ -static dct_lookup_t pl_DCT_tab5[16] = - { - {0,40,15}, {0,39,15}, {0,38,15}, {0,37,15}, - {0,36,15}, {0,35,15}, {0,34,15}, {0,33,15}, - {0,32,15}, {1,14,15}, {1,13,15}, {1,12,15}, - {1,11,15}, {1,10,15}, {1,9,15}, {1,8,15} - }; - - /* Table B-14/15, DCT coefficients table zero / one, - * codes 0000000000010000 ... 0000000000011111 - */ -static dct_lookup_t pl_DCT_tab6[16] = + /* If scan table has changed, we must change the quantization matrices. */ + for( i = 0; i < 64; i++ ) { - {1,18,16}, {1,17,16}, {1,16,16}, {1,15,16}, - {6,3,16}, {16,2,16}, {15,2,16}, {14,2,16}, - {13,2,16}, {12,2,16}, {11,2,16}, {31,1,16}, - {30,1,16}, {29,1,16}, {28,1,16}, {27,1,16} - }; - - /* Pointers on tables of dct coefficients */ -static dct_lookup_t * ppl_dct_tab1[2] = { pl_DCT_tab_ac, pl_DCT_tab0a }; - -static dct_lookup_t * ppl_dct_tab2[2] = { pl_DCT_tab_ac, pl_DCT_tab_dc }; - -/* Replacement for memset( p_table, 0, 8*sizeof( int ) ); */ -static __inline__ void bzero8int( void *p_table ) -{ - ((int*)p_table)[0] = ((int*)p_table)[1] = - ((int*)p_table)[2] = ((int*)p_table)[3] = - ((int*)p_table)[4] = ((int*)p_table)[5] = - ((int*)p_table)[6] = ((int*)p_table)[7] = 0; + p_vpar->pi_default_intra_quant[ p_vpar->ppi_scan[0][i] ] = + pi_default_intra_quant[ pi_scan[0][i] ]; + p_vpar->pi_default_nonintra_quant[ p_vpar->ppi_scan[0][i] ] = + pi_default_nonintra_quant[ pi_scan[0][i] ]; + } } + /* - * Initialization of lookup tables + * Block parsing */ /***************************************************************************** - * vpar_InitMbAddrInc : Initialize the lookup table for mb_addr_inc + * GetLumaDCDiff : Get the luminance DC coefficient difference *****************************************************************************/ - -/* Function for filling up the lookup table for mb_addr_inc */ -static void FillMbAddrIncTable( vpar_thread_t * p_vpar, - int i_start, int i_end, int i_step, - int * pi_value, int i_length ) +static __inline__ int GetLumaDCDiff( vpar_thread_t * p_vpar ) { - int i_pos, i_offset; - for( i_pos = i_start ; i_pos < i_end ; i_pos += i_step ) + lookup_t * p_tab; + int i_size, i_dc_diff, i_code; + + if( (i_code = ShowBits( &p_vpar->bit_stream, 5 )) < 0x1F ) { - for( i_offset = 0 ; i_offset < i_step ; i_offset ++ ) + p_tab = DC_lum_5 + i_code; + i_size = p_tab->i_value; + if( i_size ) + { + RemoveBits( &p_vpar->bit_stream, p_tab->i_length ); + i_dc_diff = GetBits( &p_vpar->bit_stream, i_size ); + if ((i_dc_diff & (1 << (i_size - 1))) == 0) + { + i_dc_diff -= (1 << i_size) - 1; + } + return( i_dc_diff ); + } + else { - p_vpar->pl_mb_addr_inc[i_pos + i_offset].i_value = * pi_value; - p_vpar->pl_mb_addr_inc[i_pos + i_offset].i_length = i_length; + RemoveBits( &p_vpar->bit_stream, 3 ); + return 0; } - (*pi_value)--; } -} - -/* Function that initialize the table using the last one */ -void vpar_InitMbAddrInc( vpar_thread_t * p_vpar ) -{ - int i_dummy; - int i_value; - - for( i_dummy = 0 ; i_dummy < 8 ; i_dummy++ ) + else { - p_vpar->pl_mb_addr_inc[i_dummy].i_value = MB_ERROR; - p_vpar->pl_mb_addr_inc[i_dummy].i_length = 0; + p_tab = DC_long - 0x1e0 + ShowBits( &p_vpar->bit_stream, 9 ); + RemoveBits( &p_vpar->bit_stream, p_tab->i_length ); + i_size = p_tab->i_value; + i_dc_diff = GetBits( &p_vpar->bit_stream, i_size ); + if ((i_dc_diff & (1 << (i_size - 1))) == 0) + { + i_dc_diff -= (1 << i_size) - 1; + } + return( i_dc_diff ); } +} - p_vpar->pl_mb_addr_inc[8].i_value = MB_ADDRINC_ESCAPE; - p_vpar->pl_mb_addr_inc[8].i_length = 11; +/***************************************************************************** + * GetChromaDCDiff : Get the chrominance DC coefficient difference + *****************************************************************************/ +static __inline__ int GetChromaDCDiff( vpar_thread_t * p_vpar ) +{ + lookup_t * p_tab; + int i_size, i_dc_diff, i_code; - for( i_dummy = 9 ; i_dummy < 15 ; i_dummy ++ ) + if( (i_code = ShowBits( &p_vpar->bit_stream, 5 )) < 0x1F ) { - p_vpar->pl_mb_addr_inc[i_dummy].i_value = MB_ERROR; - p_vpar->pl_mb_addr_inc[i_dummy].i_length = 0; + p_tab = DC_chrom_5 + i_code; + i_size = p_tab->i_value; + if( i_size ) + { + RemoveBits( &p_vpar->bit_stream, p_tab->i_length ); + i_dc_diff = GetBits( &p_vpar->bit_stream, i_size ); + if ((i_dc_diff & (1 << (i_size - 1))) == 0) + { + i_dc_diff -= (1 << i_size) - 1; + } + return( i_dc_diff ); + } + else + { + RemoveBits( &p_vpar->bit_stream, 2 ); + return 0; + } } - - p_vpar->pl_mb_addr_inc[15].i_value = MB_ADDRINC_STUFFING; - p_vpar->pl_mb_addr_inc[15].i_length = 11; - - for( i_dummy = 16; i_dummy < 24; i_dummy++ ) + else { - p_vpar->pl_mb_addr_inc[i_dummy].i_value = MB_ERROR; - p_vpar->pl_mb_addr_inc[i_dummy].i_length = 0; + p_tab = DC_long - 0x3e0 + ShowBits( &p_vpar->bit_stream, 10 ); + RemoveBits( &p_vpar->bit_stream, p_tab->i_length + 1 ); + i_size = p_tab->i_value; + i_dc_diff = GetBits( &p_vpar->bit_stream, i_size ); + if ((i_dc_diff & (1 << (i_size - 1))) == 0) + { + i_dc_diff -= (1 << i_size) - 1; + } + return( i_dc_diff ); } +} - i_value = 33; - FillMbAddrIncTable( p_vpar, 24, 36, 1, &i_value, 11 ); - FillMbAddrIncTable( p_vpar, 36, 48, 2, &i_value, 10 ); - FillMbAddrIncTable( p_vpar, 48, 96, 8, &i_value, 8 ); - FillMbAddrIncTable( p_vpar, 96, 128, 16, &i_value, 7 ); - FillMbAddrIncTable( p_vpar, 128, 256, 64, &i_value, 5 ); - FillMbAddrIncTable( p_vpar, 256, 512, 128, &i_value, 4 ); - FillMbAddrIncTable( p_vpar, 512, 1024, 256, &i_value, 3 ); - FillMbAddrIncTable( p_vpar, 1024, 2048, 1024, &i_value, 1 ); -} +#define SATURATE(val) \ + if( val > 2047 ) \ + val = 2047; \ + else if( val < -2048 ) \ + val = -2048; /***************************************************************************** - * vpar_Init*MBType : Initialize lookup table for the Macroblock type + * MPEG2IntraB14 : Decode an intra block according to ISO/IEC 13818-2 table B14 *****************************************************************************/ - -/* Fonction for filling up the tables */ -static void FillMBType( vpar_thread_t * p_vpar, - int i_mb_type, - int i_start, - int i_end, - int i_value, - int i_length ) +static void MPEG2IntraB14( vpar_thread_t * p_vpar, idct_inner_t * p_idct ) { - int i_dummy; + int i_coeff, i_mismatch, i_code, i_pos, i_value, i_nc; + s32 i_sign; + dct_lookup_t * p_tab; - for( i_dummy = i_start ; i_dummy < i_end ; i_dummy++ ) - { - p_vpar->ppl_mb_type[i_mb_type][i_dummy].i_value = i_value; - p_vpar->ppl_mb_type[i_mb_type][i_dummy].i_length = i_length; - } -} + int i_q_scale = p_vpar->mb.i_quantizer_scale; + u8 * pi_quant = p_vpar->sequence.intra_quant.pi_matrix; + dctelem_t * p_dest = p_idct->pi_block; + u8 * p_scan = p_vpar->picture.pi_scan; -/* Fonction that fills the table for P MB_Type */ -void vpar_InitPMBType( vpar_thread_t * p_vpar ) -{ - FillMBType( p_vpar, 0, 32, 64, MB_MOTION_FORWARD|MB_PATTERN, 1 ); - FillMBType( p_vpar, 0, 16, 32, MB_PATTERN, 2 ); - FillMBType( p_vpar, 0, 8, 16, MB_MOTION_FORWARD, 3 ); - FillMBType( p_vpar, 0, 6, 8, MB_INTRA, 5 ); - FillMBType( p_vpar, 0, 4, 6, MB_QUANT|MB_MOTION_FORWARD|MB_PATTERN, 5 ); - FillMBType( p_vpar, 0, 2, 4, MB_QUANT|MB_PATTERN, 5 ); - p_vpar->ppl_mb_type[0][1].i_value = MB_QUANT|MB_INTRA; - p_vpar->ppl_mb_type[0][1].i_length = 6; - p_vpar->ppl_mb_type[0][0].i_value = MB_ERROR; - p_vpar->ppl_mb_type[0][0].i_length = 0; -} + i_coeff = 0; + i_mismatch = ~p_dest[0]; + i_nc = (p_dest[0] != 0); -/* Fonction that fills the table for B MB_Type */ -void vpar_InitBMBType( vpar_thread_t * p_vpar ) -{ - FillMBType( p_vpar, 1, 48, 64, MB_MOTION_FORWARD - |MB_MOTION_BACKWARD|MB_PATTERN, 2 ); - FillMBType( p_vpar, 1, 32, 48, MB_MOTION_FORWARD|MB_MOTION_BACKWARD, 2 ); - FillMBType( p_vpar, 1, 24, 32, MB_MOTION_BACKWARD|MB_PATTERN, 3 ); - FillMBType( p_vpar, 1, 16, 24, MB_MOTION_BACKWARD, 3 ); - FillMBType( p_vpar, 1, 12, 16, MB_MOTION_FORWARD|MB_PATTERN, 4 ); - FillMBType( p_vpar, 1, 8, 12, MB_MOTION_FORWARD, 4 ); - FillMBType( p_vpar, 1, 6, 8, MB_INTRA, 5 ); - FillMBType( p_vpar, 1, 4, 6, MB_QUANT|MB_MOTION_FORWARD - |MB_MOTION_BACKWARD|MB_PATTERN, 5 ); - p_vpar->ppl_mb_type[1][3].i_value = MB_QUANT|MB_MOTION_FORWARD|MB_PATTERN; - p_vpar->ppl_mb_type[1][3].i_length = 6; - p_vpar->ppl_mb_type[1][2].i_value = MB_QUANT|MB_MOTION_BACKWARD|MB_PATTERN; - p_vpar->ppl_mb_type[1][2].i_length = 6; - p_vpar->ppl_mb_type[1][1].i_value = MB_QUANT|MB_INTRA; - p_vpar->ppl_mb_type[1][1].i_length = 6; - p_vpar->ppl_mb_type[1][0].i_value =MB_ERROR; - p_vpar->ppl_mb_type[1][0].i_length = 0; -} + for( ; ; ) + { + if( (i_code = ShowBits( &p_vpar->bit_stream, 5 )) >= 0x5 ) + { + p_tab = DCT_B14AC_5 - 5 + i_code; + i_coeff += p_tab->i_run; + if( i_coeff >= 64 ) + { + /* End of block */ + break; + } +store_coeff: + i_nc++; + i_pos = p_scan[ i_coeff ]; + RemoveBits( &p_vpar->bit_stream, p_tab->i_length ); + i_value = (p_tab->i_level * i_q_scale * pi_quant[i_pos]) + >> 4; -/***************************************************************************** - * vpar_InitDCTTables : Initialize tables giving the length of the dct - * coefficient from the vlc code - *****************************************************************************/ + i_sign = GetSignedBits( &p_vpar->bit_stream, 1 ); + /* if (i_sign) i_value = -i_value; */ + i_value = (i_value ^ i_sign) - i_sign; -/* First fonction for filling the table */ -static void FillDCTTable( dct_lookup_t * p_tab_dest, dct_lookup_t * p_tab_src, - int i_step, int i_nb_elem, int i_offset ) -{ - int i_dummy, i_dummy2; + SATURATE( i_value ); + p_dest[i_pos] = i_value; + i_mismatch ^= i_value; - for( i_dummy=0 ; i_dummy < i_nb_elem ; i_dummy++ ) - { - for( i_dummy2=0 ; i_dummy2 < i_step ; i_dummy2++ ) - { - p_tab_dest[(i_dummy+i_offset)*i_step+i_dummy2] = p_tab_src[i_dummy]; + continue; } - } -} + else if( (i_code = ShowBits( &p_vpar->bit_stream, 8 )) >= 0x4 ) + { + p_tab = DCT_B14_8 - 4 + i_code; + i_coeff += p_tab->i_run; + if( i_coeff < 64 ) + { + /* Normal coefficient */ + goto store_coeff; + } + /* Escape code */ + i_coeff += (GetBits( &p_vpar->bit_stream, 12 ) & 0x3F) - 64; + if( i_coeff >= 64 ) + { + /* Illegal, but needed to avoid overflow */ + intf_WarnMsg( 2, "Intra-B14 coeff is out of bound" ); + p_vpar->picture.b_error = 1; + break; + } -/* Fonction that actually fills the table or create the pointers */ -void vpar_InitDCTTables( vpar_thread_t * p_vpar ) -{ - /* Tables are cut in two parts to reduce memory occupation */ - p_vpar->pppl_dct_dc_size[0][0] = pl_dct_dc_lum_init_table_1; - p_vpar->pppl_dct_dc_size[0][1] = pl_dct_dc_lum_init_table_2; - p_vpar->pppl_dct_dc_size[1][0] = pl_dct_dc_chrom_init_table_1; - p_vpar->pppl_dct_dc_size[1][1] = pl_dct_dc_chrom_init_table_2; - - /* XXX?? MB_ERROR is replaced by 0 because if we use -1 we - * can block in DecodeMPEG2Intra and others */ - memset( p_vpar->ppl_dct_coef[0], 0, 16 ); - memset( p_vpar->ppl_dct_coef[1], 0, 16 ); - - /* For table B14 & B15, we have a pointer to tables */ - /* We fill the table thanks to the fonction defined above */ - FillDCTTable( p_vpar->ppl_dct_coef[0], pl_DCT_tab0, 256, 60, 4 ); - FillDCTTable( p_vpar->ppl_dct_coef[0], pl_DCT_tab1, 64, 8, 8 ); - FillDCTTable( p_vpar->ppl_dct_coef[0], pl_DCT_tab2, 16, 16, 16 ); - FillDCTTable( p_vpar->ppl_dct_coef[0], pl_DCT_tab3, 8, 16, 16 ); - FillDCTTable( p_vpar->ppl_dct_coef[0], pl_DCT_tab4, 4, 16, 16 ); - FillDCTTable( p_vpar->ppl_dct_coef[0], pl_DCT_tab5, 2, 16, 16 ); - FillDCTTable( p_vpar->ppl_dct_coef[0], pl_DCT_tab6, 1, 16, 16 ); - - FillDCTTable( p_vpar->ppl_dct_coef[1], pl_DCT_tab0a, 256, 60, 4 ); - FillDCTTable( p_vpar->ppl_dct_coef[1], pl_DCT_tab1a, 64, 8, 8 ); - FillDCTTable( p_vpar->ppl_dct_coef[1], pl_DCT_tab2, 16, 16, 16 ); - FillDCTTable( p_vpar->ppl_dct_coef[1], pl_DCT_tab3, 8, 16, 16 ); - FillDCTTable( p_vpar->ppl_dct_coef[1], pl_DCT_tab4, 4, 16, 16 ); - FillDCTTable( p_vpar->ppl_dct_coef[1], pl_DCT_tab5, 2, 16, 16 ); - FillDCTTable( p_vpar->ppl_dct_coef[1], pl_DCT_tab6, 1, 16, 16 ); -} + i_nc++; + i_pos = p_scan[i_coeff]; + i_value = (GetSignedBits( &p_vpar->bit_stream, 12 ) + * i_q_scale * pi_quant[i_pos]) / 16; -/***************************************************************************** - * vpar_InitScanTable : Initialize scan table - *****************************************************************************/ -void vpar_InitScanTable( vpar_thread_t * p_vpar ) -{ - int i; + SATURATE( i_value ); + p_dest[i_pos] = i_value; + i_mismatch ^= i_value; + continue; + } + else if( (i_code = ShowBits( &p_vpar->bit_stream, 16)) >= 0x0200 ) + { + p_tab = DCT_B14_10 - 8 + (i_code >> 6); + i_coeff += p_tab->i_run; + if( i_coeff < 64 ) + { + goto store_coeff; + } + } + else if( i_code >= 0x0080 ) + { + p_tab = DCT_13 - 16 + (i_code >> 3); + i_coeff += p_tab->i_run; + if( i_coeff < 64 ) + { + goto store_coeff; + } + } + else if( i_code >= 0x0020 ) + { + p_tab = DCT_15 - 16 + (i_code >> 1); + i_coeff += p_tab->i_run; + if( i_coeff < 64 ) + { + goto store_coeff; + } + } + else + { + p_tab = DCT_16 + i_code; + i_coeff += p_tab->i_run; + if( i_coeff < 64 ) + { + goto store_coeff; + } + } - memcpy( p_vpar->ppi_scan, pi_scan, sizeof(pi_scan) ); - p_vpar->pf_norm_scan( p_vpar->ppi_scan ); + intf_WarnMsg( 2, "Intra-B14 coeff is out of bound" ); + p_vpar->picture.b_error = 1; + break; + } - /* If scan table has changed, we must change the quantization matrices. */ - for( i = 0; i < 64; i++ ) + p_dest[63] ^= i_mismatch & 1; + RemoveBits( &p_vpar->bit_stream, 2 ); /* End of Block */ + + if( i_nc <= 1 ) { - p_vpar->pi_default_intra_quant[ p_vpar->ppi_scan[0][i] ] = - pi_default_intra_quant[ pi_scan[0][i] ]; - p_vpar->pi_default_nonintra_quant[ p_vpar->ppi_scan[0][i] ] = - pi_default_nonintra_quant[ pi_scan[0][i] ]; + if( p_dest[63] ) + { + if( i_nc == 0 ) + { + p_idct->pf_idct = p_vpar->pf_sparse_idct; + p_idct->i_sparse_pos = 63; + } + else + { + p_idct->pf_idct = p_vpar->pf_idct; + } + } + else + { + p_idct->pf_idct = p_vpar->pf_sparse_idct; + p_idct->i_sparse_pos = i_coeff - p_tab->i_run; + } + } + else + { + p_idct->pf_idct = p_vpar->pf_idct; } } - -/* - * Block parsing - */ - -#define SATURATE(val) \ - if( val > 2047 ) \ - val = 2047; \ - else if( val < -2048 ) \ - val = -2048; - /***************************************************************************** - * DecodeMPEG1NonIntra : decode MPEG-1 non-intra blocks + * MPEG2IntraB15 : Decode an intra block according to ISO/IEC 13818-2 table B15 *****************************************************************************/ -static __inline__ void DecodeMPEG1NonIntra( vpar_thread_t * p_vpar, - macroblock_t * p_mb, int i_b, - boolean_t b_chroma, int i_cc ) +static void MPEG2IntraB15( vpar_thread_t * p_vpar, idct_inner_t * p_idct ) { - int i_parse; - int i_nc; - int i_coef; - int i_code; - int i_length; - int i_pos; - int i_run; - int i_level; - boolean_t b_sign; - dct_lookup_t * p_tab; - - /* Decoding of the AC coefficients */ + int i_coeff, i_mismatch, i_code, i_pos, i_value, i_nc; + s32 i_sign; + dct_lookup_t * p_tab; - i_nc = 0; - i_coef = 0; - b_sign = 0; + int i_q_scale = p_vpar->mb.i_quantizer_scale; + u8 * pi_quant = p_vpar->sequence.intra_quant.pi_matrix; + dctelem_t * p_dest = p_idct->pi_block; + u8 * p_scan = p_vpar->picture.pi_scan; - for( i_parse = 0; !p_vpar->p_fifo->b_die; i_parse++ ) + i_coeff = 0; + i_mismatch = ~p_dest[0]; + i_nc = (p_dest[0] != 0); + + for( ; ; ) { - i_code = ShowBits( &p_vpar->bit_stream, 16 ); - if( i_code >= 16384 ) - { - p_tab = &ppl_dct_tab2[(i_parse == 0)][(i_code>>12)-4]; - } - else + if( (i_code = ShowBits( &p_vpar->bit_stream, 8 )) >= 0x4 ) { - p_tab = &p_vpar->ppl_dct_coef[0][i_code]; - } - i_run = p_tab->i_run; - i_level = p_tab->i_level; - i_length = p_tab->i_length; + p_tab = DCT_B15_8 - 4 + i_code; + i_coeff += p_tab->i_run; + if( i_coeff < 64 ) + { - RemoveBits( &p_vpar->bit_stream, i_length ); +store_coeff: + i_nc++; + i_pos = p_scan[ i_coeff ]; + RemoveBits( &p_vpar->bit_stream, p_tab->i_length ); + i_value = (p_tab->i_level * i_q_scale * pi_quant[i_pos]) + >> 4; - switch( i_run ) - { - case DCT_ESCAPE: - i_run = GetBits( &p_vpar->bit_stream, 6 ); - i_level = GetBits( &p_vpar->bit_stream, 8 ); - if (i_level == 0) - i_level = GetBits( &p_vpar->bit_stream, 8 ); - else if (i_level == 128) - i_level = GetBits( &p_vpar->bit_stream, 8 ) - 256; - else if (i_level > 128) - i_level -= 256; + i_sign = GetSignedBits( &p_vpar->bit_stream, 1 ); + /* if (i_sign) i_value = -i_value; */ + i_value = (i_value ^ i_sign) - i_sign; - if( (b_sign = i_level < 0) ) - i_level = -i_level; - - break; - case DCT_EOB: - if( i_nc <= 1 ) + SATURATE( i_value ); + p_dest[i_pos] = i_value; + i_mismatch ^= i_value; + + continue; + } + else + { + if( i_coeff >= 128 ) { - p_mb->pf_idct[i_b] = p_vpar->pf_sparse_idct; - p_mb->pi_sparse_pos[i_b] = i_coef; + /* End of block */ + break; } - else + + /* Escape code */ + i_coeff += (GetBits( &p_vpar->bit_stream, 12 ) & 0x3F) - 64; + if( i_coeff >= 64 ) { - p_mb->pf_idct[i_b] = p_vpar->pf_idct; + /* Illegal, but needed to avoid overflow */ + intf_WarnMsg( 2, "Intra-B15 coeff is out of bound" ); + p_vpar->picture.b_error = 1; + break; } - return; - break; - default: - b_sign = GetBits( &p_vpar->bit_stream, 1 ); - } - i_coef = i_parse; - i_parse += i_run; - i_nc ++; + i_nc++; + i_pos = p_scan[i_coeff]; + i_value = (GetSignedBits( &p_vpar->bit_stream, 12 ) + * i_q_scale * pi_quant[i_pos]) / 16; - if( i_parse >= 64 ) + SATURATE( i_value ); + p_dest[i_pos] = i_value; + i_mismatch ^= i_value; + continue; + } + } + else if( (i_code = ShowBits( &p_vpar->bit_stream, 16)) >= 0x0200 ) { - break; + p_tab = DCT_B15_10 - 8 + (i_code >> 6); + i_coeff += p_tab->i_run; + if( i_coeff < 64 ) + { + goto store_coeff; + } + } + else if( i_code >= 0x0080 ) + { + p_tab = DCT_13 - 16 + (i_code >> 3); + i_coeff += p_tab->i_run; + if( i_coeff < 64 ) + { + goto store_coeff; + } + } + else if( i_code >= 0x0020 ) + { + p_tab = DCT_15 - 16 + (i_code >> 1); + i_coeff += p_tab->i_run; + if( i_coeff < 64 ) + { + goto store_coeff; + } + } + else + { + p_tab = DCT_16 + i_code; + i_coeff += p_tab->i_run; + if( i_coeff < 64 ) + { + goto store_coeff; + } } - i_pos = p_vpar->ppi_scan[p_vpar->picture.b_alternate_scan][i_parse]; - i_level = ( ((i_level << 1) + 1) * p_vpar->mb.i_quantizer_scale - * p_vpar->sequence.nonintra_quant.pi_matrix[i_pos] ) >> 4; + intf_WarnMsg( 2, "Intra-B15 coeff is out of bound" ); + p_vpar->picture.b_error = 1; + break; + } - /* Mismatch control */ - /* Equivalent to : if( (val & 1) == 0 ) val = val - 1; */ - i_level = (i_level - 1) | 1; + p_dest[63] ^= i_mismatch & 1; + RemoveBits( &p_vpar->bit_stream, 4 ); /* End of Block */ - i_level = b_sign ? -i_level : i_level; - - SATURATE( i_level ); - - p_mb->ppi_blocks[i_b][i_pos] = i_level; + if( i_nc <= 1 ) + { + if( p_dest[63] ) + { + if( i_nc == 0 ) + { + p_idct->pf_idct = p_vpar->pf_sparse_idct; + p_idct->i_sparse_pos = 63; + } + else + { + p_idct->pf_idct = p_vpar->pf_idct; + } + } + else + { + p_idct->pf_idct = p_vpar->pf_sparse_idct; + p_idct->i_sparse_pos = i_coeff - p_tab->i_run; + } + } + else + { + p_idct->pf_idct = p_vpar->pf_idct; } - - intf_WarnMsg( 2, "DCT coeff (non-intra) is out of bounds" ); - p_vpar->picture.b_error = 1; } /***************************************************************************** - * DecodeMPEG1Intra : decode MPEG-1 intra blocks + * MPEG2NonIntra : Decode a non-intra MPEG-2 block *****************************************************************************/ -static __inline__ void DecodeMPEG1Intra( vpar_thread_t * p_vpar, - macroblock_t * p_mb, int i_b, - boolean_t b_chroma, int i_cc ) +static void MPEG2NonIntra( vpar_thread_t * p_vpar, idct_inner_t * p_idct ) { - int i_parse; - int i_nc; - int i_coef; - int i_code; - int i_length; - int i_pos; - int i_dct_dc_size; - int i_dct_dc_diff; - int i_run; - int i_level; - boolean_t b_sign; - dct_lookup_t * p_tab; - lookup_t * p_lookup; - u8 * pi_quant = p_vpar->sequence.intra_quant.pi_matrix; - - /* decode length */ - i_code = ShowBits(&p_vpar->bit_stream, 5); - - if (i_code<31) + int i_coeff, i_mismatch, i_code, i_pos, i_value, i_nc; + s32 i_sign; + dct_lookup_t * p_tab; + + int i_q_scale = p_vpar->mb.i_quantizer_scale; + u8 * pi_quant = p_vpar->sequence.nonintra_quant.pi_matrix; + dctelem_t * p_dest = p_idct->pi_block; + u8 * p_scan = p_vpar->picture.pi_scan; +static int meuh = 0; +meuh++; + if( meuh == 3745 ) + i_coeff = 0; + + i_coeff = -1; + i_mismatch = 1; + i_nc = 0; + + if( (i_code = ShowBits( &p_vpar->bit_stream, 5 )) >= 0x5 ) { - p_lookup = &ppl_dct_dc_init_table_1[b_chroma][i_code]; + p_tab = DCT_B14DC_5 - 5 + i_code; + goto coeff_1; } else { - i_code = ShowBits(&p_vpar->bit_stream, (9+b_chroma)) - (0x1f0 * (b_chroma + 1)); - p_lookup = &ppl_dct_dc_init_table_2[b_chroma][i_code]; + goto coeff_2; } - i_dct_dc_size = p_lookup->i_value; - i_length = p_lookup->i_length; - RemoveBits( &p_vpar->bit_stream, i_length ); - if (i_dct_dc_size == 0) - i_dct_dc_diff = 0; - else + for( ; ; ) { - i_dct_dc_diff = GetBits( &p_vpar->bit_stream, i_dct_dc_size); - if ((i_dct_dc_diff & (1<<(i_dct_dc_size-1))) == 0) - i_dct_dc_diff -= (1<bit_stream, 5 )) >= 0x5 ) + { + p_tab = DCT_B14AC_5 - 5 + i_code; +coeff_1: + i_coeff += p_tab->i_run; + if( i_coeff >= 64 ) + { + /* End of block */ + break; + } - /* Read the actual code with the good length */ - p_vpar->mb.pi_dc_dct_pred[i_cc] += i_dct_dc_diff; +store_coeff: + i_nc++; + i_pos = p_scan[ i_coeff ]; + RemoveBits( &p_vpar->bit_stream, p_tab->i_length ); + i_value = ((2 * p_tab->i_level + 1) * i_q_scale * pi_quant[i_pos]) + >> 5; - p_mb->ppi_blocks[i_b][0] = p_vpar->mb.pi_dc_dct_pred[i_cc] << 3; + i_sign = GetSignedBits( &p_vpar->bit_stream, 1 ); + /* if (i_sign) i_value = -i_value; */ + i_value = (i_value ^ i_sign) - i_sign; - i_nc = ( p_vpar->mb.pi_dc_dct_pred[i_cc] != 0 ); + SATURATE( i_value ); + p_dest[i_pos] = i_value; + i_mismatch ^= i_value; - if( p_vpar->picture.i_coding_type == D_CODING_TYPE ) - { - /* Remove end_of_macroblock (always 1, prevents startcode emulation) - * ISO/IEC 11172-2 section 2.4.2.7 and 2.4.3.6 */ - RemoveBits( &p_vpar->bit_stream, 1 ); - /* D pictures do not have AC coefficients */ - return; - } + continue; + } +coeff_2: + if( (i_code = ShowBits( &p_vpar->bit_stream, 8 )) >= 0x4 ) + { + p_tab = DCT_B14_8 - 4 + i_code; + i_coeff += p_tab->i_run; + if( i_coeff < 64 ) + { + /* Normal coefficient */ + goto store_coeff; + } - - /* Decoding of the AC coefficients */ - i_coef = 0; - b_sign = 0; + /* Escape code */ + i_coeff += (GetBits( &p_vpar->bit_stream, 12 ) & 0x3F) - 64; + if( i_coeff >= 64 ) + { + /* Illegal, but needed to avoid overflow */ + intf_WarnMsg( 2, "MPEG2NonIntra coeff is out of bound" ); + p_vpar->picture.b_error = 1; + break; + } - for( i_parse = 1; !p_vpar->p_fifo->b_die; i_parse++ ) - { - i_code = ShowBits( &p_vpar->bit_stream, 16 ); - /* We use 2 main tables for the coefficients */ - if( i_code >= 16384 ) + i_nc++; + i_pos = p_scan[i_coeff]; + i_value = 2 * (ShowSignedBits( &p_vpar->bit_stream, 1 ) + + GetSignedBits( &p_vpar->bit_stream, 12 )) + 1; + + i_value = (i_value * i_q_scale * pi_quant[i_pos]) / 32; + + SATURATE( i_value ); + p_dest[i_pos] = i_value; + i_mismatch ^= i_value; + continue; + } + else if( (i_code = ShowBits( &p_vpar->bit_stream, 16)) >= 0x0200 ) { - p_tab = &ppl_dct_tab1[0][(i_code>>12)-4]; + p_tab = DCT_B14_10 - 8 + (i_code >> 6); + i_coeff += p_tab->i_run; + if( i_coeff < 64 ) + { + goto store_coeff; + } } - else + else if( i_code >= 0x0080 ) { - p_tab = &p_vpar->ppl_dct_coef[0][i_code]; + p_tab = DCT_13 - 16 + (i_code >> 3); + i_coeff += p_tab->i_run; + if( i_coeff < 64 ) + { + goto store_coeff; + } } - i_run = p_tab->i_run; - i_length = p_tab->i_length; - i_level = p_tab->i_level; - - RemoveBits( &p_vpar->bit_stream, i_length ); - - switch( i_run ) + else if( i_code >= 0x0020 ) { - case DCT_ESCAPE: - i_run = GetBits( &p_vpar->bit_stream, 6 ); - i_level = GetBits( &p_vpar->bit_stream, 8 ); - if (i_level == 0) - i_level = GetBits( &p_vpar->bit_stream, 8 ); - else if (i_level == 128) - i_level = GetBits( &p_vpar->bit_stream, 8 ) - 256; - else if (i_level > 128) - i_level -= 256; - if( (b_sign = i_level < 0) ) - i_level = -i_level; - break; - case DCT_EOB: - if( i_nc <= 1 ) - { - p_mb->pf_idct[i_b] = p_vpar->pf_sparse_idct; - p_mb->pi_sparse_pos[i_b] = i_coef; - } - else - { - p_mb->pf_idct[i_b] = p_vpar->pf_idct; - } - return; - - break; - default: - b_sign = GetBits( &p_vpar->bit_stream, 1 ); + p_tab = DCT_15 - 16 + (i_code >> 1); + i_coeff += p_tab->i_run; + if( i_coeff < 64 ) + { + goto store_coeff; + } } - - /* Prepare the next block */ - i_coef = i_parse; - i_parse += i_run; - i_nc ++; - - if( i_parse >= 64 ) + else { - /* We have an error in the stream */ - break; + p_tab = DCT_16 + i_code; + i_coeff += p_tab->i_run; + if( i_coeff < 64 ) + { + goto store_coeff; + } } - /* Determine the position of the block in the frame */ - i_pos = p_vpar->ppi_scan[p_vpar->picture.b_alternate_scan][i_parse]; - i_level = ( i_level * - p_vpar->mb.i_quantizer_scale * pi_quant[i_pos] ) >> 3; - - /* Mismatch control */ - /* Equivalent to : if( (val & 1) == 0 ) val = val - 1; */ - i_level = (i_level - 1) | 1; - - i_level = b_sign ? -i_level : i_level; - - SATURATE( i_level ); - - p_mb->ppi_blocks[i_b][i_pos] = i_level; + intf_WarnMsg( 2, "MPEG2NonIntra coeff is out of bound" ); + p_vpar->picture.b_error = 1; + break; } - intf_WarnMsg( 2, "DCT coeff (intra) is out of bounds" ); - p_vpar->picture.b_error = 1; -} + p_dest[63] ^= i_mismatch & 1; + RemoveBits( &p_vpar->bit_stream, 2 ); /* End of Block */ -/***************************************************************************** - * DecodeMPEG2NonIntra : decode MPEG-2 non-intra blocks - *****************************************************************************/ -static __inline__ void DecodeMPEG2NonIntra( vpar_thread_t * p_vpar, - macroblock_t * p_mb, int i_b, - boolean_t b_chroma, int i_cc ) -{ - int i_parse; - int i_nc; - int i_coef; - int i_code; - int i_length; - int i_pos; - int i_run; - int i_level; - int i_mismatch = 1; - boolean_t b_sign; - u8 * pi_quant; - dct_lookup_t * p_tab; - /* FIXME : if you want to enable other types of chroma, replace this - * by p_vpar->sequence.i_chroma_format. */ - int i_chroma_format = CHROMA_420; - - /* Give a pointer to the quantization matrices for intra blocks */ - if( (i_chroma_format == CHROMA_420) || (!b_chroma) ) + if( i_nc <= 1 ) { - pi_quant = p_vpar->sequence.nonintra_quant.pi_matrix; + if( p_dest[63] ) + { + if( i_nc == 0 ) + { + p_idct->pf_idct = p_vpar->pf_sparse_idct; + p_idct->i_sparse_pos = 63; + } + else + { + p_idct->pf_idct = p_vpar->pf_idct; + } + } + else + { + p_idct->pf_idct = p_vpar->pf_sparse_idct; + if( i_nc == 0 ) + { + p_idct->i_sparse_pos = 0; + } + else + { + p_idct->i_sparse_pos = i_coeff - p_tab->i_run; + } + } } else { - pi_quant = p_vpar->sequence.chroma_nonintra_quant.pi_matrix; + p_idct->pf_idct = p_vpar->pf_idct; } +} + +/***************************************************************************** + * MPEG1Intra : Decode an MPEG-1 intra block + *****************************************************************************/ +static void MPEG1Intra( vpar_thread_t * p_vpar, idct_inner_t * p_idct ) +{ + int i_coeff, i_code, i_pos, i_value, i_nc; + s32 i_sign; + dct_lookup_t * p_tab; - /* Decoding of the AC coefficients */ + int i_q_scale = p_vpar->mb.i_quantizer_scale; + u8 * pi_quant = p_vpar->sequence.intra_quant.pi_matrix; + dctelem_t * p_dest = p_idct->pi_block; + u8 * p_scan = p_vpar->picture.pi_scan; - i_nc = 0; - i_coef = 0; - for( i_parse = 0; !p_vpar->p_fifo->b_die; i_parse++ ) + i_coeff = 0; + i_nc = (p_dest[0] != 0); + + for( ; ; ) { - i_code = ShowBits( &p_vpar->bit_stream, 16 ); - if( i_code >= 16384 ) - { - p_tab = &ppl_dct_tab2[(i_parse == 0)][(i_code>>12)-4]; - } - else + if( (i_code = ShowBits( &p_vpar->bit_stream, 5 )) >= 0x5 ) { - p_tab = &p_vpar->ppl_dct_coef[0][i_code]; - } - i_run = p_tab->i_run; - i_level = p_tab->i_level; - i_length = p_tab->i_length; + p_tab = DCT_B14AC_5 - 5 + i_code; + i_coeff += p_tab->i_run; + if( i_coeff >= 64 ) + { + /* End of block */ + break; + } + +store_coeff: + i_nc++; + i_pos = p_scan[ i_coeff ]; + RemoveBits( &p_vpar->bit_stream, p_tab->i_length ); + i_value = (p_tab->i_level * i_q_scale * pi_quant[i_pos]) + >> 4; + + /* Oddification */ + i_value = (i_value - 1) | 1; - RemoveBits( &p_vpar->bit_stream, i_length ); + i_sign = GetSignedBits( &p_vpar->bit_stream, 1 ); + /* if (i_sign) i_value = -i_value; */ + i_value = (i_value ^ i_sign) - i_sign; - switch( i_run ) + SATURATE( i_value ); + p_dest[i_pos] = i_value; + + continue; + } + else if( (i_code = ShowBits( &p_vpar->bit_stream, 8 )) >= 0x4 ) { - case DCT_ESCAPE: - i_run = GetBits( &p_vpar->bit_stream, 6 ); - i_level = GetBits( &p_vpar->bit_stream, 12 ); - i_level = (b_sign = ( i_level > 2047 )) ? 4096 - i_level - : i_level; - break; - case DCT_EOB: - if( i_nc <= 1 ) - { - p_mb->pf_idct[i_b] = p_vpar->pf_sparse_idct; - p_mb->pi_sparse_pos[i_b] = i_coef; - } - else - { - p_mb->pf_idct[i_b] = p_vpar->pf_idct; - } - - /* Mismatch control */ - p_mb->ppi_blocks[i_b][63] ^= i_mismatch & 1; - return; + p_tab = DCT_B14_8 - 4 + i_code; + i_coeff += p_tab->i_run; + if( i_coeff < 64 ) + { + /* Normal coefficient */ + goto store_coeff; + } + /* Escape code */ + i_coeff += (GetBits( &p_vpar->bit_stream, 12 ) & 0x3F) - 64; + if( i_coeff >= 64 ) + { + /* Illegal, but needed to avoid overflow */ + intf_WarnMsg( 2, "MPEG1Intra coeff is out of bound" ); + p_vpar->picture.b_error = 1; break; - default: - b_sign = GetBits( &p_vpar->bit_stream, 1 ); - } - i_coef = i_parse; - i_parse += i_run; - i_nc ++; + } + + i_nc++; + i_pos = p_scan[i_coeff]; + + i_value = ShowSignedBits( &p_vpar->bit_stream, 8 ); + if( !(i_value & 0x7F) ) + { + RemoveBits( &p_vpar->bit_stream, 8 ); + i_value = ShowBits( &p_vpar->bit_stream, 8 ) + 2 * i_value; + } - if( i_parse >= 64 ) + i_value = (i_value * i_q_scale * pi_quant[i_pos]) / 16; + + /* Oddification */ + i_value = (i_value + ~ShowSignedBits( &p_vpar->bit_stream, 1 )) | 1; + + SATURATE( i_value ); + p_dest[i_pos] = i_value; + RemoveBits( &p_vpar->bit_stream, 8 ); + continue; + } + else if( (i_code = ShowBits( &p_vpar->bit_stream, 16)) >= 0x0200 ) { - break; + p_tab = DCT_B14_10 - 8 + (i_code >> 6); + i_coeff += p_tab->i_run; + if( i_coeff < 64 ) + { + goto store_coeff; + } + } + else if( i_code >= 0x0080 ) + { + p_tab = DCT_13 - 16 + (i_code >> 3); + i_coeff += p_tab->i_run; + if( i_coeff < 64 ) + { + goto store_coeff; + } + } + else if( i_code >= 0x0020 ) + { + p_tab = DCT_15 - 16 + (i_code >> 1); + i_coeff += p_tab->i_run; + if( i_coeff < 64 ) + { + goto store_coeff; + } + } + else + { + p_tab = DCT_16 + i_code; + i_coeff += p_tab->i_run; + if( i_coeff < 64 ) + { + goto store_coeff; + } } - i_pos = p_vpar->ppi_scan[p_vpar->picture.b_alternate_scan][i_parse]; - i_level = ( ((i_level << 1) + 1) * p_vpar->mb.i_quantizer_scale - * pi_quant[i_pos] ) >> 5; - - /* Could be replaced by (i_level ^ sign) - sign */ - i_level = b_sign ? -i_level : i_level; - - SATURATE( i_level ); - - p_mb->ppi_blocks[i_b][i_pos] = i_level; - - /* Mismatch control */ - i_mismatch ^= i_level; + intf_WarnMsg( 2, "MPEG1Intra coeff is out of bound" ); + p_vpar->picture.b_error = 1; + break; } - intf_WarnMsg( 2, "DCT coeff (non-intra) is out of bounds" ); - p_vpar->picture.b_error = 1; -} + RemoveBits( &p_vpar->bit_stream, 2 ); /* End of Block */ -/***************************************************************************** - * DecodeMPEG2Intra : decode MPEG-2 intra blocks - *****************************************************************************/ -static __inline__ void DecodeMPEG2Intra( vpar_thread_t * p_vpar, - macroblock_t * p_mb, int i_b, - boolean_t b_chroma, int i_cc ) -{ - int i_parse; - int i_nc; - int i_coef; - int i_code; - int i_length; - int i_pos; - int i_dct_dc_size; - int i_dct_dc_diff; - int i_run; - int i_level; - int i_mismatch = 1; - boolean_t b_vlc_intra; - boolean_t b_sign; - u8 * pi_quant; - dct_lookup_t * p_tab; - lookup_t * p_lookup; - /* FIXME : if you want to enable other types of chroma, replace this - * by p_vpar->sequence.i_chroma_format. */ - int i_chroma_format = CHROMA_420; - - /* Give a pointer to the quantization matrices for intra blocks */ - if( (i_chroma_format == CHROMA_420) || (!b_chroma) ) + if( i_nc <= 1 ) { - pi_quant = p_vpar->sequence.intra_quant.pi_matrix; + p_idct->pf_idct = p_vpar->pf_sparse_idct; + p_idct->i_sparse_pos = i_coeff - p_tab->i_run; } else { - pi_quant = p_vpar->sequence.chroma_intra_quant.pi_matrix; + p_idct->pf_idct = p_vpar->pf_idct; } +} + +/***************************************************************************** + * MPEG1NonIntra : Decode a non-intra MPEG-1 block + *****************************************************************************/ +static void MPEG1NonIntra( vpar_thread_t * p_vpar, idct_inner_t * p_idct ) +{ + int i_coeff, i_code, i_pos, i_value, i_nc; + s32 i_sign; + dct_lookup_t * p_tab; - /* decode length */ - i_code = ShowBits( &p_vpar->bit_stream, 5 ); + int i_q_scale = p_vpar->mb.i_quantizer_scale; + u8 * pi_quant = p_vpar->sequence.nonintra_quant.pi_matrix; + dctelem_t * p_dest = p_idct->pi_block; + u8 * p_scan = p_vpar->picture.pi_scan; - if (i_code < 31) + i_coeff = -1; + i_nc = 0; + + if( (i_code = ShowBits( &p_vpar->bit_stream, 5 )) >= 0x5 ) { - p_lookup = &ppl_dct_dc_init_table_1[b_chroma][i_code]; + p_tab = DCT_B14DC_5 - 5 + i_code; + goto coeff_1; } else { - i_code = ShowBits(&p_vpar->bit_stream, (9+b_chroma)) - (0x1f0 * (b_chroma + 1)); - p_lookup = &ppl_dct_dc_init_table_2[b_chroma][i_code]; + goto coeff_2; } - i_dct_dc_size = p_lookup->i_value; - i_length = p_lookup->i_length; - RemoveBits( &p_vpar->bit_stream, i_length ); - if (i_dct_dc_size == 0) - i_dct_dc_diff = 0; - else + for( ; ; ) { - i_dct_dc_diff = GetBits( &p_vpar->bit_stream, i_dct_dc_size); - if ((i_dct_dc_diff & (1<<(i_dct_dc_size-1))) == 0) - i_dct_dc_diff -= (1<bit_stream, 5 )) >= 0x5 ) + { + p_tab = DCT_B14AC_5 - 5 + i_code; +coeff_1: + i_coeff += p_tab->i_run; + if( i_coeff >= 64 ) + { + /* End of block */ + break; + } - /* Read the actual code with the good length */ - p_vpar->mb.pi_dc_dct_pred[i_cc] += i_dct_dc_diff; +store_coeff: + i_nc++; + i_pos = p_scan[ i_coeff ]; + RemoveBits( &p_vpar->bit_stream, p_tab->i_length ); + i_value = ((2 * p_tab->i_level + 1) * i_q_scale * pi_quant[i_pos]) + >> 5; - p_mb->ppi_blocks[i_b][0] = ( p_vpar->mb.pi_dc_dct_pred[i_cc] << - ( 3 - p_vpar->picture.i_intra_dc_precision ) ); + /* Oddification */ + i_value = (i_value - 1) | 1; - i_nc = ( p_vpar->mb.pi_dc_dct_pred[i_cc] != 0 ); + i_sign = GetSignedBits( &p_vpar->bit_stream, 1 ); + /* if (i_sign) i_value = -i_value; */ + i_value = (i_value ^ i_sign) - i_sign; - /* Decoding of the AC coefficients */ + SATURATE( i_value ); + p_dest[i_pos] = i_value; - i_coef = 0; - b_vlc_intra = p_vpar->picture.b_intra_vlc_format; - for( i_parse = 1; !p_vpar->p_fifo->b_die; i_parse++ ) - { - i_code = ShowBits( &p_vpar->bit_stream, 16 ); - /* We use 2 main tables for the coefficients */ - if( i_code >= 16384 ) + continue; + } +coeff_2: + if( (i_code = ShowBits( &p_vpar->bit_stream, 8 )) >= 0x4 ) + { + p_tab = DCT_B14_8 - 4 + i_code; + i_coeff += p_tab->i_run; + if( i_coeff < 64 ) + { + /* Normal coefficient */ + goto store_coeff; + } + + /* Escape code */ + i_coeff += (GetBits( &p_vpar->bit_stream, 12 ) & 0x3F) - 64; + if( i_coeff >= 64 ) + { + /* Illegal, but needed to avoid overflow */ + intf_WarnMsg( 2, "MPEG1NonIntra coeff is out of bound" ); + p_vpar->picture.b_error = 1; + break; + } + + i_nc++; + i_pos = p_scan[i_coeff]; + i_value = ShowSignedBits( &p_vpar->bit_stream, 8 ); + if( !(i_value & 0x7F) ) + { + RemoveBits( &p_vpar->bit_stream, 8 ); + i_value = ShowBits( &p_vpar->bit_stream, 8 ) + 2 * i_value; + } + i_sign = ShowSignedBits( &p_vpar->bit_stream, 1 ); + i_value = 2 * (i_sign + i_value) + 1; + i_value = (i_value * i_q_scale * pi_quant[i_pos]) / 32; + + /* Oddification */ + i_value = (i_value + ~i_sign) | 1; + + SATURATE( i_value ); + p_dest[i_pos] = i_value; + RemoveBits( &p_vpar->bit_stream, 8 ); + continue; + } + else if( (i_code = ShowBits( &p_vpar->bit_stream, 16)) >= 0x0200 ) { - p_tab = &ppl_dct_tab1[b_vlc_intra][(i_code>>(12-(4*b_vlc_intra)))-4]; + p_tab = DCT_B14_10 - 8 + (i_code >> 6); + i_coeff += p_tab->i_run; + if( i_coeff < 64 ) + { + goto store_coeff; + } + } + else if( i_code >= 0x0080 ) + { + p_tab = DCT_13 - 16 + (i_code >> 3); + i_coeff += p_tab->i_run; + if( i_coeff < 64 ) + { + goto store_coeff; + } + } + else if( i_code >= 0x0020 ) + { + p_tab = DCT_15 - 16 + (i_code >> 1); + i_coeff += p_tab->i_run; + if( i_coeff < 64 ) + { + goto store_coeff; + } } else { - p_tab = &p_vpar->ppl_dct_coef[b_vlc_intra][i_code]; + p_tab = DCT_16 + i_code; + i_coeff += p_tab->i_run; + if( i_coeff < 64 ) + { + goto store_coeff; + } } - i_run = p_tab->i_run; - i_level = p_tab->i_level; - i_length = p_tab->i_length; - RemoveBits( &p_vpar->bit_stream, i_length ); + intf_WarnMsg( 2, "MPEG1NonIntra coeff is out of bound" ); + p_vpar->picture.b_error = 1; + break; + } - switch( i_run ) - { - case DCT_ESCAPE: - i_run = GetBits( &p_vpar->bit_stream, 6 ); - i_level = GetBits( &p_vpar->bit_stream, 12 ); - i_level = (b_sign = ( i_level > 2047 )) ? 4096 - i_level - : i_level; - break; - case DCT_EOB: - if( i_nc <= 1 ) - { - p_mb->pf_idct[i_b] = p_vpar->pf_sparse_idct; - p_mb->pi_sparse_pos[i_b] = i_coef; - } - else - { - p_mb->pf_idct[i_b] = p_vpar->pf_idct; - } - - /* Mismatch control */ - p_mb->ppi_blocks[i_b][63] ^= i_mismatch & 1; - return; + RemoveBits( &p_vpar->bit_stream, 2 ); /* End of Block */ - break; - default: - b_sign = GetBits( &p_vpar->bit_stream, 1 ); + if( i_nc <= 1 ) + { + p_idct->pf_idct = p_vpar->pf_sparse_idct; + if( i_nc == 0 ) + { + p_idct->i_sparse_pos = 0; } - - /* Prepare the next block */ - i_coef = i_parse; - i_parse += i_run; - i_nc ++; - - if( i_parse >= 64 ) + else { - /* We have an error in the stream */ - break; + p_idct->i_sparse_pos = i_coeff - p_tab->i_run; } - - /* Determine the position of the block in the frame */ - i_pos = p_vpar->ppi_scan[p_vpar->picture.b_alternate_scan][i_parse]; - i_level = ( i_level * - p_vpar->mb.i_quantizer_scale * - pi_quant[i_pos] ) >> 4; - - i_level = b_sign ? -i_level : i_level; - - SATURATE( i_level ); - - p_mb->ppi_blocks[i_b][i_pos] = i_level; - - /* Mismatch control */ - i_mismatch ^= i_level; } - - intf_WarnMsg( 2, "DCT coeff (intra) is out of bounds" ); - p_vpar->picture.b_error = 1; + else + { + p_idct->pf_idct = p_vpar->pf_idct; + } } +#undef SATURATE + /***************************************************************************** - * Decode*Blocks : decode blocks + * *MB : decode all blocks of the macroblock *****************************************************************************/ -static int pi_x[12] = {0,8,0,8,0,0,0,0,8,8,8,8}; -static int pi_y[2][12] = { {0,0,8,8,0,0,8,8,0,0,8,8}, - {0,0,1,1,0,0,1,1,0,0,1,1} }; -#define PARSEERROR \ -if( p_vpar->picture.b_error ) \ -{ \ - return; \ +#define DECODE_LUMABLOCK( i_b, p_dest, PF_MBFUNC ) \ + p_idct = &p_mb->p_idcts[i_b]; \ + memset( p_idct->pi_block, 0, 64*sizeof(dctelem_t) ); \ + p_idct->p_dct_data = p_dest; \ + p_vpar->mb.pi_dc_dct_pred[0] += GetLumaDCDiff( p_vpar ); \ + p_idct->pi_block[0] = p_vpar->mb.pi_dc_dct_pred[0] \ + << (3 - p_vpar->picture.i_intra_dc_precision ); \ + PF_MBFUNC( p_vpar, p_idct ); + +#define DECLARE_INTRAMB( PSZ_NAME, PF_MBFUNC ) \ +static __inline__ void PSZ_NAME( vpar_thread_t * p_vpar, \ + macroblock_t * p_mb ) \ +{ \ + int i_dct_offset; \ + yuv_data_t * p_lum_dest; \ + idct_inner_t * p_idct; \ + \ + p_lum_dest = p_mb->pp_dest[0] + p_vpar->mb.i_offset; \ + \ + if( p_mb->i_mb_modes & DCT_TYPE_INTERLACED ) \ + { \ + i_dct_offset = p_vpar->picture.i_field_width; \ + p_mb->i_lum_dct_stride = p_vpar->picture.i_field_width * 2; \ + } \ + else \ + { \ + i_dct_offset = p_vpar->picture.i_field_width * 8; \ + p_mb->i_lum_dct_stride = p_vpar->picture.i_field_width; \ + } \ + p_mb->i_chrom_dct_stride = p_vpar->picture.i_field_width >> 1; \ + \ + DECODE_LUMABLOCK( 0, p_lum_dest, PF_MBFUNC ); \ + DECODE_LUMABLOCK( 1, p_lum_dest + 8, PF_MBFUNC ); \ + DECODE_LUMABLOCK( 2, p_lum_dest + i_dct_offset, PF_MBFUNC ); \ + DECODE_LUMABLOCK( 3, p_lum_dest + i_dct_offset + 8, PF_MBFUNC ); \ + \ + p_idct = &p_mb->p_idcts[4]; \ + memset( p_idct->pi_block, 0, 64*sizeof(dctelem_t) ); \ + p_idct->p_dct_data = p_mb->pp_dest[1] + (p_vpar->mb.i_offset >> 1); \ + p_vpar->mb.pi_dc_dct_pred[1] += GetChromaDCDiff( p_vpar ); \ + p_idct->pi_block[0] = p_vpar->mb.pi_dc_dct_pred[1] \ + << (3 - p_vpar->picture.i_intra_dc_precision ); \ + PF_MBFUNC( p_vpar, p_idct ); \ + \ + p_idct = &p_mb->p_idcts[5]; \ + memset( p_idct->pi_block, 0, 64*sizeof(dctelem_t) ); \ + p_idct->p_dct_data = p_mb->pp_dest[2] + (p_vpar->mb.i_offset >> 1); \ + p_vpar->mb.pi_dc_dct_pred[2] += GetChromaDCDiff( p_vpar ); \ + p_idct->pi_block[0] = p_vpar->mb.pi_dc_dct_pred[2] \ + << (3 - p_vpar->picture.i_intra_dc_precision ); \ + PF_MBFUNC( p_vpar, p_idct ); \ } -#define DECODEBLOCKS( MBFUNC, BLOCKFUNC ) \ -static void MBFUNC( vpar_thread_t * p_vpar, macroblock_t * p_mb ) \ -{ \ - /* FIXME : if you want to enable other types of chroma, replace this\ - * by p_vpar->sequence.i_chroma_format. */ \ - int i_chroma_format = CHROMA_420; \ - int i_mask, i_b; \ - yuv_data_t * p_data1; \ - yuv_data_t * p_data2; \ - \ - i_mask = 1 << (3 + (1 << i_chroma_format)); \ - \ - /* luminance */ \ - p_data1 = p_mb->p_picture->p_y \ - + p_mb->i_l_x + p_vpar->mb.i_l_y * (p_vpar->sequence.i_width); \ - \ - for( i_b = 0 ; i_b < 4 ; i_b++, i_mask >>= 1 ) \ - { \ - if( p_mb->i_coded_block_pattern & i_mask ) \ - { \ - memset( p_mb->ppi_blocks[i_b], 0, 64*sizeof(dctelem_t) ); \ - BLOCKFUNC( p_vpar, p_mb, i_b, 0, 0 ); \ - \ - /* Calculate block coordinates. */ \ - p_mb->p_data[i_b] = p_data1 \ - + pi_y[p_vpar->mb.b_dct_type][i_b] \ - * p_vpar->picture.i_l_stride \ - + pi_x[i_b]; \ - \ - PARSEERROR \ - } \ - } \ - \ - /* chrominance */ \ - p_data1 = p_mb->p_picture->p_u \ - + p_mb->i_c_x \ - + p_vpar->mb.i_c_y \ - * (p_vpar->sequence.i_chroma_width); \ - p_data2 = p_mb->p_picture->p_v \ - + p_mb->i_c_x \ - + p_vpar->mb.i_c_y \ - * (p_vpar->sequence.i_chroma_width); \ - \ - for( i_b = 4; i_b < 4 + (1 << i_chroma_format); \ - i_b++, i_mask >>= 1 ) \ - { \ - yuv_data_t * pp_data[2] = {p_data1, p_data2}; \ - \ - if( p_mb->i_coded_block_pattern & i_mask ) \ - { \ - memset( p_mb->ppi_blocks[i_b], 0, 64*sizeof(dctelem_t) ); \ - BLOCKFUNC( p_vpar, p_mb, i_b, 1, 1 + ((i_b - 4) & 1) ); \ - \ - /* Calculate block coordinates. */ \ - p_mb->p_data[i_b] = pp_data[i_b & 1] \ - + pi_y[p_vpar->mb.b_dct_type][i_b] \ - * p_vpar->picture.i_c_stride \ - + pi_x[i_b]; \ - \ - PARSEERROR \ - } \ - } \ +DECLARE_INTRAMB( MPEG1IntraMB, MPEG1Intra ); +DECLARE_INTRAMB( MPEG2IntraB14MB, MPEG2IntraB14 ); +DECLARE_INTRAMB( MPEG2IntraB15MB, MPEG2IntraB15 ); + +#undef DECLARE_INTRAMB +#undef DECODE_LUMABLOCK + +#define DECODE_BLOCK( i_b, p_dest, PF_MBFUNC ) \ + if( p_mb->i_coded_block_pattern & (1 << (5 - i_b)) ) \ + { \ + p_idct = &p_mb->p_idcts[i_b]; \ + memset( p_idct->pi_block, 0, 64*sizeof(dctelem_t) ); \ + p_idct->p_dct_data = p_dest; \ + PF_MBFUNC( p_vpar, p_idct ); \ + } + +#define DECLARE_NONINTRAMB( PSZ_NAME, PF_MBFUNC ) \ +static __inline__ void PSZ_NAME( vpar_thread_t * p_vpar, \ + macroblock_t * p_mb ) \ +{ \ + int i_dct_offset; \ + yuv_data_t * p_lum_dest; \ + idct_inner_t * p_idct; \ + \ + p_lum_dest = p_mb->pp_dest[0] + p_vpar->mb.i_offset; \ + \ + if( p_mb->i_mb_modes & DCT_TYPE_INTERLACED ) \ + { \ + i_dct_offset = p_vpar->picture.i_field_width; \ + p_mb->i_lum_dct_stride = p_vpar->picture.i_field_width * 2; \ + } \ + else \ + { \ + i_dct_offset = p_vpar->picture.i_field_width * 8; \ + p_mb->i_lum_dct_stride = p_vpar->picture.i_field_width; \ + } \ + p_mb->i_chrom_dct_stride = p_vpar->picture.i_field_width >> 1; \ + \ + DECODE_BLOCK( 0, p_lum_dest, PF_MBFUNC ); \ + DECODE_BLOCK( 1, p_lum_dest + 8, PF_MBFUNC ); \ + DECODE_BLOCK( 2, p_lum_dest + i_dct_offset, PF_MBFUNC ); \ + DECODE_BLOCK( 3, p_lum_dest + i_dct_offset + 8, PF_MBFUNC ); \ + DECODE_BLOCK( 4, p_mb->pp_dest[1] + (p_vpar->mb.i_offset >> 1), \ + PF_MBFUNC ); \ + DECODE_BLOCK( 5, p_mb->pp_dest[2] + (p_vpar->mb.i_offset >> 1), \ + PF_MBFUNC ); \ } -DECODEBLOCKS( DecodeMPEG1NonIntraMB, DecodeMPEG1NonIntra ); -DECODEBLOCKS( DecodeMPEG1IntraMB, DecodeMPEG1Intra ); -DECODEBLOCKS( DecodeMPEG2NonIntraMB, DecodeMPEG2NonIntra ); -DECODEBLOCKS( DecodeMPEG2IntraMB, DecodeMPEG2Intra ); +DECLARE_NONINTRAMB( MPEG1NonIntraMB, MPEG1NonIntra ); +DECLARE_NONINTRAMB( MPEG2NonIntraMB, MPEG2NonIntra ); -#undef PARSEERROR +#undef DECLARE_NONINTRAMB +#undef DECODE_BLOCK /* @@ -1210,834 +1064,1065 @@ DECODEBLOCKS( DecodeMPEG2IntraMB, DecodeMPEG2Intra ); */ /**************************************************************************** - * MotionCode : Parse the next motion code + * MotionDelta : Parse the next motion delta ****************************************************************************/ -static __inline__ int MotionCode( vpar_thread_t * p_vpar ) +static __inline__ int MotionDelta( vpar_thread_t * p_vpar, int i_f_code ) { - int i_code; - static lookup_t pl_mv_tab0[8] = - { {-1,0}, {3,3}, {2,2}, {2,2}, {1,1}, {1,1}, {1,1}, {1,1} }; - /* Table B-10, motion_code, codes 0000011 ... 000011x */ - static lookup_t pl_mv_tab1[8] = - { {-1,0}, {-1,0}, {-1,0}, {7,6}, {6,6}, {5,6}, {4,5}, {4,5} }; - /* Table B-10, motion_code, codes 0000001100 ... 000001011x */ - static lookup_t pl_mv_tab2[12] = { - {16,9}, {15,9}, {14,9}, {13,9}, - {12,9}, {11,9}, {10,8}, {10,8}, - {9,8}, {9,8}, {8,8}, {8,8} }; + int i_delta, i_sign, i_code; + lookup_t * p_tab; - if( GetBits( &p_vpar->bit_stream, 1 ) ) + if( ShowBits( &p_vpar->bit_stream, 1 ) ) { + RemoveBits( &p_vpar->bit_stream, 1 ); return 0; } - if( (i_code = ShowBits( &p_vpar->bit_stream, 9) ) >= 64 ) - { - i_code >>= 6; - RemoveBits( &p_vpar->bit_stream, pl_mv_tab0[i_code].i_length ); - return( GetBits( &p_vpar->bit_stream, 1 ) ? - -pl_mv_tab0[i_code].i_value : pl_mv_tab0[i_code].i_value ); - } - if( i_code >= 24 ) + if( (i_code = ShowBits( &p_vpar->bit_stream, 6 )) >= 0x3 ) { - i_code >>= 3; - RemoveBits( &p_vpar->bit_stream, pl_mv_tab1[i_code].i_length ); - return( GetBits( &p_vpar->bit_stream, 1 ) ? - -pl_mv_tab1[i_code].i_value : pl_mv_tab1[i_code].i_value ); - } + p_tab = MV_4 + (i_code >> 2); + i_delta = (p_tab->i_value << i_f_code) + 1; + RemoveBits( &p_vpar->bit_stream, p_tab->i_length ); + + i_sign = GetSignedBits( &p_vpar->bit_stream, 1 ); + if( i_f_code ) + { + i_delta += GetBits( &p_vpar->bit_stream, i_f_code ); + } + + return (i_delta ^ i_sign) - i_sign; - if( (i_code -= 12) < 0 ) - { - p_vpar->picture.b_error = 1; - intf_WarnMsg( 2, "Invalid motion_vector code" ); - return 0; } + else + { + p_tab = MV_10 + ShowBits( &p_vpar->bit_stream, 10 ); + i_delta = (p_tab->i_value << i_f_code) + 1; + RemoveBits( &p_vpar->bit_stream, p_tab->i_length ); + + i_sign = GetSignedBits( &p_vpar->bit_stream, 1 ); + if( i_f_code ) + { + i_delta += GetBits( &p_vpar->bit_stream, i_f_code ); + } - RemoveBits( &p_vpar->bit_stream, pl_mv_tab2[i_code].i_length ); - return( GetBits( &p_vpar->bit_stream, 1 ) ? - -pl_mv_tab2[i_code].i_value : pl_mv_tab2[i_code].i_value ); + return (i_delta ^ i_sign) - i_sign; + } } /**************************************************************************** - * DecodeMotionVector : Decode a motion_vector + * BoundMotionVector : Bound a motion_vector :-) ****************************************************************************/ -static __inline__ void DecodeMotionVector( int * pi_prediction, int i_r_size, - int i_motion_code, int i_motion_residual, int i_full_pel ) +static __inline__ int BoundMotionVector( int i_vector, int i_f_code ) { - int i_limit, i_vector; + int i_limit; - /* ISO/IEC 13818-1 section 7.6.3.1 */ - i_limit = 16 << i_r_size; - i_vector = *pi_prediction >> i_full_pel; + i_limit = 16 << i_f_code; - if( i_motion_code > 0 ) + if( i_vector >= i_limit ) + { + return i_vector - 2 * i_limit; + } + else if( i_vector < -i_limit) { - i_vector += ((i_motion_code-1) << i_r_size) + i_motion_residual + 1; - if( i_vector >= i_limit ) - i_vector -= i_limit + i_limit; + return i_vector + 2 * i_limit; } - else if( i_motion_code < 0 ) + else { - i_vector -= ((-i_motion_code-1) << i_r_size) + i_motion_residual + 1; - if( i_vector < -i_limit ) - i_vector += i_limit + i_limit; + return i_vector; } - *pi_prediction = i_vector << i_full_pel; } /**************************************************************************** - * MotionVector : Parse the next motion_vector field + * GetDMV : Decode a differential motion vector (Dual Prime Arithmetic) ****************************************************************************/ -static __inline__ void MotionVector( vpar_thread_t * p_vpar, - macroblock_t * p_mb, int i_r, - int i_s, int i_full_pel, int i_structure, - int i_h_r_size, int i_v_r_size ) +static __inline__ int GetDMV( vpar_thread_t * p_vpar ) { - int i_motion_code, i_motion_residual; - int pi_dm_vector[2]; - - i_motion_code = MotionCode( p_vpar ); - i_motion_residual = (i_h_r_size != 0 && i_motion_code != 0) ? - GetBits( &p_vpar->bit_stream, i_h_r_size) : 0; - DecodeMotionVector( &p_vpar->mb.pppi_pmv[i_r][i_s][0], i_h_r_size, - i_motion_code, i_motion_residual, i_full_pel ); - p_mb->pppi_motion_vectors[i_r][i_s][0] = p_vpar->mb.pppi_pmv[i_r][i_s][0]; + dmv_lookup_t * p_tab; - if( p_vpar->mb.b_dmv ) - { - if( GetBits(&p_vpar->bit_stream, 1) ) - { - pi_dm_vector[0] = GetBits( &p_vpar->bit_stream, 1 ) ? -1 : 1; - } - else - { - pi_dm_vector[0] = 0; - } - } + p_tab = DMV_2 + ShowBits( &p_vpar->bit_stream, 2 ); + RemoveBits( &p_vpar->bit_stream, p_tab->i_length ); + return( p_tab->i_value ); +} - i_motion_code = MotionCode( p_vpar ); - i_motion_residual = (i_v_r_size != 0 && i_motion_code != 0) ? - GetBits( &p_vpar->bit_stream, i_v_r_size) : 0; +/**************************************************************************** + * Motion* : Parse motion vectors + ****************************************************************************/ +#define MOTION_BLOCK( b_aver, i_x, i_y, i_dest, \ + pp_src, i_src, i_str, i_hei, \ + b_s_half ) \ + do { \ + motion_inner_t * p_m_inner = p_mb->p_motions + p_mb->i_nb_motions; \ + p_m_inner->b_average = b_aver; \ + p_m_inner->i_x_pred = i_x; \ + p_m_inner->i_y_pred = i_y; \ + p_m_inner->pp_source[0] = pp_src[0]; \ + p_m_inner->pp_source[1] = pp_src[1]; \ + p_m_inner->pp_source[2] = pp_src[2]; \ + p_m_inner->i_dest_offset = i_dest; \ + p_m_inner->i_src_offset = i_src; \ + p_m_inner->i_stride = i_str; \ + p_m_inner->i_height = i_hei; \ + p_m_inner->b_second_half = b_s_half; \ + p_mb->i_nb_motions++; \ + } while( 0 ); + +/* MPEG-1 predictions. */ + +static void MotionMPEG1( vpar_thread_t * p_vpar, + macroblock_t * p_mb, + motion_t * p_motion, + boolean_t b_average ) +{ + int i_motion_x, i_motion_y; + int i_offset = p_vpar->mb.i_offset; + int i_width = p_vpar->picture.i_field_width; + + i_motion_x = p_motion->ppi_pmv[0][0] + + MotionDelta( p_vpar, p_motion->pi_f_code[0] ); + i_motion_x = BoundMotionVector( i_motion_x, p_motion->pi_f_code[0] ); + p_motion->ppi_pmv[0][0] = i_motion_x; + i_motion_y = p_motion->ppi_pmv[0][1] + + MotionDelta( p_vpar, p_motion->pi_f_code[0] ); + i_motion_y = BoundMotionVector( i_motion_y, p_motion->pi_f_code[0] ); + p_motion->ppi_pmv[0][1] = i_motion_y; - if( (p_vpar->mb.i_mv_format == MOTION_FIELD) - && (i_structure == FRAME_STRUCTURE) ) + if( p_motion->pi_f_code[1] ) { - p_vpar->mb.pppi_pmv[i_r][i_s][1] >>= 1; + i_motion_x <<= 1; + i_motion_y <<= 1; } - DecodeMotionVector( &p_vpar->mb.pppi_pmv[i_r][i_s][1], i_v_r_size, - i_motion_code, i_motion_residual, i_full_pel ); + MOTION_BLOCK( b_average, i_motion_x, i_motion_y, i_offset, + p_motion->pppi_ref[0], i_offset, i_width, 16, 0 ); +} - if( (p_vpar->mb.i_mv_format == MOTION_FIELD) - && (i_structure == FRAME_STRUCTURE) ) - p_vpar->mb.pppi_pmv[i_r][i_s][1] <<= 1; +static void MotionMPEG1Reuse( vpar_thread_t * p_vpar, + macroblock_t * p_mb, + motion_t * p_motion, + boolean_t b_average ) +{ + int i_motion_x, i_motion_y; + int i_offset = p_vpar->mb.i_offset; + int i_width = p_vpar->picture.i_field_width; - p_mb->pppi_motion_vectors[i_r][i_s][1] = p_vpar->mb.pppi_pmv[i_r][i_s][1]; + i_motion_x = p_motion->ppi_pmv[0][0]; + i_motion_y = p_motion->ppi_pmv[0][1]; - if( p_vpar->mb.b_dmv ) + if( p_motion->pi_f_code[1] ) { - if( GetBits(&p_vpar->bit_stream, 1) ) - { - pi_dm_vector[1] = GetBits( &p_vpar->bit_stream, 1 ) ? -1 : 1; - } - else - { - pi_dm_vector[1] = 0; - } - - /* Dual Prime Arithmetic (ISO/IEC 13818-2 section 7.6.3.6). */ - /* FIXME */ - //intf_Msg( "Your stream uses Dual Prime Arithmetic. Please send a mail" - // " to massiot@via.ecp.fr for debugging purposes. Thank you." ); - -#define i_mv_x p_mb->pppi_motion_vectors[0][0][0] - if( i_structure == FRAME_STRUCTURE ) - { -#define i_mv_y (p_mb->pppi_motion_vectors[0][0][1] << 1) - if( p_vpar->picture.b_top_field_first ) - { - /* vector for prediction of top field from bottom field */ - p_mb->ppi_dmv[0][0] = ((i_mv_x + (i_mv_x > 0)) >> 1) + pi_dm_vector[0]; - p_mb->ppi_dmv[0][1] = ((i_mv_y + (i_mv_y > 0)) >> 1) + pi_dm_vector[1] - 1; + i_motion_x <<= 1; + i_motion_y <<= 1; + } - /* vector for prediction of bottom field from top field */ - p_mb->ppi_dmv[1][0] = ((3*i_mv_x + (i_mv_x > 0)) >> 1) + pi_dm_vector[0]; - p_mb->ppi_dmv[1][1] = ((3*i_mv_y + (i_mv_y > 0)) >> 1) + pi_dm_vector[1] + 1; - } - else - { - /* vector for prediction of top field from bottom field */ - p_mb->ppi_dmv[0][0] = ((3*i_mv_x + (i_mv_x > 0)) >> 1) + pi_dm_vector[0]; - p_mb->ppi_dmv[0][1] = ((3*i_mv_y + (i_mv_y > 0)) >> 1) + pi_dm_vector[1] - 1; + MOTION_BLOCK( b_average, p_motion->ppi_pmv[0][0], p_motion->ppi_pmv[0][1], + i_offset, p_motion->pppi_ref[0], i_offset, i_width, 16, 0 ); +} - /* vector for prediction of bottom field from top field */ - p_mb->ppi_dmv[1][0] = ((i_mv_x + (i_mv_x > 0)) >> 1) + pi_dm_vector[0]; - p_mb->ppi_dmv[1][1] = ((i_mv_y + (i_mv_y > 0)) >> 1) + pi_dm_vector[1] + 1; - } -#undef i_mv_y - } - else - { -#define i_mv_y p_mb->pppi_motion_vectors[0][0][1] - /* vector for prediction from field of opposite 'parity' */ - p_mb->ppi_dmv[0][0] = ((i_mv_x + (i_mv_x > 0)) >> 1) + pi_dm_vector[0]; - p_mb->ppi_dmv[0][1] = ((i_mv_y + (i_mv_y > 0)) >> 1) + pi_dm_vector[1]; +/* MPEG-2 frame predictions. */ - /* correct for vertical field shift */ - if( i_structure == TOP_FIELD ) - p_mb->ppi_dmv[0][1]--; - else - p_mb->ppi_dmv[0][1]++; -#undef i_mv_y - } -#undef i_mv_x - } +static void MotionFrameFrame( vpar_thread_t * p_vpar, + macroblock_t * p_mb, + motion_t * p_motion, + boolean_t b_average ) +{ + int i_motion_x, i_motion_y; + int i_offset = p_vpar->mb.i_offset; + int i_width = p_vpar->picture.i_field_width; + + i_motion_x = p_motion->ppi_pmv[0][0] + + MotionDelta( p_vpar, p_motion->pi_f_code[0] ); + i_motion_x = BoundMotionVector( i_motion_x, p_motion->pi_f_code[0] ); + p_motion->ppi_pmv[1][0] = p_motion->ppi_pmv[0][0] = i_motion_x; + + i_motion_y = p_motion->ppi_pmv[0][1] + + MotionDelta( p_vpar, p_motion->pi_f_code[1] ); + i_motion_y = BoundMotionVector( i_motion_y, p_motion->pi_f_code[1] ); + p_motion->ppi_pmv[1][1] = p_motion->ppi_pmv[0][1] = i_motion_y; + + MOTION_BLOCK( b_average, i_motion_x, i_motion_y, i_offset, + p_motion->pppi_ref[0], i_offset, i_width, 16, 0 ); } -/***************************************************************************** - * DecodeMVMPEG1 : Parse the next MPEG-1 motion vectors - *****************************************************************************/ -static void DecodeMVMPEG1( vpar_thread_t * p_vpar, - macroblock_t * p_mb, int i_s, int i_structure ) +static void MotionFrameField( vpar_thread_t * p_vpar, + macroblock_t * p_mb, + motion_t * p_motion, + boolean_t b_average ) { - int i_r_size = i_s ? p_vpar->picture.i_backward_f_code - 1 : - p_vpar->picture.i_forward_f_code - 1; - MotionVector( p_vpar, p_mb, 0, i_s, - p_vpar->picture.pb_full_pel_vector[i_s], FRAME_STRUCTURE, - i_r_size, i_r_size ); + int i_motion_x, i_motion_y, i_field_select; + int i_offset = p_vpar->mb.i_offset; + int i_width = p_vpar->picture.i_field_width; + + i_field_select = GetSignedBits( &p_vpar->bit_stream, 1 ); + + i_motion_x = p_motion->ppi_pmv[0][0] + + MotionDelta( p_vpar, p_motion->pi_f_code[0] ); + i_motion_x = BoundMotionVector( i_motion_x, p_motion->pi_f_code[0] ); + p_motion->ppi_pmv[0][0] = i_motion_x; + + i_motion_y = (p_motion->ppi_pmv[0][1] >> 1) + + MotionDelta( p_vpar, p_motion->pi_f_code[1] ); + /* I have no idea why this is commented out, since walken doesn't put + * comments in its code. --Meuuh */ + /* i_motion_y = BoundMotionVector( i_motion_y, p_motion->pi_f_code[1] ); */ + p_motion->ppi_pmv[0][1] = i_motion_y << 1; + + MOTION_BLOCK( b_average, i_motion_x, i_motion_y, i_offset, + p_motion->pppi_ref[0], i_offset + (i_field_select & i_width), + i_width * 2, 8, 0 ); + + i_field_select = GetSignedBits( &p_vpar->bit_stream, 1 ); + + i_motion_x = p_motion->ppi_pmv[1][0] + + MotionDelta( p_vpar, p_motion->pi_f_code[0] ); + i_motion_x = BoundMotionVector( i_motion_x, p_motion->pi_f_code[0] ); + p_motion->ppi_pmv[1][0] = i_motion_x; + + i_motion_y = (p_motion->ppi_pmv[1][1] >> 1) + + MotionDelta( p_vpar, p_motion->pi_f_code[1] ); + /* i_motion_y = BoundMotionVector( i_motion_y, p_motion->pi_f_code[1] ); */ + p_motion->ppi_pmv[1][1] = i_motion_y << 1; + + MOTION_BLOCK( b_average, i_motion_x, i_motion_y, i_offset + i_width, + p_motion->pppi_ref[0], i_offset + (i_field_select & i_width), + i_width * 2, 8, 0 ); } -/***************************************************************************** - * DecodeMVMPEG2 : Parse the next MPEG-2 motion_vectors field - *****************************************************************************/ -static void DecodeMVMPEG2( vpar_thread_t * p_vpar, - macroblock_t * p_mb, int i_s, int i_structure ) +static void MotionFrameDMV( vpar_thread_t * p_vpar, + macroblock_t * p_mb, + motion_t * p_motion, + boolean_t b_average ) { - if( p_vpar->mb.i_mv_count == 1 ) - { - if( p_vpar->mb.i_mv_format == MOTION_FIELD && !p_vpar->mb.b_dmv ) - { - p_mb->ppi_field_select[0][i_s] = p_mb->ppi_field_select[1][i_s] - = GetBits( &p_vpar->bit_stream, 1 ); - } - MotionVector( p_vpar, p_mb, 0, i_s, 0, i_structure, - p_vpar->picture.ppi_f_code[i_s][0] - 1, - p_vpar->picture.ppi_f_code[i_s][1] - 1 ); - p_vpar->mb.pppi_pmv[1][i_s][0] = p_vpar->mb.pppi_pmv[0][i_s][0]; - p_vpar->mb.pppi_pmv[1][i_s][1] = p_vpar->mb.pppi_pmv[0][i_s][1]; - p_mb->pppi_motion_vectors[1][i_s][0] = p_vpar->mb.pppi_pmv[0][i_s][0]; - p_mb->pppi_motion_vectors[1][i_s][1] = p_vpar->mb.pppi_pmv[0][i_s][1]; - } - else - { - p_mb->ppi_field_select[0][i_s] = GetBits( &p_vpar->bit_stream, 1 ); - MotionVector( p_vpar, p_mb, 0, i_s, 0, i_structure, - p_vpar->picture.ppi_f_code[i_s][0] - 1, - p_vpar->picture.ppi_f_code[i_s][1] - 1 ); - p_mb->ppi_field_select[1][i_s] = GetBits( &p_vpar->bit_stream, 1 ); - MotionVector( p_vpar, p_mb, 1, i_s, 0, i_structure, - p_vpar->picture.ppi_f_code[i_s][0] - 1, - p_vpar->picture.ppi_f_code[i_s][1] - 1 ); - } + int i_motion_x, i_motion_y; + int i_dmv_x, i_dmv_y; + int i_tmp_x, i_tmp_y; + + int i_offset = p_vpar->mb.i_offset; + int i_width = p_vpar->picture.i_field_width; + int m; + + i_motion_x = p_motion->ppi_pmv[0][0] + + MotionDelta( p_vpar, p_motion->pi_f_code[0] ); + i_motion_x = BoundMotionVector( i_motion_x, p_motion->pi_f_code[0] ); + p_motion->ppi_pmv[1][0] = p_motion->ppi_pmv[0][0] = i_motion_x; + + i_dmv_x = GetDMV( p_vpar ); + + i_motion_y = (p_motion->ppi_pmv[0][1] >> 1) + + MotionDelta( p_vpar, p_motion->pi_f_code[1] ); + /* i_motion_y = BoundMotionVector( i_motion_y, p_motion->pi_f_code[1] ); */ + p_motion->ppi_pmv[1][1] = p_motion->ppi_pmv[0][1] = i_motion_y << 1; + + i_dmv_y = GetDMV( p_vpar ); + + /* First field. */ + MOTION_BLOCK( 0, i_motion_x, i_motion_y, i_offset, + p_motion->pppi_ref[0], i_offset, i_width * 2, 8, 0 ); + m = p_vpar->picture.b_top_field_first ? 1 : 3; + i_tmp_x = ((i_motion_x * m + (i_motion_x > 0)) >> 1) + i_dmv_x; + i_tmp_y = ((i_motion_y * m + (i_motion_y > 0)) >> 1) + i_dmv_y - 1; + MOTION_BLOCK( 1, i_tmp_x, i_tmp_y, i_offset, p_motion->pppi_ref[0], + i_offset + i_width, i_width * 2, 8, 0 ); + + /* Second field. */ + MOTION_BLOCK( 0, i_motion_x, i_motion_y, i_offset + i_width, + p_motion->pppi_ref[0], i_offset + i_width, i_width * 2, 8, 0 ); + m = p_vpar->picture.b_top_field_first ? 3 : 1; + i_tmp_x = ((i_motion_x * m + (i_motion_x > 0)) >> 1) + i_dmv_x; + i_tmp_y = ((i_motion_y * m + (i_motion_y > 0)) >> 1) + i_dmv_y + 1; + MOTION_BLOCK( 1, i_tmp_x, i_tmp_y, i_offset + i_width, + p_motion->pppi_ref[0], i_offset, i_width * 2, 8, 0 ); } - -/* - * Macroblock information structures - */ - -/***************************************************************************** - * MacroblockAddressIncrement : Get the macroblock_address_increment field - *****************************************************************************/ -static __inline__ int MacroblockAddressIncrement( vpar_thread_t * p_vpar ) +static void MotionFrameZero( vpar_thread_t * p_vpar, + macroblock_t * p_mb, + motion_t * p_motion, + boolean_t b_average ) { - int i_addr_inc = 0; - /* Index in the lookup table mb_addr_inc */ - int i_index = ShowBits( &p_vpar->bit_stream, 11 ); - - /* Test the presence of the escape character */ - while( i_index == 8 ) - { - RemoveBits( &p_vpar->bit_stream, 11 ); - i_addr_inc += 33; - i_index = ShowBits( &p_vpar->bit_stream, 11 ); - } + int i_offset = p_vpar->mb.i_offset; + int i_width = p_vpar->picture.i_field_width; - /* Affect the value from the lookup table */ - i_addr_inc += p_vpar->pl_mb_addr_inc[i_index].i_value; - - /* Dump the good number of bits */ - RemoveBits( &p_vpar->bit_stream, p_vpar->pl_mb_addr_inc[i_index].i_length ); - - return i_addr_inc; + MOTION_BLOCK( b_average, 0, 0, i_offset, p_motion->pppi_ref[0], + i_offset, i_width, 16, 0 ); } -/***************************************************************************** - * IMBType : macroblock_type in I pictures - *****************************************************************************/ -static __inline__ int IMBType( vpar_thread_t * p_vpar ) +static void MotionFrameReuse( vpar_thread_t * p_vpar, + macroblock_t * p_mb, + motion_t * p_motion, + boolean_t b_average ) { - /* Take two bits for testing */ - int i_type = ShowBits( &p_vpar->bit_stream, 2 ); - - /* Lookup table for macroblock_type */ - static lookup_t pl_mb_Itype[4] = { {MB_ERROR, 0}, - {MB_QUANT|MB_INTRA, 2}, - {MB_INTRA, 1}, - {MB_INTRA, 1} }; - /* Dump the good number of bits */ - RemoveBits( &p_vpar->bit_stream, pl_mb_Itype[i_type].i_length ); - return pl_mb_Itype[i_type].i_value; + int i_offset = p_vpar->mb.i_offset; + int i_width = p_vpar->picture.i_field_width; + + MOTION_BLOCK( b_average, p_motion->ppi_pmv[0][0], p_motion->ppi_pmv[0][1], + i_offset, p_motion->pppi_ref[0], i_offset, i_width, 16, 0 ); } -/***************************************************************************** - * PMBType : macroblock_type in P pictures - *****************************************************************************/ -static __inline__ int PMBType( vpar_thread_t * p_vpar ) +/* MPEG-2 field predictions. */ + +static void MotionFieldField( vpar_thread_t * p_vpar, + macroblock_t * p_mb, + motion_t * p_motion, + boolean_t b_average ) { - /* Testing on 6 bits */ - int i_type = ShowBits( &p_vpar->bit_stream, 6 ); + int i_motion_x, i_motion_y; + boolean_t b_field_select; + int i_offset = p_vpar->mb.i_offset; + int i_width = p_vpar->picture.i_field_width; - /* Dump the good number of bits */ - RemoveBits( &p_vpar->bit_stream, p_vpar->ppl_mb_type[0][i_type].i_length ); - /* return the value from the lookup table for P type */ - return p_vpar->ppl_mb_type[0][i_type].i_value; -} + b_field_select = GetBits( &p_vpar->bit_stream, 1 ); -/***************************************************************************** - * BMBType : macroblock_type in B pictures - *****************************************************************************/ -static __inline__ int BMBType( vpar_thread_t * p_vpar ) -{ - /* Testing on 6 bits */ - int i_type = ShowBits( &p_vpar->bit_stream, 6 ); + i_motion_x = p_motion->ppi_pmv[0][0] + + MotionDelta( p_vpar, p_motion->pi_f_code[0] ); + i_motion_x = BoundMotionVector( i_motion_x, p_motion->pi_f_code[0] ); + p_motion->ppi_pmv[1][0] = p_motion->ppi_pmv[0][0] = i_motion_x; - /* Dump the good number of bits */ - RemoveBits( &p_vpar->bit_stream, p_vpar->ppl_mb_type[1][i_type].i_length ); + i_motion_y = p_motion->ppi_pmv[0][1] + + MotionDelta( p_vpar, p_motion->pi_f_code[1] ); + i_motion_y = BoundMotionVector( i_motion_y, p_motion->pi_f_code[1] ); + p_motion->ppi_pmv[1][1] = p_motion->ppi_pmv[0][1] = i_motion_y; - /* return the value from the lookup table for B type */ - return p_vpar->ppl_mb_type[1][i_type].i_value; + MOTION_BLOCK( b_average, i_motion_x, i_motion_y, i_offset, + p_motion->pppi_ref[b_field_select], i_offset, i_width, 16, 0 ); } -/***************************************************************************** - * DMBType : macroblock_type in D pictures - *****************************************************************************/ -static __inline__ int DMBType( vpar_thread_t * p_vpar ) +static void MotionField16x8( vpar_thread_t * p_vpar, + macroblock_t * p_mb, + motion_t * p_motion, + boolean_t b_average ) { - return GetBits( &p_vpar->bit_stream, 1 ); + int i_motion_x, i_motion_y; + boolean_t b_field_select; + int i_offset = p_vpar->mb.i_offset; + int i_width = p_vpar->picture.i_field_width; + + /* First half. */ + b_field_select = GetBits( &p_vpar->bit_stream, 1 ); + + i_motion_x = p_motion->ppi_pmv[0][0] + + MotionDelta( p_vpar, p_motion->pi_f_code[0] ); + i_motion_x = BoundMotionVector( i_motion_x, p_motion->pi_f_code[0] ); + p_motion->ppi_pmv[0][0] = i_motion_x; + + i_motion_y = p_motion->ppi_pmv[0][1] + + MotionDelta( p_vpar, p_motion->pi_f_code[1] ); + i_motion_y = BoundMotionVector( i_motion_y, p_motion->pi_f_code[1] ); + p_motion->ppi_pmv[0][1] = i_motion_y; + + MOTION_BLOCK( b_average, i_motion_x, i_motion_y, i_offset, + p_motion->pppi_ref[b_field_select], i_offset, i_width, 8, 0 ); + + /* Second half. */ + b_field_select = GetBits( &p_vpar->bit_stream, 1 ); + + i_motion_x = p_motion->ppi_pmv[1][0] + + MotionDelta( p_vpar, p_motion->pi_f_code[0] ); + i_motion_x = BoundMotionVector( i_motion_x, p_motion->pi_f_code[0] ); + p_motion->ppi_pmv[1][0] = i_motion_x; + + i_motion_y = p_motion->ppi_pmv[1][1] + + MotionDelta( p_vpar, p_motion->pi_f_code[1] ); + i_motion_y = BoundMotionVector( i_motion_y, p_motion->pi_f_code[1] ); + p_motion->ppi_pmv[1][1] = i_motion_y; + + MOTION_BLOCK( b_average, i_motion_x, i_motion_y, i_offset, + p_motion->pppi_ref[b_field_select], i_offset, i_width, 8, 1 ); } -/***************************************************************************** - * CodedPattern420 : coded_block_pattern with 4:2:0 chroma - *****************************************************************************/ -static __inline__ int CodedPattern420( vpar_thread_t * p_vpar ) +static void MotionFieldDMV( vpar_thread_t * p_vpar, + macroblock_t * p_mb, + motion_t * p_motion, + boolean_t b_average ) { - /* Take the max 9 bits length vlc code for testing */ - int i_vlc = ShowBits( &p_vpar->bit_stream, 9 ); + int i_motion_x, i_motion_y; + int i_dmv_x, i_dmv_y; + int i_offset = p_vpar->mb.i_offset; + int i_width = p_vpar->picture.i_field_width; + boolean_t b_current_field = p_vpar->picture.b_current_field; + + i_motion_x = p_motion->ppi_pmv[0][0] + + MotionDelta( p_vpar, p_motion->pi_f_code[0] ); + i_motion_x = BoundMotionVector( i_motion_x, p_motion->pi_f_code[0] ); + p_motion->ppi_pmv[1][0] = p_motion->ppi_pmv[0][0] = i_motion_x; + + i_dmv_x = GetDMV( p_vpar ); + + i_motion_y = p_motion->ppi_pmv[0][1] + + MotionDelta( p_vpar, p_motion->pi_f_code[1] ); + i_motion_y = BoundMotionVector( i_motion_y, p_motion->pi_f_code[1] ); + p_motion->ppi_pmv[1][1] = p_motion->ppi_pmv[0][1] = i_motion_y; + + i_dmv_y = GetDMV( p_vpar ); + + MOTION_BLOCK( 0, i_motion_x, i_motion_y, i_offset, + p_motion->pppi_ref[b_current_field], + i_offset, i_width, 16, 0 ); + + i_motion_x = ((i_motion_x + (i_motion_x > 0)) >> 1) + i_dmv_x; + i_motion_y = ((i_motion_y + (i_motion_y > 0)) >> 1) + i_dmv_y + + 2 * b_current_field - 1; + MOTION_BLOCK( 1, i_motion_x, i_motion_y, i_offset, + p_motion->pppi_ref[!b_current_field], + i_offset, i_width, 16, 0 ); +} - /* Trash the good number of bits read in the lookup table */ - RemoveBits( &p_vpar->bit_stream, pl_coded_pattern[i_vlc].i_length ); +static void MotionFieldZero( vpar_thread_t * p_vpar, + macroblock_t * p_mb, + motion_t * p_motion, + boolean_t b_average ) +{ + int i_offset = p_vpar->mb.i_offset; + int i_width = p_vpar->picture.i_field_width; + boolean_t b_current_field = p_vpar->picture.b_current_field; - /* return the value from the vlc table */ - return pl_coded_pattern[i_vlc].i_value; + MOTION_BLOCK( b_average, 0, 0, i_offset, p_motion->pppi_ref[b_current_field], + i_offset, i_width, 16, 0 ); } -/***************************************************************************** - * CodedPattern422 : coded_block_pattern with 4:2:2 chroma - *****************************************************************************/ -static __inline__ int CodedPattern422( vpar_thread_t * p_vpar ) +static void MotionFieldReuse( vpar_thread_t * p_vpar, + macroblock_t * p_mb, + motion_t * p_motion, + boolean_t b_average ) { - int i_vlc = ShowBits( &p_vpar->bit_stream, 9 ); - - RemoveBits( &p_vpar->bit_stream, pl_coded_pattern[i_vlc].i_length ); + int i_offset = p_vpar->mb.i_offset; + int i_width = p_vpar->picture.i_field_width; + boolean_t b_current_field = p_vpar->picture.b_current_field; - /* Supplementary 2 bits long code for 4:2:2 format */ - return pl_coded_pattern[i_vlc].i_value | - (GetBits( &p_vpar->bit_stream, 2 ) << 6); + MOTION_BLOCK( b_average, p_motion->ppi_pmv[0][0], p_motion->ppi_pmv[0][1], + i_offset, p_motion->pppi_ref[b_current_field], + i_offset, i_width, 16, 0 ); } -/***************************************************************************** - * CodedPattern444 : coded_block_pattern with 4:4:4 chroma - *****************************************************************************/ -static __inline__ int CodedPattern444( vpar_thread_t * p_vpar ) +/* MPEG-2 concealment motion vectors. */ + +static void MotionFrameConceal( vpar_thread_t * p_vpar, + macroblock_t * p_mv, + motion_t * p_motion ) { - int i_vlc = ShowBits( &p_vpar->bit_stream, 9 ); + int i_tmp; + + i_tmp = p_motion->ppi_pmv[0][0] + + MotionDelta( p_vpar, p_motion->pi_f_code[0] ); + i_tmp = BoundMotionVector( i_tmp, p_motion->pi_f_code[0] ); + p_motion->ppi_pmv[1][0] = p_motion->ppi_pmv[0][0] = i_tmp; - RemoveBits( &p_vpar->bit_stream, pl_coded_pattern[i_vlc].i_length ); + i_tmp = p_motion->ppi_pmv[0][1] + + MotionDelta( p_vpar, p_motion->pi_f_code[1] ); + i_tmp = BoundMotionVector( i_tmp, p_motion->pi_f_code[1] ); + p_motion->ppi_pmv[1][1] = p_motion->ppi_pmv[0][1] = i_tmp; - return pl_coded_pattern[i_vlc].i_value | - (GetBits( &p_vpar->bit_stream, 6 ) << 6); + /* Marker bit. */ + RemoveBits( &p_vpar->bit_stream, 1 ); } -/***************************************************************************** - * InitMacroblock : Initialize macroblock values - *****************************************************************************/ -static __inline__ void InitMacroblock( vpar_thread_t * p_vpar, - macroblock_t * p_mb, int i_coding_type, - int i_structure ) +static void MotionFieldConceal( vpar_thread_t * p_vpar, + macroblock_t * p_mv, + motion_t * p_motion ) { - int i_chroma_format = CHROMA_420; /* FIXME : MP@ML */ + int i_tmp; - p_mb->i_chroma_nb_blocks = 1 << i_chroma_format; - p_mb->p_picture = p_vpar->picture.p_picture; + /* field_select */ + RemoveBits( &p_vpar->bit_stream, 1 ); - if( i_coding_type == B_CODING_TYPE ) - p_mb->p_backward = p_vpar->sequence.p_backward; - else - p_mb->p_backward = NULL; + i_tmp = p_motion->ppi_pmv[0][0] + + MotionDelta( p_vpar, p_motion->pi_f_code[0] ); + i_tmp = BoundMotionVector( i_tmp, p_motion->pi_f_code[0] ); + p_motion->ppi_pmv[1][0] = p_motion->ppi_pmv[0][0] = i_tmp; - if( (i_coding_type == P_CODING_TYPE) || (i_coding_type == B_CODING_TYPE) ) - p_mb->p_forward = p_vpar->sequence.p_forward; - else - p_mb->p_forward = NULL; + i_tmp = p_motion->ppi_pmv[0][1] + + MotionDelta( p_vpar, p_motion->pi_f_code[1] ); + i_tmp = BoundMotionVector( i_tmp, p_motion->pi_f_code[1] ); + p_motion->ppi_pmv[1][1] = p_motion->ppi_pmv[0][1] = i_tmp; - p_mb->i_l_x = p_vpar->mb.i_l_x; - p_mb->i_c_x = p_vpar->mb.i_c_x; - p_mb->i_motion_l_y = p_vpar->mb.i_l_y; - p_mb->i_motion_c_y = p_vpar->mb.i_c_y; - if( (p_mb->b_motion_field = (i_structure == BOTTOM_FIELD)) ) - { - p_mb->i_motion_l_y--; - p_mb->i_motion_c_y--; - } - p_mb->i_addb_l_stride = (p_mb->i_l_stride = p_vpar->picture.i_l_stride) - 8; - p_mb->i_addb_c_stride = (p_mb->i_c_stride = p_vpar->picture.i_c_stride) - 8; - p_mb->b_P_second = ( (i_structure != p_vpar->picture.i_current_structure) - && i_coding_type == P_CODING_TYPE ); + /* Marker bit. */ + RemoveBits( &p_vpar->bit_stream, 1 ); } -/***************************************************************************** - * UpdateContext : Update the p_vpar contextual values - *****************************************************************************/ -static __inline__ void UpdateContext( vpar_thread_t * p_vpar, int i_structure ) -{ - /* Update macroblock real position. */ - p_vpar->mb.i_l_x += 16; - p_vpar->mb.i_l_y += (p_vpar->mb.i_l_x / p_vpar->sequence.i_width) - * (2 - (i_structure == FRAME_STRUCTURE)) * 16; - p_vpar->mb.i_l_x %= p_vpar->sequence.i_width; - - p_vpar->mb.i_c_x += p_vpar->sequence.i_chroma_mb_width; - p_vpar->mb.i_c_y += (p_vpar->mb.i_c_x / p_vpar->sequence.i_chroma_width) - * (2 - (i_structure == FRAME_STRUCTURE)) - * p_vpar->sequence.i_chroma_mb_height; - p_vpar->mb.i_c_x %= p_vpar->sequence.i_chroma_width; -} + +/* + * Macroblock information structures + */ /***************************************************************************** - * SkippedMacroblock : Generate a skipped macroblock with NULL motion vector + * MacroblockAddressIncrement : Get the macroblock_address_increment field *****************************************************************************/ -static __inline__ void SkippedMacroblock( vpar_thread_t * p_vpar, int i_mb, - int i_mb_base, int i_coding_type, - int i_structure ) +static __inline__ int MacroblockAddressIncrement( vpar_thread_t * p_vpar ) { - macroblock_t * p_mb; - int i_chroma_format = CHROMA_420; /* FIXME : MP@ML */ + lookup_t * p_tab; + int i_code; + int i_mba = 0; - if( i_coding_type == I_CODING_TYPE ) + for( ; ; ) { - intf_WarnMsg( 2, "skipped macroblock in I-picture" ); - p_vpar->picture.b_error = 1; - return; - } - - p_mb = p_vpar->pool.pf_new_mb( &p_vpar->pool ); + if( (i_code = ShowBits( &p_vpar->bit_stream, 5 ) ) >= 0x2 ) + { + p_tab = MBA_5 - 2 + i_code; + RemoveBits( &p_vpar->bit_stream, p_tab->i_length ); + return( i_mba + p_tab->i_value ); + } + else if( (i_code = ShowBits( &p_vpar->bit_stream, 11 )) >= 0x18 ) + { + p_tab = MBA_11 - 24 + i_code; + RemoveBits( &p_vpar->bit_stream, p_tab->i_length ); + return( i_mba + p_tab->i_value ); + } + else switch( i_code ) + { + case 8: + /* Macroblock escape */ + i_mba += 33; + /* continue... */ + case 15: + /* Macroblock stuffing (MPEG-1 ONLY) */ + RemoveBits( &p_vpar->bit_stream, 11 ); + break; - InitMacroblock( p_vpar, p_mb, i_coding_type, i_structure ); + default: + /* End of slice, or error */ + return 0; + } + } +} - /* Motion type is picture structure. */ - p_mb->pf_motion = p_vpar->ppf_motion_skipped[i_chroma_format] - [i_structure]; - p_mb->i_coded_block_pattern = 0; +/***************************************************************************** + * CodedPattern : coded_block_pattern + *****************************************************************************/ +static __inline__ int CodedPattern( vpar_thread_t * p_vpar ) +{ + lookup_t * p_tab; + int i_code; - /* Motion direction and motion vectors depend on the coding type. */ - if( i_coding_type == B_CODING_TYPE ) + if( (i_code = ShowBits( &p_vpar->bit_stream, 7 )) >= 0x10 ) /* ? */ { - p_mb->i_mb_type = p_vpar->mb.i_motion_dir; - memcpy( p_mb->pppi_motion_vectors, p_vpar->mb.pppi_pmv, - sizeof( p_vpar->mb.pppi_pmv ) ); + p_tab = CBP_7 - 16 + i_code; + RemoveBits( &p_vpar->bit_stream, p_tab->i_length ); + return( p_tab->i_value ); } else { - p_mb->i_mb_type = MB_MOTION_FORWARD; - bzero8int( p_mb->pppi_motion_vectors ); + p_tab = CBP_9 + ShowBits( &p_vpar->bit_stream, 9 ); + RemoveBits( &p_vpar->bit_stream, p_tab->i_length ); + return( p_tab->i_value ); } - - /* Set the field we use for motion compensation */ - p_mb->ppi_field_select[0][0] = p_mb->ppi_field_select[0][1] - = ( i_structure == BOTTOM_FIELD ); - - UpdateContext( p_vpar, i_structure ); - - /* Decode the macroblock NOW ! */ - p_vpar->pool.pf_decode_mb( &p_vpar->pool, p_mb ); } /***************************************************************************** * MacroblockModes : Get the macroblock_modes structure *****************************************************************************/ -static __inline__ void MacroblockModes( vpar_thread_t * p_vpar, - macroblock_t * p_mb, - int i_coding_type, - int i_structure ) +static __inline__ int MacroblockModes( vpar_thread_t * p_vpar, + macroblock_t * p_mb, + int i_coding_type, + int i_structure ) { - static int ppi_mv_count[2][4] = { {0, 1, 2, 1}, {0, 2, 1, 1} }; - static int ppi_mv_format[2][4] = { {0, 1, 1, 1}, {0, 1, 2, 1} }; + int i_mb_modes; + lookup_t * p_tab; - /* Get macroblock_type. */ switch( i_coding_type ) { - case P_CODING_TYPE: - p_mb->i_mb_type = PMBType( p_vpar ); - break; - case B_CODING_TYPE: - p_mb->i_mb_type = BMBType( p_vpar ); - break; case I_CODING_TYPE: - p_mb->i_mb_type = IMBType( p_vpar ); - break; - case D_CODING_TYPE: - p_mb->i_mb_type = DMBType( p_vpar ); - } + p_tab = MB_I + ShowBits( &p_vpar->bit_stream, 1 ); + RemoveBits( &p_vpar->bit_stream, p_tab->i_length ); + i_mb_modes = p_tab->i_value; - if( i_coding_type == B_CODING_TYPE ) - { - /* We need to remember the motion direction of the last macroblock - * before a skipped macroblock (ISO/IEC 13818-2 7.6.6) */ - p_vpar->mb.i_motion_dir = p_mb->i_mb_type - & (MB_MOTION_FORWARD | MB_MOTION_BACKWARD); - } + if( (i_structure == FRAME_STRUCTURE) && + (!p_vpar->picture.b_frame_pred_frame_dct) ) + { + i_mb_modes |= GetBits( &p_vpar->bit_stream, 1 ) + * DCT_TYPE_INTERLACED; + } + return( i_mb_modes ); - /* SCALABILITY : warning, we don't know if spatial_temporal_weight_code - * has to be dropped, take care if you use scalable streams. */ - /* RemoveBits( &p_vpar->bit_stream, 2 ); */ + case P_CODING_TYPE: + p_tab = MB_P + ShowBits( &p_vpar->bit_stream, 5 ); + RemoveBits( &p_vpar->bit_stream, p_tab->i_length ); + i_mb_modes = p_tab->i_value; - if( (i_coding_type == P_CODING_TYPE || i_coding_type == B_CODING_TYPE) - && (p_mb->i_mb_type & (MB_MOTION_FORWARD | MB_MOTION_BACKWARD)) ) - { - if( !(i_structure == FRAME_STRUCTURE - && p_vpar->picture.b_frame_pred_frame_dct) ) + if( i_structure != FRAME_STRUCTURE ) + { + if( i_mb_modes & MB_MOTION_FORWARD ) + { + i_mb_modes |= GetBits( &p_vpar->bit_stream, 2 ) + * MOTION_TYPE_BASE; + } + return( i_mb_modes ); + } + else if( p_vpar->picture.b_frame_pred_frame_dct ) { - p_vpar->mb.i_motion_type = GetBits( &p_vpar->bit_stream, 2 ); + if( i_mb_modes & MB_MOTION_FORWARD ) + { + i_mb_modes |= MC_FRAME; + } + return( i_mb_modes ); } else { - p_vpar->mb.i_motion_type = MOTION_FRAME; + if( i_mb_modes & MB_MOTION_FORWARD ) + { + i_mb_modes |= GetBits( &p_vpar->bit_stream, 2 ) + * MOTION_TYPE_BASE; + } + if( i_mb_modes & (MB_INTRA | MB_PATTERN) ) + { + i_mb_modes |= GetBits( &p_vpar->bit_stream, 1 ) + * DCT_TYPE_INTERLACED; + } + return( i_mb_modes ); } - /* XXX?? */ - p_vpar->mb.i_mv_count = ppi_mv_count[i_structure == FRAME_STRUCTURE] - [p_vpar->mb.i_motion_type]; - p_vpar->mb.i_mv_format = ppi_mv_format[i_structure == FRAME_STRUCTURE] - [p_vpar->mb.i_motion_type]; - p_vpar->mb.b_dmv = p_vpar->mb.i_motion_type == MOTION_DMV; - } + case B_CODING_TYPE: + p_tab = MB_B + ShowBits( &p_vpar->bit_stream, 6 ); + RemoveBits( &p_vpar->bit_stream, p_tab->i_length ); + i_mb_modes = p_tab->i_value; - p_vpar->mb.b_dct_type = 0; - if( (i_structure == FRAME_STRUCTURE) && - (!p_vpar->picture.b_frame_pred_frame_dct) && - (p_mb->i_mb_type & (MB_PATTERN|MB_INTRA)) ) - { - if( (p_vpar->mb.b_dct_type = GetBits( &p_vpar->bit_stream, 1 )) ) + if( i_structure != FRAME_STRUCTURE ) { - /* The DCT is coded on fields. Jump one line between each - * sample. */ - p_mb->i_addb_l_stride <<= 1; - p_mb->i_addb_l_stride += 8; -#if 0 - /* FIXME: MP@ML */ - /* With CHROMA_420, the DCT is necessarily frame-coded. */ - if( i_chroma_format != CHROMA_420 ) + if( !( i_mb_modes & MB_INTRA ) ) { - p_mb->i_addb_c_stride <<= 1; - p_mb->i_addb_c_stride += 8; + i_mb_modes |= GetBits( &p_vpar->bit_stream, 2 ) + * MOTION_TYPE_BASE; } -#endif + return( i_mb_modes ); + } + else if( p_vpar->picture.b_frame_pred_frame_dct ) + { + i_mb_modes |= MC_FRAME; + return( i_mb_modes ); + } + else + { + if( i_mb_modes & MB_INTRA ) + { + goto mb_intra; + } + i_mb_modes |= GetBits( &p_vpar->bit_stream, 2 ) + * MOTION_TYPE_BASE; + if( i_mb_modes & (MB_INTRA | MB_PATTERN) ) + { +mb_intra: + i_mb_modes |= GetBits( &p_vpar->bit_stream, 1 ) + * DCT_TYPE_INTERLACED; + } + return( i_mb_modes ); } + + case D_CODING_TYPE: + RemoveBits( &p_vpar->bit_stream, 1 ); + return( MB_INTRA ); + + default: + return( 0 ); } } + +/* + * Picture data parsing management + */ + /***************************************************************************** - * ParseMacroblock : Parse the next macroblock + * ParseSlice : Parse the next slice structure *****************************************************************************/ -#define PARSEERROR \ -if( p_vpar->picture.b_error ) \ -{ \ - /* Go to the next slice. */ \ - p_vpar->pool.pf_free_mb( &p_vpar->pool, p_mb ); \ - return; \ -} +#define MOTION( pf_routine, i_direction ) \ + if( (i_direction) & MB_MOTION_FORWARD ) \ + { \ + pf_routine( p_vpar, p_mb, &p_vpar->mb.f_motion, 0 ); \ + if( (i_coding_type == B_CODING_TYPE) \ + && ((i_direction) & MB_MOTION_BACKWARD) ) \ + { \ + pf_routine( p_vpar, p_mb, &p_vpar->mb.b_motion, 1 ); \ + } \ + } \ + else if( (i_coding_type == B_CODING_TYPE) \ + && ((i_direction) & MB_MOTION_BACKWARD) ) \ + { \ + pf_routine( p_vpar, p_mb, &p_vpar->mb.b_motion, 0 ); \ + } + +#define CHECK_BOUNDARIES \ + i_offset = p_vpar->mb.i_offset; \ + if( i_offset == i_width ) \ + { \ + if( i_coding_type != I_CODING_TYPE || \ + p_vpar->picture.b_concealment_mv ) \ + { \ + p_f_motion->pppi_ref[0][0] += 16 * i_offset; \ + p_f_motion->pppi_ref[0][1] += 4 * i_offset; \ + p_f_motion->pppi_ref[0][2] += 4 * i_offset; \ + } \ + if( i_coding_type == B_CODING_TYPE ) \ + { \ + p_b_motion->pppi_ref[0][0] += 16 * i_offset; \ + p_b_motion->pppi_ref[0][1] += 4 * i_offset; \ + p_b_motion->pppi_ref[0][2] += 4 * i_offset; \ + } \ + p_dest[0] += 16 * i_offset; \ + p_dest[1] += 4 * i_offset; \ + p_dest[2] += 4 * i_offset; \ + i_offset = 0; \ + } \ + p_vpar->mb.i_offset = i_offset; + +#define PARSEERROR \ + if( p_vpar->picture.b_error ) \ + { \ + /* Go to the next slice. */ \ + p_vpar->pool.pf_free_mb( &p_vpar->pool, p_mb ); \ + return; \ + } -static __inline__ void ParseMacroblock( - vpar_thread_t * p_vpar, - int * pi_mb_address, /* previous address to be - * used for mb_addr_incr */ - int i_mb_previous, /* actual previous mb */ - int i_mb_base, /* non-zero if field structure */ - /* The following parameters are explicit in - * optimized routines : */ - boolean_t b_mpeg2, /* you know what ? */ - int i_coding_type, /* I, P, B or D */ - int i_structure ) /* T(OP), B(OTTOM) or F(RAME) */ +static __inline__ void ParseSlice( vpar_thread_t * p_vpar, + u32 i_vert_code, boolean_t b_mpeg2, + int i_coding_type, int i_structure ) { - int i_mb; - int i_inc; - int i_chroma_format = CHROMA_420; /* FIXME : MP@ML */ - macroblock_t * p_mb; + int i_offset, i_width; + picture_t * pp_forward_ref[2]; + yuv_data_t * p_dest[3]; + + motion_t * p_f_motion = &p_vpar->mb.f_motion; + motion_t * p_b_motion = &p_vpar->mb.b_motion; - i_inc = MacroblockAddressIncrement( p_vpar ); - *pi_mb_address += i_inc; + /* Parse header. */ + LoadQuantizerScale( p_vpar ); - if( i_inc < 0 ) + if( GetBits( &p_vpar->bit_stream, 1 ) ) { - intf_WarnMsg( 2, "Bad address increment (%d)", i_inc ); - p_vpar->picture.b_error = 1; - return; + /* intra_slice, slice_id */ + RemoveBits( &p_vpar->bit_stream, 8 ); + /* extra_information_slice */ + while( GetBits( &p_vpar->bit_stream, 1 ) ) + { + RemoveBits( &p_vpar->bit_stream, 8 ); + } } - if( *pi_mb_address - i_mb_previous - 1 ) - { - /* Skipped macroblock (ISO/IEC 13818-2 7.6.6). */ + /* Calculate the position of the macroblock. */ + i_width = p_vpar->sequence.i_width; + i_offset = (i_vert_code - 1) * i_width * 4; + + /* Initialize motion context. */ + pp_forward_ref[0] = p_vpar->sequence.p_forward; - /* Reset DC predictors (7.2.1). */ - p_vpar->mb.pi_dc_dct_pred[0] = p_vpar->mb.pi_dc_dct_pred[1] - = p_vpar->mb.pi_dc_dct_pred[2] - = 1 << (7 + p_vpar->picture.i_intra_dc_precision); + if( i_structure != FRAME_STRUCTURE ) + { + i_offset <<= 1; + pp_forward_ref[1] = p_vpar->sequence.p_forward; - if( i_coding_type == P_CODING_TYPE ) + if( i_coding_type != B_CODING_TYPE && p_vpar->picture.b_second_field ) { - /* Reset motion vector predictors (ISO/IEC 13818-2 7.6.3.4). */ - bzero8int( p_vpar->mb.pppi_pmv ); + pp_forward_ref[!p_vpar->picture.b_current_field] = + p_vpar->picture.p_picture; } - - for( i_mb = i_mb_previous + 1; i_mb < *pi_mb_address; i_mb++ ) + if( i_coding_type != I_CODING_TYPE || p_vpar->picture.b_concealment_mv ) { - SkippedMacroblock( p_vpar, i_mb, i_mb_base, i_coding_type, - i_structure ); + p_f_motion->pppi_ref[1][0] = + pp_forward_ref[1]->p_y + i_offset * 4 + i_width; + p_f_motion->pppi_ref[1][1] = + pp_forward_ref[1]->p_u + i_offset + (i_width >> 1); + p_f_motion->pppi_ref[1][2] = + pp_forward_ref[1]->p_v + i_offset + (i_width >> 1); + } + if( i_coding_type == B_CODING_TYPE ) + { + p_b_motion->pppi_ref[1][0] = + p_vpar->sequence.p_backward->p_y + i_offset * 4 + i_width; + p_b_motion->pppi_ref[1][1] = + p_vpar->sequence.p_backward->p_u + i_offset + (i_width >> 1); + p_b_motion->pppi_ref[1][2] = + p_vpar->sequence.p_backward->p_v + i_offset + (i_width >> 1); } } - /* Get a macroblock structure. */ - p_mb = p_vpar->pool.pf_new_mb( &p_vpar->pool ); - - InitMacroblock( p_vpar, p_mb, i_coding_type, i_structure ); - - /* Parse off macroblock_modes structure. */ - MacroblockModes( p_vpar, p_mb, i_coding_type, i_structure ); - - if( p_mb->i_mb_type & MB_QUANT ) + if( i_coding_type != I_CODING_TYPE || p_vpar->picture.b_concealment_mv ) { - LoadQuantizerScale( p_vpar ); + p_f_motion->pppi_ref[0][0] = pp_forward_ref[0]->p_y + i_offset * 4; + p_f_motion->pppi_ref[0][1] = pp_forward_ref[0]->p_u + i_offset; + p_f_motion->pppi_ref[0][2] = pp_forward_ref[0]->p_v + i_offset; + p_f_motion->pi_f_code[0] = p_vpar->picture.ppi_f_code[0][0]; + p_f_motion->pi_f_code[1] = p_vpar->picture.ppi_f_code[0][1]; + p_f_motion->ppi_pmv[0][0] = p_f_motion->ppi_pmv[0][1] = 0; + p_f_motion->ppi_pmv[1][0] = p_f_motion->ppi_pmv[1][1] = 0; } - if( (i_coding_type == P_CODING_TYPE || i_coding_type == B_CODING_TYPE) - && (p_mb->i_mb_type & MB_MOTION_FORWARD) ) + if( i_coding_type == B_CODING_TYPE ) { - if( b_mpeg2 ) - DecodeMVMPEG2( p_vpar, p_mb, 0, i_structure ); - else - DecodeMVMPEG1( p_vpar, p_mb, 0, i_structure ); - PARSEERROR + p_b_motion->pppi_ref[0][0] = p_vpar->sequence.p_backward->p_y + + i_offset * 4; + p_b_motion->pppi_ref[0][1] = p_vpar->sequence.p_backward->p_u + + i_offset; + p_b_motion->pppi_ref[0][2] = p_vpar->sequence.p_backward->p_v + + i_offset; + p_b_motion->pi_f_code[0] = p_vpar->picture.ppi_f_code[1][0]; + p_b_motion->pi_f_code[1] = p_vpar->picture.ppi_f_code[1][1]; + p_b_motion->ppi_pmv[0][0] = p_b_motion->ppi_pmv[0][1] = 0; + p_b_motion->ppi_pmv[1][0] = p_b_motion->ppi_pmv[1][1] = 0; } - if( (i_coding_type == B_CODING_TYPE) - && (p_mb->i_mb_type & MB_MOTION_BACKWARD) ) - { - if( b_mpeg2 ) - DecodeMVMPEG2( p_vpar, p_mb, 1, i_structure ); - else - DecodeMVMPEG1( p_vpar, p_mb, 1, i_structure ); - PARSEERROR - } + /* Initialize destination pointers. */ + p_dest[0] = p_vpar->picture.p_picture->p_y + i_offset * 4; + p_dest[1] = p_vpar->picture.p_picture->p_u + i_offset; + p_dest[2] = p_vpar->picture.p_picture->p_v + i_offset; - if( i_coding_type == P_CODING_TYPE - && !(p_mb->i_mb_type & (MB_MOTION_FORWARD|MB_INTRA)) ) + if( i_structure == BOTTOM_FIELD ) { - /* Special No-MC macroblock in P pictures (7.6.3.5). */ - p_mb->i_mb_type |= MB_MOTION_FORWARD; - bzero8int( p_vpar->mb.pppi_pmv ); - bzero8int( p_mb->pppi_motion_vectors ); - p_vpar->mb.i_motion_type = 1 + (i_structure == FRAME_STRUCTURE); - p_mb->ppi_field_select[0][0] = (i_structure == BOTTOM_FIELD); + p_dest[0] += i_width; + p_dest[1] += i_width >> 1; + p_dest[2] += i_width >> 1; } + i_width = p_vpar->picture.i_field_width; + + /* Reset intra DC coefficients predictors (ISO/IEC 13818-2 7.2.1). */ + p_vpar->mb.pi_dc_dct_pred[0] = p_vpar->mb.pi_dc_dct_pred[1] + = p_vpar->mb.pi_dc_dct_pred[2] + = 1 << (7 + p_vpar->picture.i_intra_dc_precision); - if( (i_coding_type != I_CODING_TYPE) && !(p_mb->i_mb_type & MB_INTRA) ) + p_vpar->mb.i_offset = MacroblockAddressIncrement( p_vpar ) << 4; + + for( ; ; ) { - /* Reset DC predictors (7.2.1). */ - p_vpar->mb.pi_dc_dct_pred[0] = p_vpar->mb.pi_dc_dct_pred[1] - = p_vpar->mb.pi_dc_dct_pred[2] - = 1 << (7 + p_vpar->picture.i_intra_dc_precision); + /* Decode macroblocks. */ + macroblock_t * p_mb; + int i_mb_modes; - /* Motion function pointer. */ - p_mb->pf_motion = p_vpar->pppf_motion[i_chroma_format] - [i_structure == FRAME_STRUCTURE] - [p_vpar->mb.i_motion_type]; + /* Get a macroblock structure. */ + p_mb = p_vpar->pool.pf_new_mb( &p_vpar->pool ); + p_mb->i_nb_motions = 0; + p_mb->pp_dest[0] = p_dest[0]; + p_mb->pp_dest[1] = p_dest[1]; + p_mb->pp_dest[2] = p_dest[2]; - if( p_mb->i_mb_type & MB_PATTERN ) - { - switch( i_chroma_format ) - { - case CHROMA_420: - p_mb->i_coded_block_pattern = CodedPattern420( p_vpar ); - break; - case CHROMA_422: - p_mb->i_coded_block_pattern = CodedPattern422( p_vpar ); - break; - case CHROMA_444: - p_mb->i_coded_block_pattern = CodedPattern444( p_vpar ); - } - } - else - { - p_mb->i_coded_block_pattern = 0; - } + /* Parse off macroblock_modes structure. */ + p_mb->i_mb_modes = i_mb_modes = + MacroblockModes( p_vpar, p_mb, i_coding_type, i_structure ); - /* - * Effectively decode blocks. - */ - if( b_mpeg2 ) - DecodeMPEG2NonIntraMB( p_vpar, p_mb ); - else - DecodeMPEG1NonIntraMB( p_vpar, p_mb ); - PARSEERROR - } - else - { - if( !p_vpar->picture.b_concealment_mv ) + if( i_mb_modes & MB_QUANT ) { - /* Reset MV predictors. */ - bzero8int( p_vpar->mb.pppi_pmv ); + LoadQuantizerScale( p_vpar ); } - else + + if( i_mb_modes & MB_INTRA ) { - if( b_mpeg2 ) - DecodeMVMPEG2( p_vpar, p_mb, 0, i_structure ); + if( p_vpar->picture.b_concealment_mv ) + { + if( i_structure == FRAME_STRUCTURE ) + { + MotionFrameConceal( p_vpar, p_mb, p_f_motion ); + } + else + { + MotionFieldConceal( p_vpar, p_mb, p_f_motion ); + } + } else - DecodeMVMPEG1( p_vpar, p_mb, 0, i_structure ); - RemoveBits( &p_vpar->bit_stream, 1 ); - } + { + /* Reset motion vectors predictors. */ + p_f_motion->ppi_pmv[0][0] = p_f_motion->ppi_pmv[0][1] = 0; + p_f_motion->ppi_pmv[1][0] = p_f_motion->ppi_pmv[1][1] = 0; + p_b_motion->ppi_pmv[0][0] = p_b_motion->ppi_pmv[0][1] = 0; + p_b_motion->ppi_pmv[1][0] = p_b_motion->ppi_pmv[1][1] = 0; + } - if( p_mb->i_mb_type & MB_PATTERN ) - { - switch( i_chroma_format ) + /* Decode blocks */ + p_mb->i_coded_block_pattern = (1 << 6) - 1; + if( b_mpeg2 ) { - case CHROMA_420: - p_mb->i_coded_block_pattern = CodedPattern420( p_vpar ); - break; - case CHROMA_422: - p_mb->i_coded_block_pattern = CodedPattern422( p_vpar ); - break; - case CHROMA_444: - p_mb->i_coded_block_pattern = CodedPattern444( p_vpar ); + if( p_vpar->picture.b_intra_vlc_format ) + { + MPEG2IntraB15MB( p_vpar, p_mb ); + } + else + { + MPEG2IntraB14MB( p_vpar, p_mb ); + } + } + else + { + MPEG1IntraMB( p_vpar, p_mb ); } - } - else - { - p_mb->i_coded_block_pattern = - (1 << (4 + (1 << i_chroma_format))) - 1; - } - /* - * Effectively decode blocks. - */ - if( b_mpeg2 ) - { - DecodeMPEG2IntraMB( p_vpar, p_mb ); + if( i_coding_type == D_CODING_TYPE ) + { + RemoveBits( &p_vpar->bit_stream, 1 ); + } } else { - DecodeMPEG1IntraMB( p_vpar, p_mb ); - } - PARSEERROR - } + /* Non-intra block */ + if( !b_mpeg2 ) + { + if( (i_mb_modes & MOTION_TYPE_MASK) == MC_FRAME ) + { + MOTION( MotionMPEG1, i_mb_modes ); + } + else + { + /* Non-intra MB without forward mv in a P picture. */ + p_f_motion->ppi_pmv[0][0] = p_f_motion->ppi_pmv[0][1] = 0; + p_f_motion->ppi_pmv[1][0] = p_f_motion->ppi_pmv[1][1] = 0; + MOTION( MotionFrameZero, MB_MOTION_FORWARD ); + } + } + else if( i_structure == FRAME_STRUCTURE ) + { + switch( i_mb_modes & MOTION_TYPE_MASK ) + { + case MC_FRAME: + MOTION( MotionFrameFrame, i_mb_modes ); + break; + + case MC_FIELD: + MOTION( MotionFrameField, i_mb_modes ); + break; + + case MC_DMV: + MOTION( MotionFrameDMV, MB_MOTION_FORWARD ); + break; + + case 0: + /* Non-intra MB without forward mv in a P picture. */ + p_f_motion->ppi_pmv[0][0] = p_f_motion->ppi_pmv[0][1] = 0; + p_f_motion->ppi_pmv[1][0] = p_f_motion->ppi_pmv[1][1] = 0; + MOTION( MotionFrameZero, MB_MOTION_FORWARD ); + } + } + else + { + /* Field structure. */ + switch( i_mb_modes & MOTION_TYPE_MASK ) + { + case MC_FIELD: + MOTION( MotionFieldField, i_mb_modes ); + break; - if( !p_vpar->picture.b_error ) - { - UpdateContext( p_vpar, i_structure ); + case MC_16X8: + MOTION( MotionField16x8, i_mb_modes ); + break; - /* Decode the macroblock NOW ! */ - p_vpar->pool.pf_decode_mb( &p_vpar->pool, p_mb ); - } - else - { - /* Go to the next slice. */ - p_vpar->pool.pf_free_mb( &p_vpar->pool, p_mb ); - } -} + case MC_DMV: + MOTION( MotionFieldDMV, i_mb_modes ); + break; -#undef PARSEERROR + case 0: + /* Non-intra MB without forward mv in a P picture. */ + p_f_motion->ppi_pmv[0][0] = p_f_motion->ppi_pmv[0][1] = 0; + p_f_motion->ppi_pmv[1][0] = p_f_motion->ppi_pmv[1][1] = 0; + MOTION( MotionFieldZero, MB_MOTION_FORWARD ); + } + } -/* - * Picture data parsing management - */ + /* ISO/IEC 13818-2 6.3.17.4 : Coded Block Pattern */ + if( i_mb_modes & MB_PATTERN ) + { + p_mb->i_coded_block_pattern = CodedPattern( p_vpar ); + if( b_mpeg2 ) + { + MPEG2NonIntraMB( p_vpar, p_mb ); + } + else + { + MPEG1NonIntraMB( p_vpar, p_mb ); + } + } + else + { + p_mb->i_coded_block_pattern = 0; + } -/***************************************************************************** - * SliceHeader : Parse the next slice structure - *****************************************************************************/ -static __inline__ void SliceHeader( vpar_thread_t * p_vpar, - int * pi_mb_address, int i_mb_base, - u32 i_vert_code, boolean_t b_mpeg2, - int i_coding_type, int i_structure ) -{ - int i_mb_address_save = *pi_mb_address; + /* Reset intra DC coefficients predictors. */ + p_vpar->mb.pi_dc_dct_pred[0] = p_vpar->mb.pi_dc_dct_pred[1] + = p_vpar->mb.pi_dc_dct_pred[2] + = 1 << (7 + p_vpar->picture.i_intra_dc_precision); + } -#if 0 - /* FIXME : MP@ML doesn't support this. */ - if( b_high ) - { - /* Picture with more than 2800 lines. */ - i_vert_code += GetBits( &p_vpar->bit_stream, 3 ) << 7; - } - if( b_dp_scalable ) - { - /* DATA_PARTITIONING scalability. */ - RemoveBits( &p_vpar->bit_stream, 7 ); /* priority_breakpoint */ - } -#endif + /* End of macroblock. */ + PARSEERROR; + p_vpar->pool.pf_decode_mb( &p_vpar->pool, p_mb ); - LoadQuantizerScale( p_vpar ); + /* Prepare context for the next macroblock. */ + p_vpar->mb.i_offset += 16; + CHECK_BOUNDARIES; - if( GetBits( &p_vpar->bit_stream, 1 ) ) - { - /* intra_slice, slice_id */ - RemoveBits( &p_vpar->bit_stream, 8 ); - /* extra_information_slice */ - while( GetBits( &p_vpar->bit_stream, 1 ) ) + if( ShowBits( &p_vpar->bit_stream, 1 ) ) { - RemoveBits( &p_vpar->bit_stream, 8 ); + /* Macroblock Address Increment == 1 */ + RemoveBits( &p_vpar->bit_stream, 1 ); } - } - *pi_mb_address = (i_vert_code - 1) * p_vpar->sequence.i_mb_width; - - if( *pi_mb_address < i_mb_address_save ) - { - intf_WarnMsg( 2, "Slices do not follow" ); - p_vpar->picture.b_error = 1; - return; - } - - /* Reset DC coefficients predictors (ISO/IEC 13818-2 7.2.1). */ - p_vpar->mb.pi_dc_dct_pred[0] = p_vpar->mb.pi_dc_dct_pred[1] - = p_vpar->mb.pi_dc_dct_pred[2] - = 1 << (7 + p_vpar->picture.i_intra_dc_precision); + else + { + /* Check for skipped macroblock(s). */ + int i_mba_inc; - /* Reset motion vector predictors (ISO/IEC 13818-2 7.6.3.4). */ - bzero8int( p_vpar->mb.pppi_pmv ); + i_mba_inc = MacroblockAddressIncrement( p_vpar ); + if( !i_mba_inc ) + { + /* End of slice. */ + break; + } - do - { - ParseMacroblock( p_vpar, pi_mb_address, i_mb_address_save, - i_mb_base, b_mpeg2, i_coding_type, i_structure ); + /* Reset intra DC predictors. */ + p_vpar->mb.pi_dc_dct_pred[0] = p_vpar->mb.pi_dc_dct_pred[1] + = p_vpar->mb.pi_dc_dct_pred[2] + = 1 << (7 + p_vpar->picture.i_intra_dc_precision); - i_mb_address_save = *pi_mb_address; - if( p_vpar->picture.b_error ) - { - return; + if( i_coding_type == P_CODING_TYPE ) + { + p_f_motion->ppi_pmv[0][0] = p_f_motion->ppi_pmv[0][1] = 0; + p_f_motion->ppi_pmv[1][0] = p_f_motion->ppi_pmv[1][1] = 0; + + do { + p_mb = p_vpar->pool.pf_new_mb( &p_vpar->pool ); + p_mb->i_mb_modes = 0; + p_mb->i_nb_motions = 0; + p_mb->i_coded_block_pattern = 0; + p_mb->pp_dest[0] = p_dest[0]; + p_mb->pp_dest[1] = p_dest[1]; + p_mb->pp_dest[2] = p_dest[2]; + + if( i_structure == FRAME_STRUCTURE ) + { + MOTION( MotionFrameZero, MB_MOTION_FORWARD ); + } + else + { + MOTION( MotionFieldZero, MB_MOTION_FORWARD ); + } + + p_vpar->pool.pf_decode_mb( &p_vpar->pool, p_mb ); + p_vpar->mb.i_offset += 16; + CHECK_BOUNDARIES; + } while( --i_mba_inc ); + } + else + { + do { + p_mb = p_vpar->pool.pf_new_mb( &p_vpar->pool ); + p_mb->i_mb_modes = 0; + p_mb->i_nb_motions = 0; + p_mb->i_coded_block_pattern = 0; + p_mb->pp_dest[0] = p_dest[0]; + p_mb->pp_dest[1] = p_dest[1]; + p_mb->pp_dest[2] = p_dest[2]; + + if( !b_mpeg2 ) + { + MOTION( MotionMPEG1Reuse, i_mb_modes ); + } + else if( i_structure == FRAME_STRUCTURE ) + { + MOTION( MotionFrameReuse, i_mb_modes ); + } + else + { + MOTION( MotionFieldReuse, i_mb_modes ); + } + + p_vpar->pool.pf_decode_mb( &p_vpar->pool, p_mb ); + p_vpar->mb.i_offset += 16; + CHECK_BOUNDARIES; + } while( --i_mba_inc ); + } } } - while( ShowBits( &p_vpar->bit_stream, 23 ) && !p_vpar->p_fifo->b_die ); + NextStartCode( &p_vpar->bit_stream ); } @@ -2045,69 +2130,32 @@ static __inline__ void SliceHeader( vpar_thread_t * p_vpar, * PictureData : Parse off all macroblocks (ISO/IEC 13818-2 6.2.3.7) *****************************************************************************/ static __inline__ void vpar_PictureData( vpar_thread_t * p_vpar, - int i_mb_base, boolean_t b_mpeg2, + boolean_t b_mpeg2, int i_coding_type, int i_structure ) { - int i_mb_address = 0; u32 i_dummy; NextStartCode( &p_vpar->bit_stream ); - while( ((i_coding_type != I_CODING_TYPE && i_coding_type != D_CODING_TYPE) - || !p_vpar->picture.b_error) - && i_mb_address < (p_vpar->sequence.i_mb_size - >> (i_structure != FRAME_STRUCTURE)) - && !p_vpar->picture.b_error - && !p_vpar->p_fifo->b_die ) + while( !p_vpar->picture.b_error && !p_vpar->p_fifo->b_die ) { if( ((i_dummy = ShowBits( &p_vpar->bit_stream, 32 )) < SLICE_START_CODE_MIN) || (i_dummy > SLICE_START_CODE_MAX) ) { - intf_WarnMsg( 2, "Premature end of picture" ); - p_vpar->picture.b_error = 1; break; } RemoveBits32( &p_vpar->bit_stream ); /* Decode slice data. */ - SliceHeader( p_vpar, &i_mb_address, i_mb_base, i_dummy & 255, - b_mpeg2, i_coding_type, i_structure ); + ParseSlice( p_vpar, i_dummy & 255, b_mpeg2, i_coding_type, + i_structure ); } - -#if 0 - /* BUGGY */ - /* Try to recover from error. If we missed less than half the - * number of macroblocks of the picture, mark the missed ones - * as skipped. */ - if( (i_coding_type == P_CODING_TYPE || i_coding_type == B_CODING_TYPE) - && !p_vpar->sequence.b_expect_discontinuity - && p_vpar->picture.b_error && - ( (i_mb_address-i_mb_base) > (p_vpar->sequence.i_mb_size >> 1) - || (i_structure != FRAME_STRUCTURE - && (i_mb_address-i_mb_base) > - (p_vpar->sequence.i_mb_size >> 2) ) ) ) - { - int i_mb; - - p_vpar->picture.b_error = 0; - for( i_mb = i_mb_address + 1; - i_mb < (p_vpar->sequence.i_mb_size - << (i_structure != FRAME_STRUCTURE)); - i_mb++ ) - { - SkippedMacroblock( p_vpar, i_mb, i_mb_base, - i_coding_type, - i_structure ); - } - } -#endif } #define DECLARE_PICD( FUNCNAME, B_MPEG2, I_CODING_TYPE, I_STRUCTURE ) \ -void FUNCNAME( vpar_thread_t * p_vpar, int i_mb_base ) \ +void FUNCNAME( vpar_thread_t * p_vpar ) \ { \ - vpar_PictureData( p_vpar, i_mb_base, B_MPEG2, I_CODING_TYPE, \ - I_STRUCTURE ); \ + vpar_PictureData( p_vpar, B_MPEG2, I_CODING_TYPE, I_STRUCTURE ); \ } DECLARE_PICD( vpar_PictureDataGENERIC, p_vpar->sequence.b_mpeg2, @@ -2130,3 +2178,5 @@ DECLARE_PICD( vpar_PictureData2PB, 1, P_CODING_TYPE, BOTTOM_FIELD ); DECLARE_PICD( vpar_PictureData2BB, 1, B_CODING_TYPE, BOTTOM_FIELD ); #endif +#undef DECLARE_PICD + diff --git a/src/video_decoder/vpar_blocks.h b/src/video_decoder/vpar_blocks.h new file mode 100644 index 0000000000..f03dd138eb --- /dev/null +++ b/src/video_decoder/vpar_blocks.h @@ -0,0 +1,432 @@ +/***************************************************************************** + * video_parser.h : Variable Length Codes + ***************************************************************************** + * Copyright (C) 1999, 2000 VideoLAN + * $Id: vpar_blocks.h,v 1.6 2001/08/22 17:21:46 massiot Exp $ + * + * Authors: Christophe Massiot + * Jean-Marc Dressler + * Stéphane Borel + * Aaron Holtzman + * Michel Lespinasse + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. + *****************************************************************************/ + +/***************************************************************************** + * lookup_t : entry type for lookup tables * + *****************************************************************************/ +typedef struct lookup_s +{ + u8 i_value; + u8 i_length; +} lookup_t; + +typedef struct dmv_lookup_s +{ + s8 i_value; + u8 i_length; +} dmv_lookup_t; + +/***************************************************************************** + * dct_lookup_t : special entry type for lookup tables about ac coefficients + *****************************************************************************/ +typedef struct dct_lookup_s +{ + u8 i_run; + u8 i_level; + u8 i_length; +} dct_lookup_t; + +/***************************************************************************** + * Standard codes + *****************************************************************************/ + +/* Motion types */ +#define MOTION_TYPE_MASK (3*64) +#define MOTION_TYPE_BASE 64 +#define MC_FIELD (1*64) +#define MC_FRAME (2*64) +#define MC_16X8 (2*64) +#define MC_DMV (3*64) + +/* Macroblock Address Increment types */ +#define MB_ADDRINC_ESCAPE 8 +#define MB_ADDRINC_STUFFING 15 + +/* Error constant for lookup tables */ +#define MB_ERROR (-1) + +/* Scan */ +#define SCAN_ZIGZAG 0 +#define SCAN_ALT 1 + +/* Constant for block decoding */ +#define DCT_EOB 64 +#define DCT_ESCAPE 65 + + +/***************************************************************************** + * Lookup tables for macroblock modes + *****************************************************************************/ + +#define INTRA MB_INTRA +#define QUANT MB_QUANT + +static lookup_t MB_I [] = { + {INTRA|QUANT, 2}, {INTRA, 1} +}; + +#define MC MB_MOTION_FORWARD +#define CODED MB_PATTERN + +static lookup_t MB_P [] = { + {INTRA|QUANT, 6}, {CODED|QUANT, 5}, {MC|CODED|QUANT, 5}, {INTRA, 5}, + {MC, 3}, {MC, 3}, {MC, 3}, {MC, 3}, + {CODED, 2}, {CODED, 2}, {CODED, 2}, {CODED, 2}, + {CODED, 2}, {CODED, 2}, {CODED, 2}, {CODED, 2}, + {MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1}, + {MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1}, + {MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1}, + {MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1} +}; + +#define FWD MB_MOTION_FORWARD +#define BWD MB_MOTION_BACKWARD +#define INTER MB_MOTION_FORWARD|MB_MOTION_BACKWARD + +static lookup_t MB_B [] = { + {0, 0}, {INTRA|QUANT, 6}, + {BWD|CODED|QUANT, 6}, {FWD|CODED|QUANT, 6}, + {INTER|CODED|QUANT, 5}, {INTER|CODED|QUANT, 5}, + {INTRA, 5}, {INTRA, 5}, + {FWD, 4}, {FWD, 4}, {FWD, 4}, {FWD, 4}, + {FWD|CODED, 4}, {FWD|CODED, 4}, {FWD|CODED, 4}, {FWD|CODED, 4}, + {BWD, 3}, {BWD, 3}, {BWD, 3}, {BWD, 3}, + {BWD, 3}, {BWD, 3}, {BWD, 3}, {BWD, 3}, + {BWD|CODED, 3}, {BWD|CODED, 3}, {BWD|CODED, 3}, {BWD|CODED, 3}, + {BWD|CODED, 3}, {BWD|CODED, 3}, {BWD|CODED, 3}, {BWD|CODED, 3}, + {INTER, 2}, {INTER, 2}, {INTER, 2}, {INTER, 2}, + {INTER, 2}, {INTER, 2}, {INTER, 2}, {INTER, 2}, + {INTER, 2}, {INTER, 2}, {INTER, 2}, {INTER, 2}, + {INTER, 2}, {INTER, 2}, {INTER, 2}, {INTER, 2}, + {INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2}, + {INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2}, + {INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2}, + {INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2} +}; + +#undef INTRA +#undef QUANT +#undef MC +#undef CODED +#undef FWD +#undef BWD +#undef INTER + + +/***************************************************************************** + * Lookup tables for motion vectors + *****************************************************************************/ + +static lookup_t MV_4 [] = { + { 3, 6}, { 2, 4}, { 1, 3}, { 1, 3}, { 0, 2}, { 0, 2}, { 0, 2}, { 0, 2} +}; + +static lookup_t MV_10 [] = { + { 0,10}, { 0,10}, { 0,10}, { 0,10}, { 0,10}, { 0,10}, { 0,10}, { 0,10}, + { 0,10}, { 0,10}, { 0,10}, { 0,10}, {15,10}, {14,10}, {13,10}, {12,10}, + {11,10}, {10,10}, { 9, 9}, { 9, 9}, { 8, 9}, { 8, 9}, { 7, 9}, { 7, 9}, + { 6, 7}, { 6, 7}, { 6, 7}, { 6, 7}, { 6, 7}, { 6, 7}, { 6, 7}, { 6, 7}, + { 5, 7}, { 5, 7}, { 5, 7}, { 5, 7}, { 5, 7}, { 5, 7}, { 5, 7}, { 5, 7}, + { 4, 7}, { 4, 7}, { 4, 7}, { 4, 7}, { 4, 7}, { 4, 7}, { 4, 7}, { 4, 7} +}; + + +static dmv_lookup_t DMV_2 [] = { + { 0, 1}, { 0, 1}, { 1, 2}, {-1, 2} +}; + + +/***************************************************************************** + * Lookup tables for Coded Block Patterns + *****************************************************************************/ + +static lookup_t CBP_7 [] = { + {0x22, 7}, {0x12, 7}, {0x0a, 7}, {0x06, 7}, + {0x21, 7}, {0x11, 7}, {0x09, 7}, {0x05, 7}, + {0x3f, 6}, {0x3f, 6}, {0x03, 6}, {0x03, 6}, + {0x24, 6}, {0x24, 6}, {0x18, 6}, {0x18, 6}, + {0x3e, 5}, {0x3e, 5}, {0x3e, 5}, {0x3e, 5}, + {0x02, 5}, {0x02, 5}, {0x02, 5}, {0x02, 5}, + {0x3d, 5}, {0x3d, 5}, {0x3d, 5}, {0x3d, 5}, + {0x01, 5}, {0x01, 5}, {0x01, 5}, {0x01, 5}, + {0x38, 5}, {0x38, 5}, {0x38, 5}, {0x38, 5}, + {0x34, 5}, {0x34, 5}, {0x34, 5}, {0x34, 5}, + {0x2c, 5}, {0x2c, 5}, {0x2c, 5}, {0x2c, 5}, + {0x1c, 5}, {0x1c, 5}, {0x1c, 5}, {0x1c, 5}, + {0x28, 5}, {0x28, 5}, {0x28, 5}, {0x28, 5}, + {0x14, 5}, {0x14, 5}, {0x14, 5}, {0x14, 5}, + {0x30, 5}, {0x30, 5}, {0x30, 5}, {0x30, 5}, + {0x0c, 5}, {0x0c, 5}, {0x0c, 5}, {0x0c, 5}, + {0x20, 4}, {0x20, 4}, {0x20, 4}, {0x20, 4}, + {0x20, 4}, {0x20, 4}, {0x20, 4}, {0x20, 4}, + {0x10, 4}, {0x10, 4}, {0x10, 4}, {0x10, 4}, + {0x10, 4}, {0x10, 4}, {0x10, 4}, {0x10, 4}, + {0x08, 4}, {0x08, 4}, {0x08, 4}, {0x08, 4}, + {0x08, 4}, {0x08, 4}, {0x08, 4}, {0x08, 4}, + {0x04, 4}, {0x04, 4}, {0x04, 4}, {0x04, 4}, + {0x04, 4}, {0x04, 4}, {0x04, 4}, {0x04, 4}, + {0x3c, 3}, {0x3c, 3}, {0x3c, 3}, {0x3c, 3}, + {0x3c, 3}, {0x3c, 3}, {0x3c, 3}, {0x3c, 3}, + {0x3c, 3}, {0x3c, 3}, {0x3c, 3}, {0x3c, 3}, + {0x3c, 3}, {0x3c, 3}, {0x3c, 3}, {0x3c, 3} +}; + +static lookup_t CBP_9 [] = { + {0, 0}, {0x00, 9}, {0x27, 9}, {0x1b, 9}, + {0x3b, 9}, {0x37, 9}, {0x2f, 9}, {0x1f, 9}, + {0x3a, 8}, {0x3a, 8}, {0x36, 8}, {0x36, 8}, + {0x2e, 8}, {0x2e, 8}, {0x1e, 8}, {0x1e, 8}, + {0x39, 8}, {0x39, 8}, {0x35, 8}, {0x35, 8}, + {0x2d, 8}, {0x2d, 8}, {0x1d, 8}, {0x1d, 8}, + {0x26, 8}, {0x26, 8}, {0x1a, 8}, {0x1a, 8}, + {0x25, 8}, {0x25, 8}, {0x19, 8}, {0x19, 8}, + {0x2b, 8}, {0x2b, 8}, {0x17, 8}, {0x17, 8}, + {0x33, 8}, {0x33, 8}, {0x0f, 8}, {0x0f, 8}, + {0x2a, 8}, {0x2a, 8}, {0x16, 8}, {0x16, 8}, + {0x32, 8}, {0x32, 8}, {0x0e, 8}, {0x0e, 8}, + {0x29, 8}, {0x29, 8}, {0x15, 8}, {0x15, 8}, + {0x31, 8}, {0x31, 8}, {0x0d, 8}, {0x0d, 8}, + {0x23, 8}, {0x23, 8}, {0x13, 8}, {0x13, 8}, + {0x0b, 8}, {0x0b, 8}, {0x07, 8}, {0x07, 8} +}; + + +/***************************************************************************** + * Lookup tables for coefficients + *****************************************************************************/ + +static lookup_t DC_lum_5 [] = { + {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, + {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, + {0, 3}, {0, 3}, {0, 3}, {0, 3}, {3, 3}, {3, 3}, {3, 3}, {3, 3}, + {4, 3}, {4, 3}, {4, 3}, {4, 3}, {5, 4}, {5, 4}, {6, 5} +}; + +static lookup_t DC_chrom_5 [] = { + {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, + {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, + {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, + {3, 3}, {3, 3}, {3, 3}, {3, 3}, {4, 4}, {4, 4}, {5, 5} +}; + +static lookup_t DC_long [] = { + {6, 5}, {6, 5}, {6, 5}, {6, 5}, {6, 5}, {6, 5}, { 6, 5}, { 6, 5}, + {6, 5}, {6, 5}, {6, 5}, {6, 5}, {6, 5}, {6, 5}, { 6, 5}, { 6, 5}, + {7, 6}, {7, 6}, {7, 6}, {7, 6}, {7, 6}, {7, 6}, { 7, 6}, { 7, 6}, + {8, 7}, {8, 7}, {8, 7}, {8, 7}, {9, 8}, {9, 8}, {10, 9}, {11, 9} +}; + + +static dct_lookup_t DCT_16 [] = { + {129, 0, 16}, {129, 0, 16}, {129, 0, 16}, {129, 0, 16}, + {129, 0, 16}, {129, 0, 16}, {129, 0, 16}, {129, 0, 16}, + {129, 0, 16}, {129, 0, 16}, {129, 0, 16}, {129, 0, 16}, + {129, 0, 16}, {129, 0, 16}, {129, 0, 16}, {129, 0, 16}, + { 2,18, 16}, { 2,17, 16}, { 2,16, 16}, { 2,15, 16}, + { 7, 3, 16}, { 17, 2, 16}, { 16, 2, 16}, { 15, 2, 16}, + { 14, 2, 16}, { 13, 2, 16}, { 12, 2, 16}, { 32, 1, 16}, + { 31, 1, 16}, { 30, 1, 16}, { 29, 1, 16}, { 28, 1, 16} +}; + +static dct_lookup_t DCT_15 [] = { + { 1,40,15}, { 1,39,15}, { 1,38,15}, { 1,37,15}, + { 1,36,15}, { 1,35,15}, { 1,34,15}, { 1,33,15}, + { 1,32,15}, { 2,14,15}, { 2,13,15}, { 2,12,15}, + { 2,11,15}, { 2,10,15}, { 2, 9,15}, { 2, 8,15}, + { 1,31,14}, { 1,31,14}, { 1,30,14}, { 1,30,14}, + { 1,29,14}, { 1,29,14}, { 1,28,14}, { 1,28,14}, + { 1,27,14}, { 1,27,14}, { 1,26,14}, { 1,26,14}, + { 1,25,14}, { 1,25,14}, { 1,24,14}, { 1,24,14}, + { 1,23,14}, { 1,23,14}, { 1,22,14}, { 1,22,14}, + { 1,21,14}, { 1,21,14}, { 1,20,14}, { 1,20,14}, + { 1,19,14}, { 1,19,14}, { 1,18,14}, { 1,18,14}, + { 1,17,14}, { 1,17,14}, { 1,16,14}, { 1,16,14} +}; + +static dct_lookup_t DCT_13 [] = { + { 11, 2,13}, { 10, 2,13}, { 6, 3,13}, { 4, 4,13}, + { 3, 5,13}, { 2, 7,13}, { 2, 6,13}, { 1,15,13}, + { 1,14,13}, { 1,13,13}, { 1,12,13}, { 27, 1,13}, + { 26, 1,13}, { 25, 1,13}, { 24, 1,13}, { 23, 1,13}, + { 1,11,12}, { 1,11,12}, { 9, 2,12}, { 9, 2,12}, + { 5, 3,12}, { 5, 3,12}, { 1,10,12}, { 1,10,12}, + { 3, 4,12}, { 3, 4,12}, { 8, 2,12}, { 8, 2,12}, + { 22, 1,12}, { 22, 1,12}, { 21, 1,12}, { 21, 1,12}, + { 1, 9,12}, { 1, 9,12}, { 20, 1,12}, { 20, 1,12}, + { 19, 1,12}, { 19, 1,12}, { 2, 5,12}, { 2, 5,12}, + { 4, 3,12}, { 4, 3,12}, { 1, 8,12}, { 1, 8,12}, + { 7, 2,12}, { 7, 2,12}, { 18, 1,12}, { 18, 1,12} +}; + +static dct_lookup_t DCT_B14_10 [] = { + { 17, 1,10}, { 6, 2,10}, { 1, 7,10}, { 3, 3,10}, + { 2, 4,10}, { 16, 1,10}, { 15, 1,10}, { 5, 2,10} +}; + +static dct_lookup_t DCT_B14_8 [] = { + { 65, 0, 6}, { 65, 0, 6}, { 65, 0, 6}, { 65, 0, 6}, + { 3, 2, 7}, { 3, 2, 7}, { 10, 1, 7}, { 10, 1, 7}, + { 1, 4, 7}, { 1, 4, 7}, { 9, 1, 7}, { 9, 1, 7}, + { 8, 1, 6}, { 8, 1, 6}, { 8, 1, 6}, { 8, 1, 6}, + { 7, 1, 6}, { 7, 1, 6}, { 7, 1, 6}, { 7, 1, 6}, + { 2, 2, 6}, { 2, 2, 6}, { 2, 2, 6}, { 2, 2, 6}, + { 6, 1, 6}, { 6, 1, 6}, { 6, 1, 6}, { 6, 1, 6}, + { 14, 1, 8}, { 1, 6, 8}, { 13, 1, 8}, { 12, 1, 8}, + { 4, 2, 8}, { 2, 3, 8}, { 1, 5, 8}, { 11, 1, 8} +}; + +static dct_lookup_t DCT_B14AC_5 [] = { + { 1, 3, 5}, { 5, 1, 5}, { 4, 1, 5}, + { 1, 2, 4}, { 1, 2, 4}, { 3, 1, 4}, { 3, 1, 4}, + { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, + {129, 0, 2}, {129, 0, 2}, {129, 0, 2}, {129, 0, 2}, + {129, 0, 2}, {129, 0, 2}, {129, 0, 2}, {129, 0, 2}, + { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, + { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2} +}; + +static dct_lookup_t DCT_B14DC_5 [] = { + { 1, 3, 5}, { 5, 1, 5}, { 4, 1, 5}, + { 1, 2, 4}, { 1, 2, 4}, { 3, 1, 4}, { 3, 1, 4}, + { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, + { 1, 1, 1}, { 1, 1, 1}, { 1, 1, 1}, { 1, 1, 1}, + { 1, 1, 1}, { 1, 1, 1}, { 1, 1, 1}, { 1, 1, 1}, + { 1, 1, 1}, { 1, 1, 1}, { 1, 1, 1}, { 1, 1, 1}, + { 1, 1, 1}, { 1, 1, 1}, { 1, 1, 1}, { 1, 1, 1} +}; + +static dct_lookup_t DCT_B15_10 [] = { + { 6, 2, 9}, { 6, 2, 9}, { 15, 1, 9}, { 15, 1, 9}, + { 3, 4,10}, { 17, 1,10}, { 16, 1, 9}, { 16, 1, 9} +}; + +static dct_lookup_t DCT_B15_8 [] = { + { 65, 0, 6}, { 65, 0, 6}, { 65, 0, 6}, { 65, 0, 6}, + { 8, 1, 7}, { 8, 1, 7}, { 9, 1, 7}, { 9, 1, 7}, + { 7, 1, 7}, { 7, 1, 7}, { 3, 2, 7}, { 3, 2, 7}, + { 1, 7, 6}, { 1, 7, 6}, { 1, 7, 6}, { 1, 7, 6}, + { 1, 6, 6}, { 1, 6, 6}, { 1, 6, 6}, { 1, 6, 6}, + { 5, 1, 6}, { 5, 1, 6}, { 5, 1, 6}, { 5, 1, 6}, + { 6, 1, 6}, { 6, 1, 6}, { 6, 1, 6}, { 6, 1, 6}, + { 2, 5, 8}, { 12, 1, 8}, { 1,11, 8}, { 1,10, 8}, + { 14, 1, 8}, { 13, 1, 8}, { 4, 2, 8}, { 2, 4, 8}, + { 3, 1, 5}, { 3, 1, 5}, { 3, 1, 5}, { 3, 1, 5}, + { 3, 1, 5}, { 3, 1, 5}, { 3, 1, 5}, { 3, 1, 5}, + { 2, 2, 5}, { 2, 2, 5}, { 2, 2, 5}, { 2, 2, 5}, + { 2, 2, 5}, { 2, 2, 5}, { 2, 2, 5}, { 2, 2, 5}, + { 4, 1, 5}, { 4, 1, 5}, { 4, 1, 5}, { 4, 1, 5}, + { 4, 1, 5}, { 4, 1, 5}, { 4, 1, 5}, { 4, 1, 5}, + { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, + { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, + { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, + { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, + { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, + { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, + { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, + { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, + {129, 0, 4}, {129, 0, 4}, {129, 0, 4}, {129, 0, 4}, + {129, 0, 4}, {129, 0, 4}, {129, 0, 4}, {129, 0, 4}, + {129, 0, 4}, {129, 0, 4}, {129, 0, 4}, {129, 0, 4}, + {129, 0, 4}, {129, 0, 4}, {129, 0, 4}, {129, 0, 4}, + { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4}, + { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4}, + { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4}, + { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4}, + { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, + { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, + { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, + { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, + { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, + { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, + { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, + { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, + { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, + { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, + { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, + { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, + { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, + { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, + { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, + { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, + { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, + { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, + { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, + { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, + { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, + { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, + { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, + { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, + { 1, 4, 5}, { 1, 4, 5}, { 1, 4, 5}, { 1, 4, 5}, + { 1, 4, 5}, { 1, 4, 5}, { 1, 4, 5}, { 1, 4, 5}, + { 1, 5, 5}, { 1, 5, 5}, { 1, 5, 5}, { 1, 5, 5}, + { 1, 5, 5}, { 1, 5, 5}, { 1, 5, 5}, { 1, 5, 5}, + { 10, 1, 7}, { 10, 1, 7}, { 2, 3, 7}, { 2, 3, 7}, + { 11, 1, 7}, { 11, 1, 7}, { 1, 8, 7}, { 1, 8, 7}, + { 1, 9, 7}, { 1, 9, 7}, { 1,12, 8}, { 1,13, 8}, + { 3, 3, 8}, { 5, 2, 8}, { 1,14, 8}, { 1,15, 8} +}; + + +/***************************************************************************** + * Lookup tables for Macroblock Address Increment + *****************************************************************************/ + +static lookup_t MBA_5 [] = { + {6, 5}, {5, 5}, {4, 4}, {4, 4}, {3, 4}, {3, 4}, + {2, 3}, {2, 3}, {2, 3}, {2, 3}, {1, 3}, {1, 3}, {1, 3}, {1, 3}, + {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, + {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1} +}; + +static lookup_t MBA_11 [] = { + {32, 11}, {31, 11}, {30, 11}, {29, 11}, + {28, 11}, {27, 11}, {26, 11}, {25, 11}, + {24, 11}, {23, 11}, {22, 11}, {21, 11}, + {20, 10}, {20, 10}, {19, 10}, {19, 10}, + {18, 10}, {18, 10}, {17, 10}, {17, 10}, + {16, 10}, {16, 10}, {15, 10}, {15, 10}, + {14, 8}, {14, 8}, {14, 8}, {14, 8}, + {14, 8}, {14, 8}, {14, 8}, {14, 8}, + {13, 8}, {13, 8}, {13, 8}, {13, 8}, + {13, 8}, {13, 8}, {13, 8}, {13, 8}, + {12, 8}, {12, 8}, {12, 8}, {12, 8}, + {12, 8}, {12, 8}, {12, 8}, {12, 8}, + {11, 8}, {11, 8}, {11, 8}, {11, 8}, + {11, 8}, {11, 8}, {11, 8}, {11, 8}, + {10, 8}, {10, 8}, {10, 8}, {10, 8}, + {10, 8}, {10, 8}, {10, 8}, {10, 8}, + { 9, 8}, { 9, 8}, { 9, 8}, { 9, 8}, + { 9, 8}, { 9, 8}, { 9, 8}, { 9, 8}, + { 8, 7}, { 8, 7}, { 8, 7}, { 8, 7}, + { 8, 7}, { 8, 7}, { 8, 7}, { 8, 7}, + { 8, 7}, { 8, 7}, { 8, 7}, { 8, 7}, + { 8, 7}, { 8, 7}, { 8, 7}, { 8, 7}, + { 7, 7}, { 7, 7}, { 7, 7}, { 7, 7}, + { 7, 7}, { 7, 7}, { 7, 7}, { 7, 7}, + { 7, 7}, { 7, 7}, { 7, 7}, { 7, 7}, + { 7, 7}, { 7, 7}, { 7, 7}, { 7, 7} +}; diff --git a/src/video_decoder/vpar_headers.c b/src/video_decoder/vpar_headers.c index d3bb919e2d..ecc4eab43d 100644 --- a/src/video_decoder/vpar_headers.c +++ b/src/video_decoder/vpar_headers.c @@ -2,7 +2,7 @@ * vpar_headers.c : headers parsing ***************************************************************************** * Copyright (C) 1999, 2000 VideoLAN - * $Id: vpar_headers.c,v 1.6 2001/07/26 11:36:52 massiot Exp $ + * $Id: vpar_headers.c,v 1.7 2001/08/22 17:21:46 massiot Exp $ * * Authors: Christophe Massiot * Stéphane Borel @@ -70,7 +70,7 @@ static void CopyrightExtension( vpar_thread_t * p_vpar ); /***************************************************************************** * pi_default_intra_quant : default quantization matrix *****************************************************************************/ -u8 pi_default_intra_quant[] = +u8 pi_default_intra_quant[] ATTR_ALIGN(16) = { 8, 16, 19, 22, 26, 27, 29, 34, 16, 16, 22, 24, 27, 29, 34, 37, @@ -85,7 +85,7 @@ u8 pi_default_intra_quant[] = /***************************************************************************** * pi_default_nonintra_quant : default quantization matrix *****************************************************************************/ -u8 pi_default_nonintra_quant[] = +u8 pi_default_nonintra_quant[] ATTR_ALIGN(16) = { 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, @@ -100,7 +100,7 @@ u8 pi_default_nonintra_quant[] = /***************************************************************************** * pi_scan : zig-zag and alternate scan patterns *****************************************************************************/ -u8 pi_scan[2][64] = +u8 pi_scan[2][64] ATTR_ALIGN(16) = { { /* Zig-Zag pattern */ 0,1,8,16,9,2,3,10,17,24,32,25,18,11,4,5, @@ -196,15 +196,9 @@ static __inline__ void LoadMatrix( vpar_thread_t * p_vpar, for( i_dummy = 0; i_dummy < 64; i_dummy++ ) { - p_matrix->pi_matrix[p_vpar->ppi_scan[SCAN_ZIGZAG][i_dummy]] + p_matrix->pi_matrix[p_vpar->ppi_scan[0][i_dummy]] = GetBits( &p_vpar->bit_stream, 8 ); } - -#ifdef VDEC_DFT - /* Discrete Fourier Transform requires the quantization matrices to - * be normalized before using them. */ - vdec_NormQuantMatrix( p_matrix->pi_matrix ); -#endif } /***************************************************************************** @@ -405,38 +399,11 @@ static void SequenceHeader( vpar_thread_t * p_vpar ) p_vpar->sequence.i_size = p_vpar->sequence.i_width * p_vpar->sequence.i_height; - /* Update chromatic information. */ - switch( p_vpar->sequence.i_chroma_format ) - { - case CHROMA_420: - p_vpar->sequence.i_chroma_nb_blocks = 2; - p_vpar->sequence.i_chroma_width = p_vpar->sequence.i_width >> 1; - p_vpar->sequence.i_chroma_mb_width = 8; - p_vpar->sequence.i_chroma_mb_height = 8; - break; - - case CHROMA_422: - p_vpar->sequence.i_chroma_nb_blocks = 4; - p_vpar->sequence.i_chroma_width = p_vpar->sequence.i_width >> 1; - p_vpar->sequence.i_chroma_mb_width = 8; - p_vpar->sequence.i_chroma_mb_height = 16; - break; - - case CHROMA_444: - p_vpar->sequence.i_chroma_nb_blocks = 8; - p_vpar->sequence.i_chroma_width = p_vpar->sequence.i_width; - p_vpar->sequence.i_chroma_mb_width = 16; - p_vpar->sequence.i_chroma_mb_height = 16; - } - - /* Reset scalable_mode. */ - p_vpar->sequence.i_scalable_mode = SC_NONE; - #if 0 if( p_vpar->sequence.i_width != i_width_save || p_vpar->sequence.i_height != i_height_save ) { - /* FIXME: What do we do in case of a size change ?? */ + /* FIXME: Warn the video output */ } #endif @@ -492,7 +459,6 @@ static void GroupHeader( vpar_thread_t * p_vpar ) static void PictureHeader( vpar_thread_t * p_vpar ) { int i_structure; - int i_mb_base; boolean_t b_parsable; #ifdef VDEC_SMP int i_mb; @@ -520,13 +486,15 @@ static void PictureHeader( vpar_thread_t * p_vpar ) if( p_vpar->picture.i_coding_type == P_CODING_TYPE || p_vpar->picture.i_coding_type == B_CODING_TYPE ) { - p_vpar->picture.pb_full_pel_vector[0] = GetBits( &p_vpar->bit_stream, 1 ); - p_vpar->picture.i_forward_f_code = GetBits( &p_vpar->bit_stream, 3 ); + p_vpar->picture.ppi_f_code[0][1] = GetBits( &p_vpar->bit_stream, 1 ); + p_vpar->picture.ppi_f_code[0][0] = GetBits( &p_vpar->bit_stream, 3 ) + - 1; } if( p_vpar->picture.i_coding_type == B_CODING_TYPE ) { - p_vpar->picture.pb_full_pel_vector[1] = GetBits( &p_vpar->bit_stream, 1 ); - p_vpar->picture.i_backward_f_code = GetBits( &p_vpar->bit_stream, 3 ); + p_vpar->picture.ppi_f_code[1][1] = GetBits( &p_vpar->bit_stream, 1 ); + p_vpar->picture.ppi_f_code[1][0] = GetBits( &p_vpar->bit_stream, 3 ) + - 1; } /* extra_information_picture */ @@ -546,10 +514,11 @@ static void PictureHeader( vpar_thread_t * p_vpar ) /* extension_start_code_identifier */ RemoveBits( &p_vpar->bit_stream, 4 ); - p_vpar->picture.ppi_f_code[0][0] = GetBits( &p_vpar->bit_stream, 4 ); - p_vpar->picture.ppi_f_code[0][1] = GetBits( &p_vpar->bit_stream, 4 ); - p_vpar->picture.ppi_f_code[1][0] = GetBits( &p_vpar->bit_stream, 4 ); - p_vpar->picture.ppi_f_code[1][1] = GetBits( &p_vpar->bit_stream, 4 ); + /* Pre-substract 1 for later use in MotionDelta(). */ + p_vpar->picture.ppi_f_code[0][0] = GetBits( &p_vpar->bit_stream, 4 ) -1; + p_vpar->picture.ppi_f_code[0][1] = GetBits( &p_vpar->bit_stream, 4 ) -1; + p_vpar->picture.ppi_f_code[1][0] = GetBits( &p_vpar->bit_stream, 4 ) -1; + p_vpar->picture.ppi_f_code[1][1] = GetBits( &p_vpar->bit_stream, 4 ) -1; p_vpar->picture.i_intra_dc_precision = GetBits( &p_vpar->bit_stream, 2 ); i_structure = GetBits( &p_vpar->bit_stream, 2 ); p_vpar->picture.b_top_field_first = GetBits( &p_vpar->bit_stream, 1 ); @@ -558,7 +527,9 @@ static void PictureHeader( vpar_thread_t * p_vpar ) p_vpar->picture.b_concealment_mv = GetBits( &p_vpar->bit_stream, 1 ); p_vpar->picture.b_q_scale_type = GetBits( &p_vpar->bit_stream, 1 ); p_vpar->picture.b_intra_vlc_format = GetBits( &p_vpar->bit_stream, 1 ); - p_vpar->picture.b_alternate_scan = GetBits( &p_vpar->bit_stream, 1 ); + /* Alternate scan */ + p_vpar->picture.pi_scan = + p_vpar->ppi_scan[ GetBits( &p_vpar->bit_stream, 1 ) ]; p_vpar->picture.b_repeat_first_field = GetBits( &p_vpar->bit_stream, 1 ); /* chroma_420_type (obsolete) */ RemoveBits( &p_vpar->bit_stream, 1 ); @@ -582,11 +553,14 @@ static void PictureHeader( vpar_thread_t * p_vpar ) p_vpar->picture.b_concealment_mv = 0; p_vpar->picture.b_q_scale_type = 0; p_vpar->picture.b_intra_vlc_format = 0; - p_vpar->picture.b_alternate_scan = 0; /* zigzag */ + p_vpar->picture.pi_scan = p_vpar->ppi_scan[0]; p_vpar->picture.b_repeat_first_field = 0; p_vpar->picture.b_progressive = 1; } + /* Extension and User data. */ + ExtensionAndUserData( p_vpar ); + #ifdef STATS p_vpar->pc_pictures[p_vpar->picture.i_coding_type]++; #endif @@ -611,7 +585,8 @@ static void PictureHeader( vpar_thread_t * p_vpar ) } /* Do we have the reference pictures ? */ - b_parsable = !(((p_vpar->picture.i_coding_type == P_CODING_TYPE) && + b_parsable = !(((p_vpar->picture.i_coding_type == P_CODING_TYPE || + p_vpar->picture.b_concealment_mv) && (p_vpar->sequence.p_backward == NULL)) || /* p_backward will become p_forward later */ ((p_vpar->picture.i_coding_type == B_CODING_TYPE) && @@ -738,10 +713,8 @@ static void PictureHeader( vpar_thread_t * p_vpar ) vpar_SynchroDecode( p_vpar, p_vpar->picture.i_coding_type, i_structure ); P_picture->i_aspect_ratio = p_vpar->sequence.i_aspect_ratio; P_picture->i_matrix_coefficients = p_vpar->sequence.i_matrix_coefficients; - p_vpar->picture.i_l_stride = ( p_vpar->sequence.i_width + p_vpar->picture.i_field_width = ( p_vpar->sequence.i_width << ( 1 - p_vpar->picture.b_frame_structure ) ); - p_vpar->picture.i_c_stride = ( p_vpar->sequence.i_chroma_width - << ( 1 - p_vpar->picture.b_frame_structure )); /* FIXME ! remove asap ?? */ //memset( P_picture->p_data, 0, (p_vpar->sequence.i_mb_size*384)); @@ -749,34 +722,15 @@ static void PictureHeader( vpar_thread_t * p_vpar ) /* Update the reference pointers. */ ReferenceUpdate( p_vpar, p_vpar->picture.i_coding_type, P_picture ); } - p_vpar->picture.i_current_structure |= i_structure; - p_vpar->picture.i_structure = i_structure; /* Initialize picture data for decoding. */ - if( i_structure == BOTTOM_FIELD ) - { - i_mb_base = p_vpar->sequence.i_mb_size >> 1; - p_vpar->mb.i_l_y = 1; - p_vpar->mb.i_c_y = 1; - } - else - { - i_mb_base = 0; - p_vpar->mb.i_l_y = p_vpar->mb.i_c_y = 0; - } - p_vpar->mb.i_l_x = p_vpar->mb.i_c_x = 0; - - /* Extension and User data. */ - ExtensionAndUserData( p_vpar ); + p_vpar->picture.i_current_structure |= i_structure; + p_vpar->picture.i_structure = i_structure; + p_vpar->picture.b_second_field = + (i_structure != p_vpar->picture.i_current_structure); + p_vpar->picture.b_current_field = + (i_structure == BOTTOM_FIELD ); - /* This is an MP@ML decoder, please note that neither of the following - * assertions can be true : - * p_vpar->sequence.i_chroma_format != CHROMA_420 - * p_vpar->sequence.i_height > 2800 - * p_vpar->sequence.i_scalable_mode == SC_DP - * Be cautious if you try to use the decoder for other profiles and - * levels. - */ if( p_vpar->sequence.b_mpeg2 ) { static f_picture_data_t ppf_picture_data[4][4] = @@ -817,7 +771,7 @@ static void PictureHeader( vpar_thread_t * p_vpar ) }; ppf_picture_data[p_vpar->picture.i_structure] - [p_vpar->picture.i_coding_type]( p_vpar, i_mb_base ); + [p_vpar->picture.i_coding_type]( p_vpar ); } else { @@ -826,9 +780,9 @@ static void PictureHeader( vpar_thread_t * p_vpar ) { NULL, vpar_PictureData1I, vpar_PictureData1P, vpar_PictureData1B, vpar_PictureData1D }; - pf_picture_data[p_vpar->picture.i_coding_type]( p_vpar, i_mb_base ); + pf_picture_data[p_vpar->picture.i_coding_type]( p_vpar ); #else - vpar_PictureDataGENERIC( p_vpar, i_mb_base ); + vpar_PictureDataGENERIC( p_vpar ); #endif } diff --git a/src/video_decoder/vpar_pool.c b/src/video_decoder/vpar_pool.c index d1ecf6575f..d051608174 100644 --- a/src/video_decoder/vpar_pool.c +++ b/src/video_decoder/vpar_pool.c @@ -2,7 +2,7 @@ * vpar_pool.c : management of the pool of decoder threads ***************************************************************************** * Copyright (C) 1999, 2000, 2001 VideoLAN - * $Id: vpar_pool.c,v 1.1 2001/07/18 14:21:00 massiot Exp $ + * $Id: vpar_pool.c,v 1.2 2001/08/22 17:21:46 massiot Exp $ * * Authors: Christophe Massiot * @@ -186,11 +186,11 @@ void vpar_SpawnPool( vpar_thread_t * p_vpar ) if( !b_grayscale ) { - p_vpar->pool.pf_vdec_decode = p_vpar->pf_decode_mb_c; + p_vpar->pool.pf_vdec_decode = vdec_DecodeMacroblockC; } else { - p_vpar->pool.pf_vdec_decode = p_vpar->pf_decode_mb_bw; + p_vpar->pool.pf_vdec_decode = vdec_DecodeMacroblockBW; } } diff --git a/src/video_decoder/vpar_pool.h b/src/video_decoder/vpar_pool.h index 76cb96b53b..a4d7830ab8 100644 --- a/src/video_decoder/vpar_pool.h +++ b/src/video_decoder/vpar_pool.h @@ -2,7 +2,7 @@ * vpar_pool.h : video parser/video decoders communication ***************************************************************************** * Copyright (C) 1999, 2000 VideoLAN - * $Id: vpar_pool.h,v 1.1 2001/07/18 14:21:00 massiot Exp $ + * $Id: vpar_pool.h,v 1.2 2001/08/22 17:21:46 massiot Exp $ * * Authors: Christophe Massiot * @@ -73,8 +73,13 @@ typedef struct vdec_pool_s boolean_t b_bw; /* Current value for B&W */ /* Access to the plug-ins needed by the video decoder thread */ - void ( * pf_decode_init ) ( struct vdec_thread_s * ); - void ( * pf_idct_init ) ( struct vdec_thread_s * ); + void ( * pf_idct_init ) ( void ** ); + void ( * pf_decode_init ) ( ); + void ( * pf_addblock ) ( dctelem_t *, yuv_data_t *, int ); + void ( * pf_copyblock ) ( dctelem_t *, yuv_data_t *, int ); + + void ( * ppppf_motion[2][2][4] ) ( yuv_data_t *, yuv_data_t *, + int, int ); } vdec_pool_t; /*****************************************************************************