[FFmpeg-soc] libavfilter audio work - qualification task

S.N. Hemanth Meenakshisundaram smeenaks at ucsd.edu
Mon Apr 26 00:15:26 CEST 2010


On 04/25/2010 12:13 PM, Bobby Bingham wrote:
>> [...]
>>
>> +static void store_ref(YadifContext *yadif, uint8_t *src[3], int src_stride[3], int width, int height) {
>> +    int i;
>> +
>> +    memcpy(yadif->ref[3], yadif->ref[0], sizeof(uint8_t *)*3);
>> +    memmove(yadif->ref[0], yadif->ref[1], sizeof(uint8_t *)*3*3);
>> +
>> +    for(i=0; i<3; i++){
>> +        int is_chroma= !!i;
>> +        memcpy_pic(yadif->ref[2][i], src[i], width>>is_chroma, height>>is_chroma, yadif->stride[i], src_stride[i]);
>> +    }
>> +}
>>      
> Why do you copy the frames?  You should be able to simply store the
> input AVFilterPicRef pointers.  You'll need to set rej_perms for your
> input pad to reject AV_PERM_REUSE2, and free the references when you7re
> done with them.
>    
[...]
>> +        int refs= yadif->stride[i];
>> +
>> +        for(y=0; y<h; y++) {
>> +            if((y ^ parity)&  1) {
>> +                uint8_t *prev=&yadif->ref[0][i][y*refs];
>> +                uint8_t *cur =&yadif->ref[1][i][y*refs];
>> +                uint8_t *next=&yadif->ref[2][i][y*refs];
>> +                uint8_t *dst2=&dst[i][y*dst_stride[i]];
>> +                filter_line(yadif, dst2, prev, cur, next, w, refs, parity ^ tff);
>> +            } else {
>> +                memcpy(&dst[i][y*dst_stride[i]],&yadif->ref[1][i][y*refs], w);
>> +            }
>> +        }
>> +    }
>> +}
>> +
>> +static int config_props_input(AVFilterLink *link)
>> +{
>> +    YadifContext *yadif = link->dst->priv;
>> +    int i, j;
>> +
>> +    for(i=0; i<3; i++) {
>> +        int is_chroma= !!i;
>> +        int w= ((link->w     + 31)&  (~31))>>is_chroma;
>> +        int h= ((link->h + 6 + 31)&  (~31))>>is_chroma;
>> +
>> +        yadif->stride[i]= w;
>> +        for(j=0; j<3; j++)
>> +            yadif->ref[j][i]= (uint8_t *)(av_mallocz(w*h*sizeof(uint8_t)))+3*w;
>>      
> If the frame copying is because you need a particular stride alignment,
> then it would be better to extend avfilter_get_buffer to let you
> specify that requirement.
>    

I am a little confused about what is required here. I want to check if I 
have understood this part of the code right :

1. The input and output frames have same width, height and stride lengths.

2. Only the intermediate storage of the current, next and previous input 
frames used for the filter calculations has a different stride length 
and height. Basically, a stride length and height rounded off to the 
next multiple of 32, with the height being increased by 6 if already a 
multiple of 32.

Is the above right? If so can I get input buffers delivered to yadif 
with the right width and height by configuring the input filter link?

>    
>> +    }
>> +    return 0;
>> +}
>> +
>> +static void continue_buffered_image(AVFilterContext *ctx)
>> +{
>> +    YadifContext *yadif = ctx->priv;
>> +    AVFilterPicRef *picref = yadif->buffered_pic;
>> +    AVFilterPicRef *dpicref = ctx->outputs[0]->outpic;
>> +    AVFilterLink *out = ctx->outputs[0];
>> +    int tff = yadif->buffered_tff;
>> +    int i;
>> +
>> +    dpicref = avfilter_get_video_buffer(out, AV_PERM_WRITE, picref->w, picref->h);
>> +    if(yadif->start_deinterlace == 0) {
>> +        yadif->start_deinterlace = 1;
>> +        dpicref->pts = picref->pts;
>> +        dpicref->pos = picref->pos;
>> +        dpicref->fields = picref->fields;
>> +        avfilter_start_frame(out, avfilter_ref_pic(dpicref, ~0));
>> +        avfilter_unref_pic(picref);
>> +        avfilter_draw_slice(out, 0, dpicref->h, 1);
>> +        avfilter_end_frame(out);
>> +        avfilter_unref_pic(dpicref);
>> +        return;
>> +    }
>>      
> I think it should be okay to not output a frame if you simply don't have
> anything to output.
>
>    

If I try to not call start_frame/draw_slice/end_frame at all after 
receiving the first input frame, the yadif filter receives no further 
input frames. So how do I not output a frame and yet receive further 
input frames. I changed the code to output a black frame instead of a 
green frame for now.

>
>> +        filter(yadif, dpicref->data, dpicref->linesize, picref->w, picref->h, i ^ tff ^ 1, tff);
>> +        avfilter_start_frame(out, avfilter_ref_pic(dpicref, ~0));
>>      
> The call to avfilter_ref_pic is unnecessary.  By passing a picture
> reference to avfilter_start_frame, you give ownership of that reference
> to the next filter.  If you don't need to use the reference any more in
> your own code, you can just give it away, rather than creating a
> duplicate reference and unrefing the original.
>
>    
>    

I modified the code as below to pass the dpicref directly to the next 
filter and removed the unref_pic call. However, I still see the leak and 
valgrind still flags the get_video_buffer call in this section to be the 
leaked memory. What am I missing? Is there a need to explicitly specify 
that the next filter must free PicRef and its data after use? The 
valgrind output is also attached below. Changes based on the rest of the 
comments are done.


Valgrind output :

==4199== 192 (104 direct, 88 indirect) bytes in 1 blocks are definitely 
lost in loss record 140 of 191
==4199==    at 0x4A04360: memalign (vg_replace_malloc.c:532)
==4199==    by 0x4A043B9: posix_memalign (vg_replace_malloc.c:660)
==4199==    by 0x913D5C: av_mallocz (mem.c:83)
==4199==    by 0x411C78: avfilter_default_get_video_buffer (defaults.c:38)
==4199==    by 0x418A19: end_frame (vf_yadif.c:448)
==4199==    by 0x4112DE: avfilter_end_frame (avfilter.c:283)
==4199==    by 0x406B38: input_request_frame (ffplay.c:1605)
==4199==    by 0x408352: video_thread (ffplay.c:1669)
==4199==    by 0x3C79C112F4: SDL_RunThread (SDL_thread.c:202)
==4199==    by 0x3C79C56848: RunThread (SDL_systhread.c:47)
==4199==    by 0x3C69C06A39: start_thread (pthread_create.c:297)
==4199==

==4199==
==4199== 1,536 (832 direct, 704 indirect) bytes in 8 blocks are 
definitely lost in loss record 173 of 191
==4199==    at 0x4A04360: memalign (vg_replace_malloc.c:532)
==4199==    by 0x4A043B9: posix_memalign (vg_replace_malloc.c:660)
==4199==    by 0x913D5C: av_mallocz (mem.c:83)
==4199==    by 0x411C78: avfilter_default_get_video_buffer (defaults.c:38)
==4199==    by 0x4186EE: end_frame (vf_yadif.c:418)
==4199==    by 0x4112DE: avfilter_end_frame (avfilter.c:283)
==4199==    by 0x406B38: input_request_frame (ffplay.c:1605)
==4199==    by 0x408352: video_thread (ffplay.c:1669)
==4199==    by 0x3C79C112F4: SDL_RunThread (SDL_thread.c:202)
==4199==    by 0x3C79C56848: RunThread (SDL_systhread.c:47)
==4199==    by 0x3C69C06A39: start_thread (pthread_create.c:297)

Regards,

-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: yadif.diff
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-soc/attachments/20100425/9a422c55/attachment.asc>
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: avfilter.diff
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-soc/attachments/20100425/9a422c55/attachment.txt>


More information about the FFmpeg-soc mailing list