This will be beneficial for use with the audio conversion API without requiring it to depend on all of dsputil.
Unified · Split
| @@ -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 \ |
| @@ -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 | ||
| @@ -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; |
| @@ -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); |
| @@ -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_CHANNELS | 61 | #undef AC3_MAX_CHANNELS |
| @@ -190,6 +191,7 @@ typedef struct { · 129 unmodified lines | |||
| 190 | 191 | ||
| 191 | ///@defgroup opt optimization | 192 | ///@defgroup opt optimization |
| 192 | DSPContext dsp; ///< for optimization | 193 | DSPContext dsp; ///< for optimization |
| 194 | FmtConvertContext fmt_conv; ///< optimized conversion functions | ||
| 193 | float mul_bias; ///< scaling for float_to_int16 conversion | 195 | float mul_bias; ///< scaling for float_to_int16 conversion |
| 194 | ///@} | 196 | ///@} |
| 195 | 197 | ||
| @@ -9,6 +9,7 @@ OBJS-$(CONFIG_H264PRED) += arm/h264pred_init_arm.o · 8 unmodified lines | |||
| 9 | OBJS += arm/dsputil_init_arm.o \ | 9 | OBJS += 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 | ||
| 26 | VFP-OBJS-$(HAVE_ARMV6) += arm/fmtconvert_vfp.o \ | ||
| 27 | |||
| 25 | OBJS-$(HAVE_ARMVFP) += arm/dsputil_vfp.o \ | 28 | OBJS-$(HAVE_ARMVFP) += arm/dsputil_vfp.o \ |
| 26 | arm/dsputil_init_vfp.o \ | 29 | arm/dsputil_init_vfp.o \ |
| 30 | $(VFP-OBJS-yes) | ||
| 27 | 31 | ||
| 28 | OBJS-$(HAVE_IWMMXT) += arm/dsputil_iwmmxt.o \ | 32 | OBJS-$(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 | ||
| 53 | OBJS-$(HAVE_NEON) += arm/dsputil_init_neon.o \ | 57 | OBJS-$(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 \ |
| @@ -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); |
| 154 | void ff_butterflies_float_neon(float *v1, float *v2, int len); | 154 | void ff_butterflies_float_neon(float *v1, float *v2, int len); |
| 155 | float ff_scalarproduct_float_neon(const float *v1, const float *v2, int len); | 155 | float ff_scalarproduct_float_neon(const float *v1, const float *v2, int len); |
| 156 | void ff_int32_to_float_fmul_scalar_neon(float *dst, const int *src, | ||
| 157 | float mul, int len); | ||
| 158 | void ff_vector_fmul_reverse_neon(float *dst, const float *src0, | 156 | void ff_vector_fmul_reverse_neon(float *dst, const float *src0, |
| 159 | const float *src1, int len); | 157 | const float *src1, int len); |
| 160 | void ff_vector_fmul_add_neon(float *dst, const float *src0, const float *src1, | 158 | void 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 | ||
| 163 | void ff_vector_clipf_neon(float *dst, const float *src, float min, float max, | 161 | void ff_vector_clipf_neon(float *dst, const float *src, float min, float max, |
| 164 | int len); | 162 | int len); |
| 165 | void ff_float_to_int16_neon(int16_t *, const float *, long); | ||
| 166 | void ff_float_to_int16_interleave_neon(int16_t *, const float **, long, int); | ||
| 167 | 163 | ||
| 168 | void ff_vorbis_inverse_coupling_neon(float *mag, float *ang, int blocksize); | 164 | void 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 | ||
| @@ -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); |
| 26 | void ff_vector_fmul_reverse_vfp(float *dst, const float *src0, | 26 | void ff_vector_fmul_reverse_vfp(float *dst, const float *src0, |
| 27 | const float *src1, int len); | 27 | const float *src1, int len); |
| 28 | void ff_float_to_int16_vfp(int16_t *dst, const float *src, long len); | ||
| 29 | 28 | ||
| 30 | void ff_dsputil_init_vfp(DSPContext* c, AVCodecContext *avctx) | 29 | void 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 | } |
| @@ -400,343 +400,6 @@ function ff_add_pixels_clamped_neon, export=1 · 399 unmodified lines | |||
| 400 | bx lr | 400 | bx lr |
| 401 | endfunc | 401 | endfunc |
| 402 | 402 | ||
| 403 | function 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 | ||
| 412 | 1: 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 | ||
| 430 | 2: 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 | ||
| 441 | 3: vshrn.s32 d4, q8, #16 | ||
| 442 | vshrn.s32 d5, q9, #16 | ||
| 443 | vst1.64 {d4-d5}, [r0,:128]! | ||
| 444 | bx lr | ||
| 445 | endfunc | ||
| 446 | |||
| 447 | function 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 | ||
| 468 | 1: 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 | ||
| 496 | 2: 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 | ||
| 512 | 3: vsri.32 q10, q8, #16 | ||
| 513 | vsri.32 q11, q9, #16 | ||
| 514 | vst1.64 {d20-d23},[r0,:128]! | ||
| 515 | bx lr | ||
| 516 | |||
| 517 | 4: push {r4-r8,lr} | ||
| 518 | cmp r3, #4 | ||
| 519 | lsl ip, r3, #1 | ||
| 520 | blt 4f | ||
| 521 | |||
| 522 | @ 4 channels | ||
| 523 | 5: 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 | ||
| 534 | 6: 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 | ||
| 569 | 7: 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 | ||
| 580 | 4: 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 | ||
| 617 | 6: 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 | ||
| 660 | 6: 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 | ||
| 669 | 7: 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 | ||
| 681 | 8: subs r3, r3, #2 | ||
| 682 | add r0, r0, #4 | ||
| 683 | popeq {r4-r8,pc} | ||
| 684 | |||
| 685 | @ 1 channel | ||
| 686 | 4: 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 | ||
| 695 | 6: 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 | ||
| 713 | 7: 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} | ||
| 723 | 8: 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 | ||
| 738 | endfunc | ||
| 739 | |||
| 740 | function ff_vector_fmul_neon, export=1 | 403 | function ff_vector_fmul_neon, export=1 |
| 741 | subs r3, r3, #8 | 404 | 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 lr | 713 | bx lr |
| 1051 | endfunc | 714 | endfunc |
| 1052 | 715 | ||
| 1053 | function ff_int32_to_float_fmul_scalar_neon, export=1 | ||
| 1054 | VFP vdup.32 q0, d0[0] | ||
| 1055 | VFP len .req r2 | ||
| 1056 | NOVFP vdup.32 q0, r2 | ||
| 1057 | NOVFP 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 | ||
| 1063 | 1: 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 | ||
| 1075 | 2: vst1.32 {q9}, [r0,:128]! | ||
| 1076 | vst1.32 {q10},[r0,:128]! | ||
| 1077 | bx lr | ||
| 1078 | .unreq len | ||
| 1079 | endfunc | ||
| 1080 | |||
| 1081 | function ff_vector_fmul_reverse_neon, export=1 | 716 | function ff_vector_fmul_reverse_neon, export=1 |
| 1082 | add r2, r2, r3, lsl #2 | 717 | add r2, r2, r3, lsl #2 |
| 1083 | sub r2, r2, #32 | 718 | sub r2, r2, #32 |
| @@ -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 lr | 132 | bx lr |
| 133 | endfunc | 133 | endfunc |
| 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) | ||
| 143 | function 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 | ||
| 155 | 1: | ||
| 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} | ||
| 187 | endfunc | ||
| 188 | #endif | ||
| @@ -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 | |||
| 26 | void ff_int32_to_float_fmul_scalar_neon(float *dst, const int *src, | ||
| 27 | float mul, int len); | ||
| 28 | |||
| 29 | void ff_float_to_int16_neon(int16_t *dst, const float *src, long len); | ||
| 30 | void ff_float_to_int16_interleave_neon(int16_t *, const float **, long, int); | ||
| 31 | |||
| 32 | void ff_float_to_int16_vfp(int16_t *dst, const float *src, long len); | ||
| 33 | |||
| 34 | void 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 | } | ||
| @@ -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 | |||
| 28 | function 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 | ||
| 37 | 1: 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 | ||
| 55 | 2: 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 | ||
| 66 | 3: vshrn.s32 d4, q8, #16 | ||
| 67 | vshrn.s32 d5, q9, #16 | ||
| 68 | vst1.64 {d4-d5}, [r0,:128]! | ||
| 69 | bx lr | ||
| 70 | endfunc | ||
| 71 | |||
| 72 | function 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 | ||
| 93 | 1: 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 | ||
| 121 | 2: 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 | ||
| 137 | 3: vsri.32 q10, q8, #16 | ||
| 138 | vsri.32 q11, q9, #16 | ||
| 139 | vst1.64 {d20-d23},[r0,:128]! | ||
| 140 | bx lr | ||
| 141 | |||
| 142 | 4: push {r4-r8,lr} | ||
| 143 | cmp r3, #4 | ||
| 144 | lsl ip, r3, #1 | ||
| 145 | blt 4f | ||
| 146 | |||
| 147 | @ 4 channels | ||
| 148 | 5: 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 | ||
| 159 | 6: 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 | ||
| 194 | 7: 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 | ||
| 205 | 4: 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 | ||
| 242 | 6: 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 | ||
| 285 | 6: 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 | ||
| 294 | 7: 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 | ||
| 306 | 8: subs r3, r3, #2 | ||
| 307 | add r0, r0, #4 | ||
| 308 | popeq {r4-r8,pc} | ||
| 309 | |||
| 310 | @ 1 channel | ||
| 311 | 4: 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 | ||
| 320 | 6: 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 | ||
| 338 | 7: 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} | ||
| 348 | 8: 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 | ||
| 363 | endfunc | ||
| 364 | |||
| 365 | function ff_int32_to_float_fmul_scalar_neon, export=1 | ||
| 366 | VFP vdup.32 q0, d0[0] | ||
| 367 | VFP len .req r2 | ||
| 368 | NOVFP vdup.32 q0, r2 | ||
| 369 | NOVFP 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 | ||
| 375 | 1: 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 | ||
| 387 | 2: vst1.32 {q9}, [r0,:128]! | ||
| 388 | vst1.32 {q10},[r0,:128]! | ||
| 389 | bx lr | ||
| 390 | .unreq len | ||
| 391 | endfunc | ||
| @@ -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) | ||
| 33 | function 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 | ||
| 45 | 1: | ||
| 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} | ||
| 77 | endfunc | ||
| @@ -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 | ||
| 37 | extern const uint16_t ff_wma_critical_freqs[25]; | 38 | extern 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; |
| @@ -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 TRACE | 45 | //#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 | ||
| 352 | static const uint16_t dca_vlc_offs[] = { | 354 | static 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; |
| @@ -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 | ||
| 3870 | static 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 | |||
| 3876 | static inline uint32_t clipf_c_one(uint32_t a, uint32_t mini, | 3870 | static 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 | ||
| 3921 | static av_always_inline int float_to_int16_one(const float *src){ | ||
| 3922 | return av_clip_int16(lrintf(*src)); | ||
| 3923 | } | ||
| 3924 | |||
| 3925 | static 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 | |||
| 3931 | static 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 | |||
| 3945 | static int32_t scalarproduct_int16_c(const int16_t * v1, const int16_t * v2, int order, int shift) | 3915 | static 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; |
| @@ -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 and | 397 | * 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*/); |
| @@ -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 | |||
| 26 | static 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 | |||
| 32 | static av_always_inline int float_to_int16_one(const float *src){ | ||
| 33 | return av_clip_int16(lrintf(*src)); | ||
| 34 | } | ||
| 35 | |||
| 36 | static 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 | |||
| 43 | static 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 | |||
| 59 | av_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 | } | ||
| @@ -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 | |||
| 28 | typedef 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 | |||
| 73 | void ff_fmt_convert_init(FmtConvertContext *c, AVCodecContext *avctx); | ||
| 74 | |||
| 75 | void ff_fmt_convert_init_arm(FmtConvertContext *c, AVCodecContext *avctx); | ||
| 76 | void ff_fmt_convert_init_ppc(FmtConvertContext *c, AVCodecContext *avctx); | ||
| 77 | void ff_fmt_convert_init_x86(FmtConvertContext *c, AVCodecContext *avctx); | ||
| 78 | |||
| 79 | #endif /* AVCODEC_FMTCONVERT_H */ | ||
| @@ -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_LE | 43 | #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 | ||
| @@ -21,6 +21,7 @@ ALTIVEC-OBJS-$(CONFIG_FFT) += ppc/fft_altivec.o \ · 20 unmodified lines | |||
| 21 | OBJS-$(HAVE_ALTIVEC) += ppc/dsputil_altivec.o \ | 21 | OBJS-$(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 \ |
| @@ -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 | ||
| 125 | static 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 | |||
| 149 | static vector signed short | ||
| 150 | float_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 | |||
| 159 | static 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 | |||
| 183 | static void | ||
| 184 | float_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 | |||
| 234 | void float_init_altivec(DSPContext* c, AVCodecContext *avctx) | 125 | void 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 | } |
| @@ -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 | |||
| 26 | static 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 | |||
| 50 | static vector signed short | ||
| 51 | float_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 | |||
| 60 | static 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 | |||
| 84 | static void | ||
| 85 | float_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 | |||
| 135 | void 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 | } | ||
| @@ -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 ; |
| @@ -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; |
| @@ -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 7 | 32 | #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 TRACE | 140 | #ifdef TRACE |
| 139 | int frame_count; | 141 | int frame_count; |
| @@ -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)); |
| @@ -39,6 +39,7 @@ YASM-OBJS-$(CONFIG_VP8_DECODER) += x86/vp8dsp.o · 38 unmodified lines | |||
| 39 | MMX-OBJS-$(CONFIG_VP8_DECODER) += x86/vp8dsp-init.o | 39 | MMX-OBJS-$(CONFIG_VP8_DECODER) += x86/vp8dsp-init.o |
| 40 | MMX-OBJS-$(HAVE_YASM) += x86/dsputil_yasm.o \ | 40 | MMX-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 | |||
| 47 | OBJS-$(HAVE_MMX) += x86/dnxhd_mmx.o \ | 48 | OBJS-$(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 \ |
| @@ -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 | ||
| 2352 | static 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 | |||
| 2376 | static 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 | |||
| 2396 | static void vector_clipf_sse(float *dst, const float *src, float min, float max, | 2352 | static 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 | ||
| 2430 | static 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 | } | ||
| 2453 | static 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 | |||
| 2476 | static 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 | |||
| 2494 | void ff_vp3_idct_mmx(int16_t *input_data); | 2386 | void ff_vp3_idct_mmx(int16_t *input_data); |
| 2495 | void ff_vp3_idct_put_mmx(uint8_t *dest, int line_size, DCTELEM *block); | 2387 | void ff_vp3_idct_put_mmx(uint8_t *dest, int line_size, DCTELEM *block); |
| 2496 | void ff_vp3_idct_add_mmx(uint8_t *dest, int line_size, DCTELEM *block); | 2388 | void 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 | |||
| 2504 | void ff_vp3_idct_put_sse2(uint8_t *dest, int line_size, DCTELEM *block); | 2396 | void ff_vp3_idct_put_sse2(uint8_t *dest, int line_size, DCTELEM *block); |
| 2505 | void ff_vp3_idct_add_sse2(uint8_t *dest, int line_size, DCTELEM *block); | 2397 | void ff_vp3_idct_add_sse2(uint8_t *dest, int line_size, DCTELEM *block); |
| 2506 | 2398 | ||
| 2507 | void ff_float_to_int16_interleave6_sse(int16_t *dst, const float **src, int len); | ||
| 2508 | void ff_float_to_int16_interleave6_3dnow(int16_t *dst, const float **src, int len); | ||
| 2509 | void ff_float_to_int16_interleave6_3dn2(int16_t *dst, const float **src, int len); | ||
| 2510 | int32_t ff_scalarproduct_int16_mmx2(const int16_t *v1, const int16_t *v2, int order, int shift); | 2399 | int32_t ff_scalarproduct_int16_mmx2(const int16_t *v1, const int16_t *v2, int order, int shift); |
| 2511 | int32_t ff_scalarproduct_int16_sse2(const int16_t *v1, const int16_t *v2, int order, int shift); | 2400 | int32_t ff_scalarproduct_int16_sse2(const int16_t *v1, const int16_t *v2, int order, int shift); |
| 2512 | int32_t ff_scalarproduct_and_madd_int16_mmx2(int16_t *v1, const int16_t *v2, const int16_t *v3, int order, int mul); | 2401 | int32_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 | |||
| 2516 | int ff_add_hfyu_left_prediction_ssse3(uint8_t *dst, const uint8_t *src, int w, int left); | 2405 | int ff_add_hfyu_left_prediction_ssse3(uint8_t *dst, const uint8_t *src, int w, int left); |
| 2517 | int ff_add_hfyu_left_prediction_sse4(uint8_t *dst, const uint8_t *src, int w, int left); | 2406 | int 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*/\ | ||
| 2528 | static 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 | \ | ||
| 2538 | static 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 | |||
| 2560 | FLOAT_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 | |||
| 2578 | FLOAT_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 | |||
| 2596 | FLOAT_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 | |||
| 2608 | static 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 | |||
| 2615 | float ff_scalarproduct_float_sse(const float *v1, const float *v2, int order); | 2408 | float ff_scalarproduct_float_sse(const float *v1, const float *v2, int order); |
| 2616 | 2409 | ||
| 2617 | void dsputil_init_mmx(DSPContext* c, AVCodecContext *avctx) | 2410 | void 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_6REGS | 2767 | #if HAVE_6REGS |
| 2979 | c->vector_fmul_window = vector_fmul_window_3dnow2; | 2768 | c->vector_fmul_window = vector_fmul_window_3dnow2; |
| 2980 | #endif | 2769 | #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_YASM | 2772 | #if HAVE_YASM |
| @@ -2997,10 +2783,7 @@ void dsputil_init_mmx(DSPContext* c, AVCodecContext *avctx) · 10 unmodified lines | |||
| 2997 | #if HAVE_6REGS | 2783 | #if HAVE_6REGS |
| 2998 | c->vector_fmul_window = vector_fmul_window_sse; | 2784 | c->vector_fmul_window = vector_fmul_window_sse; |
| 2999 | #endif | 2785 | #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_YASM | 2787 | #if HAVE_YASM |
| 3005 | c->scalarproduct_float = ff_scalarproduct_float_sse; | 2788 | c->scalarproduct_float = ff_scalarproduct_float_sse; |
| 3006 | #endif | 2789 | #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 sse | 2792 | 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_YASM | 2794 | #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; |
| @@ -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 | ||
| 31 | section .text align=16 | 31 | section .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) | ||
| 44 | cglobal 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 | ||
| 92 | FLOAT_TO_INT16_INTERLEAVE6 sse | ||
| 93 | %define cvtps2pi pf2id | ||
| 94 | %define pswapd PSWAPD_3DN1 | ||
| 95 | FLOAT_TO_INT16_INTERLEAVE6 3dnow | ||
| 96 | %undef pswapd | ||
| 97 | FLOAT_TO_INT16_INTERLEAVE6 3dn2 | ||
| 98 | %undef cvtps2pi | ||
| 99 | |||
| 100 | |||
| 101 | |||
| 102 | %macro SCALARPRODUCT 1 | 33 | %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) |
| 104 | cglobal scalarproduct_int16_%1, 3,3,4, v1, v2, order, shift | 35 | cglobal scalarproduct_int16_%1, 3,3,4, v1, v2, order, shift |
| @@ -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 | |||
| 24 | section .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) | ||
| 37 | cglobal 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 | ||
| 85 | FLOAT_TO_INT16_INTERLEAVE6 sse | ||
| 86 | %define cvtps2pi pf2id | ||
| 87 | %define pswapd PSWAPD_3DN1 | ||
| 88 | FLOAT_TO_INT16_INTERLEAVE6 3dnow | ||
| 89 | %undef pswapd | ||
| 90 | FLOAT_TO_INT16_INTERLEAVE6 3dn2 | ||
| 91 | %undef cvtps2pi | ||
| @@ -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 | |||
| 29 | static 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 | |||
| 53 | static 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 | |||
| 73 | static 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 | |||
| 97 | static 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 | |||
| 120 | static 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 | |||
| 138 | void ff_float_to_int16_interleave6_sse(int16_t *dst, const float **src, int len); | ||
| 139 | void ff_float_to_int16_interleave6_3dnow(int16_t *dst, const float **src, int len); | ||
| 140 | void 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*/\ | ||
| 151 | static 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 | \ | ||
| 161 | static 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 | |||
| 183 | FLOAT_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 | |||
| 201 | FLOAT_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 | |||
| 219 | FLOAT_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 | |||
| 231 | static 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 | |||
| 238 | void 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 | } | ||