[FFmpeg-devel] [PATCH] Port tinterlace filter from MPlayer.

Michael Niedermayer michaelni
Sun Sep 26 20:32:48 CEST 2010


On Sun, Sep 26, 2010 at 07:32:45PM +0200, Stefano Sabatini wrote:
[...]
> +static void end_frame(AVFilterLink *inlink)
> +{
> +    AVFilterContext *ctx = inlink->dst;
> +    AVFilterLink *outlink = ctx->outputs[0];
> +    TInterlaceContext *tinterlace = ctx->priv;
> +    AVFilterBufferRef *outpicref;
> +    AVFilterBufferRef *picref = inlink->cur_buf;
> +
> +    if (tinterlace->mode == 0 || tinterlace->mode == 4) {
> +        int half_src_fields = tinterlace->mode == 4;
> +
> +        if (!tinterlace->picref) {
> +            outpicref = avfilter_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h);
> +            avfilter_copy_buffer_ref_props(outpicref, picref);
> +            outpicref->video->w = outlink->w;
> +            outpicref->video->h = outlink->h;
> +            outpicref->video->interlaced = 1;
> +            outpicref->video->top_field_first = 1;
> +
> +            /* write odd frame fields into the upper fields of the new frame */
> +            copy_picture_fields(outpicref->data, outpicref->linesize,
> +                                picref   ->data, picref   ->linesize,
> +                                outlink->format, inlink->w, inlink->h, 0, half_src_fields, 0);
> +            tinterlace->picref = outpicref;
> +        } else {
> +            outpicref = tinterlace->picref;
> +
> +            /* write even frame fields into the lower fields of the new frame */
> +            copy_picture_fields(outpicref->data, outpicref->linesize,
> +                                picref   ->data, picref   ->linesize,
> +                                outlink->format, inlink->w, inlink->h, 1, half_src_fields, half_src_fields);
> +            tinterlace->frame_pending = 1;
> +        }
> +    } else if ((tinterlace->mode == 1 &&   tinterlace->frame & 1) ||  /* send only odd  frames */
> +               (tinterlace->mode == 2 && !(tinterlace->frame & 1))) { /* send only even frames */
> +        tinterlace->picref = avfilter_ref_buffer(picref, AV_PERM_READ);
> +        tinterlace->frame_pending = 1;
> +    } else if (tinterlace->mode == 3) {
> +        outpicref = avfilter_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h);
> +        avfilter_copy_buffer_ref_props(outpicref, picref);
> +        outpicref->video->w = outlink->w;
> +        outpicref->video->h = outlink->h;
> +        outpicref->video->interlaced = 1;
> +        outpicref->video->top_field_first = tinterlace->frame & 1;
> +
> +        /* cleanup the destination picture */
> +        memset(outpicref->data[0], 0, outpicref->linesize[0] * outlink->h);
> +        if (outpicref->data[1])
> +            memset(outpicref->data[1], 128, outpicref->linesize[1] * (outlink->h >> tinterlace->vsub));
> +        if (outpicref->data[2])
> +            memset(outpicref->data[2], 128, outpicref->linesize[2] * (outlink->h >> tinterlace->vsub));
> +
> +        /* copy fields */
> +        copy_picture_fields(outpicref->data, outpicref->linesize,
> +                            picref   ->data, picref   ->linesize,
> +                            outlink->format, inlink->w, inlink->h, tinterlace->frame & 1, 0, 0);
> +        tinterlace->picref = outpicref;
> +        tinterlace->frame_pending = 1;
> +    }
> +
> +    tinterlace->frame++;
> +    avfilter_unref_buffer(inlink->cur_buf);
> +}
> +
> +static void null_start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref) { }
> +
> +static int request_frame(AVFilterLink *outlink)
> +{
> +    AVFilterContext *ctx = outlink->src;
> +    TInterlaceContext *tinterlace = ctx->priv;
> +
> +    while (!tinterlace->frame_pending) {
> +        int ret;
> +
> +        if ((ret = avfilter_request_frame(outlink->src->inputs[0])))
> +            return ret;
> +    }
> +
> +    avfilter_start_frame(outlink, tinterlace->picref);
> +    avfilter_draw_slice(outlink, 0, outlink->h, 1);
> +    avfilter_end_frame(outlink);
> +    tinterlace->picref = NULL;
> +    tinterlace->frame_pending = 0;
> +    return 0;
> +}

imagine your filter is called with start_frame/draw_slice/end_frame but no
request_frame (this happens after a split filter for example)


> +
> +static int poll_frame(AVFilterLink *outlink)
> +{
> +    TInterlaceContext *tinterlace = outlink->src->priv;
> +
> +    return tinterlace->frame_pending;
> +}

this doesnt look correct

[...]
-- 
Michael     GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB

I have never wished to cater to the crowd; for what I know they do not
approve, and what they approve I do not know. -- Epicurus
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: Digital signature
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20100926/c6646791/attachment.pgp>



More information about the ffmpeg-devel mailing list