From cb4dc4aee33f679ba4f73010c9b88f5d54799740 Mon Sep 17 00:00:00 2001 From: Loren Merritt Date: Sat, 17 May 2008 03:39:59 -0600 Subject: [PATCH] x264_median_mv_mmxext this is the first non-runtime-detected use of mmxext, but it has to be inlined --- common/common.h | 27 +++++++++++++++------------ common/macroblock.c | 20 ++++---------------- common/x86/util.h | 44 ++++++++++++++++++++++++++++++++++++++++++++ encoder/slicetype.c | 4 +--- 4 files changed, 64 insertions(+), 31 deletions(-) create mode 100644 common/x86/util.h diff --git a/common/common.h b/common/common.h index a53509b4..425fc8fa 100644 --- a/common/common.h +++ b/common/common.h @@ -116,20 +116,23 @@ static inline double x264_clip3f( double v, double f_min, double f_max ) static inline int x264_median( int a, int b, int c ) { - int min = a, max =a; - if( b < min ) - min = b; - else - max = b; /* no need to do 'b > max' (more consuming than always doing affectation) */ - - if( c < min ) - min = c; - else if( c > max ) - max = c; - - return a + b + c - min - max; + int t = (a-b)&((a-b)>>31); + a -= t; + b += t; + b -= (b-c)&((b-c)>>31); + b += (a-b)&((a-b)>>31); + return b; } +static inline void x264_median_mv( int16_t *dst, int16_t *a, int16_t *b, int16_t *c ) +{ + dst[0] = x264_median( a[0], b[0], c[0] ); + dst[1] = x264_median( a[1], b[1], c[1] ); +} + +#ifdef HAVE_MMX +#include "x86/util.h" +#endif /**************************************************************************** * diff --git a/common/macroblock.c b/common/macroblock.c index d2fc0cbc..7c8b939f 100644 --- a/common/macroblock.c +++ b/common/macroblock.c @@ -140,10 +140,7 @@ void x264_mb_predict_mv( x264_t *h, int i_list, int idx, int i_width, int16_t mv if( i_refc == i_ref ) i_count++; if( i_count > 1 ) - { - mvp[0] = x264_median( mv_a[0], mv_b[0], mv_c[0] ); - mvp[1] = x264_median( mv_a[1], mv_b[1], mv_c[1] ); - } + x264_median_mv( mvp, mv_a, mv_b, mv_c ); else if( i_count == 1 ) { if( i_refa == i_ref ) @@ -156,10 +153,7 @@ void x264_mb_predict_mv( x264_t *h, int i_list, int idx, int i_width, int16_t mv else if( i_refb == -2 && i_refc == -2 && i_refa != -2 ) *(uint32_t*)mvp = *(uint32_t*)mv_a; else - { - mvp[0] = x264_median( mv_a[0], mv_b[0], mv_c[0] ); - mvp[1] = x264_median( mv_a[1], mv_b[1], mv_c[1] ); - } + x264_median_mv( mvp, mv_a, mv_b, mv_c ); } void x264_mb_predict_mv_16x16( x264_t *h, int i_list, int i_ref, int16_t mvp[2] ) @@ -185,10 +179,7 @@ void x264_mb_predict_mv_16x16( x264_t *h, int i_list, int i_ref, int16_t mvp[2] if( i_refc == i_ref ) i_count++; if( i_count > 1 ) - { - mvp[0] = x264_median( mv_a[0], mv_b[0], mv_c[0] ); - mvp[1] = x264_median( mv_a[1], mv_b[1], mv_c[1] ); - } + x264_median_mv( mvp, mv_a, mv_b, mv_c ); else if( i_count == 1 ) { if( i_refa == i_ref ) @@ -201,10 +192,7 @@ void x264_mb_predict_mv_16x16( x264_t *h, int i_list, int i_ref, int16_t mvp[2] else if( i_refb == -2 && i_refc == -2 && i_refa != -2 ) *(uint32_t*)mvp = *(uint32_t*)mv_a; else - { - mvp[0] = x264_median( mv_a[0], mv_b[0], mv_c[0] ); - mvp[1] = x264_median( mv_a[1], mv_b[1], mv_c[1] ); - } + x264_median_mv( mvp, mv_a, mv_b, mv_c ); } diff --git a/common/x86/util.h b/common/x86/util.h new file mode 100644 index 00000000..73f49046 --- /dev/null +++ b/common/x86/util.h @@ -0,0 +1,44 @@ +/***************************************************************************** + * mc.h: h264 encoder library + ***************************************************************************** + * Copyright (C) 2008 Loren Merritt + * + * 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. + *****************************************************************************/ + +#ifndef X264_X86_UTIL_H +#define X264_X86_UTIL_H + +#ifdef __GNUC__ +#define x264_median_mv x264_median_mv_mmxext +static inline void x264_median_mv_mmxext( int16_t *dst, int16_t *a, int16_t *b, int16_t *c ) +{ + asm( + "movd %1, %%mm0 \n" + "movd %2, %%mm1 \n" + "movq %%mm0, %%mm3 \n" + "movd %3, %%mm2 \n" + "pmaxsw %%mm1, %%mm0 \n" + "pminsw %%mm3, %%mm1 \n" + "pminsw %%mm2, %%mm0 \n" + "pmaxsw %%mm1, %%mm0 \n" + "movd %%mm0, %0 \n" + :"=m"(*(uint32_t*)dst) + :"m"(*(uint32_t*)a), "m"(*(uint32_t*)b), "m"(*(uint32_t*)c) + ); +} +#endif + +#endif diff --git a/encoder/slicetype.c b/encoder/slicetype.c index 58e666be..fff7bc45 100644 --- a/encoder/slicetype.c +++ b/encoder/slicetype.c @@ -168,9 +168,7 @@ int x264_slicetype_mb_cost( x264_t *h, x264_mb_analysis_t *a, MVC(fenc_mv[-i_mb_stride-1]); } #undef MVC - m[l].mvp[0] = x264_median( mvc[0][0], mvc[1][0], mvc[2][0] ); - m[l].mvp[1] = x264_median( mvc[0][1], mvc[1][1], mvc[2][1] ); - + x264_median_mv( m[l].mvp, mvc[0], mvc[1], mvc[2] ); x264_me_search( h, &m[l], mvc, i_mvc ); m[l].cost -= 2; // remove mvcost from skip mbs -- 2.40.0