Instead of returning all zeroes as result and Syy=1.0,
place all the K pulses in the first element y[0]
and return Syy=K*K.
This is how the original opus function handles the case.
This is how the existing pvq_search_c handles the case.
Also, according to Rostislav, the encoded all zeros vector
would be decoded as such y[0]=K vector, before dequantization.
So it is better to do that explicitly and calculate
the proper gain in the encoder.
--
I must point out that ppp_pvq_search_c() does generate
y[0]=-K vector, not +K.
This is because FFSIGN(0.0) returns -1.
I do consider this bug, however I'm not quite sure what
is the best way to handle it.
1. Fix localy
#undef FFSIGN
#define FFSIGN(a) ((a) >= 0 ? 1 : -1)
2. Use different name for that macro
#define OPUS_SIGN(a) ...
3. Fix by special case in ppp_pvq_search_c():
if( !(res > 0.0) ) { y[0]=K; for(i=1;i<N;i++) y[i]=0; return K*K; }
4. Fix FFSIGN globally.
That might have some side effects in addition of changing public API.
Best Regards
From 33d29a33dcf5ad8c4850edf9ed8d83292f10b03f Mon Sep 17 00:00:00 2001
From: Ivan Kalvachev <[email protected]>
Date: Fri, 25 Aug 2017 17:14:28 +0300
Subject: [PATCH] opus_pvq_search.asm: Handle zero vector input differently.
Instead of returning all zeroes as result and Syy=1.0,
place all the K pulses in the first element y[0]
and return Syy=K*K.
This is how the original opus function handles the case.
This is how the existing pvq_search_c handles the case.
Also, according to Rostislav, the encoded all zeros vector
would be decoded as such y[0]=K vector, before dequantization.
So it is better to do that explicitly and calculate
the proper gain in the encoder.
Signed-off-by: Ivan Kalvachev <[email protected]>
---
libavcodec/x86/opus_pvq_search.asm | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/libavcodec/x86/opus_pvq_search.asm b/libavcodec/x86/opus_pvq_search.asm
index 5c1e6d6174..adf3e6f87c 100644
--- a/libavcodec/x86/opus_pvq_search.asm
+++ b/libavcodec/x86/opus_pvq_search.asm
@@ -252,9 +252,9 @@ align 16
xorps m0, m0
comiss xm0, xm1 ;
+ cvtsi2ss xm0, dword Kd ; m0 = K
jz %%zero_input ; if (Sx==0) goto zero_input
- cvtsi2ss xm0, dword Kd ; m0 = K
%if USE_APPROXIMATION == 1
rcpss xm1, xm1 ; m1 = approx(1/Sx)
mulss xm0, xm1 ; m0 = K*(1/Sx)
@@ -355,7 +355,8 @@ align 16
RET
align 16
-%%zero_input:
+%%zero_input: ; expected m0 = K
+ mulss xm6, xm0, xm0 ; Syy_norm = K*K
lea r4d, [Nd - mmsize]
xorps m0, m0
%%zero_loop:
@@ -363,7 +364,7 @@ align 16
sub r4d, mmsize
jnc %%zero_loop
- movaps m6, [const_float_1]
+ mov [outYq], Kd
jmp %%return
%endmacro
--
2.14.1
_______________________________________________
ffmpeg-devel mailing list
[email protected]
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel