History

Separate format conversion DSP functions from DSPContext.

This will be beneficial for use with the audio conversion API without requiring it to depend on all of dsputil.

Justin Ruggles committed 15 years ago

Commit fe2ff6d1 parent a35d78232 files · +1204 −882Browse files

Unified · Split

32 files
  1. libavcodec/Makefile +1 −0
  2. libavcodec/aac.h +2 −0
  3. libavcodec/aacdec.c +3 −1
  4. libavcodec/ac3dec.c +3 −2
  5. libavcodec/ac3dec.h +2 −0
  6. libavcodec/arm/Makefile +5 −0
  7. libavcodec/arm/dsputil_init_neon.c +0 −10
  8. libavcodec/arm/dsputil_init_vfp.c +0 −4
  9. libavcodec/arm/dsputil_neon.S +0 −365
  10. libavcodec/arm/dsputil_vfp.S +0 −55
  11. libavcodec/arm/fmtconvert_init_arm.c +48 −0
  12. libavcodec/arm/fmtconvert_neon.S +391 −0
  13. libavcodec/arm/fmtconvert_vfp.S +77 −0
  14. libavcodec/binkaudio.c +5 −1
  15. libavcodec/dca.c +5 −2
  16. libavcodec/dsputil.c +0 −33
  17. libavcodec/dsputil.h +0 −5
  18. libavcodec/fmtconvert.c +68 −0
  19. libavcodec/fmtconvert.h +79 −0
  20. libavcodec/nellymoserdec.c +4 −1
  21. libavcodec/ppc/Makefile +1 −0
  22. libavcodec/ppc/float_altivec.c +0 −112
  23. libavcodec/ppc/fmtconvert_altivec.c +142 −0
  24. libavcodec/vorbis_dec.c +5 −1
  25. libavcodec/wma.c +1 −0
  26. libavcodec/wma.h +2 −0
  27. libavcodec/wmadec.c +1 −1
  28. libavcodec/x86/Makefile +2 −0
  29. libavcodec/x86/dsputil_mmx.c +0 −220
  30. libavcodec/x86/dsputil_yasm.asm +0 −69
  31. libavcodec/x86/fmtconvert.asm +91 −0
  32. libavcodec/x86/fmtconvert_mmx.c +266 −0
