* commit '9d5c62ba5b586c80af508b5914934b1c439f6652': lavu/opt: do not filter out the initial sign character except for flags eval: treat dB as decibels instead of decibytes float_dsp: add vector_dmul_scalar() to multiply a vector of doubles Conflicts: libavutil/eval.c tests/ref/fate/eval Merged-by: Michael Niedermayer <michaelni@gmx.at>tags/n1.1
| @@ -94,7 +94,11 @@ double av_strtod(const char *numstr, char **tail) | |||||
| d = strtod(numstr, &next); | d = strtod(numstr, &next); | ||||
| /* if parsing succeeded, check for and interpret postfixes */ | /* if parsing succeeded, check for and interpret postfixes */ | ||||
| if (next!=numstr) { | if (next!=numstr) { | ||||
| if (*next >= 'E' && *next <= 'z') { | |||||
| if (next[0] == 'd' && next[1] == 'B') { | |||||
| /* treat dB as decibels instead of decibytes */ | |||||
| d = pow(10, d / 20); | |||||
| next += 2; | |||||
| } else if (*next >= 'E' && *next <= 'z') { | |||||
| int e= si_prefixes[*next - 'E']; | int e= si_prefixes[*next - 'E']; | ||||
| if (e) { | if (e) { | ||||
| if (next[1] == 'i') { | if (next[1] == 'i') { | ||||
| @@ -448,16 +452,31 @@ static int parse_pow(AVExpr **e, Parser *p, int *sign) | |||||
| return parse_primary(e, p); | return parse_primary(e, p); | ||||
| } | } | ||||
| static int parse_dB(AVExpr **e, Parser *p, int *sign) | |||||
| { | |||||
| /* do not filter out the negative sign when parsing a dB value. | |||||
| for example, -3dB is not the same as -(3dB) */ | |||||
| if (*p->s == '-') { | |||||
| char *next; | |||||
| strtod(p->s, &next); | |||||
| if (next != p->s && next[0] == 'd' && next[1] == 'B') { | |||||
| *sign = 0; | |||||
| return parse_primary(e, p); | |||||
| } | |||||
| } | |||||
| return parse_pow(e, p, sign); | |||||
| } | |||||
| static int parse_factor(AVExpr **e, Parser *p) | static int parse_factor(AVExpr **e, Parser *p) | ||||
| { | { | ||||
| int sign, sign2, ret; | int sign, sign2, ret; | ||||
| AVExpr *e0, *e1, *e2; | AVExpr *e0, *e1, *e2; | ||||
| if ((ret = parse_pow(&e0, p, &sign)) < 0) | |||||
| if ((ret = parse_dB(&e0, p, &sign)) < 0) | |||||
| return ret; | return ret; | ||||
| while(p->s[0]=='^'){ | while(p->s[0]=='^'){ | ||||
| e1 = e0; | e1 = e0; | ||||
| p->s++; | p->s++; | ||||
| if ((ret = parse_pow(&e2, p, &sign2)) < 0) { | |||||
| if ((ret = parse_dB(&e2, p, &sign2)) < 0) { | |||||
| av_expr_free(e1); | av_expr_free(e1); | ||||
| return ret; | return ret; | ||||
| } | } | ||||
| @@ -744,6 +763,8 @@ int main(int argc, char **argv) | |||||
| "not(1)", | "not(1)", | ||||
| "not(NAN)", | "not(NAN)", | ||||
| "not(0)", | "not(0)", | ||||
| "6.0206dB", | |||||
| "-3.0103dB", | |||||
| "pow(0,1.23)", | "pow(0,1.23)", | ||||
| "pow(PI,1.23)", | "pow(PI,1.23)", | ||||
| "PI^1.23", | "PI^1.23", | ||||
| @@ -47,11 +47,20 @@ static void vector_fmul_scalar_c(float *dst, const float *src, float mul, | |||||
| dst[i] = src[i] * mul; | dst[i] = src[i] * mul; | ||||
| } | } | ||||
| static void vector_dmul_scalar_c(double *dst, const double *src, double mul, | |||||
| int len) | |||||
| { | |||||
| int i; | |||||
| for (i = 0; i < len; i++) | |||||
| dst[i] = src[i] * mul; | |||||
| } | |||||
| void avpriv_float_dsp_init(AVFloatDSPContext *fdsp, int bit_exact) | void avpriv_float_dsp_init(AVFloatDSPContext *fdsp, int bit_exact) | ||||
| { | { | ||||
| fdsp->vector_fmul = vector_fmul_c; | fdsp->vector_fmul = vector_fmul_c; | ||||
| fdsp->vector_fmac_scalar = vector_fmac_scalar_c; | fdsp->vector_fmac_scalar = vector_fmac_scalar_c; | ||||
| fdsp->vector_fmul_scalar = vector_fmul_scalar_c; | fdsp->vector_fmul_scalar = vector_fmul_scalar_c; | ||||
| fdsp->vector_dmul_scalar = vector_dmul_scalar_c; | |||||
| #if ARCH_ARM | #if ARCH_ARM | ||||
| ff_float_dsp_init_arm(fdsp); | ff_float_dsp_init_arm(fdsp); | ||||
| @@ -66,6 +66,21 @@ typedef struct AVFloatDSPContext { | |||||
| */ | */ | ||||
| void (*vector_fmul_scalar)(float *dst, const float *src, float mul, | void (*vector_fmul_scalar)(float *dst, const float *src, float mul, | ||||
| int len); | int len); | ||||
| /** | |||||
| * Multiply a vector of double by a scalar double. Source and | |||||
| * destination vectors must overlap exactly or not at all. | |||||
| * | |||||
| * @param dst result vector | |||||
| * constraints: 32-byte aligned | |||||
| * @param src input vector | |||||
| * constraints: 32-byte aligned | |||||
| * @param mul scalar value | |||||
| * @param len length of vector | |||||
| * constraints: multiple of 8 | |||||
| */ | |||||
| void (*vector_dmul_scalar)(double *dst, const double *src, double mul, | |||||
| int len); | |||||
| } AVFloatDSPContext; | } AVFloatDSPContext; | ||||
| /** | /** | ||||
| @@ -184,10 +184,15 @@ static int set_string_number(void *obj, const AVOption *o, const char *val, void | |||||
| double d, num = 1; | double d, num = 1; | ||||
| int64_t intnum = 1; | int64_t intnum = 1; | ||||
| if (*val == '+' || *val == '-') | |||||
| cmd = *(val++); | |||||
| i = 0; | |||||
| if (*val == '+' || *val == '-') { | |||||
| if (o->type == AV_OPT_TYPE_FLAGS) | |||||
| cmd = *(val++); | |||||
| else if (!notfirst) | |||||
| buf[i++] = *val; | |||||
| } | |||||
| for (i = 0; i < sizeof(buf) - 1 && val[i] && val[i] != '+' && val[i] != '-'; i++) | |||||
| for (; i < sizeof(buf) - 1 && val[i] && val[i] != '+' && val[i] != '-'; i++) | |||||
| buf[i] = val[i]; | buf[i] = val[i]; | ||||
| buf[i] = 0; | buf[i] = 0; | ||||
| @@ -120,3 +120,48 @@ cglobal vector_fmul_scalar, 4,4,3, dst, src, mul, len | |||||
| INIT_XMM sse | INIT_XMM sse | ||||
| VECTOR_FMUL_SCALAR | VECTOR_FMUL_SCALAR | ||||
| ;------------------------------------------------------------------------------ | |||||
| ; void ff_vector_dmul_scalar(double *dst, const double *src, double mul, | |||||
| ; int len) | |||||
| ;------------------------------------------------------------------------------ | |||||
| %macro VECTOR_DMUL_SCALAR 0 | |||||
| %if UNIX64 | |||||
| cglobal vector_dmul_scalar, 3,3,3, dst, src, len | |||||
| %else | |||||
| cglobal vector_dmul_scalar, 4,4,3, dst, src, mul, len | |||||
| %endif | |||||
| %if ARCH_X86_32 | |||||
| VBROADCASTSD m0, mulm | |||||
| %else | |||||
| %if WIN64 | |||||
| movlhps xmm2, xmm2 | |||||
| %if cpuflag(avx) | |||||
| vinsertf128 ymm2, ymm2, xmm2, 1 | |||||
| %endif | |||||
| SWAP 0, 2 | |||||
| %else | |||||
| movlhps xmm0, xmm0 | |||||
| %if cpuflag(avx) | |||||
| vinsertf128 ymm0, ymm0, xmm0, 1 | |||||
| %endif | |||||
| %endif | |||||
| %endif | |||||
| lea lenq, [lend*8-2*mmsize] | |||||
| .loop: | |||||
| mulpd m1, m0, [srcq+lenq ] | |||||
| mulpd m2, m0, [srcq+lenq+mmsize] | |||||
| mova [dstq+lenq ], m1 | |||||
| mova [dstq+lenq+mmsize], m2 | |||||
| sub lenq, 2*mmsize | |||||
| jge .loop | |||||
| REP_RET | |||||
| %endmacro | |||||
| INIT_XMM sse2 | |||||
| VECTOR_DMUL_SCALAR | |||||
| %if HAVE_AVX_EXTERNAL | |||||
| INIT_YMM avx | |||||
| VECTOR_DMUL_SCALAR | |||||
| %endif | |||||
| @@ -35,6 +35,11 @@ extern void ff_vector_fmac_scalar_avx(float *dst, const float *src, float mul, | |||||
| extern void ff_vector_fmul_scalar_sse(float *dst, const float *src, float mul, | extern void ff_vector_fmul_scalar_sse(float *dst, const float *src, float mul, | ||||
| int len); | int len); | ||||
| extern void ff_vector_dmul_scalar_sse2(double *dst, const double *src, | |||||
| double mul, int len); | |||||
| extern void ff_vector_dmul_scalar_avx(double *dst, const double *src, | |||||
| double mul, int len); | |||||
| void ff_float_dsp_init_x86(AVFloatDSPContext *fdsp) | void ff_float_dsp_init_x86(AVFloatDSPContext *fdsp) | ||||
| { | { | ||||
| int mm_flags = av_get_cpu_flags(); | int mm_flags = av_get_cpu_flags(); | ||||
| @@ -44,8 +49,12 @@ void ff_float_dsp_init_x86(AVFloatDSPContext *fdsp) | |||||
| fdsp->vector_fmac_scalar = ff_vector_fmac_scalar_sse; | fdsp->vector_fmac_scalar = ff_vector_fmac_scalar_sse; | ||||
| fdsp->vector_fmul_scalar = ff_vector_fmul_scalar_sse; | fdsp->vector_fmul_scalar = ff_vector_fmul_scalar_sse; | ||||
| } | } | ||||
| if (EXTERNAL_SSE2(mm_flags)) { | |||||
| fdsp->vector_dmul_scalar = ff_vector_dmul_scalar_sse2; | |||||
| } | |||||
| if (EXTERNAL_AVX(mm_flags)) { | if (EXTERNAL_AVX(mm_flags)) { | ||||
| fdsp->vector_fmul = ff_vector_fmul_avx; | fdsp->vector_fmul = ff_vector_fmul_avx; | ||||
| fdsp->vector_fmac_scalar = ff_vector_fmac_scalar_avx; | fdsp->vector_fmac_scalar = ff_vector_fmac_scalar_avx; | ||||
| fdsp->vector_dmul_scalar = ff_vector_dmul_scalar_avx; | |||||
| } | } | ||||
| } | } | ||||
| @@ -631,6 +631,17 @@ | |||||
| %endif | %endif | ||||
| %endmacro | %endmacro | ||||
| %macro VBROADCASTSD 2 ; dst xmm/ymm, src m64 | |||||
| %if cpuflag(avx) && mmsize == 32 | |||||
| vbroadcastsd %1, %2 | |||||
| %elif cpuflag(sse3) | |||||
| movddup %1, %2 | |||||
| %else ; sse2 | |||||
| movsd %1, %2 | |||||
| movlhps %1, %1 | |||||
| %endif | |||||
| %endmacro | |||||
| %macro SHUFFLE_MASK_W 8 | %macro SHUFFLE_MASK_W 8 | ||||
| %rep 8 | %rep 8 | ||||
| %if %1>=0x80 | %if %1>=0x80 | ||||
| @@ -184,6 +184,12 @@ Evaluating 'not(NAN)' | |||||
| Evaluating 'not(0)' | Evaluating 'not(0)' | ||||
| 'not(0)' -> 1.000000 | 'not(0)' -> 1.000000 | ||||
| Evaluating '6.0206dB' | |||||
| '6.0206dB' -> 2.000000 | |||||
| Evaluating '-3.0103dB' | |||||
| '-3.0103dB' -> 0.707107 | |||||
| Evaluating 'pow(0,1.23)' | Evaluating 'pow(0,1.23)' | ||||
| 'pow(0,1.23)' -> 0.000000 | 'pow(0,1.23)' -> 0.000000 | ||||