[FFmpeg-devel] [PATCH 4/4] lavfi/fieldorder: work with non writtable frames too

Stefano Sabatini stefasab at gmail.com
Fri Sep 6 20:03:07 CEST 2013


On date Friday 2013-09-06 14:45:31 +0000, Paul B Mahol encoded:
> Signed-off-by: Paul B Mahol <onemda at gmail.com>
> ---
>  libavfilter/vf_fieldorder.c | 46 +++++++++++++++++++++++++++++++--------------
>  1 file changed, 32 insertions(+), 14 deletions(-)
> 
> diff --git a/libavfilter/vf_fieldorder.c b/libavfilter/vf_fieldorder.c
> index 15204e3..92c222c 100644
> --- a/libavfilter/vf_fieldorder.c
> +++ b/libavfilter/vf_fieldorder.c
> @@ -79,21 +79,35 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
>      AVFilterContext   *ctx     = inlink->dst;
>      FieldOrderContext *s       = ctx->priv;
>      AVFilterLink      *outlink = ctx->outputs[0];
> -    int h, plane, line_step, line_size, line;
> -    uint8_t *data;
> +    int h, plane, src_line_step, dst_line_step, line_size, line;
> +    uint8_t *dst, *src;
> +    AVFrame *out;
>  
>      if (!frame->interlaced_frame ||
>          frame->top_field_first == s->dst_tff)
>          return ff_filter_frame(outlink, frame);
>  
> +    if (av_frame_is_writable(frame)) {
> +        out = frame;
> +    } else {
> +        out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
> +        if (!out) {
> +            av_frame_free(&frame);
> +            return AVERROR(ENOMEM);
> +        }
> +        av_frame_copy_props(out, frame);
> +    }
> +
>      av_dlog(ctx,
>              "picture will move %s one line\n",
>              s->dst_tff ? "up" : "down");
>      h = frame->height;
>      for (plane = 0; plane < 4 && frame->data[plane] && frame->linesize[plane]; plane++) {
> -        line_step = frame->linesize[plane];
> +        dst_line_step = out->linesize[plane];
> +        src_line_step = frame->linesize[plane];
>          line_size = s->line_size[plane];
> -        data = frame->data[plane];
> +        dst = out->data[plane];
> +        src = frame->data[plane];
>          if (s->dst_tff) {
>              /** Move every line up one line, working from
>               *  the top to the bottom of the frame.
> @@ -102,11 +116,12 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
>               *  penultimate line from that field. */
>              for (line = 0; line < h; line++) {
>                  if (1 + line < frame->height) {
> -                    memcpy(data, data + line_step, line_size);
> +                    memcpy(dst, src + src_line_step, line_size);
>                  } else {
> -                    memcpy(data, data - line_step - line_step, line_size);
> +                    memcpy(dst, src - 2 * src_line_step, line_size);
>                  }
> -                data += line_step;
> +                dst += dst_line_step;
> +                src += src_line_step;
>              }
>          } else {
>              /** Move every line down one line, working from
> @@ -114,20 +129,24 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
>               *  The original bottom line is lost.
>               *  The new first line is created as a copy of the
>               *  second line from that field. */
> -            data += (h - 1) * line_step;
> +            dst += (h - 1) * dst_line_step;
> +            src += (h - 1) * src_line_step;
>              for (line = h - 1; line >= 0 ; line--) {
>                  if (line > 0) {
> -                    memcpy(data, data - line_step, line_size);
> +                    memcpy(dst, src - src_line_step, line_size);
>                  } else {
> -                    memcpy(data, data + line_step + line_step, line_size);
> +                    memcpy(dst, src + 2 * src_line_step, line_size);
>                  }
> -                data -= line_step;
> +                dst -= dst_line_step;
> +                src -= src_line_step;
>              }
>          }
>      }
> -    frame->top_field_first = s->dst_tff;
> +    out->top_field_first = s->dst_tff;
>  
> -    return ff_filter_frame(outlink, frame);
> +    if (frame != out)
> +        av_frame_free(&frame);
> +    return ff_filter_frame(outlink, out);
>  }
>  
>  #define OFFSET(x) offsetof(FieldOrderContext, x)
> @@ -148,7 +167,6 @@ static const AVFilterPad avfilter_vf_fieldorder_inputs[] = {
>          .type             = AVMEDIA_TYPE_VIDEO,
>          .config_props     = config_input,
>          .filter_frame     = filter_frame,
> -        .needs_writable   = 1,

All four patches look good to me, assuming they have been tested, thanks.
-- 
FFmpeg = Frightening and Freak Minimalistic Pacific Elastic Gospel


More information about the ffmpeg-devel mailing list