ffmpeg / libavfilter / vf_hflip.c @ c90626b2
History | View | Annotate | Download (5.68 KB)
1 |
/*
|
---|---|
2 |
* Copyright (c) 2007 Benoit Fouet
|
3 |
* Copyright (c) 2010 Stefano Sabatini
|
4 |
*
|
5 |
* This file is part of Libav.
|
6 |
*
|
7 |
* Libav 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 |
* Libav 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 Libav; if not, write to the Free Software
|
19 |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
20 |
*/
|
21 |
|
22 |
/**
|
23 |
* @file
|
24 |
* horizontal flip filter
|
25 |
*/
|
26 |
|
27 |
#include "avfilter.h" |
28 |
#include "libavutil/pixdesc.h" |
29 |
#include "libavutil/intreadwrite.h" |
30 |
#include "libavutil/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_BGR48BE, PIX_FMT_BGR48LE, |
42 |
PIX_FMT_ARGB, PIX_FMT_RGBA, |
43 |
PIX_FMT_ABGR, PIX_FMT_BGRA, |
44 |
PIX_FMT_RGB24, PIX_FMT_BGR24, |
45 |
PIX_FMT_RGB565BE, PIX_FMT_RGB565LE, |
46 |
PIX_FMT_RGB555BE, PIX_FMT_RGB555LE, |
47 |
PIX_FMT_BGR565BE, PIX_FMT_BGR565LE, |
48 |
PIX_FMT_BGR555BE, PIX_FMT_BGR555LE, |
49 |
PIX_FMT_GRAY16BE, PIX_FMT_GRAY16LE, |
50 |
PIX_FMT_YUV420P16LE, PIX_FMT_YUV420P16BE, |
51 |
PIX_FMT_YUV422P16LE, PIX_FMT_YUV422P16BE, |
52 |
PIX_FMT_YUV444P16LE, PIX_FMT_YUV444P16BE, |
53 |
PIX_FMT_YUV444P, PIX_FMT_YUV422P, |
54 |
PIX_FMT_YUV420P, PIX_FMT_YUV411P, |
55 |
PIX_FMT_YUV410P, PIX_FMT_YUV440P, |
56 |
PIX_FMT_YUVJ444P, PIX_FMT_YUVJ422P, |
57 |
PIX_FMT_YUVJ420P, PIX_FMT_YUVJ440P, |
58 |
PIX_FMT_YUVA420P, |
59 |
PIX_FMT_RGB8, PIX_FMT_BGR8, |
60 |
PIX_FMT_RGB4_BYTE, PIX_FMT_BGR4_BYTE, |
61 |
PIX_FMT_PAL8, PIX_FMT_GRAY8, |
62 |
PIX_FMT_NONE |
63 |
}; |
64 |
|
65 |
avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts)); |
66 |
return 0; |
67 |
} |
68 |
|
69 |
static int config_props(AVFilterLink *inlink) |
70 |
{ |
71 |
FlipContext *flip = inlink->dst->priv; |
72 |
const AVPixFmtDescriptor *pix_desc = &av_pix_fmt_descriptors[inlink->format];
|
73 |
|
74 |
av_image_fill_max_pixsteps(flip->max_step, NULL, pix_desc);
|
75 |
flip->hsub = av_pix_fmt_descriptors[inlink->format].log2_chroma_w; |
76 |
flip->vsub = av_pix_fmt_descriptors[inlink->format].log2_chroma_h; |
77 |
|
78 |
return 0; |
79 |
} |
80 |
|
81 |
static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) |
82 |
{ |
83 |
FlipContext *flip = inlink->dst->priv; |
84 |
AVFilterBufferRef *inpic = inlink->cur_buf; |
85 |
AVFilterBufferRef *outpic = inlink->dst->outputs[0]->out_buf;
|
86 |
uint8_t *inrow, *outrow; |
87 |
int i, j, plane, step, hsub, vsub;
|
88 |
|
89 |
for (plane = 0; plane < 4 && inpic->data[plane]; plane++) { |
90 |
step = flip->max_step[plane]; |
91 |
hsub = (plane == 1 || plane == 2) ? flip->hsub : 0; |
92 |
vsub = (plane == 1 || plane == 2) ? flip->vsub : 0; |
93 |
|
94 |
outrow = outpic->data[plane] + (y>>vsub) * outpic->linesize[plane]; |
95 |
inrow = inpic ->data[plane] + (y>>vsub) * inpic ->linesize[plane] + ((inlink->w >> hsub) - 1) * step;
|
96 |
for (i = 0; i < h>>vsub; i++) { |
97 |
switch (step) {
|
98 |
case 1: |
99 |
{ |
100 |
for (j = 0; j < (inlink->w >> hsub); j++) |
101 |
outrow[j] = inrow[-j]; |
102 |
} |
103 |
break;
|
104 |
|
105 |
case 2: |
106 |
{ |
107 |
uint16_t *outrow16 = (uint16_t *)outrow; |
108 |
uint16_t * inrow16 = (uint16_t *) inrow; |
109 |
for (j = 0; j < (inlink->w >> hsub); j++) |
110 |
outrow16[j] = inrow16[-j]; |
111 |
} |
112 |
break;
|
113 |
|
114 |
case 3: |
115 |
{ |
116 |
uint8_t *in = inrow; |
117 |
uint8_t *out = outrow; |
118 |
for (j = 0; j < (inlink->w >> hsub); j++, out += 3, in -= 3) { |
119 |
int32_t v = AV_RB24(in); |
120 |
AV_WB24(out, v); |
121 |
} |
122 |
} |
123 |
break;
|
124 |
|
125 |
case 4: |
126 |
{ |
127 |
uint32_t *outrow32 = (uint32_t *)outrow; |
128 |
uint32_t * inrow32 = (uint32_t *) inrow; |
129 |
for (j = 0; j < (inlink->w >> hsub); j++) |
130 |
outrow32[j] = inrow32[-j]; |
131 |
} |
132 |
break;
|
133 |
|
134 |
default:
|
135 |
for (j = 0; j < (inlink->w >> hsub); j++) |
136 |
memcpy(outrow + j*step, inrow - j*step, step); |
137 |
} |
138 |
|
139 |
inrow += inpic ->linesize[plane]; |
140 |
outrow += outpic->linesize[plane]; |
141 |
} |
142 |
} |
143 |
|
144 |
avfilter_draw_slice(inlink->dst->outputs[0], y, h, slice_dir);
|
145 |
} |
146 |
|
147 |
AVFilter avfilter_vf_hflip = { |
148 |
.name = "hflip",
|
149 |
.description = NULL_IF_CONFIG_SMALL("Horizontally flip the input video."),
|
150 |
.priv_size = sizeof(FlipContext),
|
151 |
.query_formats = query_formats, |
152 |
|
153 |
.inputs = (AVFilterPad[]) {{ .name = "default",
|
154 |
.type = AVMEDIA_TYPE_VIDEO, |
155 |
.draw_slice = draw_slice, |
156 |
.config_props = config_props, |
157 |
.min_perms = AV_PERM_READ, }, |
158 |
{ .name = NULL}},
|
159 |
.outputs = (AVFilterPad[]) {{ .name = "default",
|
160 |
.type = AVMEDIA_TYPE_VIDEO, }, |
161 |
{ .name = NULL}},
|
162 |
}; |