static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref)
{
    IlContext *il = inlink->dst->priv;
    AVFilterLink *outlink = inlink->dst->outputs[0];
    AVFilterBufferRef *out;
    int ret, comp;

    out = ff_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h);
    if (!out) {
        avfilter_unref_bufferp(&inpicref);
        return AVERROR(ENOMEM);
    }
    avfilter_copy_buffer_ref_props(out, inpicref);

    interleave(out->data[0], inpicref->data[0],
               il->linesize[0], inlink->h,
               out->linesize[0], inpicref->linesize[0],
               il->luma_mode, il->luma_swap);

    for (comp = 1; comp < (il->nb_planes - il->has_alpha); comp++) {
        interleave(out->data[comp], inpicref->data[comp],
                   il->linesize[comp], il->chroma_height,
                   out->linesize[comp], inpicref->linesize[comp],
                   il->chroma_mode, il->chroma_swap);
    }

    if (il->has_alpha) {
        int comp = il->nb_planes - 1;
        interleave(out->data[comp], inpicref->data[comp],
                   il->linesize[comp], inlink->h,
                   out->linesize[comp], inpicref->linesize[comp],
                   il->alpha_mode, il->alpha_swap);
    }

    ret = ff_filter_frame(outlink, out);
    avfilter_unref_bufferp(&inpicref);
    return ret;
}