• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • Examples
  • File List
  • Globals

libavcodec/x86/fmtconvert_mmx.c

Go to the documentation of this file.
00001 /*
00002  * Format Conversion Utils
00003  * Copyright (c) 2000, 2001 Fabrice Bellard
00004  * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
00005  *
00006  * This file is part of Libav.
00007  *
00008  * Libav is free software; you can redistribute it and/or
00009  * modify it under the terms of the GNU Lesser General Public
00010  * License as published by the Free Software Foundation; either
00011  * version 2.1 of the License, or (at your option) any later version.
00012  *
00013  * Libav is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016  * Lesser General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU Lesser General Public
00019  * License along with Libav; if not, write to the Free Software
00020  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00021  *
00022  * MMX optimization by Nick Kurshev <nickols_k@mail.ru>
00023  */
00024 
00025 #include "libavutil/cpu.h"
00026 #include "libavutil/x86_cpu.h"
00027 #include "libavcodec/fmtconvert.h"
00028 
00029 #if HAVE_YASM
00030 
00031 void ff_int32_to_float_fmul_scalar_sse (float *dst, const int *src, float mul, int len);
00032 void ff_int32_to_float_fmul_scalar_sse2(float *dst, const int *src, float mul, int len);
00033 
00034 void ff_float_to_int16_3dnow(int16_t *dst, const float *src, long len);
00035 void ff_float_to_int16_sse  (int16_t *dst, const float *src, long len);
00036 void ff_float_to_int16_sse2 (int16_t *dst, const float *src, long len);
00037 
00038 void ff_float_to_int16_interleave2_3dnow(int16_t *dst, const float **src, long len);
00039 void ff_float_to_int16_interleave2_sse  (int16_t *dst, const float **src, long len);
00040 void ff_float_to_int16_interleave2_sse2 (int16_t *dst, const float **src, long len);
00041 
00042 void ff_float_to_int16_interleave6_sse(int16_t *dst, const float **src, int len);
00043 void ff_float_to_int16_interleave6_3dnow(int16_t *dst, const float **src, int len);
00044 void ff_float_to_int16_interleave6_3dn2(int16_t *dst, const float **src, int len);
00045 
00046 #define ff_float_to_int16_interleave6_sse2 ff_float_to_int16_interleave6_sse
00047 
00048 #define FLOAT_TO_INT16_INTERLEAVE(cpu) \
00049 /* gcc pessimizes register allocation if this is in the same function as float_to_int16_interleave_sse2*/\
00050 static av_noinline void float_to_int16_interleave_misc_##cpu(int16_t *dst, const float **src, long len, int channels){\
00051     DECLARE_ALIGNED(16, int16_t, tmp)[len];\
00052     int i,j,c;\
00053     for(c=0; c<channels; c++){\
00054         ff_float_to_int16_##cpu(tmp, src[c], len);\
00055         for(i=0, j=c; i<len; i++, j+=channels)\
00056             dst[j] = tmp[i];\
00057     }\
00058 }\
00059 \
00060 static void float_to_int16_interleave_##cpu(int16_t *dst, const float **src, long len, int channels){\
00061     if(channels==1)\
00062         ff_float_to_int16_##cpu(dst, src[0], len);\
00063     else if(channels==2){\
00064         ff_float_to_int16_interleave2_##cpu(dst, src, len);\
00065     }else if(channels==6){\
00066         ff_float_to_int16_interleave6_##cpu(dst, src, len);\
00067     }else\
00068         float_to_int16_interleave_misc_##cpu(dst, src, len, channels);\
00069 }
00070 
00071 FLOAT_TO_INT16_INTERLEAVE(3dnow)
00072 FLOAT_TO_INT16_INTERLEAVE(sse)
00073 FLOAT_TO_INT16_INTERLEAVE(sse2)
00074 
00075 static void float_to_int16_interleave_3dn2(int16_t *dst, const float **src, long len, int channels){
00076     if(channels==6)
00077         ff_float_to_int16_interleave6_3dn2(dst, src, len);
00078     else
00079         float_to_int16_interleave_3dnow(dst, src, len, channels);
00080 }
00081 
00082 void ff_float_interleave2_mmx(float *dst, const float **src, unsigned int len);
00083 void ff_float_interleave2_sse(float *dst, const float **src, unsigned int len);
00084 
00085 void ff_float_interleave6_mmx(float *dst, const float **src, unsigned int len);
00086 void ff_float_interleave6_sse(float *dst, const float **src, unsigned int len);
00087 
00088 static void float_interleave_mmx(float *dst, const float **src,
00089                                  unsigned int len, int channels)
00090 {
00091     if (channels == 2) {
00092         ff_float_interleave2_mmx(dst, src, len);
00093     } else if (channels == 6)
00094         ff_float_interleave6_mmx(dst, src, len);
00095     else
00096         ff_float_interleave_c(dst, src, len, channels);
00097 }
00098 
00099 static void float_interleave_sse(float *dst, const float **src,
00100                                  unsigned int len, int channels)
00101 {
00102     if (channels == 2) {
00103         ff_float_interleave2_sse(dst, src, len);
00104     } else if (channels == 6)
00105         ff_float_interleave6_sse(dst, src, len);
00106     else
00107         ff_float_interleave_c(dst, src, len, channels);
00108 }
00109 #endif
00110 
00111 void ff_fmt_convert_init_x86(FmtConvertContext *c, AVCodecContext *avctx)
00112 {
00113     int mm_flags = av_get_cpu_flags();
00114 
00115 #if HAVE_YASM
00116     if (mm_flags & AV_CPU_FLAG_MMX) {
00117         c->float_interleave = float_interleave_mmx;
00118 
00119         if (HAVE_AMD3DNOW && mm_flags & AV_CPU_FLAG_3DNOW) {
00120             if(!(avctx->flags & CODEC_FLAG_BITEXACT)){
00121                 c->float_to_int16 = ff_float_to_int16_3dnow;
00122                 c->float_to_int16_interleave = float_to_int16_interleave_3dnow;
00123             }
00124         }
00125         if (HAVE_AMD3DNOWEXT && mm_flags & AV_CPU_FLAG_3DNOWEXT) {
00126             if(!(avctx->flags & CODEC_FLAG_BITEXACT)){
00127                 c->float_to_int16_interleave = float_to_int16_interleave_3dn2;
00128             }
00129         }
00130         if (HAVE_SSE && mm_flags & AV_CPU_FLAG_SSE) {
00131             c->int32_to_float_fmul_scalar = ff_int32_to_float_fmul_scalar_sse;
00132             c->float_to_int16 = ff_float_to_int16_sse;
00133             c->float_to_int16_interleave = float_to_int16_interleave_sse;
00134             c->float_interleave = float_interleave_sse;
00135         }
00136         if (HAVE_SSE && mm_flags & AV_CPU_FLAG_SSE2) {
00137             c->int32_to_float_fmul_scalar = ff_int32_to_float_fmul_scalar_sse2;
00138             c->float_to_int16 = ff_float_to_int16_sse2;
00139             c->float_to_int16_interleave = float_to_int16_interleave_sse2;
00140         }
00141     }
00142 #endif
00143 }
Generated on Thu Jul 11 2013 15:38:22 for Libav by doxygen 1.7.1