[FFmpeg-devel] [PATCH] VC-1 MMX DSP functions
Christophe GISQUET
christophe.gisquet
Thu Nov 15 21:58:39 CET 2007
Michael Niedermayer a ?crit :
>> +static void vc1_put_hor_16b_shift2_mmx(uint8_t *dst, long int stride,
>> + const int16_t *src, int rnd)
>> +{
>> + int h = 8;
>> + src -= 1;
>> +
>> + asm volatile(
>> + LOAD_ROUNDER_MMX("%4")
>> + "1: \n\t"
>> + "movq 2*0+0(%1), %%mm1 \n\t"
>> + "movq 2*0+8(%1), %%mm2 \n\t"
>> + "movq 2*1+0(%1), %%mm3 \n\t"
>> + "movq 2*1+8(%1), %%mm4 \n\t"
>> + "paddsw 2*3+0(%1), %%mm1 \n\t"
>> + "paddsw 2*3+8(%1), %%mm2 \n\t"
>> + "paddsw 2*2+0(%1), %%mm3 \n\t"
>> + "paddsw 2*2+8(%1), %%mm4 \n\t"
>> + "psubsw %%mm3, %%mm1 \n\t"
>> + "psubsw %%mm4, %%mm2 \n\t"
>> + /* Multiplying by 9 here overflows */
>> + "psllw $3, %%mm3 \n\t"
>> + "psllw $3, %%mm4 \n\t"
>> + "psubsw %%mm1, %%mm3 \n\t"
>> + "psubsw %%mm2, %%mm4 \n\t"
>
> what overflows here?
> also please replace all p*sw by p*w if saturation happens then your code
> is buggy
Allow me a rather long explanation (which should prove I'm wrong anyway)...
This is the horizontal pass of the bicubic filter when there is an
initial vertical pass beforehand. From the code, you probably have
noticed the filters coefficients are [-1 9 9 1] or [-3 18 53 -4] with a
scaling depending on the pair of filters used.
Let's start from the first pass then, the vertical one. Imagine the
input values:
255 255 255 255
255 255 255 255
255 255 255 255
255 255 255 255
The filters applied can be [-3 18 53 -4]/2? or [-1 9 9 -1]/2?, so
ignoring rounding, output would be: 2040 2040 2040 2040
Now if we apply the filter in the above function, considering input:
p1 p2 p3 p4 which are int16_t values
If we were to use a multiplication, that would give:
-(p1+p4)+(p2+p3)*9
The intermediate result (p2+p3)*9 with the above test case is
(2040+2040)*9=36720, which doesn't fit in an int16_t value. Other values
in the expression are also signed, so we can't use uint16_t arithmetics
either. My code was a feeble attempt at mitigating this. I made an
identical and equally wrong comment for the other functions
Discovering this, I tried to prescale the input values, which obviously
fail. To sum it up, it seems to me 17bits arithmetics are needed here
(contrary to what the document I have was affirming). I don't have the
SMPTE 421M official documentation, but from what I saw, it now makes me
think I can scrap my whole code for the horizontal pass. I don't see how
to overcome this except by using pmaddwd.
>> + return;
>> + }
>> + else { /* No horizontal filter, output 8 lines to dst */
>> + vc1_put_shift_8bits[vmode](dst, src, stride, 1-rnd, stride);
>> + return;
>> + }
>
> the return can be factored out of teh if/else
Ok.
Best regards,
--
Christophe GISQUET
More information about the ffmpeg-devel
mailing list