libavfilter/vf_setfield.c
b7d45d0b
 /*
  * Copyright (c) 2012 Stefano Sabatini
  *
  * This file is part of FFmpeg.
  *
  * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
  * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
  * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 /**
  * @file
  * set field order
  */
 
642a60f1
 #include "libavutil/opt.h"
b7d45d0b
 #include "avfilter.h"
7f154bd5
 #include "internal.h"
c9e183b4
 #include "video.h"
b7d45d0b
 
459414b4
 enum SetFieldMode {
     MODE_AUTO = -1,
     MODE_BFF,
     MODE_TFF,
     MODE_PROG,
 };
 
b7d45d0b
 typedef struct {
642a60f1
     const AVClass *class;
459414b4
     enum SetFieldMode mode;
b7d45d0b
 } SetFieldContext;
 
642a60f1
 #define OFFSET(x) offsetof(SetFieldContext, x)
 #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
 
 static const AVOption setfield_options[] = {
     {"mode", "select interlace mode", OFFSET(mode), AV_OPT_TYPE_INT, {.i64=MODE_AUTO}, -1, MODE_PROG, FLAGS, "mode"},
     {"auto", "keep the same input field",  0, AV_OPT_TYPE_CONST, {.i64=MODE_AUTO}, INT_MIN, INT_MAX, FLAGS, "mode"},
     {"bff",  "mark as bottom-field-first", 0, AV_OPT_TYPE_CONST, {.i64=MODE_BFF},  INT_MIN, INT_MAX, FLAGS, "mode"},
     {"tff",  "mark as top-field-first",    0, AV_OPT_TYPE_CONST, {.i64=MODE_TFF},  INT_MIN, INT_MAX, FLAGS, "mode"},
     {"prog", "mark as progressive",        0, AV_OPT_TYPE_CONST, {.i64=MODE_PROG}, INT_MIN, INT_MAX, FLAGS, "mode"},
     {NULL}
 };
 
 AVFILTER_DEFINE_CLASS(setfield);
 
a05a44e2
 static int filter_frame(AVFilterLink *inlink, AVFrame *picref)
b7d45d0b
 {
     SetFieldContext *setfield = inlink->dst->priv;
 
459414b4
     if (setfield->mode == MODE_PROG) {
a05a44e2
         picref->interlaced_frame = 0;
459414b4
     } else if (setfield->mode != MODE_AUTO) {
a05a44e2
         picref->interlaced_frame = 1;
         picref->top_field_first = setfield->mode;
b7d45d0b
     }
7f154bd5
     return ff_filter_frame(inlink->dst->outputs[0], picref);
b7d45d0b
 }
 
2d9d4440
 static const AVFilterPad setfield_inputs[] = {
     {
         .name             = "default",
         .type             = AVMEDIA_TYPE_VIDEO,
         .get_video_buffer = ff_null_get_video_buffer,
7f154bd5
         .filter_frame     = filter_frame,
2d9d4440
     },
     { NULL }
 };
 
 static const AVFilterPad setfield_outputs[] = {
     {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
     { NULL }
 };
 
b7d45d0b
 AVFilter avfilter_vf_setfield = {
     .name      = "setfield",
     .description = NULL_IF_CONFIG_SMALL("Force field for the output video frame."),
     .priv_size = sizeof(SetFieldContext),
2d9d4440
     .inputs    = setfield_inputs,
     .outputs   = setfield_outputs,
642a60f1
     .priv_class = &setfield_class,
b7d45d0b
 };