1/* 2 * copyright (c) 2007 Bobby Bingham 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 * video vertical flip filter 24 */ 25 26#include "libavutil/pixdesc.h" 27#include "avfilter.h" 28 29typedef struct { 30 int vsub; ///< vertical chroma subsampling 31} FlipContext; 32 33static int config_input(AVFilterLink *link) 34{ 35 FlipContext *flip = link->dst->priv; 36 37 flip->vsub = av_pix_fmt_descriptors[link->format].log2_chroma_h; 38 39 return 0; 40} 41 42static AVFilterPicRef *get_video_buffer(AVFilterLink *link, int perms, 43 int w, int h) 44{ 45 FlipContext *flip = link->dst->priv; 46 int i; 47 48 AVFilterPicRef *picref = avfilter_get_video_buffer(link->dst->outputs[0], 49 perms, w, h); 50 51 for (i = 0; i < 4; i ++) { 52 int vsub = i == 1 || i == 2 ? flip->vsub : 0; 53 54 if (picref->data[i]) { 55 picref->data[i] += ((h >> vsub)-1) * picref->linesize[i]; 56 picref->linesize[i] = -picref->linesize[i]; 57 } 58 } 59 60 return picref; 61} 62 63static void start_frame(AVFilterLink *link, AVFilterPicRef *picref) 64{ 65 FlipContext *flip = link->dst->priv; 66 int i; 67 68 for (i = 0; i < 4; i ++) { 69 int vsub = i == 1 || i == 2 ? flip->vsub : 0; 70 71 if (picref->data[i]) { 72 picref->data[i] += ((link->h >> vsub)-1) * picref->linesize[i]; 73 picref->linesize[i] = -picref->linesize[i]; 74 } 75 } 76 77 avfilter_start_frame(link->dst->outputs[0], picref); 78} 79 80static void draw_slice(AVFilterLink *link, int y, int h, int slice_dir) 81{ 82 AVFilterContext *ctx = link->dst; 83 84 avfilter_draw_slice(ctx->outputs[0], link->h - (y+h), h, -1 * slice_dir); 85} 86 87AVFilter avfilter_vf_vflip = { 88 .name = "vflip", 89 .description = NULL_IF_CONFIG_SMALL("Flip the input video vertically."), 90 91 .priv_size = sizeof(FlipContext), 92 93 .inputs = (AVFilterPad[]) {{ .name = "default", 94 .type = AVMEDIA_TYPE_VIDEO, 95 .get_video_buffer = get_video_buffer, 96 .start_frame = start_frame, 97 .draw_slice = draw_slice, 98 .end_frame = avfilter_null_end_frame, 99 .config_props = config_input, }, 100 { .name = NULL}}, 101 .outputs = (AVFilterPad[]) {{ .name = "default", 102 .type = AVMEDIA_TYPE_VIDEO, }, 103 { .name = NULL}}, 104}; 105