## ffmpeg / libavcodec / x86 / mpegaudiodec_mmx.c @ 98c6053c

History | View | Annotate | Download (5 KB)

1 | bc2b3682 | Vitor Sessak | ```
/*
``` |
---|---|---|---|

2 | ```
* MMX optimized MP3 decoding functions
``` |
||

3 | ```
* Copyright (c) 2010 Vitor Sessak
``` |
||

4 | ```
*
``` |
||

5 | ```
* This file is part of FFmpeg.
``` |
||

6 | ```
*
``` |
||

7 | ```
* FFmpeg is free software; you can redistribute it and/or
``` |
||

8 | ```
* modify it under the terms of the GNU Lesser General Public
``` |
||

9 | ```
* License as published by the Free Software Foundation; either
``` |
||

10 | ```
* version 2.1 of the License, or (at your option) any later version.
``` |
||

11 | ```
*
``` |
||

12 | ```
* FFmpeg is distributed in the hope that it will be useful,
``` |
||

13 | ```
* but WITHOUT ANY WARRANTY; without even the implied warranty of
``` |
||

14 | ```
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
``` |
||

15 | ```
* Lesser General Public License for more details.
``` |
||

16 | ```
*
``` |
||

17 | ```
* You should have received a copy of the GNU Lesser General Public
``` |
||

18 | ```
* License along with FFmpeg; if not, write to the Free Software
``` |
||

19 | ```
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
``` |
||

20 | ```
*/
``` |
||

21 | |||

22 | c6c98d08 | Stefano Sabatini | #include "libavutil/cpu.h" |

23 | bc2b3682 | Vitor Sessak | #include "libavutil/x86_cpu.h" |

24 | |||

25 | #define CONFIG_FLOAT 1 |
||

26 | #include "libavcodec/mpegaudio.h" |
||

27 | |||

28 | ```
#define MACS(rt, ra, rb) rt+=(ra)*(rb)
``` |
||

29 | ```
#define MLSS(rt, ra, rb) rt-=(ra)*(rb)
``` |
||

30 | |||

31 | ```
#define SUM8(op, sum, w, p) \
``` |
||

32 | { \ |
||

33 | op(sum, (w)[0 * 64], (p)[0 * 64]); \ |
||

34 | op(sum, (w)[1 * 64], (p)[1 * 64]); \ |
||

35 | op(sum, (w)[2 * 64], (p)[2 * 64]); \ |
||

36 | op(sum, (w)[3 * 64], (p)[3 * 64]); \ |
||

37 | op(sum, (w)[4 * 64], (p)[4 * 64]); \ |
||

38 | op(sum, (w)[5 * 64], (p)[5 * 64]); \ |
||

39 | op(sum, (w)[6 * 64], (p)[6 * 64]); \ |
||

40 | op(sum, (w)[7 * 64], (p)[7 * 64]); \ |
||

41 | } |
||

42 | |||

43 | static void apply_window(const float *buf, const float *win1, |
||

44 | const float *win2, float *sum1, float *sum2, int len) |
||

45 | { |
||

46 | ```
x86_reg count = - 4*len;
``` |
||

47 | const float *win1a = win1+len; |
||

48 | const float *win2a = win2+len; |
||

49 | const float *bufa = buf+len; |
||

50 | ```
float *sum1a = sum1+len;
``` |
||

51 | ```
float *sum2a = sum2+len;
``` |
||

52 | |||

53 | |||

54 | ```
#define MULT(a, b) \
``` |
||

55 | 57dbd12b | Vitor Sessak | "movaps " #a "(%1,%0), %%xmm1 \n\t" \ |

56 | "movaps " #a "(%3,%0), %%xmm2 \n\t" \ |
||

57 | bc2b3682 | Vitor Sessak | ```
"mulps %%xmm2, %%xmm1 \n\t" \
``` |

58 | ```
"subps %%xmm1, %%xmm0 \n\t" \
``` |
||

59 | 57dbd12b | Vitor Sessak | "mulps " #b "(%2,%0), %%xmm2 \n\t" \ |

60 | bc2b3682 | Vitor Sessak | ```
"subps %%xmm2, %%xmm4 \n\t" \
``` |

61 | |||

62 | ```
__asm__ volatile(
``` |
||

63 | ```
"1: \n\t"
``` |
||

64 | ```
"xorps %%xmm0, %%xmm0 \n\t"
``` |
||

65 | ```
"xorps %%xmm4, %%xmm4 \n\t"
``` |
||

66 | |||

67 | MULT( 0, 0) |
||

68 | MULT( 256, 64) |
||

69 | MULT( 512, 128) |
||

70 | MULT( 768, 192) |
||

71 | MULT(1024, 256) |
||

72 | MULT(1280, 320) |
||

73 | MULT(1536, 384) |
||

74 | MULT(1792, 448) |
||

75 | |||

76 | 57dbd12b | Vitor Sessak | ```
"movaps %%xmm0, (%4,%0) \n\t"
``` |

77 | ```
"movaps %%xmm4, (%5,%0) \n\t"
``` |
||

78 | 89c7d805 | Vitor Sessak | ```
"add $16, %0 \n\t"
``` |

79 | bc2b3682 | Vitor Sessak | ```
"jl 1b \n\t"
``` |

80 | 57dbd12b | Vitor Sessak | ```
:"+&r"(count)
``` |

81 | :"r"(win1a), "r"(win2a), "r"(bufa), "r"(sum1a), "r"(sum2a) |
||

82 | bc2b3682 | Vitor Sessak | ); |

