Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4349 Serge 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/internal.h"
27
#include "libavutil/pixdesc.h"
28
#include "avfilter.h"
29
#include "internal.h"
30
#include "video.h"
31
 
32
typedef struct {
33
    int vsub;   ///< vertical chroma subsampling
34
} FlipContext;
35
 
36
static int config_input(AVFilterLink *link)
37
{
38
    FlipContext *flip = link->dst->priv;
39
    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(link->format);
40
 
41
    flip->vsub = desc->log2_chroma_h;
42
 
43
    return 0;
44
}
45
 
46
static AVFrame *get_video_buffer(AVFilterLink *link, int w, int h)
47
{
48
    FlipContext *flip = link->dst->priv;
49
    AVFrame *frame;
50
    int i;
51
 
52
    frame = ff_get_video_buffer(link->dst->outputs[0], w, h);
53
    if (!frame)
54
        return NULL;
55
 
56
    for (i = 0; i < 4; i ++) {
57
        int vsub = i == 1 || i == 2 ? flip->vsub : 0;
58
        int height = FF_CEIL_RSHIFT(h, vsub);
59
 
60
        if (frame->data[i]) {
61
            frame->data[i] += (height - 1) * frame->linesize[i];
62
            frame->linesize[i] = -frame->linesize[i];
63
        }
64
    }
65
 
66
    return frame;
67
}
68
 
69
static int filter_frame(AVFilterLink *link, AVFrame *frame)
70
{
71
    FlipContext *flip = link->dst->priv;
72
    int i;
73
 
74
    for (i = 0; i < 4; i ++) {
75
        int vsub = i == 1 || i == 2 ? flip->vsub : 0;
76
        int height = FF_CEIL_RSHIFT(link->h, vsub);
77
 
78
        if (frame->data[i]) {
79
            frame->data[i] += (height - 1) * frame->linesize[i];
80
            frame->linesize[i] = -frame->linesize[i];
81
        }
82
    }
83
 
84
    return ff_filter_frame(link->dst->outputs[0], frame);
85
}
86
static const AVFilterPad avfilter_vf_vflip_inputs[] = {
87
    {
88
        .name             = "default",
89
        .type             = AVMEDIA_TYPE_VIDEO,
90
        .get_video_buffer = get_video_buffer,
91
        .filter_frame     = filter_frame,
92
        .config_props     = config_input,
93
    },
94
    { NULL }
95
};
96
 
97
static const AVFilterPad avfilter_vf_vflip_outputs[] = {
98
    {
99
        .name = "default",
100
        .type = AVMEDIA_TYPE_VIDEO,
101
    },
102
    { NULL }
103
};
104
 
105
AVFilter avfilter_vf_vflip = {
106
    .name        = "vflip",
107
    .description = NULL_IF_CONFIG_SMALL("Flip the input video vertically."),
108
    .priv_size   = sizeof(FlipContext),
109
    .inputs      = avfilter_vf_vflip_inputs,
110
    .outputs     = avfilter_vf_vflip_outputs,
111
};