libavcodec/Makefile+1−0
@@ -12,6 +12,7 @@ OBJS = allcodecs.o \ · 11 unmodified lines
12 bitstream_filter.o \12 bitstream_filter.o \
13 dsputil.o \13 dsputil.o \
14 faanidct.o \14 faanidct.o \
15 fmtconvert.o \
15 imgconvert.o \16 imgconvert.o \
16 jrevdct.o \17 jrevdct.o \
17 opt.o \18 opt.o \
libavcodec/aac.h+2−0
@@ -35,6 +35,7 @@ · 34 unmodified lines
35#include "fft.h"35#include "fft.h"
36#include "mpeg4audio.h"36#include "mpeg4audio.h"
37#include "sbr.h"37#include "sbr.h"
38#include "fmtconvert.h"
38 39
39#include <stdint.h>40#include <stdint.h>
40 41
@@ -268,6 +269,7 @@ typedef struct { · 227 unmodified lines
268 FFTContext mdct;269 FFTContext mdct;
269 FFTContext mdct_small;270 FFTContext mdct_small;
270 DSPContext dsp;271 DSPContext dsp;
272 FmtConvertContext fmt_conv;
271 int random_state;273 int random_state;
272 /** @} */274 /** @} */
273 275
libavcodec/aacdec.c+3−1
@@ -85,6 +85,7 @@ · 84 unmodified lines
85#include "get_bits.h"85#include "get_bits.h"
86#include "dsputil.h"86#include "dsputil.h"
87#include "fft.h"87#include "fft.h"
88#include "fmtconvert.h"
88#include "lpc.h"89#include "lpc.h"
89 90
90#include "aac.h"91#include "aac.h"
@@ -562,6 +563,7 @@ static av_cold int aac_decode_init(AVCodecContext *avctx) · 471 unmodified lines
562 ff_aac_sbr_init();563 ff_aac_sbr_init();
563 564
564 dsputil_init(&ac->dsp, avctx);565 dsputil_init(&ac->dsp, avctx);
566 ff_fmt_convert_init(&ac->fmt_conv, avctx);
565 567
566 ac->random_state = 0x1f2e3d4c;568 ac->random_state = 0x1f2e3d4c;
567 569
@@ -2032,7 +2034,7 @@ static int aac_decode_frame_int(AVCodecContext *avctx, void *data, · 1464 unmodified lines
2032 *data_size = data_size_tmp;2034 *data_size = data_size_tmp;
2033 2035
2034 if (samples)2036 if (samples)
2035 ac->dsp.float_to_int16_interleave(data, (const float **)ac->output_data, samples, avctx->channels);2037 ac->fmt_conv.float_to_int16_interleave(data, (const float **)ac->output_data, samples, avctx->channels);
2036 2038
2037 if (ac->output_configured)2039 if (ac->output_configured)
2038 ac->output_configured = OC_LOCKED;2040 ac->output_configured = OC_LOCKED;
libavcodec/ac3dec.c+3−2
@@ -193,6 +193,7 @@ static av_cold int ac3_decode_init(AVCodecContext *avctx) · 192 unmodified lines
193 ff_mdct_init(&s->imdct_512, 9, 1, 1.0);193 ff_mdct_init(&s->imdct_512, 9, 1, 1.0);
194 ff_kbd_window_init(s->window, 5.0, 256);194 ff_kbd_window_init(s->window, 5.0, 256);
195 dsputil_init(&s->dsp, avctx);195 dsputil_init(&s->dsp, avctx);
196 ff_fmt_convert_init(&s->fmt_conv, avctx);
196 av_lfg_init(&s->dith_state, 0);197 av_lfg_init(&s->dith_state, 0);
197 198
198 /* set scale value for float to int16 conversion */199 /* set scale value for float to int16 conversion */
@@ -1255,7 +1256,7 @@ static int decode_audio_block(AC3DecodeContext *s, int blk) · 1056 unmodified lines
1255 } else {1256 } else {
1256 gain *= s->dynamic_range[0];1257 gain *= s->dynamic_range[0];
1257 }1258 }
1258 s->dsp.int32_to_float_fmul_scalar(s->transform_coeffs[ch], s->fixed_coeffs[ch], gain, 256);1259 s->fmt_conv.int32_to_float_fmul_scalar(s->transform_coeffs[ch], s->fixed_coeffs[ch], gain, 256);
1259 }1260 }
1260 1261
1261 /* apply spectral extension to high frequency bins */1262 /* apply spectral extension to high frequency bins */
@@ -1407,7 +1408,7 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data, int *data_size, · 145 unmodified lines
1407 av_log(avctx, AV_LOG_ERROR, "error decoding the audio block\n");1408 av_log(avctx, AV_LOG_ERROR, "error decoding the audio block\n");
1408 err = 1;1409 err = 1;
1409 }1410 }
1410 s->dsp.float_to_int16_interleave(out_samples, output, 256, s->out_channels);1411 s->fmt_conv.float_to_int16_interleave(out_samples, output, 256, s->out_channels);
1411 out_samples += 256 * s->out_channels;1412 out_samples += 256 * s->out_channels;
1412 }1413 }
1413 *data_size = s->num_blocks * 256 * avctx->channels * sizeof (int16_t);1414 *data_size = s->num_blocks * 256 * avctx->channels * sizeof (int16_t);
libavcodec/ac3dec.h+2−0
@@ -55,6 +55,7 @@ · 54 unmodified lines
55#include "get_bits.h"55#include "get_bits.h"
56#include "dsputil.h"56#include "dsputil.h"
57#include "fft.h"57#include "fft.h"
58#include "fmtconvert.h"
58 59
59/* override ac3.h to include coupling channel */60/* override ac3.h to include coupling channel */
60#undef AC3_MAX_CHANNELS61#undef AC3_MAX_CHANNELS
@@ -190,6 +191,7 @@ typedef struct { · 129 unmodified lines
190 191
191///@defgroup opt optimization192///@defgroup opt optimization
192 DSPContext dsp; ///< for optimization193 DSPContext dsp; ///< for optimization
194 FmtConvertContext fmt_conv; ///< optimized conversion functions
193 float mul_bias; ///< scaling for float_to_int16 conversion195 float mul_bias; ///< scaling for float_to_int16 conversion
194///@}196///@}
195 197
libavcodec/arm/Makefile+5−0
@@ -9,6 +9,7 @@ OBJS-$(CONFIG_H264PRED) += arm/h264pred_init_arm.o · 8 unmodified lines
9OBJS += arm/dsputil_init_arm.o \9OBJS += arm/dsputil_init_arm.o \
10 arm/dsputil_arm.o \10 arm/dsputil_arm.o \
11 arm/fft_init_arm.o \11 arm/fft_init_arm.o \
12 arm/fmtconvert_init_arm.o \
12 arm/jrevdct_arm.o \13 arm/jrevdct_arm.o \
13 arm/mpegvideo_arm.o \14 arm/mpegvideo_arm.o \
14 arm/simple_idct_arm.o \15 arm/simple_idct_arm.o \
@@ -22,8 +23,11 @@ OBJS-$(HAVE_ARMV6) += arm/dsputil_init_armv6.o \ · 7 unmodified lines
22 arm/dsputil_armv6.o \23 arm/dsputil_armv6.o \
23 arm/simple_idct_armv6.o \24 arm/simple_idct_armv6.o \
24 25
26VFP-OBJS-$(HAVE_ARMV6) += arm/fmtconvert_vfp.o \
27
25OBJS-$(HAVE_ARMVFP) += arm/dsputil_vfp.o \28OBJS-$(HAVE_ARMVFP) += arm/dsputil_vfp.o \
26 arm/dsputil_init_vfp.o \29 arm/dsputil_init_vfp.o \
30 $(VFP-OBJS-yes)
27 31
28OBJS-$(HAVE_IWMMXT) += arm/dsputil_iwmmxt.o \32OBJS-$(HAVE_IWMMXT) += arm/dsputil_iwmmxt.o \
29 arm/mpegvideo_iwmmxt.o \33 arm/mpegvideo_iwmmxt.o \
@@ -52,6 +56,7 @@ NEON-OBJS-$(CONFIG_VP6_DECODER) += arm/vp56dsp_neon.o \ · 22 unmodified lines
52 56
53OBJS-$(HAVE_NEON) += arm/dsputil_init_neon.o \57OBJS-$(HAVE_NEON) += arm/dsputil_init_neon.o \
54 arm/dsputil_neon.o \58 arm/dsputil_neon.o \
59 arm/fmtconvert_neon.o \
55 arm/int_neon.o \60 arm/int_neon.o \
56 arm/mpegvideo_neon.o \61 arm/mpegvideo_neon.o \
57 arm/simple_idct_neon.o \62 arm/simple_idct_neon.o \
libavcodec/arm/dsputil_init_neon.c+0−10
@@ -153,8 +153,6 @@ void ff_sv_fmul_scalar_4_neon(float *dst, const float **vp, float mul, · 152 unmodified lines
153 int len);153 int len);
154void ff_butterflies_float_neon(float *v1, float *v2, int len);154void ff_butterflies_float_neon(float *v1, float *v2, int len);
155float ff_scalarproduct_float_neon(const float *v1, const float *v2, int len);155float ff_scalarproduct_float_neon(const float *v1, const float *v2, int len);
156void ff_int32_to_float_fmul_scalar_neon(float *dst, const int *src,
157 float mul, int len);
158void ff_vector_fmul_reverse_neon(float *dst, const float *src0,156void ff_vector_fmul_reverse_neon(float *dst, const float *src0,
159 const float *src1, int len);157 const float *src1, int len);
160void ff_vector_fmul_add_neon(float *dst, const float *src0, const float *src1,158void ff_vector_fmul_add_neon(float *dst, const float *src0, const float *src1,
@@ -162,8 +160,6 @@ void ff_vector_fmul_add_neon(float *dst, const float *src0, const float *src1, · 1 unmodified line
162 160
163void ff_vector_clipf_neon(float *dst, const float *src, float min, float max,161void ff_vector_clipf_neon(float *dst, const float *src, float min, float max,
164 int len);162 int len);
165void ff_float_to_int16_neon(int16_t *, const float *, long);
166void ff_float_to_int16_interleave_neon(int16_t *, const float **, long, int);
167 163
168void ff_vorbis_inverse_coupling_neon(float *mag, float *ang, int blocksize);164void ff_vorbis_inverse_coupling_neon(float *mag, float *ang, int blocksize);
169 165
@@ -308,7 +304,6 @@ void ff_dsputil_init_neon(DSPContext *c, AVCodecContext *avctx) · 138 unmodified lines
308 c->vector_fmul_scalar = ff_vector_fmul_scalar_neon;304 c->vector_fmul_scalar = ff_vector_fmul_scalar_neon;
309 c->butterflies_float = ff_butterflies_float_neon;305 c->butterflies_float = ff_butterflies_float_neon;
310 c->scalarproduct_float = ff_scalarproduct_float_neon;306 c->scalarproduct_float = ff_scalarproduct_float_neon;
311 c->int32_to_float_fmul_scalar = ff_int32_to_float_fmul_scalar_neon;
312 c->vector_fmul_reverse = ff_vector_fmul_reverse_neon;307 c->vector_fmul_reverse = ff_vector_fmul_reverse_neon;
313 c->vector_fmul_add = ff_vector_fmul_add_neon;308 c->vector_fmul_add = ff_vector_fmul_add_neon;
314 c->vector_clipf = ff_vector_clipf_neon;309 c->vector_clipf = ff_vector_clipf_neon;
@@ -319,11 +314,6 @@ void ff_dsputil_init_neon(DSPContext *c, AVCodecContext *avctx) · 4 unmodified lines
319 c->sv_fmul_scalar[0] = ff_sv_fmul_scalar_2_neon;314 c->sv_fmul_scalar[0] = ff_sv_fmul_scalar_2_neon;
320 c->sv_fmul_scalar[1] = ff_sv_fmul_scalar_4_neon;315 c->sv_fmul_scalar[1] = ff_sv_fmul_scalar_4_neon;
321 316
322 if (!(avctx->flags & CODEC_FLAG_BITEXACT)) {
323 c->float_to_int16 = ff_float_to_int16_neon;
324 c->float_to_int16_interleave = ff_float_to_int16_interleave_neon;
325 }
326
327 if (CONFIG_VORBIS_DECODER)317 if (CONFIG_VORBIS_DECODER)
328 c->vorbis_inverse_coupling = ff_vorbis_inverse_coupling_neon;318 c->vorbis_inverse_coupling = ff_vorbis_inverse_coupling_neon;
329 319
libavcodec/arm/dsputil_init_vfp.c+0−4
@@ -25,13 +25,9 @@ void ff_vector_fmul_vfp(float *dst, const float *src0, · 24 unmodified lines
25 const float *src1, int len);25 const float *src1, int len);
26void ff_vector_fmul_reverse_vfp(float *dst, const float *src0,26void ff_vector_fmul_reverse_vfp(float *dst, const float *src0,
27 const float *src1, int len);27 const float *src1, int len);
28void ff_float_to_int16_vfp(int16_t *dst, const float *src, long len);
29 28
30void ff_dsputil_init_vfp(DSPContext* c, AVCodecContext *avctx)29void ff_dsputil_init_vfp(DSPContext* c, AVCodecContext *avctx)
31{30{
32 c->vector_fmul = ff_vector_fmul_vfp;31 c->vector_fmul = ff_vector_fmul_vfp;
33 c->vector_fmul_reverse = ff_vector_fmul_reverse_vfp;32 c->vector_fmul_reverse = ff_vector_fmul_reverse_vfp;
34#if HAVE_ARMV6
35 c->float_to_int16 = ff_float_to_int16_vfp;
36#endif
37}33}
libavcodec/arm/dsputil_neon.S+0−365
@@ -400,343 +400,6 @@ function ff_add_pixels_clamped_neon, export=1 · 399 unmodified lines
400 bx lr400 bx lr
401endfunc401endfunc
402 402
403function ff_float_to_int16_neon, export=1
404 subs r2, r2, #8
405 vld1.64 {d0-d1}, [r1,:128]!
406 vcvt.s32.f32 q8, q0, #16
407 vld1.64 {d2-d3}, [r1,:128]!
408 vcvt.s32.f32 q9, q1, #16
409 beq 3f
410 bics ip, r2, #15
411 beq 2f
4121: subs ip, ip, #16
413 vshrn.s32 d4, q8, #16
414 vld1.64 {d0-d1}, [r1,:128]!
415 vcvt.s32.f32 q0, q0, #16
416 vshrn.s32 d5, q9, #16
417 vld1.64 {d2-d3}, [r1,:128]!
418 vcvt.s32.f32 q1, q1, #16
419 vshrn.s32 d6, q0, #16
420 vst1.64 {d4-d5}, [r0,:128]!
421 vshrn.s32 d7, q1, #16
422 vld1.64 {d16-d17},[r1,:128]!
423 vcvt.s32.f32 q8, q8, #16
424 vld1.64 {d18-d19},[r1,:128]!
425 vcvt.s32.f32 q9, q9, #16
426 vst1.64 {d6-d7}, [r0,:128]!
427 bne 1b
428 ands r2, r2, #15
429 beq 3f
4302: vld1.64 {d0-d1}, [r1,:128]!
431 vshrn.s32 d4, q8, #16
432 vcvt.s32.f32 q0, q0, #16
433 vld1.64 {d2-d3}, [r1,:128]!
434 vshrn.s32 d5, q9, #16
435 vcvt.s32.f32 q1, q1, #16
436 vshrn.s32 d6, q0, #16
437 vst1.64 {d4-d5}, [r0,:128]!
438 vshrn.s32 d7, q1, #16
439 vst1.64 {d6-d7}, [r0,:128]!
440 bx lr
4413: vshrn.s32 d4, q8, #16
442 vshrn.s32 d5, q9, #16
443 vst1.64 {d4-d5}, [r0,:128]!
444 bx lr
445endfunc
446
447function ff_float_to_int16_interleave_neon, export=1
448 cmp r3, #2
449 ldrlt r1, [r1]
450 blt ff_float_to_int16_neon
451 bne 4f
452
453 ldr r3, [r1]
454 ldr r1, [r1, #4]
455
456 subs r2, r2, #8
457 vld1.64 {d0-d1}, [r3,:128]!
458 vcvt.s32.f32 q8, q0, #16
459 vld1.64 {d2-d3}, [r3,:128]!
460 vcvt.s32.f32 q9, q1, #16
461 vld1.64 {d20-d21},[r1,:128]!
462 vcvt.s32.f32 q10, q10, #16
463 vld1.64 {d22-d23},[r1,:128]!
464 vcvt.s32.f32 q11, q11, #16
465 beq 3f
466 bics ip, r2, #15
467 beq 2f
4681: subs ip, ip, #16
469 vld1.64 {d0-d1}, [r3,:128]!
470 vcvt.s32.f32 q0, q0, #16
471 vsri.32 q10, q8, #16
472 vld1.64 {d2-d3}, [r3,:128]!
473 vcvt.s32.f32 q1, q1, #16
474 vld1.64 {d24-d25},[r1,:128]!
475 vcvt.s32.f32 q12, q12, #16
476 vld1.64 {d26-d27},[r1,:128]!
477 vsri.32 q11, q9, #16
478 vst1.64 {d20-d21},[r0,:128]!
479 vcvt.s32.f32 q13, q13, #16
480 vst1.64 {d22-d23},[r0,:128]!
481 vsri.32 q12, q0, #16
482 vld1.64 {d16-d17},[r3,:128]!
483 vsri.32 q13, q1, #16
484 vst1.64 {d24-d25},[r0,:128]!
485 vcvt.s32.f32 q8, q8, #16
486 vld1.64 {d18-d19},[r3,:128]!
487 vcvt.s32.f32 q9, q9, #16
488 vld1.64 {d20-d21},[r1,:128]!
489 vcvt.s32.f32 q10, q10, #16
490 vld1.64 {d22-d23},[r1,:128]!
491 vcvt.s32.f32 q11, q11, #16
492 vst1.64 {d26-d27},[r0,:128]!
493 bne 1b
494 ands r2, r2, #15
495 beq 3f
4962: vsri.32 q10, q8, #16
497 vld1.64 {d0-d1}, [r3,:128]!
498 vcvt.s32.f32 q0, q0, #16
499 vld1.64 {d2-d3}, [r3,:128]!
500 vcvt.s32.f32 q1, q1, #16
501 vld1.64 {d24-d25},[r1,:128]!
502 vcvt.s32.f32 q12, q12, #16
503 vsri.32 q11, q9, #16
504 vld1.64 {d26-d27},[r1,:128]!
505 vcvt.s32.f32 q13, q13, #16
506 vst1.64 {d20-d21},[r0,:128]!
507 vsri.32 q12, q0, #16
508 vst1.64 {d22-d23},[r0,:128]!
509 vsri.32 q13, q1, #16
510 vst1.64 {d24-d27},[r0,:128]!
511 bx lr
5123: vsri.32 q10, q8, #16
513 vsri.32 q11, q9, #16
514 vst1.64 {d20-d23},[r0,:128]!
515 bx lr
516
5174: push {r4-r8,lr}
518 cmp r3, #4
519 lsl ip, r3, #1
520 blt 4f
521
522 @ 4 channels
5235: ldmia r1!, {r4-r7}
524 mov lr, r2
525 mov r8, r0
526 vld1.64 {d16-d17},[r4,:128]!
527 vcvt.s32.f32 q8, q8, #16
528 vld1.64 {d18-d19},[r5,:128]!
529 vcvt.s32.f32 q9, q9, #16
530 vld1.64 {d20-d21},[r6,:128]!
531 vcvt.s32.f32 q10, q10, #16
532 vld1.64 {d22-d23},[r7,:128]!
533 vcvt.s32.f32 q11, q11, #16
5346: subs lr, lr, #8
535 vld1.64 {d0-d1}, [r4,:128]!
536 vcvt.s32.f32 q0, q0, #16
537 vsri.32 q9, q8, #16
538 vld1.64 {d2-d3}, [r5,:128]!
539 vcvt.s32.f32 q1, q1, #16
540 vsri.32 q11, q10, #16
541 vld1.64 {d4-d5}, [r6,:128]!
542 vcvt.s32.f32 q2, q2, #16
543 vzip.32 d18, d22
544 vld1.64 {d6-d7}, [r7,:128]!
545 vcvt.s32.f32 q3, q3, #16
546 vzip.32 d19, d23
547 vst1.64 {d18}, [r8], ip
548 vsri.32 q1, q0, #16
549 vst1.64 {d22}, [r8], ip
550 vsri.32 q3, q2, #16
551 vst1.64 {d19}, [r8], ip
552 vzip.32 d2, d6
553 vst1.64 {d23}, [r8], ip
554 vzip.32 d3, d7
555 beq 7f
556 vld1.64 {d16-d17},[r4,:128]!
557 vcvt.s32.f32 q8, q8, #16
558 vst1.64 {d2}, [r8], ip
559 vld1.64 {d18-d19},[r5,:128]!
560 vcvt.s32.f32 q9, q9, #16
561 vst1.64 {d6}, [r8], ip
562 vld1.64 {d20-d21},[r6,:128]!
563 vcvt.s32.f32 q10, q10, #16
564 vst1.64 {d3}, [r8], ip
565 vld1.64 {d22-d23},[r7,:128]!
566 vcvt.s32.f32 q11, q11, #16
567 vst1.64 {d7}, [r8], ip
568 b 6b
5697: vst1.64 {d2}, [r8], ip
570 vst1.64 {d6}, [r8], ip
571 vst1.64 {d3}, [r8], ip
572 vst1.64 {d7}, [r8], ip
573 subs r3, r3, #4
574 popeq {r4-r8,pc}
575 cmp r3, #4
576 add r0, r0, #8
577 bge 5b
578
579 @ 2 channels
5804: cmp r3, #2
581 blt 4f
582 ldmia r1!, {r4-r5}
583 mov lr, r2
584 mov r8, r0
585 tst lr, #8
586 vld1.64 {d16-d17},[r4,:128]!
587 vcvt.s32.f32 q8, q8, #16
588 vld1.64 {d18-d19},[r5,:128]!
589 vcvt.s32.f32 q9, q9, #16
590 vld1.64 {d20-d21},[r4,:128]!
591 vcvt.s32.f32 q10, q10, #16
592 vld1.64 {d22-d23},[r5,:128]!
593 vcvt.s32.f32 q11, q11, #16
594 beq 6f
595 subs lr, lr, #8
596 beq 7f
597 vsri.32 d18, d16, #16
598 vsri.32 d19, d17, #16
599 vld1.64 {d16-d17},[r4,:128]!
600 vcvt.s32.f32 q8, q8, #16
601 vst1.32 {d18[0]}, [r8], ip
602 vsri.32 d22, d20, #16
603 vst1.32 {d18[1]}, [r8], ip
604 vsri.32 d23, d21, #16
605 vst1.32 {d19[0]}, [r8], ip
606 vst1.32 {d19[1]}, [r8], ip
607 vld1.64 {d18-d19},[r5,:128]!
608 vcvt.s32.f32 q9, q9, #16
609 vst1.32 {d22[0]}, [r8], ip
610 vst1.32 {d22[1]}, [r8], ip
611 vld1.64 {d20-d21},[r4,:128]!
612 vcvt.s32.f32 q10, q10, #16
613 vst1.32 {d23[0]}, [r8], ip
614 vst1.32 {d23[1]}, [r8], ip
615 vld1.64 {d22-d23},[r5,:128]!
616 vcvt.s32.f32 q11, q11, #16
6176: subs lr, lr, #16
618 vld1.64 {d0-d1}, [r4,:128]!
619 vcvt.s32.f32 q0, q0, #16
620 vsri.32 d18, d16, #16
621 vld1.64 {d2-d3}, [r5,:128]!
622 vcvt.s32.f32 q1, q1, #16
623 vsri.32 d19, d17, #16
624 vld1.64 {d4-d5}, [r4,:128]!
625 vcvt.s32.f32 q2, q2, #16
626 vld1.64 {d6-d7}, [r5,:128]!
627 vcvt.s32.f32 q3, q3, #16
628 vst1.32 {d18[0]}, [r8], ip
629 vsri.32 d22, d20, #16
630 vst1.32 {d18[1]}, [r8], ip
631 vsri.32 d23, d21, #16
632 vst1.32 {d19[0]}, [r8], ip
633 vsri.32 d2, d0, #16
634 vst1.32 {d19[1]}, [r8], ip
635 vsri.32 d3, d1, #16
636 vst1.32 {d22[0]}, [r8], ip
637 vsri.32 d6, d4, #16
638 vst1.32 {d22[1]}, [r8], ip
639 vsri.32 d7, d5, #16
640 vst1.32 {d23[0]}, [r8], ip
641 vst1.32 {d23[1]}, [r8], ip
642 beq 6f
643 vld1.64 {d16-d17},[r4,:128]!
644 vcvt.s32.f32 q8, q8, #16
645 vst1.32 {d2[0]}, [r8], ip
646 vst1.32 {d2[1]}, [r8], ip
647 vld1.64 {d18-d19},[r5,:128]!
648 vcvt.s32.f32 q9, q9, #16
649 vst1.32 {d3[0]}, [r8], ip
650 vst1.32 {d3[1]}, [r8], ip
651 vld1.64 {d20-d21},[r4,:128]!
652 vcvt.s32.f32 q10, q10, #16
653 vst1.32 {d6[0]}, [r8], ip
654 vst1.32 {d6[1]}, [r8], ip
655 vld1.64 {d22-d23},[r5,:128]!
656 vcvt.s32.f32 q11, q11, #16
657 vst1.32 {d7[0]}, [r8], ip
658 vst1.32 {d7[1]}, [r8], ip
659 bgt 6b
6606: vst1.32 {d2[0]}, [r8], ip
661 vst1.32 {d2[1]}, [r8], ip
662 vst1.32 {d3[0]}, [r8], ip
663 vst1.32 {d3[1]}, [r8], ip
664 vst1.32 {d6[0]}, [r8], ip
665 vst1.32 {d6[1]}, [r8], ip
666 vst1.32 {d7[0]}, [r8], ip
667 vst1.32 {d7[1]}, [r8], ip
668 b 8f
6697: vsri.32 d18, d16, #16
670 vsri.32 d19, d17, #16
671 vst1.32 {d18[0]}, [r8], ip
672 vsri.32 d22, d20, #16
673 vst1.32 {d18[1]}, [r8], ip
674 vsri.32 d23, d21, #16
675 vst1.32 {d19[0]}, [r8], ip
676 vst1.32 {d19[1]}, [r8], ip
677 vst1.32 {d22[0]}, [r8], ip
678 vst1.32 {d22[1]}, [r8], ip
679 vst1.32 {d23[0]}, [r8], ip
680 vst1.32 {d23[1]}, [r8], ip
6818: subs r3, r3, #2
682 add r0, r0, #4
683 popeq {r4-r8,pc}
684
685 @ 1 channel
6864: ldr r4, [r1],#4
687 tst r2, #8
688 mov lr, r2
689 mov r5, r0
690 vld1.64 {d0-d1}, [r4,:128]!
691 vcvt.s32.f32 q0, q0, #16
692 vld1.64 {d2-d3}, [r4,:128]!
693 vcvt.s32.f32 q1, q1, #16
694 bne 8f
6956: subs lr, lr, #16
696 vld1.64 {d4-d5}, [r4,:128]!
697 vcvt.s32.f32 q2, q2, #16
698 vld1.64 {d6-d7}, [r4,:128]!
699 vcvt.s32.f32 q3, q3, #16
700 vst1.16 {d0[1]}, [r5,:16], ip
701 vst1.16 {d0[3]}, [r5,:16], ip
702 vst1.16 {d1[1]}, [r5,:16], ip
703 vst1.16 {d1[3]}, [r5,:16], ip
704 vst1.16 {d2[1]}, [r5,:16], ip
705 vst1.16 {d2[3]}, [r5,:16], ip
706 vst1.16 {d3[1]}, [r5,:16], ip
707 vst1.16 {d3[3]}, [r5,:16], ip
708 beq 7f
709 vld1.64 {d0-d1}, [r4,:128]!
710 vcvt.s32.f32 q0, q0, #16
711 vld1.64 {d2-d3}, [r4,:128]!
712 vcvt.s32.f32 q1, q1, #16
7137: vst1.16 {d4[1]}, [r5,:16], ip
714 vst1.16 {d4[3]}, [r5,:16], ip
715 vst1.16 {d5[1]}, [r5,:16], ip
716 vst1.16 {d5[3]}, [r5,:16], ip
717 vst1.16 {d6[1]}, [r5,:16], ip
718 vst1.16 {d6[3]}, [r5,:16], ip
719 vst1.16 {d7[1]}, [r5,:16], ip
720 vst1.16 {d7[3]}, [r5,:16], ip
721 bgt 6b
722 pop {r4-r8,pc}
7238: subs lr, lr, #8
724 vst1.16 {d0[1]}, [r5,:16], ip
725 vst1.16 {d0[3]}, [r5,:16], ip
726 vst1.16 {d1[1]}, [r5,:16], ip
727 vst1.16 {d1[3]}, [r5,:16], ip
728 vst1.16 {d2[1]}, [r5,:16], ip
729 vst1.16 {d2[3]}, [r5,:16], ip
730 vst1.16 {d3[1]}, [r5,:16], ip
731 vst1.16 {d3[3]}, [r5,:16], ip
732 popeq {r4-r8,pc}
733 vld1.64 {d0-d1}, [r4,:128]!
734 vcvt.s32.f32 q0, q0, #16
735 vld1.64 {d2-d3}, [r4,:128]!
736 vcvt.s32.f32 q1, q1, #16
737 b 6b
738endfunc
739
740function ff_vector_fmul_neon, export=1403function ff_vector_fmul_neon, export=1
741 subs r3, r3, #8404 subs r3, r3, #8
742 vld1.64 {d0-d3}, [r1,:128]!405 vld1.64 {d0-d3}, [r1,:128]!
@@ -1050,34 +713,6 @@ NOVFP vmov.32 r0, d0[0] · 307 unmodified lines
1050 bx lr713 bx lr
1051endfunc714endfunc
1052 715
1053function ff_int32_to_float_fmul_scalar_neon, export=1
1054VFP vdup.32 q0, d0[0]
1055VFP len .req r2
1056NOVFP vdup.32 q0, r2
1057NOVFP len .req r3
1058
1059 vld1.32 {q1},[r1,:128]!
1060 vcvt.f32.s32 q3, q1
1061 vld1.32 {q2},[r1,:128]!
1062 vcvt.f32.s32 q8, q2
10631: subs len, len, #8
1064 pld [r1, #16]
1065 vmul.f32 q9, q3, q0
1066 vmul.f32 q10, q8, q0
1067 beq 2f
1068 vld1.32 {q1},[r1,:128]!
1069 vcvt.f32.s32 q3, q1
1070 vld1.32 {q2},[r1,:128]!
1071 vcvt.f32.s32 q8, q2
1072 vst1.32 {q9}, [r0,:128]!
1073 vst1.32 {q10},[r0,:128]!
1074 b 1b
10752: vst1.32 {q9}, [r0,:128]!
1076 vst1.32 {q10},[r0,:128]!
1077 bx lr
1078 .unreq len
1079endfunc
1080
1081function ff_vector_fmul_reverse_neon, export=1716function ff_vector_fmul_reverse_neon, export=1
1082 add r2, r2, r3, lsl #2717 add r2, r2, r3, lsl #2
1083 sub r2, r2, #32718 sub r2, r2, #32
libavcodec/arm/dsputil_vfp.S+0−55
@@ -131,58 +131,3 @@ function ff_vector_fmul_reverse_vfp, export=1 · 130 unmodified lines
131 vpop {d8-d15}131 vpop {d8-d15}
132 bx lr132 bx lr
133endfunc133endfunc
134
135#if HAVE_ARMV6
136/**
137 * ARM VFP optimized float to int16 conversion.
138 * Assume that len is a positive number and is multiple of 8, destination
139 * buffer is at least 4 bytes aligned (8 bytes alignment is better for
140 * performance), little endian byte sex
141 */
142@ void ff_float_to_int16_vfp(int16_t *dst, const float *src, int len)
143function ff_float_to_int16_vfp, export=1
144 push {r4-r8,lr}
145 vpush {d8-d11}
146 vldmia r1!, {s16-s23}
147 vcvt.s32.f32 s0, s16
148 vcvt.s32.f32 s1, s17
149 vcvt.s32.f32 s2, s18
150 vcvt.s32.f32 s3, s19
151 vcvt.s32.f32 s4, s20
152 vcvt.s32.f32 s5, s21
153 vcvt.s32.f32 s6, s22
154 vcvt.s32.f32 s7, s23
1551:
156 subs r2, r2, #8
157 vmov r3, r4, s0, s1
158 vmov r5, r6, s2, s3
159 vmov r7, r8, s4, s5
160 vmov ip, lr, s6, s7
161 vldmiagt r1!, {s16-s23}
162 ssat r4, #16, r4
163 ssat r3, #16, r3
164 ssat r6, #16, r6
165 ssat r5, #16, r5
166 pkhbt r3, r3, r4, lsl #16
167 pkhbt r4, r5, r6, lsl #16
168 vcvtgt.s32.f32 s0, s16
169 vcvtgt.s32.f32 s1, s17
170 vcvtgt.s32.f32 s2, s18
171 vcvtgt.s32.f32 s3, s19
172 vcvtgt.s32.f32 s4, s20
173 vcvtgt.s32.f32 s5, s21
174 vcvtgt.s32.f32 s6, s22
175 vcvtgt.s32.f32 s7, s23
176 ssat r8, #16, r8
177 ssat r7, #16, r7
178 ssat lr, #16, lr
179 ssat ip, #16, ip
180 pkhbt r5, r7, r8, lsl #16
181 pkhbt r6, ip, lr, lsl #16
182 stmia r0!, {r3-r6}
183 bgt 1b
184
185 vpop {d8-d11}
186 pop {r4-r8,pc}
187endfunc
188#endif
libavcodec/arm/fmtconvert_init_arm.c+48−0
@@ -0,0 +1,48 @@
1/*
2 * ARM optimized Format Conversion Utils
3 *
4 * This file is part of FFmpeg.
5 *
6 * FFmpeg is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * FFmpeg is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with FFmpeg; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21#include <stdint.h>
22
23#include "libavcodec/avcodec.h"
24#include "libavcodec/fmtconvert.h"
25
26void ff_int32_to_float_fmul_scalar_neon(float *dst, const int *src,
27 float mul, int len);
28
29void ff_float_to_int16_neon(int16_t *dst, const float *src, long len);
30void ff_float_to_int16_interleave_neon(int16_t *, const float **, long, int);
31
32void ff_float_to_int16_vfp(int16_t *dst, const float *src, long len);
33
34void ff_fmt_convert_init_arm(FmtConvertContext *c, AVCodecContext *avctx)
35{
36 if (HAVE_ARMVFP && HAVE_ARMV6) {
37 c->float_to_int16 = ff_float_to_int16_vfp;
38 }
39
40 if (HAVE_NEON) {
41 c->int32_to_float_fmul_scalar = ff_int32_to_float_fmul_scalar_neon;
42
43 if (!(avctx->flags & CODEC_FLAG_BITEXACT)) {
44 c->float_to_int16 = ff_float_to_int16_neon;
45 c->float_to_int16_interleave = ff_float_to_int16_interleave_neon;
46 }
47 }
48}
libavcodec/arm/fmtconvert_neon.S+391−0
@@ -0,0 +1,391 @@
1/*
2 * ARM NEON optimised Format Conversion Utils
3 * Copyright (c) 2008 Mans Rullgard <mans@mansr.com>
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#include "config.h"
23#include "asm.S"
24
25 preserve8
26 .text
27
28function ff_float_to_int16_neon, export=1
29 subs r2, r2, #8
30 vld1.64 {d0-d1}, [r1,:128]!
31 vcvt.s32.f32 q8, q0, #16
32 vld1.64 {d2-d3}, [r1,:128]!
33 vcvt.s32.f32 q9, q1, #16
34 beq 3f
35 bics ip, r2, #15
36 beq 2f
371: subs ip, ip, #16
38 vshrn.s32 d4, q8, #16
39 vld1.64 {d0-d1}, [r1,:128]!
40 vcvt.s32.f32 q0, q0, #16
41 vshrn.s32 d5, q9, #16
42 vld1.64 {d2-d3}, [r1,:128]!
43 vcvt.s32.f32 q1, q1, #16
44 vshrn.s32 d6, q0, #16
45 vst1.64 {d4-d5}, [r0,:128]!
46 vshrn.s32 d7, q1, #16
47 vld1.64 {d16-d17},[r1,:128]!
48 vcvt.s32.f32 q8, q8, #16
49 vld1.64 {d18-d19},[r1,:128]!
50 vcvt.s32.f32 q9, q9, #16
51 vst1.64 {d6-d7}, [r0,:128]!
52 bne 1b
53 ands r2, r2, #15
54 beq 3f
552: vld1.64 {d0-d1}, [r1,:128]!
56 vshrn.s32 d4, q8, #16
57 vcvt.s32.f32 q0, q0, #16
58 vld1.64 {d2-d3}, [r1,:128]!
59 vshrn.s32 d5, q9, #16
60 vcvt.s32.f32 q1, q1, #16
61 vshrn.s32 d6, q0, #16
62 vst1.64 {d4-d5}, [r0,:128]!
63 vshrn.s32 d7, q1, #16
64 vst1.64 {d6-d7}, [r0,:128]!
65 bx lr
663: vshrn.s32 d4, q8, #16
67 vshrn.s32 d5, q9, #16
68 vst1.64 {d4-d5}, [r0,:128]!
69 bx lr
70endfunc
71
72function ff_float_to_int16_interleave_neon, export=1
73 cmp r3, #2
74 ldrlt r1, [r1]
75 blt ff_float_to_int16_neon
76 bne 4f
77
78 ldr r3, [r1]
79 ldr r1, [r1, #4]
80
81 subs r2, r2, #8
82 vld1.64 {d0-d1}, [r3,:128]!
83 vcvt.s32.f32 q8, q0, #16
84 vld1.64 {d2-d3}, [r3,:128]!
85 vcvt.s32.f32 q9, q1, #16
86 vld1.64 {d20-d21},[r1,:128]!
87 vcvt.s32.f32 q10, q10, #16
88 vld1.64 {d22-d23},[r1,:128]!
89 vcvt.s32.f32 q11, q11, #16
90 beq 3f
91 bics ip, r2, #15
92 beq 2f
931: subs ip, ip, #16
94 vld1.64 {d0-d1}, [r3,:128]!
95 vcvt.s32.f32 q0, q0, #16
96 vsri.32 q10, q8, #16
97 vld1.64 {d2-d3}, [r3,:128]!
98 vcvt.s32.f32 q1, q1, #16
99 vld1.64 {d24-d25},[r1,:128]!
100 vcvt.s32.f32 q12, q12, #16
101 vld1.64 {d26-d27},[r1,:128]!
102 vsri.32 q11, q9, #16
103 vst1.64 {d20-d21},[r0,:128]!
104 vcvt.s32.f32 q13, q13, #16
105 vst1.64 {d22-d23},[r0,:128]!
106 vsri.32 q12, q0, #16
107 vld1.64 {d16-d17},[r3,:128]!
108 vsri.32 q13, q1, #16
109 vst1.64 {d24-d25},[r0,:128]!
110 vcvt.s32.f32 q8, q8, #16
111 vld1.64 {d18-d19},[r3,:128]!
112 vcvt.s32.f32 q9, q9, #16
113 vld1.64 {d20-d21},[r1,:128]!
114 vcvt.s32.f32 q10, q10, #16
115 vld1.64 {d22-d23},[r1,:128]!
116 vcvt.s32.f32 q11, q11, #16
117 vst1.64 {d26-d27},[r0,:128]!
118 bne 1b
119 ands r2, r2, #15
120 beq 3f
1212: vsri.32 q10, q8, #16
122 vld1.64 {d0-d1}, [r3,:128]!
123 vcvt.s32.f32 q0, q0, #16
124 vld1.64 {d2-d3}, [r3,:128]!
125 vcvt.s32.f32 q1, q1, #16
126 vld1.64 {d24-d25},[r1,:128]!
127 vcvt.s32.f32 q12, q12, #16
128 vsri.32 q11, q9, #16
129 vld1.64 {d26-d27},[r1,:128]!
130 vcvt.s32.f32 q13, q13, #16
131 vst1.64 {d20-d21},[r0,:128]!
132 vsri.32 q12, q0, #16
133 vst1.64 {d22-d23},[r0,:128]!
134 vsri.32 q13, q1, #16
135 vst1.64 {d24-d27},[r0,:128]!
136 bx lr
1373: vsri.32 q10, q8, #16
138 vsri.32 q11, q9, #16
139 vst1.64 {d20-d23},[r0,:128]!
140 bx lr
141
1424: push {r4-r8,lr}
143 cmp r3, #4
144 lsl ip, r3, #1
145 blt 4f
146
147 @ 4 channels
1485: ldmia r1!, {r4-r7}
149 mov lr, r2
150 mov r8, r0
151 vld1.64 {d16-d17},[r4,:128]!
152 vcvt.s32.f32 q8, q8, #16
153 vld1.64 {d18-d19},[r5,:128]!
154 vcvt.s32.f32 q9, q9, #16
155 vld1.64 {d20-d21},[r6,:128]!
156 vcvt.s32.f32 q10, q10, #16
157 vld1.64 {d22-d23},[r7,:128]!
158 vcvt.s32.f32 q11, q11, #16
1596: subs lr, lr, #8
160 vld1.64 {d0-d1}, [r4,:128]!
161 vcvt.s32.f32 q0, q0, #16
162 vsri.32 q9, q8, #16
163 vld1.64 {d2-d3}, [r5,:128]!
164 vcvt.s32.f32 q1, q1, #16
165 vsri.32 q11, q10, #16
166 vld1.64 {d4-d5}, [r6,:128]!
167 vcvt.s32.f32 q2, q2, #16
168 vzip.32 d18, d22
169 vld1.64 {d6-d7}, [r7,:128]!
170 vcvt.s32.f32 q3, q3, #16
171 vzip.32 d19, d23
172 vst1.64 {d18}, [r8], ip
173 vsri.32 q1, q0, #16
174 vst1.64 {d22}, [r8], ip
175 vsri.32 q3, q2, #16
176 vst1.64 {d19}, [r8], ip
177 vzip.32 d2, d6
178 vst1.64 {d23}, [r8], ip
179 vzip.32 d3, d7
180 beq 7f
181 vld1.64 {d16-d17},[r4,:128]!
182 vcvt.s32.f32 q8, q8, #16
183 vst1.64 {d2}, [r8], ip
184 vld1.64 {d18-d19},[r5,:128]!
185 vcvt.s32.f32 q9, q9, #16
186 vst1.64 {d6}, [r8], ip
187 vld1.64 {d20-d21},[r6,:128]!
188 vcvt.s32.f32 q10, q10, #16
189 vst1.64 {d3}, [r8], ip
190 vld1.64 {d22-d23},[r7,:128]!
191 vcvt.s32.f32 q11, q11, #16
192 vst1.64 {d7}, [r8], ip
193 b 6b
1947: vst1.64 {d2}, [r8], ip
195 vst1.64 {d6}, [r8], ip
196 vst1.64 {d3}, [r8], ip
197 vst1.64 {d7}, [r8], ip
198 subs r3, r3, #4
199 popeq {r4-r8,pc}
200 cmp r3, #4
201 add r0, r0, #8
202 bge 5b
203
204 @ 2 channels
2054: cmp r3, #2
206 blt 4f
207 ldmia r1!, {r4-r5}
208 mov lr, r2
209 mov r8, r0
210 tst lr, #8
211 vld1.64 {d16-d17},[r4,:128]!
212 vcvt.s32.f32 q8, q8, #16
213 vld1.64 {d18-d19},[r5,:128]!
214 vcvt.s32.f32 q9, q9, #16
215 vld1.64 {d20-d21},[r4,:128]!
216 vcvt.s32.f32 q10, q10, #16
217 vld1.64 {d22-d23},[r5,:128]!
218 vcvt.s32.f32 q11, q11, #16
219 beq 6f
220 subs lr, lr, #8
221 beq 7f
222 vsri.32 d18, d16, #16
223 vsri.32 d19, d17, #16
224 vld1.64 {d16-d17},[r4,:128]!
225 vcvt.s32.f32 q8, q8, #16
226 vst1.32 {d18[0]}, [r8], ip
227 vsri.32 d22, d20, #16
228 vst1.32 {d18[1]}, [r8], ip
229 vsri.32 d23, d21, #16
230 vst1.32 {d19[0]}, [r8], ip
231 vst1.32 {d19[1]}, [r8], ip
232 vld1.64 {d18-d19},[r5,:128]!
233 vcvt.s32.f32 q9, q9, #16
234 vst1.32 {d22[0]}, [r8], ip
235 vst1.32 {d22[1]}, [r8], ip
236 vld1.64 {d20-d21},[r4,:128]!
237 vcvt.s32.f32 q10, q10, #16
238 vst1.32 {d23[0]}, [r8], ip
239 vst1.32 {d23[1]}, [r8], ip
240 vld1.64 {d22-d23},[r5,:128]!
241 vcvt.s32.f32 q11, q11, #16
2426: subs lr, lr, #16
243 vld1.64 {d0-d1}, [r4,:128]!
244 vcvt.s32.f32 q0, q0, #16
245 vsri.32 d18, d16, #16
246 vld1.64 {d2-d3}, [r5,:128]!
247 vcvt.s32.f32 q1, q1, #16
248 vsri.32 d19, d17, #16
249 vld1.64 {d4-d5}, [r4,:128]!
250 vcvt.s32.f32 q2, q2, #16
251 vld1.64 {d6-d7}, [r5,:128]!
252 vcvt.s32.f32 q3, q3, #16
253 vst1.32 {d18[0]}, [r8], ip
254 vsri.32 d22, d20, #16
255 vst1.32 {d18[1]}, [r8], ip
256 vsri.32 d23, d21, #16
257 vst1.32 {d19[0]}, [r8], ip
258 vsri.32 d2, d0, #16
259 vst1.32 {d19[1]}, [r8], ip
260 vsri.32 d3, d1, #16
261 vst1.32 {d22[0]}, [r8], ip
262 vsri.32 d6, d4, #16
263 vst1.32 {d22[1]}, [r8], ip
264 vsri.32 d7, d5, #16
265 vst1.32 {d23[0]}, [r8], ip
266 vst1.32 {d23[1]}, [r8], ip
267 beq 6f
268 vld1.64 {d16-d17},[r4,:128]!
269 vcvt.s32.f32 q8, q8, #16
270 vst1.32 {d2[0]}, [r8], ip
271 vst1.32 {d2[1]}, [r8], ip
272 vld1.64 {d18-d19},[r5,:128]!
273 vcvt.s32.f32 q9, q9, #16
274 vst1.32 {d3[0]}, [r8], ip
275 vst1.32 {d3[1]}, [r8], ip
276 vld1.64 {d20-d21},[r4,:128]!
277 vcvt.s32.f32 q10, q10, #16
278 vst1.32 {d6[0]}, [r8], ip
279 vst1.32 {d6[1]}, [r8], ip
280 vld1.64 {d22-d23},[r5,:128]!
281 vcvt.s32.f32 q11, q11, #16
282 vst1.32 {d7[0]}, [r8], ip
283 vst1.32 {d7[1]}, [r8], ip
284 bgt 6b
2856: vst1.32 {d2[0]}, [r8], ip
286 vst1.32 {d2[1]}, [r8], ip
287 vst1.32 {d3[0]}, [r8], ip
288 vst1.32 {d3[1]}, [r8], ip
289 vst1.32 {d6[0]}, [r8], ip
290 vst1.32 {d6[1]}, [r8], ip
291 vst1.32 {d7[0]}, [r8], ip
292 vst1.32 {d7[1]}, [r8], ip
293 b 8f
2947: vsri.32 d18, d16, #16
295 vsri.32 d19, d17, #16
296 vst1.32 {d18[0]}, [r8], ip
297 vsri.32 d22, d20, #16
298 vst1.32 {d18[1]}, [r8], ip
299 vsri.32 d23, d21, #16
300 vst1.32 {d19[0]}, [r8], ip
301 vst1.32 {d19[1]}, [r8], ip
302 vst1.32 {d22[0]}, [r8], ip
303 vst1.32 {d22[1]}, [r8], ip
304 vst1.32 {d23[0]}, [r8], ip
305 vst1.32 {d23[1]}, [r8], ip
3068: subs r3, r3, #2
307 add r0, r0, #4
308 popeq {r4-r8,pc}
309
310 @ 1 channel
3114: ldr r4, [r1],#4
312 tst r2, #8
313 mov lr, r2
314 mov r5, r0
315 vld1.64 {d0-d1}, [r4,:128]!
316 vcvt.s32.f32 q0, q0, #16
317 vld1.64 {d2-d3}, [r4,:128]!
318 vcvt.s32.f32 q1, q1, #16
319 bne 8f
3206: subs lr, lr, #16
321 vld1.64 {d4-d5}, [r4,:128]!
322 vcvt.s32.f32 q2, q2, #16
323 vld1.64 {d6-d7}, [r4,:128]!
324 vcvt.s32.f32 q3, q3, #16
325 vst1.16 {d0[1]}, [r5,:16], ip
326 vst1.16 {d0[3]}, [r5,:16], ip
327 vst1.16 {d1[1]}, [r5,:16], ip
328 vst1.16 {d1[3]}, [r5,:16], ip
329 vst1.16 {d2[1]}, [r5,:16], ip
330 vst1.16 {d2[3]}, [r5,:16], ip
331 vst1.16 {d3[1]}, [r5,:16], ip
332 vst1.16 {d3[3]}, [r5,:16], ip
333 beq 7f
334 vld1.64 {d0-d1}, [r4,:128]!
335 vcvt.s32.f32 q0, q0, #16
336 vld1.64 {d2-d3}, [r4,:128]!
337 vcvt.s32.f32 q1, q1, #16
3387: vst1.16 {d4[1]}, [r5,:16], ip
339 vst1.16 {d4[3]}, [r5,:16], ip
340 vst1.16 {d5[1]}, [r5,:16], ip
341 vst1.16 {d5[3]}, [r5,:16], ip
342 vst1.16 {d6[1]}, [r5,:16], ip
343 vst1.16 {d6[3]}, [r5,:16], ip
344 vst1.16 {d7[1]}, [r5,:16], ip
345 vst1.16 {d7[3]}, [r5,:16], ip
346 bgt 6b
347 pop {r4-r8,pc}
3488: subs lr, lr, #8
349 vst1.16 {d0[1]}, [r5,:16], ip
350 vst1.16 {d0[3]}, [r5,:16], ip
351 vst1.16 {d1[1]}, [r5,:16], ip
352 vst1.16 {d1[3]}, [r5,:16], ip
353 vst1.16 {d2[1]}, [r5,:16], ip
354 vst1.16 {d2[3]}, [r5,:16], ip
355 vst1.16 {d3[1]}, [r5,:16], ip
356 vst1.16 {d3[3]}, [r5,:16], ip
357 popeq {r4-r8,pc}
358 vld1.64 {d0-d1}, [r4,:128]!
359 vcvt.s32.f32 q0, q0, #16
360 vld1.64 {d2-d3}, [r4,:128]!
361 vcvt.s32.f32 q1, q1, #16
362 b 6b
363endfunc
364
365function ff_int32_to_float_fmul_scalar_neon, export=1
366VFP vdup.32 q0, d0[0]
367VFP len .req r2
368NOVFP vdup.32 q0, r2
369NOVFP len .req r3
370
371 vld1.32 {q1},[r1,:128]!
372 vcvt.f32.s32 q3, q1
373 vld1.32 {q2},[r1,:128]!
374 vcvt.f32.s32 q8, q2
3751: subs len, len, #8
376 pld [r1, #16]
377 vmul.f32 q9, q3, q0
378 vmul.f32 q10, q8, q0
379 beq 2f
380 vld1.32 {q1},[r1,:128]!
381 vcvt.f32.s32 q3, q1
382 vld1.32 {q2},[r1,:128]!
383 vcvt.f32.s32 q8, q2
384 vst1.32 {q9}, [r0,:128]!
385 vst1.32 {q10},[r0,:128]!
386 b 1b
3872: vst1.32 {q9}, [r0,:128]!
388 vst1.32 {q10},[r0,:128]!
389 bx lr
390 .unreq len
391endfunc
libavcodec/arm/fmtconvert_vfp.S+77−0
@@ -0,0 +1,77 @@
1/*
2 * Copyright (c) 2008 Siarhei Siamashka <ssvb@users.sourceforge.net>
3 *
4 * This file is part of FFmpeg.
5 *
6 * FFmpeg is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * FFmpeg is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with FFmpeg; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21#include "config.h"
22#include "asm.S"
23
24 .syntax unified
25
26/**
27 * ARM VFP optimized float to int16 conversion.
28 * Assume that len is a positive number and is multiple of 8, destination
29 * buffer is at least 4 bytes aligned (8 bytes alignment is better for
30 * performance), little endian byte sex
31 */
32@ void ff_float_to_int16_vfp(int16_t *dst, const float *src, int len)
33function ff_float_to_int16_vfp, export=1
34 push {r4-r8,lr}
35 vpush {d8-d11}
36 vldmia r1!, {s16-s23}
37 vcvt.s32.f32 s0, s16
38 vcvt.s32.f32 s1, s17
39 vcvt.s32.f32 s2, s18
40 vcvt.s32.f32 s3, s19
41 vcvt.s32.f32 s4, s20
42 vcvt.s32.f32 s5, s21
43 vcvt.s32.f32 s6, s22
44 vcvt.s32.f32 s7, s23
451:
46 subs r2, r2, #8
47 vmov r3, r4, s0, s1
48 vmov r5, r6, s2, s3
49 vmov r7, r8, s4, s5
50 vmov ip, lr, s6, s7
51 vldmiagt r1!, {s16-s23}
52 ssat r4, #16, r4
53 ssat r3, #16, r3
54 ssat r6, #16, r6
55 ssat r5, #16, r5
56 pkhbt r3, r3, r4, lsl #16
57 pkhbt r4, r5, r6, lsl #16
58 vcvtgt.s32.f32 s0, s16
59 vcvtgt.s32.f32 s1, s17
60 vcvtgt.s32.f32 s2, s18
61 vcvtgt.s32.f32 s3, s19
62 vcvtgt.s32.f32 s4, s20
63 vcvtgt.s32.f32 s5, s21
64 vcvtgt.s32.f32 s6, s22
65 vcvtgt.s32.f32 s7, s23
66 ssat r8, #16, r8
67 ssat r7, #16, r7
68 ssat lr, #16, lr
69 ssat ip, #16, ip
70 pkhbt r5, r7, r8, lsl #16
71 pkhbt r6, ip, lr, lsl #16
72 stmia r0!, {r3-r6}
73 bgt 1b
74
75 vpop {d8-d11}
76 pop {r4-r8,pc}
77endfunc
libavcodec/binkaudio.c+5−1
@@ -33,6 +33,7 @@ · 32 unmodified lines
33#include "get_bits.h"33#include "get_bits.h"
34#include "dsputil.h"34#include "dsputil.h"
35#include "fft.h"35#include "fft.h"
36#include "fmtconvert.h"
36 37
37extern const uint16_t ff_wma_critical_freqs[25];38extern const uint16_t ff_wma_critical_freqs[25];
38 39
@@ -43,6 +44,7 @@ typedef struct { · 4 unmodified lines
43 AVCodecContext *avctx;44 AVCodecContext *avctx;
44 GetBitContext gb;45 GetBitContext gb;
45 DSPContext dsp;46 DSPContext dsp;
47 FmtConvertContext fmt_conv;
46 int first;48 int first;
47 int channels;49 int channels;
48 int frame_len; ///< transform size (samples)50 int frame_len; ///< transform size (samples)
@@ -71,6 +73,7 @@ static av_cold int decode_init(AVCodecContext *avctx) · 22 unmodified lines
71 73
72 s->avctx = avctx;74 s->avctx = avctx;
73 dsputil_init(&s->dsp, avctx);75 dsputil_init(&s->dsp, avctx);
76 ff_fmt_convert_init(&s->fmt_conv, avctx);
74 77
75 /* determine frame length */78 /* determine frame length */
76 if (avctx->sample_rate < 22050) {79 if (avctx->sample_rate < 22050) {
@@ -222,7 +225,8 @@ static void decode_block(BinkAudioContext *s, short *out, int use_dct) · 145 unmodified lines
222 ff_rdft_calc(&s->trans.rdft, coeffs);225 ff_rdft_calc(&s->trans.rdft, coeffs);
223 }226 }
224 227
225 s->dsp.float_to_int16_interleave(out, (const float **)s->coeffs_ptr, s->frame_len, s->channels);228 s->fmt_conv.float_to_int16_interleave(out, (const float **)s->coeffs_ptr,
229 s->frame_len, s->channels);
226 230
227 if (!s->first) {231 if (!s->first) {
228 int count = s->overlap_len * s->channels;232 int count = s->overlap_len * s->channels;
libavcodec/dca.c+5−2
@@ -40,6 +40,7 @@ · 39 unmodified lines
40#include "dca.h"40#include "dca.h"
41#include "synth_filter.h"41#include "synth_filter.h"
42#include "dcadsp.h"42#include "dcadsp.h"
43#include "fmtconvert.h"
43 44
44//#define TRACE45//#define TRACE
45 46
@@ -347,6 +348,7 @@ typedef struct { · 301 unmodified lines
347 FFTContext imdct;348 FFTContext imdct;
348 SynthFilterContext synth;349 SynthFilterContext synth;
349 DCADSPContext dcadsp;350 DCADSPContext dcadsp;
351 FmtConvertContext fmt_conv;
350} DCAContext;352} DCAContext;
351 353
352static const uint16_t dca_vlc_offs[] = {354static const uint16_t dca_vlc_offs[] = {
@@ -1115,7 +1117,7 @@ static int dca_subsubframe(DCAContext * s, int base_channel, int block_index) · 762 unmodified lines
1115 block[m] = get_bitalloc(&s->gb, &dca_smpl_bitalloc[abits], sel);1117 block[m] = get_bitalloc(&s->gb, &dca_smpl_bitalloc[abits], sel);
1116 }1118 }
1117 1119
1118 s->dsp.int32_to_float_fmul_scalar(subband_samples[k][l],1120 s->fmt_conv.int32_to_float_fmul_scalar(subband_samples[k][l],
1119 block, rscale, 8);1121 block, rscale, 8);
1120 }1122 }
1121 1123
@@ -1802,7 +1804,7 @@ static int dca_decode_frame(AVCodecContext * avctx, · 680 unmodified lines
1802 }1804 }
1803 }1805 }
1804 1806
1805 s->dsp.float_to_int16_interleave(samples, s->samples_chanptr, 256, channels);1807 s->fmt_conv.float_to_int16_interleave(samples, s->samples_chanptr, 256, channels);
1806 samples += 256 * channels;1808 samples += 256 * channels;
1807 }1809 }
1808 1810
@@ -1835,6 +1837,7 @@ static av_cold int dca_decode_init(AVCodecContext * avctx) · 26 unmodified lines
1835 ff_mdct_init(&s->imdct, 6, 1, 1.0);1837 ff_mdct_init(&s->imdct, 6, 1, 1.0);
1836 ff_synth_filter_init(&s->synth);1838 ff_synth_filter_init(&s->synth);
1837 ff_dcadsp_init(&s->dcadsp);1839 ff_dcadsp_init(&s->dcadsp);
1840 ff_fmt_convert_init(&s->fmt_conv, avctx);
1838 1841
1839 for (i = 0; i < DCA_PRIM_CHANNELS_MAX+1; i++)1842 for (i = 0; i < DCA_PRIM_CHANNELS_MAX+1; i++)
1840 s->samples_chanptr[i] = s->samples + i * 256;1843 s->samples_chanptr[i] = s->samples + i * 256;
libavcodec/dsputil.c+0−33
@@ -3867,12 +3867,6 @@ static float scalarproduct_float_c(const float *v1, const float *v2, int len) · 3866 unmodified lines
3867 return p;3867 return p;
3868}3868}
3869 3869
3870static void int32_to_float_fmul_scalar_c(float *dst, const int *src, float mul, int len){
3871 int i;
3872 for(i=0; i<len; i++)
3873 dst[i] = src[i] * mul;
3874}
3875
3876static inline uint32_t clipf_c_one(uint32_t a, uint32_t mini,3870static inline uint32_t clipf_c_one(uint32_t a, uint32_t mini,
3877 uint32_t maxi, uint32_t maxisign)3871 uint32_t maxi, uint32_t maxisign)
3878{3872{
@@ -3918,30 +3912,6 @@ static void vector_clipf_c(float *dst, const float *src, float min, float max, i · 39 unmodified lines
3918 }3912 }
3919}3913}
3920 3914
3921static av_always_inline int float_to_int16_one(const float *src){
3922 return av_clip_int16(lrintf(*src));
3923}
3924
3925static void ff_float_to_int16_c(int16_t *dst, const float *src, long len){
3926 int i;
3927 for(i=0; i<len; i++)
3928 dst[i] = float_to_int16_one(src+i);
3929}
3930
3931static void ff_float_to_int16_interleave_c(int16_t *dst, const float **src, long len, int channels){
3932 int i,j,c;
3933 if(channels==2){
3934 for(i=0; i<len; i++){
3935 dst[2*i] = float_to_int16_one(src[0]+i);
3936 dst[2*i+1] = float_to_int16_one(src[1]+i);
3937 }
3938 }else{
3939 for(c=0; c<channels; c++)
3940 for(i=0, j=c; i<len; i++, j+=channels)
3941 dst[j] = float_to_int16_one(src[c]+i);
3942 }
3943}
3944
3945static int32_t scalarproduct_int16_c(const int16_t * v1, const int16_t * v2, int order, int shift)3915static int32_t scalarproduct_int16_c(const int16_t * v1, const int16_t * v2, int order, int shift)
3946{3916{
3947 int res = 0;3917 int res = 0;
@@ -4437,10 +4407,7 @@ av_cold void dsputil_init(DSPContext* c, AVCodecContext *avctx) · 489 unmodified lines
4437 c->vector_fmul_reverse = vector_fmul_reverse_c;4407 c->vector_fmul_reverse = vector_fmul_reverse_c;
4438 c->vector_fmul_add = vector_fmul_add_c;4408 c->vector_fmul_add = vector_fmul_add_c;
4439 c->vector_fmul_window = vector_fmul_window_c;4409 c->vector_fmul_window = vector_fmul_window_c;
4440 c->int32_to_float_fmul_scalar = int32_to_float_fmul_scalar_c;
4441 c->vector_clipf = vector_clipf_c;4410 c->vector_clipf = vector_clipf_c;
4442 c->float_to_int16 = ff_float_to_int16_c;
4443 c->float_to_int16_interleave = ff_float_to_int16_interleave_c;
4444 c->scalarproduct_int16 = scalarproduct_int16_c;4411 c->scalarproduct_int16 = scalarproduct_int16_c;
4445 c->scalarproduct_and_madd_int16 = scalarproduct_and_madd_int16_c;4412 c->scalarproduct_and_madd_int16 = scalarproduct_and_madd_int16_c;
4446 c->scalarproduct_float = scalarproduct_float_c;4413 c->scalarproduct_float = scalarproduct_float_c;
libavcodec/dsputil.h+0−5
@@ -392,7 +392,6 @@ typedef struct DSPContext { · 391 unmodified lines
392 /* assume len is a multiple of 4, and arrays are 16-byte aligned */392 /* assume len is a multiple of 4, and arrays are 16-byte aligned */
393 void (*vector_fmul_window)(float *dst, const float *src0, const float *src1, const float *win, int len);393 void (*vector_fmul_window)(float *dst, const float *src0, const float *src1, const float *win, int len);
394 /* assume len is a multiple of 8, and arrays are 16-byte aligned */394 /* assume len is a multiple of 8, and arrays are 16-byte aligned */
395 void (*int32_to_float_fmul_scalar)(float *dst, const int *src, float mul, int len);
396 void (*vector_clipf)(float *dst /* align 16 */, const float *src /* align 16 */, float min, float max, int len /* align 16 */);395 void (*vector_clipf)(float *dst /* align 16 */, const float *src /* align 16 */, float min, float max, int len /* align 16 */);
397 /**396 /**
398 * Multiply a vector of floats by a scalar float. Source and397 * Multiply a vector of floats by a scalar float. Source and
@@ -445,10 +444,6 @@ typedef struct DSPContext { · 46 unmodified lines
445 */444 */
446 void (*butterflies_float)(float *restrict v1, float *restrict v2, int len);445 void (*butterflies_float)(float *restrict v1, float *restrict v2, int len);
447 446
448 /* convert floats from [-32768.0,32767.0] without rescaling and arrays are 16byte aligned */
449 void (*float_to_int16)(int16_t *dst, const float *src, long len);
450 void (*float_to_int16_interleave)(int16_t *dst, const float **src, long len, int channels);
451
452 /* (I)DCT */447 /* (I)DCT */
453 void (*fdct)(DCTELEM *block/* align 16*/);448 void (*fdct)(DCTELEM *block/* align 16*/);
454 void (*fdct248)(DCTELEM *block/* align 16*/);449 void (*fdct248)(DCTELEM *block/* align 16*/);
libavcodec/fmtconvert.c+68−0
@@ -0,0 +1,68 @@
1/*
2 * Format Conversion Utils
3 * Copyright (c) 2000, 2001 Fabrice Bellard
4 * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
5 *
6 * This file is part of FFmpeg.
7 *
8 * FFmpeg is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * FFmpeg is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with FFmpeg; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
23#include "avcodec.h"
24#include "fmtconvert.h"
25
26static void int32_to_float_fmul_scalar_c(float *dst, const int *src, float mul, int len){
27 int i;
28 for(i=0; i<len; i++)
29 dst[i] = src[i] * mul;
30}
31
32static av_always_inline int float_to_int16_one(const float *src){
33 return av_clip_int16(lrintf(*src));
34}
35
36static void float_to_int16_c(int16_t *dst, const float *src, long len)
37{
38 int i;
39 for(i=0; i<len; i++)
40 dst[i] = float_to_int16_one(src+i);
41}
42
43static void float_to_int16_interleave_c(int16_t *dst, const float **src,
44 long len, int channels)
45{
46 int i,j,c;
47 if(channels==2){
48 for(i=0; i<len; i++){
49 dst[2*i] = float_to_int16_one(src[0]+i);
50 dst[2*i+1] = float_to_int16_one(src[1]+i);
51 }
52 }else{
53 for(c=0; c<channels; c++)
54 for(i=0, j=c; i<len; i++, j+=channels)
55 dst[j] = float_to_int16_one(src[c]+i);
56 }
57}
58
59av_cold void ff_fmt_convert_init(FmtConvertContext *c, AVCodecContext *avctx)
60{
61 c->int32_to_float_fmul_scalar = int32_to_float_fmul_scalar_c;
62 c->float_to_int16 = float_to_int16_c;
63 c->float_to_int16_interleave = float_to_int16_interleave_c;
64
65 if (ARCH_ARM) ff_fmt_convert_init_arm(c, avctx);
66 if (ARCH_PPC) ff_fmt_convert_init_ppc(c, avctx);
67 if (HAVE_MMX) ff_fmt_convert_init_x86(c, avctx);
68}
libavcodec/fmtconvert.h+79−0
@@ -0,0 +1,79 @@
1/*
2 * Format Conversion Utils
3 * Copyright (c) 2000, 2001 Fabrice Bellard
4 * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
5 *
6 * This file is part of FFmpeg.
7 *
8 * FFmpeg is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * FFmpeg is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with FFmpeg; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
23#ifndef AVCODEC_FMTCONVERT_H
24#define AVCODEC_FMTCONVERT_H
25
26#include "avcodec.h"
27
28typedef struct FmtConvertContext {
29 /**
30 * Convert an array of int32_t to float and multiply by a float value.
31 * @param dst destination array of float.
32 * constraints: 16-byte aligned
33 * @param src source array of int32_t.
34 * constraints: 16-byte aligned
35 * @param len number of elements to convert.
36 * constraints: multiple of 8
37 */
38 void (*int32_to_float_fmul_scalar)(float *dst, const int *src, float mul, int len);
39
40 /**
41 * Convert an array of float to an array of int16_t.
42 *
43 * Convert floats from in the range [-32768.0,32767.0] to ints
44 * without rescaling
45 *
46 * @param dst destination array of int16_t.
47 * constraints: 16-byte aligned
48 * @param src source array of float.
49 * constraints: 16-byte aligned
50 * @param len number of elements to convert.
51 * constraints: multiple of 8
52 */
53 void (*float_to_int16)(int16_t *dst, const float *src, long len);
54
55 /**
56 * Convert multiple arrays of float to an interleaved array of int16_t.
57 *
58 * Convert floats from in the range [-32768.0,32767.0] to ints
59 * without rescaling
60 *
61 * @param dst destination array of interleaved int16_t.
62 * constraints: 16-byte aligned
63 * @param src source array of float arrays, one for each channel.
64 * constraints: 16-byte aligned
65 * @param len number of elements to convert.
66 * constraints: multiple of 8
67 * @param channels number of channels
68 */
69 void (*float_to_int16_interleave)(int16_t *dst, const float **src,
70 long len, int channels);
71} FmtConvertContext;
72
73void ff_fmt_convert_init(FmtConvertContext *c, AVCodecContext *avctx);
74
75void ff_fmt_convert_init_arm(FmtConvertContext *c, AVCodecContext *avctx);
76void ff_fmt_convert_init_ppc(FmtConvertContext *c, AVCodecContext *avctx);
77void ff_fmt_convert_init_x86(FmtConvertContext *c, AVCodecContext *avctx);
78
79#endif /* AVCODEC_FMTCONVERT_H */
libavcodec/nellymoserdec.c+4−1
@@ -38,6 +38,7 @@ · 37 unmodified lines
38#include "avcodec.h"38#include "avcodec.h"
39#include "dsputil.h"39#include "dsputil.h"
40#include "fft.h"40#include "fft.h"
41#include "fmtconvert.h"
41 42
42#define ALT_BITSTREAM_READER_LE43#define ALT_BITSTREAM_READER_LE
43#include "get_bits.h"44#include "get_bits.h"
@@ -52,6 +53,7 @@ typedef struct NellyMoserDecodeContext { · 8 unmodified lines
52 float scale_bias;53 float scale_bias;
53 DSPContext dsp;54 DSPContext dsp;
54 FFTContext imdct_ctx;55 FFTContext imdct_ctx;
56 FmtConvertContext fmt_conv;
55 DECLARE_ALIGNED(16, float,imdct_out)[NELLY_BUF_LEN * 2];57 DECLARE_ALIGNED(16, float,imdct_out)[NELLY_BUF_LEN * 2];
56} NellyMoserDecodeContext;58} NellyMoserDecodeContext;
57 59
@@ -134,6 +136,7 @@ static av_cold int decode_init(AVCodecContext * avctx) { · 76 unmodified lines
134 ff_mdct_init(&s->imdct_ctx, 8, 1, 1.0);136 ff_mdct_init(&s->imdct_ctx, 8, 1, 1.0);
135 137
136 dsputil_init(&s->dsp, avctx);138 dsputil_init(&s->dsp, avctx);
139 ff_fmt_convert_init(&s->fmt_conv, avctx);
137 140
138 s->scale_bias = 1.0/(1*8);141 s->scale_bias = 1.0/(1*8);
139 142
@@ -175,7 +178,7 @@ static int decode_tag(AVCodecContext * avctx, · 35 unmodified lines
175 178
176 for (i=0 ; i<blocks ; i++) {179 for (i=0 ; i<blocks ; i++) {
177 nelly_decode_block(s, &buf[i*NELLY_BLOCK_LEN], s->float_buf);180 nelly_decode_block(s, &buf[i*NELLY_BLOCK_LEN], s->float_buf);
178 s->dsp.float_to_int16(&samples[i*NELLY_SAMPLES], s->float_buf, NELLY_SAMPLES);181 s->fmt_conv.float_to_int16(&samples[i*NELLY_SAMPLES], s->float_buf, NELLY_SAMPLES);
179 *data_size += NELLY_SAMPLES*sizeof(int16_t);182 *data_size += NELLY_SAMPLES*sizeof(int16_t);
180 }183 }
181 184
libavcodec/ppc/Makefile+1−0
@@ -21,6 +21,7 @@ ALTIVEC-OBJS-$(CONFIG_FFT) += ppc/fft_altivec.o \ · 20 unmodified lines
21OBJS-$(HAVE_ALTIVEC) += ppc/dsputil_altivec.o \21OBJS-$(HAVE_ALTIVEC) += ppc/dsputil_altivec.o \
22 ppc/fdct_altivec.o \22 ppc/fdct_altivec.o \
23 ppc/float_altivec.o \23 ppc/float_altivec.o \
24 ppc/fmtconvert_altivec.o \
24 ppc/gmc_altivec.o \25 ppc/gmc_altivec.o \
25 ppc/idct_altivec.o \26 ppc/idct_altivec.o \
26 ppc/int_altivec.o \27 ppc/int_altivec.o \
libavcodec/ppc/float_altivec.c+0−112
@@ -122,124 +122,12 @@ static void vector_fmul_window_altivec(float *dst, const float *src0, const floa · 121 unmodified lines
122 }122 }
123}123}
124 124
125static void int32_to_float_fmul_scalar_altivec(float *dst, const int *src, float mul, int len)
126{
127 union {
128 vector float v;
129 float s[4];
130 } mul_u;
131 int i;
132 vector float src1, src2, dst1, dst2, mul_v, zero;
133
134 zero = (vector float)vec_splat_u32(0);
135 mul_u.s[0] = mul;
136 mul_v = vec_splat(mul_u.v, 0);
137
138 for(i=0; i<len; i+=8) {
139 src1 = vec_ctf(vec_ld(0, src+i), 0);
140 src2 = vec_ctf(vec_ld(16, src+i), 0);
141 dst1 = vec_madd(src1, mul_v, zero);
142 dst2 = vec_madd(src2, mul_v, zero);
143 vec_st(dst1, 0, dst+i);
144 vec_st(dst2, 16, dst+i);
145 }
146}
147
148
149static vector signed short
150float_to_int16_one_altivec(const float *src)
151{
152 vector float s0 = vec_ld(0, src);
153 vector float s1 = vec_ld(16, src);
154 vector signed int t0 = vec_cts(s0, 0);
155 vector signed int t1 = vec_cts(s1, 0);
156 return vec_packs(t0,t1);
157}
158
159static void float_to_int16_altivec(int16_t *dst, const float *src, long len)
160{
161 int i;
162 vector signed short d0, d1, d;
163 vector unsigned char align;
164 if(((long)dst)&15) //FIXME
165 for(i=0; i<len-7; i+=8) {
166 d0 = vec_ld(0, dst+i);
167 d = float_to_int16_one_altivec(src+i);
168 d1 = vec_ld(15, dst+i);
169 d1 = vec_perm(d1, d0, vec_lvsl(0,dst+i));
170 align = vec_lvsr(0, dst+i);
171 d0 = vec_perm(d1, d, align);
172 d1 = vec_perm(d, d1, align);
173 vec_st(d0, 0, dst+i);
174 vec_st(d1,15, dst+i);
175 }
176 else
177 for(i=0; i<len-7; i+=8) {
178 d = float_to_int16_one_altivec(src+i);
179 vec_st(d, 0, dst+i);
180 }
181}
182
183static void
184float_to_int16_interleave_altivec(int16_t *dst, const float **src,
185 long len, int channels)
186{
187 int i;
188 vector signed short d0, d1, d2, c0, c1, t0, t1;
189 vector unsigned char align;
190 if(channels == 1)
191 float_to_int16_altivec(dst, src[0], len);
192 else
193 if (channels == 2) {
194 if(((long)dst)&15)
195 for(i=0; i<len-7; i+=8) {
196 d0 = vec_ld(0, dst + i);
197 t0 = float_to_int16_one_altivec(src[0] + i);
198 d1 = vec_ld(31, dst + i);
199 t1 = float_to_int16_one_altivec(src[1] + i);
200 c0 = vec_mergeh(t0, t1);
201 c1 = vec_mergel(t0, t1);
202 d2 = vec_perm(d1, d0, vec_lvsl(0, dst + i));
203 align = vec_lvsr(0, dst + i);
204 d0 = vec_perm(d2, c0, align);
205 d1 = vec_perm(c0, c1, align);
206 vec_st(d0, 0, dst + i);
207 d0 = vec_perm(c1, d2, align);
208 vec_st(d1, 15, dst + i);
209 vec_st(d0, 31, dst + i);
210 dst+=8;
211 }
212 else
213 for(i=0; i<len-7; i+=8) {
214 t0 = float_to_int16_one_altivec(src[0] + i);
215 t1 = float_to_int16_one_altivec(src[1] + i);
216 d0 = vec_mergeh(t0, t1);
217 d1 = vec_mergel(t0, t1);
218 vec_st(d0, 0, dst + i);
219 vec_st(d1, 16, dst + i);
220 dst+=8;
221 }
222 } else {
223 DECLARE_ALIGNED(16, int16_t, tmp)[len];
224 int c, j;
225 for (c = 0; c < channels; c++) {
226 float_to_int16_altivec(tmp, src[c], len);
227 for (i = 0, j = c; i < len; i++, j+=channels) {
228 dst[j] = tmp[i];
229 }
230 }
231 }
232}
233
234void float_init_altivec(DSPContext* c, AVCodecContext *avctx)125void float_init_altivec(DSPContext* c, AVCodecContext *avctx)
235{126{
236 c->vector_fmul = vector_fmul_altivec;127 c->vector_fmul = vector_fmul_altivec;
237 c->vector_fmul_reverse = vector_fmul_reverse_altivec;128 c->vector_fmul_reverse = vector_fmul_reverse_altivec;
238 c->vector_fmul_add = vector_fmul_add_altivec;129 c->vector_fmul_add = vector_fmul_add_altivec;
239 c->int32_to_float_fmul_scalar = int32_to_float_fmul_scalar_altivec;
240 if(!(avctx->flags & CODEC_FLAG_BITEXACT)) {130 if(!(avctx->flags & CODEC_FLAG_BITEXACT)) {
241 c->vector_fmul_window = vector_fmul_window_altivec;131 c->vector_fmul_window = vector_fmul_window_altivec;
242 c->float_to_int16 = float_to_int16_altivec;
243 c->float_to_int16_interleave = float_to_int16_interleave_altivec;
244 }132 }
245}133}
libavcodec/ppc/fmtconvert_altivec.c+142−0
@@ -0,0 +1,142 @@
1/*
2 * Copyright (c) 2006 Luca Barbato <lu_zero@gentoo.org>
3 *
4 * This file is part of FFmpeg.
5 *
6 * FFmpeg is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * FFmpeg is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with FFmpeg; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21#include "libavcodec/fmtconvert.h"
22
23#include "dsputil_altivec.h"
24#include "util_altivec.h"
25
26static void int32_to_float_fmul_scalar_altivec(float *dst, const int *src, float mul, int len)
27{
28 union {
29 vector float v;
30 float s[4];
31 } mul_u;
32 int i;
33 vector float src1, src2, dst1, dst2, mul_v, zero;
34
35 zero = (vector float)vec_splat_u32(0);
36 mul_u.s[0] = mul;
37 mul_v = vec_splat(mul_u.v, 0);
38
39 for(i=0; i<len; i+=8) {
40 src1 = vec_ctf(vec_ld(0, src+i), 0);
41 src2 = vec_ctf(vec_ld(16, src+i), 0);
42 dst1 = vec_madd(src1, mul_v, zero);
43 dst2 = vec_madd(src2, mul_v, zero);
44 vec_st(dst1, 0, dst+i);
45 vec_st(dst2, 16, dst+i);
46 }
47}
48
49
50static vector signed short
51float_to_int16_one_altivec(const float *src)
52{
53 vector float s0 = vec_ld(0, src);
54 vector float s1 = vec_ld(16, src);
55 vector signed int t0 = vec_cts(s0, 0);
56 vector signed int t1 = vec_cts(s1, 0);
57 return vec_packs(t0,t1);
58}
59
60static void float_to_int16_altivec(int16_t *dst, const float *src, long len)
61{
62 int i;
63 vector signed short d0, d1, d;
64 vector unsigned char align;
65 if(((long)dst)&15) //FIXME
66 for(i=0; i<len-7; i+=8) {
67 d0 = vec_ld(0, dst+i);
68 d = float_to_int16_one_altivec(src+i);
69 d1 = vec_ld(15, dst+i);
70 d1 = vec_perm(d1, d0, vec_lvsl(0,dst+i));
71 align = vec_lvsr(0, dst+i);
72 d0 = vec_perm(d1, d, align);
73 d1 = vec_perm(d, d1, align);
74 vec_st(d0, 0, dst+i);
75 vec_st(d1,15, dst+i);
76 }
77 else
78 for(i=0; i<len-7; i+=8) {
79 d = float_to_int16_one_altivec(src+i);
80 vec_st(d, 0, dst+i);
81 }
82}
83
84static void
85float_to_int16_interleave_altivec(int16_t *dst, const float **src,
86 long len, int channels)
87{
88 int i;
89 vector signed short d0, d1, d2, c0, c1, t0, t1;
90 vector unsigned char align;
91 if(channels == 1)
92 float_to_int16_altivec(dst, src[0], len);
93 else
94 if (channels == 2) {
95 if(((long)dst)&15)
96 for(i=0; i<len-7; i+=8) {
97 d0 = vec_ld(0, dst + i);
98 t0 = float_to_int16_one_altivec(src[0] + i);
99 d1 = vec_ld(31, dst + i);
100 t1 = float_to_int16_one_altivec(src[1] + i);
101 c0 = vec_mergeh(t0, t1);
102 c1 = vec_mergel(t0, t1);
103 d2 = vec_perm(d1, d0, vec_lvsl(0, dst + i));
104 align = vec_lvsr(0, dst + i);
105 d0 = vec_perm(d2, c0, align);
106 d1 = vec_perm(c0, c1, align);
107 vec_st(d0, 0, dst + i);
108 d0 = vec_perm(c1, d2, align);
109 vec_st(d1, 15, dst + i);
110 vec_st(d0, 31, dst + i);
111 dst+=8;
112 }
113 else
114 for(i=0; i<len-7; i+=8) {
115 t0 = float_to_int16_one_altivec(src[0] + i);
116 t1 = float_to_int16_one_altivec(src[1] + i);
117 d0 = vec_mergeh(t0, t1);
118 d1 = vec_mergel(t0, t1);
119 vec_st(d0, 0, dst + i);
120 vec_st(d1, 16, dst + i);
121 dst+=8;
122 }
123 } else {
124 DECLARE_ALIGNED(16, int16_t, tmp)[len];
125 int c, j;
126 for (c = 0; c < channels; c++) {
127 float_to_int16_altivec(tmp, src[c], len);
128 for (i = 0, j = c; i < len; i++, j+=channels) {
129 dst[j] = tmp[i];
130 }
131 }
132 }
133}
134
135void ff_fmt_convert_init_ppc(FmtConvertContext *c, AVCodecContext *avctx)
136{
137 c->int32_to_float_fmul_scalar = int32_to_float_fmul_scalar_altivec;
138 if(!(avctx->flags & CODEC_FLAG_BITEXACT)) {
139 c->float_to_int16 = float_to_int16_altivec;
140 c->float_to_int16_interleave = float_to_int16_interleave_altivec;
141 }
142}
libavcodec/vorbis_dec.c+5−1
@@ -31,6 +31,7 @@ · 30 unmodified lines
31#include "get_bits.h"31#include "get_bits.h"
32#include "dsputil.h"32#include "dsputil.h"
33#include "fft.h"33#include "fft.h"
34#include "fmtconvert.h"
34 35
35#include "vorbis.h"36#include "vorbis.h"
36#include "xiph.h"37#include "xiph.h"
@@ -127,6 +128,7 @@ typedef struct vorbis_context_s { · 90 unmodified lines
127 AVCodecContext *avccontext;128 AVCodecContext *avccontext;
128 GetBitContext gb;129 GetBitContext gb;
129 DSPContext dsp;130 DSPContext dsp;
131 FmtConvertContext fmt_conv;
130 132
131 FFTContext mdct[2];133 FFTContext mdct[2];
132 uint_fast8_t first_frame;134 uint_fast8_t first_frame;
@@ -961,6 +963,7 @@ static av_cold int vorbis_decode_init(AVCodecContext *avccontext) · 828 unmodified lines
961 963
962 vc->avccontext = avccontext;964 vc->avccontext = avccontext;
963 dsputil_init(&vc->dsp, avccontext);965 dsputil_init(&vc->dsp, avccontext);
966 ff_fmt_convert_init(&vc->fmt_conv, avccontext);
964 967
965 vc->scale_bias = 32768.0f;968 vc->scale_bias = 32768.0f;
966 969
@@ -1636,7 +1639,8 @@ static int vorbis_decode_frame(AVCodecContext *avccontext, · 669 unmodified lines
1636 len * ff_vorbis_channel_layout_offsets[vc->audio_channels - 1][i];1639 len * ff_vorbis_channel_layout_offsets[vc->audio_channels - 1][i];
1637 }1640 }
1638 1641
1639 vc->dsp.float_to_int16_interleave(data, channel_ptrs, len, vc->audio_channels);1642 vc->fmt_conv.float_to_int16_interleave(data, channel_ptrs, len,
1643 vc->audio_channels);
1640 *data_size = len * 2 * vc->audio_channels;1644 *data_size = len * 2 * vc->audio_channels;
1641 1645
1642 return buf_size ;1646 return buf_size ;
libavcodec/wma.c+1−0
@@ -126,6 +126,7 @@ int ff_wma_init(AVCodecContext *avctx, int flags2) · 125 unmodified lines
126 s->block_align = avctx->block_align;126 s->block_align = avctx->block_align;
127 127
128 dsputil_init(&s->dsp, avctx);128 dsputil_init(&s->dsp, avctx);
129 ff_fmt_convert_init(&s->fmt_conv, avctx);
129 130
130 if (avctx->codec->id == CODEC_ID_WMAV1) {131 if (avctx->codec->id == CODEC_ID_WMAV1) {
131 s->version = 1;132 s->version = 1;
libavcodec/wma.h+2−0
@@ -26,6 +26,7 @@ · 25 unmodified lines
26#include "put_bits.h"26#include "put_bits.h"
27#include "dsputil.h"27#include "dsputil.h"
28#include "fft.h"28#include "fft.h"
29#include "fmtconvert.h"
29 30
30/* size of blocks */31/* size of blocks */
31#define BLOCK_MIN_BITS 732#define BLOCK_MIN_BITS 7
@@ -134,6 +135,7 @@ typedef struct WMACodecContext { · 102 unmodified lines
134 float lsp_pow_m_table1[(1 << LSP_POW_BITS)];135 float lsp_pow_m_table1[(1 << LSP_POW_BITS)];
135 float lsp_pow_m_table2[(1 << LSP_POW_BITS)];136 float lsp_pow_m_table2[(1 << LSP_POW_BITS)];
136 DSPContext dsp;137 DSPContext dsp;
138 FmtConvertContext fmt_conv;
137 139
138#ifdef TRACE140#ifdef TRACE
139 int frame_count;141 int frame_count;
libavcodec/wmadec.c+1−1
@@ -791,7 +791,7 @@ static int wma_decode_frame(WMACodecContext *s, int16_t *samples) · 790 unmodified lines
791 incr = s->nb_channels;791 incr = s->nb_channels;
792 for (ch = 0; ch < MAX_CHANNELS; ch++)792 for (ch = 0; ch < MAX_CHANNELS; ch++)
793 output[ch] = s->frame_out[ch];793 output[ch] = s->frame_out[ch];
794 s->dsp.float_to_int16_interleave(samples, output, n, incr);794 s->fmt_conv.float_to_int16_interleave(samples, output, n, incr);
795 for (ch = 0; ch < incr; ch++) {795 for (ch = 0; ch < incr; ch++) {
796 /* prepare for next block */796 /* prepare for next block */
797 memmove(&s->frame_out[ch][0], &s->frame_out[ch][n], n * sizeof(float));797 memmove(&s->frame_out[ch][0], &s->frame_out[ch][n], n * sizeof(float));
libavcodec/x86/Makefile+2−0
@@ -39,6 +39,7 @@ YASM-OBJS-$(CONFIG_VP8_DECODER) += x86/vp8dsp.o · 38 unmodified lines
39MMX-OBJS-$(CONFIG_VP8_DECODER) += x86/vp8dsp-init.o39MMX-OBJS-$(CONFIG_VP8_DECODER) += x86/vp8dsp-init.o
40MMX-OBJS-$(HAVE_YASM) += x86/dsputil_yasm.o \40MMX-OBJS-$(HAVE_YASM) += x86/dsputil_yasm.o \
41 x86/deinterlace.o \41 x86/deinterlace.o \
42 x86/fmtconvert.o \
42 x86/h264_chromamc.o \43 x86/h264_chromamc.o \
43 $(YASM-OBJS-yes)44 $(YASM-OBJS-yes)
44 45
@@ -47,6 +48,7 @@ MMX-OBJS-$(CONFIG_FFT) += x86/fft.o · 2 unmodified lines
47OBJS-$(HAVE_MMX) += x86/dnxhd_mmx.o \48OBJS-$(HAVE_MMX) += x86/dnxhd_mmx.o \
48 x86/dsputil_mmx.o \49 x86/dsputil_mmx.o \
49 x86/fdct_mmx.o \50 x86/fdct_mmx.o \
51 x86/fmtconvert_mmx.o \
50 x86/idct_mmx_xvid.o \52 x86/idct_mmx_xvid.o \
51 x86/idct_sse2_xvid.o \53 x86/idct_sse2_xvid.o \
52 x86/motion_est_mmx.o \54 x86/motion_est_mmx.o \
libavcodec/x86/dsputil_mmx.c+0−220
@@ -2349,50 +2349,6 @@ static void vector_fmul_window_sse(float *dst, const float *src0, const float *s · 2348 unmodified lines
2349}2349}
2350#endif /* HAVE_6REGS */2350#endif /* HAVE_6REGS */
2351 2351
2352static void int32_to_float_fmul_scalar_sse(float *dst, const int *src, float mul, int len)
2353{
2354 x86_reg i = -4*len;
2355 __asm__ volatile(
2356 "movss %3, %%xmm4 \n"
2357 "shufps $0, %%xmm4, %%xmm4 \n"
2358 "1: \n"
2359 "cvtpi2ps (%2,%0), %%xmm0 \n"
2360 "cvtpi2ps 8(%2,%0), %%xmm1 \n"
2361 "cvtpi2ps 16(%2,%0), %%xmm2 \n"
2362 "cvtpi2ps 24(%2,%0), %%xmm3 \n"
2363 "movlhps %%xmm1, %%xmm0 \n"
2364 "movlhps %%xmm3, %%xmm2 \n"
2365 "mulps %%xmm4, %%xmm0 \n"
2366 "mulps %%xmm4, %%xmm2 \n"
2367 "movaps %%xmm0, (%1,%0) \n"
2368 "movaps %%xmm2, 16(%1,%0) \n"
2369 "add $32, %0 \n"
2370 "jl 1b \n"
2371 :"+r"(i)
2372 :"r"(dst+len), "r"(src+len), "m"(mul)
2373 );
2374}
2375
2376static void int32_to_float_fmul_scalar_sse2(float *dst, const int *src, float mul, int len)
2377{
2378 x86_reg i = -4*len;
2379 __asm__ volatile(
2380 "movss %3, %%xmm4 \n"
2381 "shufps $0, %%xmm4, %%xmm4 \n"
2382 "1: \n"
2383 "cvtdq2ps (%2,%0), %%xmm0 \n"
2384 "cvtdq2ps 16(%2,%0), %%xmm1 \n"
2385 "mulps %%xmm4, %%xmm0 \n"
2386 "mulps %%xmm4, %%xmm1 \n"
2387 "movaps %%xmm0, (%1,%0) \n"
2388 "movaps %%xmm1, 16(%1,%0) \n"
2389 "add $32, %0 \n"
2390 "jl 1b \n"
2391 :"+r"(i)
2392 :"r"(dst+len), "r"(src+len), "m"(mul)
2393 );
2394}
2395
2396static void vector_clipf_sse(float *dst, const float *src, float min, float max,2352static void vector_clipf_sse(float *dst, const float *src, float min, float max,
2397 int len)2353 int len)
2398{2354{
@@ -2427,70 +2383,6 @@ static void vector_clipf_sse(float *dst, const float *src, float min, float max, · 28 unmodified lines
2427 );2383 );
2428}2384}
2429 2385
2430static void float_to_int16_3dnow(int16_t *dst, const float *src, long len){
2431 x86_reg reglen = len;
2432 // not bit-exact: pf2id uses different rounding than C and SSE
2433 __asm__ volatile(
2434 "add %0 , %0 \n\t"
2435 "lea (%2,%0,2) , %2 \n\t"
2436 "add %0 , %1 \n\t"
2437 "neg %0 \n\t"
2438 "1: \n\t"
2439 "pf2id (%2,%0,2) , %%mm0 \n\t"
2440 "pf2id 8(%2,%0,2) , %%mm1 \n\t"
2441 "pf2id 16(%2,%0,2) , %%mm2 \n\t"
2442 "pf2id 24(%2,%0,2) , %%mm3 \n\t"
2443 "packssdw %%mm1 , %%mm0 \n\t"
2444 "packssdw %%mm3 , %%mm2 \n\t"
2445 "movq %%mm0 , (%1,%0) \n\t"
2446 "movq %%mm2 , 8(%1,%0) \n\t"
2447 "add $16 , %0 \n\t"
2448 " js 1b \n\t"
2449 "femms \n\t"
2450 :"+r"(reglen), "+r"(dst), "+r"(src)
2451 );
2452}
2453static void float_to_int16_sse(int16_t *dst, const float *src, long len){
2454 x86_reg reglen = len;
2455 __asm__ volatile(
2456 "add %0 , %0 \n\t"
2457 "lea (%2,%0,2) , %2 \n\t"
2458 "add %0 , %1 \n\t"
2459 "neg %0 \n\t"
2460 "1: \n\t"
2461 "cvtps2pi (%2,%0,2) , %%mm0 \n\t"
2462 "cvtps2pi 8(%2,%0,2) , %%mm1 \n\t"
2463 "cvtps2pi 16(%2,%0,2) , %%mm2 \n\t"
2464 "cvtps2pi 24(%2,%0,2) , %%mm3 \n\t"
2465 "packssdw %%mm1 , %%mm0 \n\t"
2466 "packssdw %%mm3 , %%mm2 \n\t"
2467 "movq %%mm0 , (%1,%0) \n\t"
2468 "movq %%mm2 , 8(%1,%0) \n\t"
2469 "add $16 , %0 \n\t"
2470 " js 1b \n\t"
2471 "emms \n\t"
2472 :"+r"(reglen), "+r"(dst), "+r"(src)
2473 );
2474}
2475
2476static void float_to_int16_sse2(int16_t *dst, const float *src, long len){
2477 x86_reg reglen = len;
2478 __asm__ volatile(
2479 "add %0 , %0 \n\t"
2480 "lea (%2,%0,2) , %2 \n\t"
2481 "add %0 , %1 \n\t"
2482 "neg %0 \n\t"
2483 "1: \n\t"
2484 "cvtps2dq (%2,%0,2) , %%xmm0 \n\t"
2485 "cvtps2dq 16(%2,%0,2) , %%xmm1 \n\t"
2486 "packssdw %%xmm1 , %%xmm0 \n\t"
2487 "movdqa %%xmm0 , (%1,%0) \n\t"
2488 "add $16 , %0 \n\t"
2489 " js 1b \n\t"
2490 :"+r"(reglen), "+r"(dst), "+r"(src)
2491 );
2492}
2493
2494void ff_vp3_idct_mmx(int16_t *input_data);2386void ff_vp3_idct_mmx(int16_t *input_data);
2495void ff_vp3_idct_put_mmx(uint8_t *dest, int line_size, DCTELEM *block);2387void ff_vp3_idct_put_mmx(uint8_t *dest, int line_size, DCTELEM *block);
2496void ff_vp3_idct_add_mmx(uint8_t *dest, int line_size, DCTELEM *block);2388void ff_vp3_idct_add_mmx(uint8_t *dest, int line_size, DCTELEM *block);
@@ -2504,9 +2396,6 @@ void ff_vp3_idct_sse2(int16_t *input_data); · 7 unmodified lines
2504void ff_vp3_idct_put_sse2(uint8_t *dest, int line_size, DCTELEM *block);2396void ff_vp3_idct_put_sse2(uint8_t *dest, int line_size, DCTELEM *block);
2505void ff_vp3_idct_add_sse2(uint8_t *dest, int line_size, DCTELEM *block);2397void ff_vp3_idct_add_sse2(uint8_t *dest, int line_size, DCTELEM *block);
2506 2398
2507void ff_float_to_int16_interleave6_sse(int16_t *dst, const float **src, int len);
2508void ff_float_to_int16_interleave6_3dnow(int16_t *dst, const float **src, int len);
2509void ff_float_to_int16_interleave6_3dn2(int16_t *dst, const float **src, int len);
2510int32_t ff_scalarproduct_int16_mmx2(const int16_t *v1, const int16_t *v2, int order, int shift);2399int32_t ff_scalarproduct_int16_mmx2(const int16_t *v1, const int16_t *v2, int order, int shift);
2511int32_t ff_scalarproduct_int16_sse2(const int16_t *v1, const int16_t *v2, int order, int shift);2400int32_t ff_scalarproduct_int16_sse2(const int16_t *v1, const int16_t *v2, int order, int shift);
2512int32_t ff_scalarproduct_and_madd_int16_mmx2(int16_t *v1, const int16_t *v2, const int16_t *v3, int order, int mul);2401int32_t ff_scalarproduct_and_madd_int16_mmx2(int16_t *v1, const int16_t *v2, const int16_t *v3, int order, int mul);
@@ -2516,102 +2405,6 @@ void ff_add_hfyu_median_prediction_mmx2(uint8_t *dst, const uint8_t *top, const · 3 unmodified lines
2516int ff_add_hfyu_left_prediction_ssse3(uint8_t *dst, const uint8_t *src, int w, int left);2405int ff_add_hfyu_left_prediction_ssse3(uint8_t *dst, const uint8_t *src, int w, int left);
2517int ff_add_hfyu_left_prediction_sse4(uint8_t *dst, const uint8_t *src, int w, int left);2406int ff_add_hfyu_left_prediction_sse4(uint8_t *dst, const uint8_t *src, int w, int left);
2518 2407
2519#if !HAVE_YASM
2520#define ff_float_to_int16_interleave6_sse(a,b,c) float_to_int16_interleave_misc_sse(a,b,c,6)
2521#define ff_float_to_int16_interleave6_3dnow(a,b,c) float_to_int16_interleave_misc_3dnow(a,b,c,6)
2522#define ff_float_to_int16_interleave6_3dn2(a,b,c) float_to_int16_interleave_misc_3dnow(a,b,c,6)
2523#endif
2524#define ff_float_to_int16_interleave6_sse2 ff_float_to_int16_interleave6_sse
2525
2526#define FLOAT_TO_INT16_INTERLEAVE(cpu, body) \
2527/* gcc pessimizes register allocation if this is in the same function as float_to_int16_interleave_sse2*/\
2528static av_noinline void float_to_int16_interleave_misc_##cpu(int16_t *dst, const float **src, long len, int channels){\
2529 DECLARE_ALIGNED(16, int16_t, tmp)[len];\
2530 int i,j,c;\
2531 for(c=0; c<channels; c++){\
2532 float_to_int16_##cpu(tmp, src[c], len);\
2533 for(i=0, j=c; i<len; i++, j+=channels)\
2534 dst[j] = tmp[i];\
2535 }\
2536}\
2537\
2538static void float_to_int16_interleave_##cpu(int16_t *dst, const float **src, long len, int channels){\
2539 if(channels==1)\
2540 float_to_int16_##cpu(dst, src[0], len);\
2541 else if(channels==2){\
2542 x86_reg reglen = len; \
2543 const float *src0 = src[0];\
2544 const float *src1 = src[1];\
2545 __asm__ volatile(\
2546 "shl $2, %0 \n"\
2547 "add %0, %1 \n"\
2548 "add %0, %2 \n"\
2549 "add %0, %3 \n"\
2550 "neg %0 \n"\
2551 body\
2552 :"+r"(reglen), "+r"(dst), "+r"(src0), "+r"(src1)\
2553 );\
2554 }else if(channels==6){\
2555 ff_float_to_int16_interleave6_##cpu(dst, src, len);\
2556 }else\
2557 float_to_int16_interleave_misc_##cpu(dst, src, len, channels);\
2558}
2559
2560FLOAT_TO_INT16_INTERLEAVE(3dnow,
2561 "1: \n"
2562 "pf2id (%2,%0), %%mm0 \n"
2563 "pf2id 8(%2,%0), %%mm1 \n"
2564 "pf2id (%3,%0), %%mm2 \n"
2565 "pf2id 8(%3,%0), %%mm3 \n"
2566 "packssdw %%mm1, %%mm0 \n"
2567 "packssdw %%mm3, %%mm2 \n"
2568 "movq %%mm0, %%mm1 \n"
2569 "punpcklwd %%mm2, %%mm0 \n"
2570 "punpckhwd %%mm2, %%mm1 \n"
2571 "movq %%mm0, (%1,%0)\n"
2572 "movq %%mm1, 8(%1,%0)\n"
2573 "add $16, %0 \n"
2574 "js 1b \n"
2575 "femms \n"
2576)
2577
2578FLOAT_TO_INT16_INTERLEAVE(sse,
2579 "1: \n"
2580 "cvtps2pi (%2,%0), %%mm0 \n"
2581 "cvtps2pi 8(%2,%0), %%mm1 \n"
2582 "cvtps2pi (%3,%0), %%mm2 \n"
2583 "cvtps2pi 8(%3,%0), %%mm3 \n"
2584 "packssdw %%mm1, %%mm0 \n"
2585 "packssdw %%mm3, %%mm2 \n"
2586 "movq %%mm0, %%mm1 \n"
2587 "punpcklwd %%mm2, %%mm0 \n"
2588 "punpckhwd %%mm2, %%mm1 \n"
2589 "movq %%mm0, (%1,%0)\n"
2590 "movq %%mm1, 8(%1,%0)\n"
2591 "add $16, %0 \n"
2592 "js 1b \n"
2593 "emms \n"
2594)
2595
2596FLOAT_TO_INT16_INTERLEAVE(sse2,
2597 "1: \n"
2598 "cvtps2dq (%2,%0), %%xmm0 \n"
2599 "cvtps2dq (%3,%0), %%xmm1 \n"
2600 "packssdw %%xmm1, %%xmm0 \n"
2601 "movhlps %%xmm0, %%xmm1 \n"
2602 "punpcklwd %%xmm1, %%xmm0 \n"
2603 "movdqa %%xmm0, (%1,%0) \n"
2604 "add $16, %0 \n"
2605 "js 1b \n"
2606)
2607
2608static void float_to_int16_interleave_3dn2(int16_t *dst, const float **src, long len, int channels){
2609 if(channels==6)
2610 ff_float_to_int16_interleave6_3dn2(dst, src, len);
2611 else
2612 float_to_int16_interleave_3dnow(dst, src, len, channels);
2613}
2614
2615float ff_scalarproduct_float_sse(const float *v1, const float *v2, int order);2408float ff_scalarproduct_float_sse(const float *v1, const float *v2, int order);
2616 2409
2617void dsputil_init_mmx(DSPContext* c, AVCodecContext *avctx)2410void dsputil_init_mmx(DSPContext* c, AVCodecContext *avctx)
@@ -2968,19 +2761,12 @@ void dsputil_init_mmx(DSPContext* c, AVCodecContext *avctx) · 350 unmodified lines
2968 if(mm_flags & AV_CPU_FLAG_3DNOW){2761 if(mm_flags & AV_CPU_FLAG_3DNOW){
2969 c->vorbis_inverse_coupling = vorbis_inverse_coupling_3dnow;2762 c->vorbis_inverse_coupling = vorbis_inverse_coupling_3dnow;
2970 c->vector_fmul = vector_fmul_3dnow;2763 c->vector_fmul = vector_fmul_3dnow;
2971 if(!(avctx->flags & CODEC_FLAG_BITEXACT)){
2972 c->float_to_int16 = float_to_int16_3dnow;
2973 c->float_to_int16_interleave = float_to_int16_interleave_3dnow;
2974 }
2975 }2764 }
2976 if(mm_flags & AV_CPU_FLAG_3DNOWEXT){2765 if(mm_flags & AV_CPU_FLAG_3DNOWEXT){
2977 c->vector_fmul_reverse = vector_fmul_reverse_3dnow2;2766 c->vector_fmul_reverse = vector_fmul_reverse_3dnow2;
2978#if HAVE_6REGS2767#if HAVE_6REGS
2979 c->vector_fmul_window = vector_fmul_window_3dnow2;2768 c->vector_fmul_window = vector_fmul_window_3dnow2;
2980#endif2769#endif
2981 if(!(avctx->flags & CODEC_FLAG_BITEXACT)){
2982 c->float_to_int16_interleave = float_to_int16_interleave_3dn2;
2983 }
2984 }2770 }
2985 if(mm_flags & AV_CPU_FLAG_MMX2){2771 if(mm_flags & AV_CPU_FLAG_MMX2){
2986#if HAVE_YASM2772#if HAVE_YASM
@@ -2997,10 +2783,7 @@ void dsputil_init_mmx(DSPContext* c, AVCodecContext *avctx) · 10 unmodified lines
2997#if HAVE_6REGS2783#if HAVE_6REGS
2998 c->vector_fmul_window = vector_fmul_window_sse;2784 c->vector_fmul_window = vector_fmul_window_sse;
2999#endif2785#endif
3000 c->int32_to_float_fmul_scalar = int32_to_float_fmul_scalar_sse;
3001 c->vector_clipf = vector_clipf_sse;2786 c->vector_clipf = vector_clipf_sse;
3002 c->float_to_int16 = float_to_int16_sse;
3003 c->float_to_int16_interleave = float_to_int16_interleave_sse;
3004#if HAVE_YASM2787#if HAVE_YASM
3005 c->scalarproduct_float = ff_scalarproduct_float_sse;2788 c->scalarproduct_float = ff_scalarproduct_float_sse;
3006#endif2789#endif
@@ -3008,9 +2791,6 @@ void dsputil_init_mmx(DSPContext* c, AVCodecContext *avctx) · 1 unmodified line
3008 if(mm_flags & AV_CPU_FLAG_3DNOW)2791 if(mm_flags & AV_CPU_FLAG_3DNOW)
3009 c->vector_fmul_add = vector_fmul_add_3dnow; // faster than sse2792 c->vector_fmul_add = vector_fmul_add_3dnow; // faster than sse
3010 if(mm_flags & AV_CPU_FLAG_SSE2){2793 if(mm_flags & AV_CPU_FLAG_SSE2){
3011 c->int32_to_float_fmul_scalar = int32_to_float_fmul_scalar_sse2;
3012 c->float_to_int16 = float_to_int16_sse2;
3013 c->float_to_int16_interleave = float_to_int16_interleave_sse2;
3014#if HAVE_YASM2794#if HAVE_YASM
3015 c->scalarproduct_int16 = ff_scalarproduct_int16_sse2;2795 c->scalarproduct_int16 = ff_scalarproduct_int16_sse2;
3016 c->scalarproduct_and_madd_int16 = ff_scalarproduct_and_madd_int16_sse2;2796 c->scalarproduct_and_madd_int16 = ff_scalarproduct_and_madd_int16_sse2;
libavcodec/x86/dsputil_yasm.asm+0−69
@@ -30,75 +30,6 @@ pb_zz11zz55zz99zzdd: db -1,-1,1,1,-1,-1,5,5,-1,-1,9,9,-1,-1,13,13 · 29 unmodified lines
30 30
31section .text align=1631section .text align=16
32 32
33%macro PSWAPD_SSE 2
34 pshufw %1, %2, 0x4e
35%endmacro
36%macro PSWAPD_3DN1 2
37 movq %1, %2
38 psrlq %1, 32
39 punpckldq %1, %2
40%endmacro
41
42%macro FLOAT_TO_INT16_INTERLEAVE6 1
43; void float_to_int16_interleave6_sse(int16_t *dst, const float **src, int len)
44cglobal float_to_int16_interleave6_%1, 2,7,0, dst, src, src1, src2, src3, src4, src5
45%ifdef ARCH_X86_64
46 %define lend r10d
47 mov lend, r2d
48%else
49 %define lend dword r2m
50%endif
51 mov src1q, [srcq+1*gprsize]
52 mov src2q, [srcq+2*gprsize]
53 mov src3q, [srcq+3*gprsize]
54 mov src4q, [srcq+4*gprsize]
55 mov src5q, [srcq+5*gprsize]
56 mov srcq, [srcq]
57 sub src1q, srcq
58 sub src2q, srcq
59 sub src3q, srcq
60 sub src4q, srcq
61 sub src5q, srcq
62.loop:
63 cvtps2pi mm0, [srcq]
64 cvtps2pi mm1, [srcq+src1q]
65 cvtps2pi mm2, [srcq+src2q]
66 cvtps2pi mm3, [srcq+src3q]
67 cvtps2pi mm4, [srcq+src4q]
68 cvtps2pi mm5, [srcq+src5q]
69 packssdw mm0, mm3
70 packssdw mm1, mm4
71 packssdw mm2, mm5
72 pswapd mm3, mm0
73 punpcklwd mm0, mm1
74 punpckhwd mm1, mm2
75 punpcklwd mm2, mm3
76 pswapd mm3, mm0
77 punpckldq mm0, mm2
78 punpckhdq mm2, mm1
79 punpckldq mm1, mm3
80 movq [dstq ], mm0
81 movq [dstq+16], mm2
82 movq [dstq+ 8], mm1
83 add srcq, 8
84 add dstq, 24
85 sub lend, 2
86 jg .loop
87 emms
88 RET
89%endmacro ; FLOAT_TO_INT16_INTERLEAVE6
90
91%define pswapd PSWAPD_SSE
92FLOAT_TO_INT16_INTERLEAVE6 sse
93%define cvtps2pi pf2id
94%define pswapd PSWAPD_3DN1
95FLOAT_TO_INT16_INTERLEAVE6 3dnow
96%undef pswapd
97FLOAT_TO_INT16_INTERLEAVE6 3dn2
98%undef cvtps2pi
99
100
101
102%macro SCALARPRODUCT 133%macro SCALARPRODUCT 1
103; int scalarproduct_int16(int16_t *v1, int16_t *v2, int order, int shift)34; int scalarproduct_int16(int16_t *v1, int16_t *v2, int order, int shift)
104cglobal scalarproduct_int16_%1, 3,3,4, v1, v2, order, shift35cglobal scalarproduct_int16_%1, 3,3,4, v1, v2, order, shift
libavcodec/x86/fmtconvert.asm+91−0
@@ -0,0 +1,91 @@
1;******************************************************************************
2;* x86 optimized Format Conversion Utils
3;* Copyright (c) 2008 Loren Merritt
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;* 51, Inc., Foundation Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20;******************************************************************************
21
22%include "x86inc.asm"
23
24section .text align=16
25
26%macro PSWAPD_SSE 2
27 pshufw %1, %2, 0x4e
28%endmacro
29%macro PSWAPD_3DN1 2
30 movq %1, %2
31 psrlq %1, 32
32 punpckldq %1, %2
33%endmacro
34
35%macro FLOAT_TO_INT16_INTERLEAVE6 1
36; void float_to_int16_interleave6_sse(int16_t *dst, const float **src, int len)
37cglobal float_to_int16_interleave6_%1, 2,7,0, dst, src, src1, src2, src3, src4, src5
38%ifdef ARCH_X86_64
39 %define lend r10d
40 mov lend, r2d
41%else
42 %define lend dword r2m
43%endif
44 mov src1q, [srcq+1*gprsize]
45 mov src2q, [srcq+2*gprsize]
46 mov src3q, [srcq+3*gprsize]
47 mov src4q, [srcq+4*gprsize]
48 mov src5q, [srcq+5*gprsize]
49 mov srcq, [srcq]
50 sub src1q, srcq
51 sub src2q, srcq
52 sub src3q, srcq
53 sub src4q, srcq
54 sub src5q, srcq
55.loop:
56 cvtps2pi mm0, [srcq]
57 cvtps2pi mm1, [srcq+src1q]
58 cvtps2pi mm2, [srcq+src2q]
59 cvtps2pi mm3, [srcq+src3q]
60 cvtps2pi mm4, [srcq+src4q]
61 cvtps2pi mm5, [srcq+src5q]
62 packssdw mm0, mm3
63 packssdw mm1, mm4
64 packssdw mm2, mm5
65 pswapd mm3, mm0
66 punpcklwd mm0, mm1
67 punpckhwd mm1, mm2
68 punpcklwd mm2, mm3
69 pswapd mm3, mm0
70 punpckldq mm0, mm2
71 punpckhdq mm2, mm1
72 punpckldq mm1, mm3
73 movq [dstq ], mm0
74 movq [dstq+16], mm2
75 movq [dstq+ 8], mm1
76 add srcq, 8
77 add dstq, 24
78 sub lend, 2
79 jg .loop
80 emms
81 RET
82%endmacro ; FLOAT_TO_INT16_INTERLEAVE6
83
84%define pswapd PSWAPD_SSE
85FLOAT_TO_INT16_INTERLEAVE6 sse
86%define cvtps2pi pf2id
87%define pswapd PSWAPD_3DN1
88FLOAT_TO_INT16_INTERLEAVE6 3dnow
89%undef pswapd
90FLOAT_TO_INT16_INTERLEAVE6 3dn2
91%undef cvtps2pi
libavcodec/x86/fmtconvert_mmx.c+266−0
@@ -0,0 +1,266 @@
1/*
2 * Format Conversion Utils
3 * Copyright (c) 2000, 2001 Fabrice Bellard
4 * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
5 *
6 * This file is part of FFmpeg.
7 *
8 * FFmpeg is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * FFmpeg is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with FFmpeg; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 *
22 * MMX optimization by Nick Kurshev <nickols_k@mail.ru>
23 */
24
25#include "libavutil/cpu.h"
26#include "libavutil/x86_cpu.h"
27#include "libavcodec/fmtconvert.h"
28
29static void int32_to_float_fmul_scalar_sse(float *dst, const int *src, float mul, int len)
30{
31 x86_reg i = -4*len;
32 __asm__ volatile(
33 "movss %3, %%xmm4 \n"
34 "shufps $0, %%xmm4, %%xmm4 \n"
35 "1: \n"
36 "cvtpi2ps (%2,%0), %%xmm0 \n"
37 "cvtpi2ps 8(%2,%0), %%xmm1 \n"
38 "cvtpi2ps 16(%2,%0), %%xmm2 \n"
39 "cvtpi2ps 24(%2,%0), %%xmm3 \n"
40 "movlhps %%xmm1, %%xmm0 \n"
41 "movlhps %%xmm3, %%xmm2 \n"
42 "mulps %%xmm4, %%xmm0 \n"
43 "mulps %%xmm4, %%xmm2 \n"
44 "movaps %%xmm0, (%1,%0) \n"
45 "movaps %%xmm2, 16(%1,%0) \n"
46 "add $32, %0 \n"
47 "jl 1b \n"
48 :"+r"(i)
49 :"r"(dst+len), "r"(src+len), "m"(mul)
50 );
51}
52
53static void int32_to_float_fmul_scalar_sse2(float *dst, const int *src, float mul, int len)
54{
55 x86_reg i = -4*len;
56 __asm__ volatile(
57 "movss %3, %%xmm4 \n"
58 "shufps $0, %%xmm4, %%xmm4 \n"
59 "1: \n"
60 "cvtdq2ps (%2,%0), %%xmm0 \n"
61 "cvtdq2ps 16(%2,%0), %%xmm1 \n"
62 "mulps %%xmm4, %%xmm0 \n"
63 "mulps %%xmm4, %%xmm1 \n"
64 "movaps %%xmm0, (%1,%0) \n"
65 "movaps %%xmm1, 16(%1,%0) \n"
66 "add $32, %0 \n"
67 "jl 1b \n"
68 :"+r"(i)
69 :"r"(dst+len), "r"(src+len), "m"(mul)
70 );
71}
72
73static void float_to_int16_3dnow(int16_t *dst, const float *src, long len){
74 x86_reg reglen = len;
75 // not bit-exact: pf2id uses different rounding than C and SSE
76 __asm__ volatile(
77 "add %0 , %0 \n\t"
78 "lea (%2,%0,2) , %2 \n\t"
79 "add %0 , %1 \n\t"
80 "neg %0 \n\t"
81 "1: \n\t"
82 "pf2id (%2,%0,2) , %%mm0 \n\t"
83 "pf2id 8(%2,%0,2) , %%mm1 \n\t"
84 "pf2id 16(%2,%0,2) , %%mm2 \n\t"
85 "pf2id 24(%2,%0,2) , %%mm3 \n\t"
86 "packssdw %%mm1 , %%mm0 \n\t"
87 "packssdw %%mm3 , %%mm2 \n\t"
88 "movq %%mm0 , (%1,%0) \n\t"
89 "movq %%mm2 , 8(%1,%0) \n\t"
90 "add $16 , %0 \n\t"
91 " js 1b \n\t"
92 "femms \n\t"
93 :"+r"(reglen), "+r"(dst), "+r"(src)
94 );
95}
96
97static void float_to_int16_sse(int16_t *dst, const float *src, long len){
98 x86_reg reglen = len;
99 __asm__ volatile(
100 "add %0 , %0 \n\t"
101 "lea (%2,%0,2) , %2 \n\t"
102 "add %0 , %1 \n\t"
103 "neg %0 \n\t"
104 "1: \n\t"
105 "cvtps2pi (%2,%0,2) , %%mm0 \n\t"
106 "cvtps2pi 8(%2,%0,2) , %%mm1 \n\t"
107 "cvtps2pi 16(%2,%0,2) , %%mm2 \n\t"
108 "cvtps2pi 24(%2,%0,2) , %%mm3 \n\t"
109 "packssdw %%mm1 , %%mm0 \n\t"
110 "packssdw %%mm3 , %%mm2 \n\t"
111 "movq %%mm0 , (%1,%0) \n\t"
112 "movq %%mm2 , 8(%1,%0) \n\t"
113 "add $16 , %0 \n\t"
114 " js 1b \n\t"
115 "emms \n\t"
116 :"+r"(reglen), "+r"(dst), "+r"(src)
117 );
118}
119
120static void float_to_int16_sse2(int16_t *dst, const float *src, long len){
121 x86_reg reglen = len;
122 __asm__ volatile(
123 "add %0 , %0 \n\t"
124 "lea (%2,%0,2) , %2 \n\t"
125 "add %0 , %1 \n\t"
126 "neg %0 \n\t"
127 "1: \n\t"
128 "cvtps2dq (%2,%0,2) , %%xmm0 \n\t"
129 "cvtps2dq 16(%2,%0,2) , %%xmm1 \n\t"
130 "packssdw %%xmm1 , %%xmm0 \n\t"
131 "movdqa %%xmm0 , (%1,%0) \n\t"
132 "add $16 , %0 \n\t"
133 " js 1b \n\t"
134 :"+r"(reglen), "+r"(dst), "+r"(src)
135 );
136}
137
138void ff_float_to_int16_interleave6_sse(int16_t *dst, const float **src, int len);
139void ff_float_to_int16_interleave6_3dnow(int16_t *dst, const float **src, int len);
140void ff_float_to_int16_interleave6_3dn2(int16_t *dst, const float **src, int len);
141
142#if !HAVE_YASM
143#define ff_float_to_int16_interleave6_sse(a,b,c) float_to_int16_interleave_misc_sse(a,b,c,6)
144#define ff_float_to_int16_interleave6_3dnow(a,b,c) float_to_int16_interleave_misc_3dnow(a,b,c,6)
145#define ff_float_to_int16_interleave6_3dn2(a,b,c) float_to_int16_interleave_misc_3dnow(a,b,c,6)
146#endif
147#define ff_float_to_int16_interleave6_sse2 ff_float_to_int16_interleave6_sse
148
149#define FLOAT_TO_INT16_INTERLEAVE(cpu, body) \
150/* gcc pessimizes register allocation if this is in the same function as float_to_int16_interleave_sse2*/\
151static av_noinline void float_to_int16_interleave_misc_##cpu(int16_t *dst, const float **src, long len, int channels){\
152 DECLARE_ALIGNED(16, int16_t, tmp)[len];\
153 int i,j,c;\
154 for(c=0; c<channels; c++){\
155 float_to_int16_##cpu(tmp, src[c], len);\
156 for(i=0, j=c; i<len; i++, j+=channels)\
157 dst[j] = tmp[i];\
158 }\
159}\
160\
161static void float_to_int16_interleave_##cpu(int16_t *dst, const float **src, long len, int channels){\
162 if(channels==1)\
163 float_to_int16_##cpu(dst, src[0], len);\
164 else if(channels==2){\
165 x86_reg reglen = len; \
166 const float *src0 = src[0];\
167 const float *src1 = src[1];\
168 __asm__ volatile(\
169 "shl $2, %0 \n"\
170 "add %0, %1 \n"\
171 "add %0, %2 \n"\
172 "add %0, %3 \n"\
173 "neg %0 \n"\
174 body\
175 :"+r"(reglen), "+r"(dst), "+r"(src0), "+r"(src1)\
176 );\
177 }else if(channels==6){\
178 ff_float_to_int16_interleave6_##cpu(dst, src, len);\
179 }else\
180 float_to_int16_interleave_misc_##cpu(dst, src, len, channels);\
181}
182
183FLOAT_TO_INT16_INTERLEAVE(3dnow,
184 "1: \n"
185 "pf2id (%2,%0), %%mm0 \n"
186 "pf2id 8(%2,%0), %%mm1 \n"
187 "pf2id (%3,%0), %%mm2 \n"
188 "pf2id 8(%3,%0), %%mm3 \n"
189 "packssdw %%mm1, %%mm0 \n"
190 "packssdw %%mm3, %%mm2 \n"
191 "movq %%mm0, %%mm1 \n"
192 "punpcklwd %%mm2, %%mm0 \n"
193 "punpckhwd %%mm2, %%mm1 \n"
194 "movq %%mm0, (%1,%0)\n"
195 "movq %%mm1, 8(%1,%0)\n"
196 "add $16, %0 \n"
197 "js 1b \n"
198 "femms \n"
199)
200
201FLOAT_TO_INT16_INTERLEAVE(sse,
202 "1: \n"
203 "cvtps2pi (%2,%0), %%mm0 \n"
204 "cvtps2pi 8(%2,%0), %%mm1 \n"
205 "cvtps2pi (%3,%0), %%mm2 \n"
206 "cvtps2pi 8(%3,%0), %%mm3 \n"
207 "packssdw %%mm1, %%mm0 \n"
208 "packssdw %%mm3, %%mm2 \n"
209 "movq %%mm0, %%mm1 \n"
210 "punpcklwd %%mm2, %%mm0 \n"
211 "punpckhwd %%mm2, %%mm1 \n"
212 "movq %%mm0, (%1,%0)\n"
213 "movq %%mm1, 8(%1,%0)\n"
214 "add $16, %0 \n"
215 "js 1b \n"
216 "emms \n"
217)
218
219FLOAT_TO_INT16_INTERLEAVE(sse2,
220 "1: \n"
221 "cvtps2dq (%2,%0), %%xmm0 \n"
222 "cvtps2dq (%3,%0), %%xmm1 \n"
223 "packssdw %%xmm1, %%xmm0 \n"
224 "movhlps %%xmm0, %%xmm1 \n"
225 "punpcklwd %%xmm1, %%xmm0 \n"
226 "movdqa %%xmm0, (%1,%0) \n"
227 "add $16, %0 \n"
228 "js 1b \n"
229)
230
231static void float_to_int16_interleave_3dn2(int16_t *dst, const float **src, long len, int channels){
232 if(channels==6)
233 ff_float_to_int16_interleave6_3dn2(dst, src, len);
234 else
235 float_to_int16_interleave_3dnow(dst, src, len, channels);
236}
237
238void ff_fmt_convert_init_x86(FmtConvertContext *c, AVCodecContext *avctx)
239{
240 int mm_flags = av_get_cpu_flags();
241
242 if (mm_flags & AV_CPU_FLAG_MMX) {
243
244 if(mm_flags & AV_CPU_FLAG_3DNOW){
245 if(!(avctx->flags & CODEC_FLAG_BITEXACT)){
246 c->float_to_int16 = float_to_int16_3dnow;
247 c->float_to_int16_interleave = float_to_int16_interleave_3dnow;
248 }
249 }
250 if(mm_flags & AV_CPU_FLAG_3DNOWEXT){
251 if(!(avctx->flags & CODEC_FLAG_BITEXACT)){
252 c->float_to_int16_interleave = float_to_int16_interleave_3dn2;
253 }
254 }
255 if(mm_flags & AV_CPU_FLAG_SSE){
256 c->int32_to_float_fmul_scalar = int32_to_float_fmul_scalar_sse;
257 c->float_to_int16 = float_to_int16_sse;
258 c->float_to_int16_interleave = float_to_int16_interleave_sse;
259 }
260 if(mm_flags & AV_CPU_FLAG_SSE2){
261 c->int32_to_float_fmul_scalar = int32_to_float_fmul_scalar_sse2;
262 c->float_to_int16 = float_to_int16_sse2;
263 c->float_to_int16_interleave = float_to_int16_interleave_sse2;
264 }
265 }
266}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t