83 | |||

84 | ```
#undef MULT
``` |
||

85 | } |
||

86 | |||

87 | static void apply_window_mp3(float *in, float *win, int *unused, float *out, |
||

88 | ```
int incr)
``` |
||

89 | { |
||

90 | LOCAL_ALIGNED_16(float, suma, [17]); |
||

91 | LOCAL_ALIGNED_16(float, sumb, [17]); |
||

92 | LOCAL_ALIGNED_16(float, sumc, [17]); |
||

93 | LOCAL_ALIGNED_16(float, sumd, [17]); |
||

94 | |||

95 | ```
float sum;
``` |
||

96 | |||

97 | ```
/* copy to avoid wrap */
``` |
||

98 | memcpy(in + 512, in, 32 * sizeof(*in)); |
||

99 | |||

100 | apply_window(in + 16, win , win + 512, suma, sumc, 16); |
||

101 | apply_window(in + 32, win + 48, win + 640, sumb, sumd, 16); |
||

102 | |||

103 | SUM8(MACS, suma[0], win + 32, in + 48); |
||

104 | |||

105 | sumc[ 0] = 0; |
||

106 | sumb[16] = 0; |
||

107 | sumd[16] = 0; |
||

108 | |||

109 | ```
#define SUMS(suma, sumb, sumc, sumd, out1, out2) \
``` |
||

110 | "movups " #sumd "(%4), %%xmm0 \n\t" \ |
||

111 | ```
"shufps $0x1b, %%xmm0, %%xmm0 \n\t" \
``` |
||

112 | "subps " #suma "(%1), %%xmm0 \n\t" \ |
||

113 | "movaps %%xmm0," #out1 "(%0) \n\t" \ |
||

114 | \ |
||

115 | "movups " #sumc "(%3), %%xmm0 \n\t" \ |
||

116 | ```
"shufps $0x1b, %%xmm0, %%xmm0 \n\t" \
``` |
||

117 | "addps " #sumb "(%2), %%xmm0 \n\t" \ |
||

118 | "movaps %%xmm0," #out2 "(%0) \n\t" |
||

119 | |||

120 | if (incr == 1) { |
||

121 | ```
__asm__ volatile(
``` |
||

122 | SUMS( 0, 48, 4, 52, 0, 112) |
||

123 | SUMS(16, 32, 20, 36, 16, 96) |
||

124 | SUMS(32, 16, 36, 20, 32, 80) |
||

125 | SUMS(48, 0, 52, 4, 48, 64) |
||

126 | |||

127 | ```
:"+&r"(out)
``` |
||

128 | :"r"(&suma[0]), "r"(&sumb[0]), "r"(&sumc[0]), "r"(&sumd[0]) |
||

129 | ```
:"memory"
``` |
||

130 | ); |
||

131 | ```
out += 16*incr;
``` |
||

132 | ```
} else {
``` |
||

133 | ```
int j;
``` |
||

134 | float *out2 = out + 32 * incr; |
||

135 | out[0 ] = -suma[ 0]; |
||

136 | out += incr; |
||

137 | out2 -= incr; |
||

138 | for(j=1;j<16;j++) { |
||

139 | ```
*out = -suma[ j] + sumd[16-j];
``` |
||

140 | ```
*out2 = sumb[16-j] + sumc[ j];
``` |
||

141 | out += incr; |
||

142 | out2 -= incr; |
||

143 | } |
||

144 | } |
||

145 | |||

146 | ```
sum = 0;
``` |
||

147 | SUM8(MLSS, sum, win + 16 + 32, in + 32); |
||

148 | *out = sum; |
||

149 | } |
||

150 | |||

151 | ```
void ff_mpegaudiodec_init_mmx(MPADecodeContext *s)
``` |
||

152 | { |
||

153 | c6c98d08 | Stefano Sabatini | ```
int mm_flags = av_get_cpu_flags();
``` |

154 | bc2b3682 | Vitor Sessak | |

155 | 7160bb71 | Stefano Sabatini | ```
if (mm_flags & AV_CPU_FLAG_SSE2) {
``` |

156 | bc2b3682 | Vitor Sessak | s->apply_window_mp3 = apply_window_mp3; |

157 | } |
||

158 | } |