1/* 2 * Copyright (c) 2012 Stefano Sabatini 3 * 4 * This file is part of FFmpeg. 5 * 6 * FFmpeg is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * FFmpeg is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with FFmpeg; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 */ 20 21/** 22 * @file 23 * set field order 24 */ 25 26#include "libavutil/opt.h" 27#include "avfilter.h" 28#include "internal.h" 29#include "video.h" 30 31enum SetFieldMode { 32 MODE_AUTO = -1, 33 MODE_BFF, 34 MODE_TFF, 35 MODE_PROG, 36}; 37 38typedef struct { 39 const AVClass *class; 40 enum SetFieldMode mode; 41} SetFieldContext; 42 43#define OFFSET(x) offsetof(SetFieldContext, x) 44#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM 45 46static const AVOption setfield_options[] = { 47 {"mode", "select interlace mode", OFFSET(mode), AV_OPT_TYPE_INT, {.i64=MODE_AUTO}, -1, MODE_PROG, FLAGS, "mode"}, 48 {"auto", "keep the same input field", 0, AV_OPT_TYPE_CONST, {.i64=MODE_AUTO}, INT_MIN, INT_MAX, FLAGS, "mode"}, 49 {"bff", "mark as bottom-field-first", 0, AV_OPT_TYPE_CONST, {.i64=MODE_BFF}, INT_MIN, INT_MAX, FLAGS, "mode"}, 50 {"tff", "mark as top-field-first", 0, AV_OPT_TYPE_CONST, {.i64=MODE_TFF}, INT_MIN, INT_MAX, FLAGS, "mode"}, 51 {"prog", "mark as progressive", 0, AV_OPT_TYPE_CONST, {.i64=MODE_PROG}, INT_MIN, INT_MAX, FLAGS, "mode"}, 52 {NULL} 53}; 54 55AVFILTER_DEFINE_CLASS(setfield); 56 57static int filter_frame(AVFilterLink *inlink, AVFrame *picref) 58{ 59 SetFieldContext *setfield = inlink->dst->priv; 60 61 if (setfield->mode == MODE_PROG) { 62 picref->interlaced_frame = 0; 63 } else if (setfield->mode != MODE_AUTO) { 64 picref->interlaced_frame = 1; 65 picref->top_field_first = setfield->mode; 66 } 67 return ff_filter_frame(inlink->dst->outputs[0], picref); 68} 69 70static const AVFilterPad setfield_inputs[] = { 71 { 72 .name = "default", 73 .type = AVMEDIA_TYPE_VIDEO, 74 .filter_frame = filter_frame, 75 }, 76 { NULL } 77}; 78 79static const AVFilterPad setfield_outputs[] = { 80 { 81 .name = "default", 82 .type = AVMEDIA_TYPE_VIDEO, 83 }, 84 { NULL } 85}; 86 87AVFilter ff_vf_setfield = { 88 .name = "setfield", 89 .description = NULL_IF_CONFIG_SMALL("Force field for the output video frame."), 90 .priv_size = sizeof(SetFieldContext), 91 .priv_class = &setfield_class, 92 .inputs = setfield_inputs, 93 .outputs = setfield_outputs, 94}; 95