[FFmpeg-devel] [PATCH] avfilter/vf_interlace: add complex vertcal lowpassfilter

Thomas Mundt loudmax at yahoo.de
Sun Mar 12 14:06:22 EET 2017

> James Almer <jamrial at gmail.com> schrieb am Sa, 11.3.2017:
>>On 3/11/2017 12:39 PM, Thomas Mundt wrote:
>>> James Almer <jamrial at gmail.com> schrieb am Fr, 10.3.2017:
>>>> On 3/8/2017 1:58 PM, Thomas Mundt wrote:
>>>> Hi,
>>>> attached patch adds a complex (-1 2 6 2 -1) vertcal lowpassfilter to vf_interlace. This will better retain detail and reduce blurring compared to the existing (1 2 1) filter.
>>>> Please comment.
>>>> diff --git a/libavfilter/interlace.h b/libavfilter/interlace.h
>>>> index da073ae..7ad457e 100644
>>>> --- a/libavfilter/interlace.h
>>>> +++ b/libavfilter/interlace.h
>>>> @@ -51,6 +51,8 @@ typedef struct InterlaceContext {
>>>>      AVFrame *cur, *next;   // the two frames from which the new one is obtained
>>>>      void (*lowpass_line)(uint8_t *dstp, ptrdiff_t linesize, const uint8_t *srcp,
>>>>                           const uint8_t *srcp_above, const uint8_t *srcp_below);
>>>> +    void (*lowpass_line_complex)(uint8_t *dstp, ptrdiff_t linesize,
>>>> +                                 const uint8_t *srcp, int mref, int pref);
>>> Why not keep a single prototype, passing mref and pref for both linear
>>> and complex? You can calculate srcp_above and srcp_below for linear like
>>> you're doing it for complex in both the c and asm versions.
>> This would make sense. I just didn´t wanted to change more than necessary in one patch and I´m not such an expert in simd programming.
>> This is my second attempt ever.
>> Also there is the same function in tinterlace filter that also uses this asm. So I would also need to change the function in tinterlace.
> Yes, this would need separate patches. One to change the prototype,
> c and asm versions of the linear function for both filters, then
> another (One per interlace filter or one for both) adding the
> complex lowpass filter.
OK, c is fine, but I´m stumbling with asm since I´m a newbie there.
I changed in all files:
lowpass_line_c(uint8_t *dstp, ptrdiff_t linesize,
                       const uint8_t *srcp, const uint8_t *srcp_above,
                       const uint8_t *srcp_below)
lowpass_line_c(uint8_t *dstp, ptrdiff_t linesize,
                       const uint8_t *srcp, ptrdiff_t mref, ptrdiff_t pref)

But when I change asm to
cglobal lowpass_line, 5, 5, 7
    add r0, r1
    add r2, r1
    neg r1
    pcmpeqb m6, m6
    mova m0, [r2+r1+r3]
    mova m1, [r2+r1+r3+mmsize]
    pavgb m0, [r2+r1+r4]
    pavgb m1, [r2+r1+r4+mmsize]
    pxor m0, m6
    pxor m1, m6
    pxor m2, m6, [r2+r1]
    pxor m3, m6, [r2+r1+mmsize]
    pavgb m0, m2
    pavgb m1, m3
    pxor m0, m6
    pxor m1, m6
    mova [r0+r1], m0
    mova [r0+r1+mmsize], m1
    add r1, 2*mmsize
    jl .loop

I get error: invalid effective address
It works when I use the same scheme as I use in complex asm, but this adds some extra calculations which might not be OK.

>> I could do all this as a subsequent patch. Do you have a suggestion how to deal with the option name of complex filter in tinterlace?
>> There it´s a flag with the names "low_pass_filter" and "vlpf", so I could add "complex_low_pass_filter" and "vclpf"?
> With flags you could in theory enable both linear and complex at
> the same time, so you'd need to add code to abort in such cases
> or default to one of them.
> I'd say add a lowpass option similar to vf_interlace's, and leave
> the flags as is.

I´m not sure how to add an additional lowpass option without breaking the flag. I might need a hint.
Simplest to me would be adding the complex flag and when both flags are set using the complex function.
Otherwise the user won´t have set it.


More information about the ffmpeg-devel mailing list