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,
 };
 
ed93ed5e
 typedef struct SetFieldContext {
642a60f1
     const AVClass *class;
3a23ec0d
     int mode;                   ///< SetFieldMode
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[] = {
     {
b211607b
         .name         = "default",
         .type         = AVMEDIA_TYPE_VIDEO,
         .filter_frame = filter_frame,
2d9d4440
     },
     { NULL }
 };
 
 static const AVFilterPad setfield_outputs[] = {
     {
         .name = "default",
         .type = AVMEDIA_TYPE_VIDEO,
     },
     { NULL }
 };
 
325f6e0a
 AVFilter ff_vf_setfield = {
b211607b
     .name        = "setfield",
b7d45d0b
     .description = NULL_IF_CONFIG_SMALL("Force field for the output video frame."),
b211607b
     .priv_size   = sizeof(SetFieldContext),
     .priv_class  = &setfield_class,
     .inputs      = setfield_inputs,
     .outputs     = setfield_outputs,
b7d45d0b
 };