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 <ikalvac...@gmail.com> 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 <ikalvac...@gmail.com> --- 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 ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel