[x264-devel] commit: x264_median_mv_mmxext (Loren Merritt )
git version control
git at videolan.org
Tue May 20 12:08:26 CEST 2008
x264 | branch: master | Loren Merritt <pengvado at akuvian.org> | Sat May 17 03:39:59 2008 -0600| [a50d364ce947f9943458ca70ec6bf26f9e24475f]
x264_median_mv_mmxext
this is the first non-runtime-detected use of mmxext, but it has to be inlined
> http://git.videolan.org/gitweb.cgi/x264.git/?a=commit;h=a50d364ce947f9943458ca70ec6bf26f9e24475f
---
common/common.h | 27 +++++++++++++++------------
common/macroblock.c | 20 ++++----------------
common/x86/util.h | 44 ++++++++++++++++++++++++++++++++++++++++++++
encoder/slicetype.c | 4 +---
4 files changed, 64 insertions(+), 31 deletions(-)
diff --git a/common/common.h b/common/common.h
index a53509b..425fc8f 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 d2fc0cb..7c8b939 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 0000000..73f4904
--- /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 58e666b..fff7bc4 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
More information about the x264-devel
mailing list