ffmpeg / libavfilter / vf_hflip.c @ a6ddf8bf
History | View | Annotate | Download (5.64 KB)
1 |
/*
|
---|---|
2 |
* Copyright (c) 2007 Benoit Fouet
|
3 |
* Copyright (c) 2010 Stefano Sabatini
|
4 |
*
|
5 |
* This file is part of FFmpeg.
|
6 |
*
|
7 |
* FFmpeg is free software; you can redistribute it and/or
|
8 |
* modify it under the terms of the GNU Lesser General Public
|
9 |
* License as published by the Free Software Foundation; either
|
10 |
* version 2.1 of the License, or (at your option) any later version.
|
11 |
*
|
12 |
* FFmpeg is distributed in the hope that it will be useful,
|
13 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
15 |
* Lesser General Public License for more details.
|
16 |
*
|
17 |
* You should have received a copy of the GNU Lesser General Public
|
18 |
* License along with FFmpeg; if not, write to the Free Software
|
19 |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
20 |
*/
|
21 |
|
22 |
/**
|
23 |
* @flip
|
24 |
* horizontal flip filter
|
25 |
*/
|
26 |
|
27 |
#include "avfilter.h" |
28 |
#include "libavutil/pixdesc.h" |
29 |
#include "libavutil/intreadwrite.h" |
30 |
#include "libavcore/imgutils.h" |
31 |
|
32 |
typedef struct { |
33 |
int max_step[4]; ///< max pixel step for each plane, expressed as a number of bytes |
34 |
int hsub, vsub; ///< chroma subsampling |
35 |
} FlipContext; |
36 |
|
37 |
static int query_formats(AVFilterContext *ctx) |
38 |
{ |
39 |
static const enum PixelFormat pix_fmts[] = { |
40 |
PIX_FMT_RGB48BE, PIX_FMT_RGB48LE, |
41 |
PIX_FMT_ARGB, PIX_FMT_RGBA, |
42 |
PIX_FMT_ABGR, PIX_FMT_BGRA, |
43 |
PIX_FMT_RGB24, PIX_FMT_BGR24, |
44 |
PIX_FMT_RGB565BE, PIX_FMT_RGB565LE, |
45 |
PIX_FMT_RGB555BE, PIX_FMT_RGB555LE, |
46 |
PIX_FMT_BGR565BE, PIX_FMT_BGR565LE, |
47 |
PIX_FMT_BGR555BE, PIX_FMT_BGR555LE, |
48 |
PIX_FMT_GRAY16BE, PIX_FMT_GRAY16LE, |
49 |
PIX_FMT_YUV420P16LE, PIX_FMT_YUV420P16BE, |
50 |
PIX_FMT_YUV422P16LE, PIX_FMT_YUV422P16BE, |
51 |
PIX_FMT_YUV444P16LE, PIX_FMT_YUV444P16BE, |
52 |
PIX_FMT_YUV444P, PIX_FMT_YUV422P, |
53 |
PIX_FMT_YUV420P, PIX_FMT_YUV411P, |
54 |
PIX_FMT_YUV410P, PIX_FMT_YUV440P, |
55 |
PIX_FMT_YUVJ444P, PIX_FMT_YUVJ422P, |
56 |
PIX_FMT_YUVJ420P, PIX_FMT_YUVJ440P, |
57 |
PIX_FMT_YUVA420P, |
58 |
PIX_FMT_RGB8, PIX_FMT_BGR8, |
59 |
PIX_FMT_RGB4_BYTE, PIX_FMT_BGR4_BYTE, |
60 |
PIX_FMT_PAL8, PIX_FMT_GRAY8, |
61 |
PIX_FMT_NONE |
62 |
}; |
63 |
|
64 |
avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts)); |
65 |
return 0; |
66 |
} |
67 |
|
68 |
static int config_props(AVFilterLink *inlink) |
69 |
{ |
70 |
FlipContext *flip = inlink->dst->priv; |
71 |
const AVPixFmtDescriptor *pix_desc = &av_pix_fmt_descriptors[inlink->format];
|
72 |
|
73 |
av_fill_image_max_pixstep(flip->max_step, NULL, pix_desc);
|
74 |
flip->hsub = av_pix_fmt_descriptors[inlink->format].log2_chroma_w; |
75 |
flip->vsub = av_pix_fmt_descriptors[inlink->format].log2_chroma_h; |
76 |
|
77 |
return 0; |
78 |
} |
79 |
|
80 |
static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) |
81 |
{ |
82 |
FlipContext *flip = inlink->dst->priv; |
83 |
AVFilterBufferRef *inpic = inlink->cur_buf; |
84 |
AVFilterBufferRef *outpic = inlink->dst->outputs[0]->out_buf;
|
85 |
uint8_t *inrow, *outrow; |
86 |
int i, j, plane, step, hsub, vsub;
|
87 |
|
88 |
for (plane = 0; plane < 4 && inpic->data[plane]; plane++) { |
89 |
step = flip->max_step[plane]; |
90 |
hsub = (plane == 1 || plane == 2) ? flip->hsub : 0; |
91 |
vsub = (plane == 1 || plane == 2) ? flip->vsub : 0; |
92 |
|
93 |
outrow = outpic->data[plane] + (y>>vsub) * outpic->linesize[plane]; |
94 |
inrow = inpic ->data[plane] + (y>>vsub) * inpic ->linesize[plane] + ((inlink->w >> hsub) - 1) * step;
|
95 |
for (i = 0; i < h>>vsub; i++) { |
96 |
switch (step) {
|
97 |
case 1: |
98 |
{ |
99 |
for (j = 0; j < (inlink->w >> hsub); j++) |
100 |
outrow[j] = inrow[-j]; |
101 |
} |
102 |
break;
|
103 |
|
104 |
case 2: |
105 |
{ |
106 |
uint16_t *outrow16 = (uint16_t *)outrow; |
107 |
uint16_t * inrow16 = (uint16_t *) inrow; |
108 |
for (j = 0; j < (inlink->w >> hsub); j++) |
109 |
outrow16[j] = inrow16[-j]; |
110 |
} |
111 |
break;
|
112 |
|
113 |
case 3: |
114 |
{ |
115 |
uint8_t *in = inrow; |
116 |
uint8_t *out = outrow; |
117 |
for (j = 0; j < (inlink->w >> hsub); j++, out += 3, in -= 3) { |
118 |
int32_t v = AV_RB24(in); |
119 |
AV_WB24(out, v); |
120 |
} |
121 |
} |
122 |
break;
|
123 |
|
124 |
case 4: |
125 |
{ |
126 |
uint32_t *outrow32 = (uint32_t *)outrow; |
127 |
uint32_t * inrow32 = (uint32_t *) inrow; |
128 |
for (j = 0; j < (inlink->w >> hsub); j++) |
129 |
outrow32[j] = inrow32[-j]; |
130 |
} |
131 |
break;
|
132 |
|
133 |
default:
|
134 |
for (j = 0; j < (inlink->w >> hsub); j++) |
135 |
memcpy(outrow + j*step, inrow - j*step, step); |
136 |
} |
137 |
|
138 |
inrow += inpic ->linesize[plane]; |
139 |
outrow += outpic->linesize[plane]; |
140 |
} |
141 |
} |
142 |
|
143 |
avfilter_draw_slice(inlink->dst->outputs[0], y, h, slice_dir);
|
144 |
} |
145 |
|
146 |
AVFilter avfilter_vf_hflip = { |
147 |
.name = "hflip",
|
148 |
.description = NULL_IF_CONFIG_SMALL("Horizontally flip the input video."),
|
149 |
.priv_size = sizeof(FlipContext),
|
150 |
.query_formats = query_formats, |
151 |
|
152 |
.inputs = (AVFilterPad[]) {{ .name = "default",
|
153 |
.type = AVMEDIA_TYPE_VIDEO, |
154 |
.draw_slice = draw_slice, |
155 |
.config_props = config_props, |
156 |
.min_perms = AV_PERM_READ, }, |
157 |
{ .name = NULL}},
|
158 |
.outputs = (AVFilterPad[]) {{ .name = "default",
|
159 |
.type = AVMEDIA_TYPE_VIDEO, }, |
160 |
{ .name = NULL}},
|
161 |
}; |