blob: b0159cff00e1142af1a1c8436682bc9fd370e2c3
1 | /* |
2 | * This file is part of FFmpeg. |
3 | * |
4 | * FFmpeg is free software; you can redistribute it and/or |
5 | * modify it under the terms of the GNU Lesser General Public |
6 | * License as published by the Free Software Foundation; either |
7 | * version 2.1 of the License, or (at your option) any later version. |
8 | * |
9 | * FFmpeg is distributed in the hope that it will be useful, |
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
12 | * Lesser General Public License for more details. |
13 | * |
14 | * You should have received a copy of the GNU Lesser General Public |
15 | * License along with FFmpeg; if not, write to the Free Software |
16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
17 | */ |
18 | |
19 | /** |
20 | * @file |
21 | * copy video filter |
22 | */ |
23 | |
24 | #include "libavutil/imgutils.h" |
25 | #include "libavutil/internal.h" |
26 | #include "avfilter.h" |
27 | #include "internal.h" |
28 | #include "video.h" |
29 | |
30 | static int query_formats(AVFilterContext *ctx) |
31 | { |
32 | AVFilterFormats *formats = NULL; |
33 | int fmt; |
34 | |
35 | for (fmt = 0; av_pix_fmt_desc_get(fmt); fmt++) { |
36 | const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(fmt); |
37 | int ret; |
38 | if (desc->flags & AV_PIX_FMT_FLAG_HWACCEL) |
39 | continue; |
40 | if ((ret = ff_add_format(&formats, fmt)) < 0) |
41 | return ret; |
42 | } |
43 | |
44 | return ff_set_common_formats(ctx, formats); |
45 | } |
46 | |
47 | static int filter_frame(AVFilterLink *inlink, AVFrame *in) |
48 | { |
49 | AVFilterLink *outlink = inlink->dst->outputs[0]; |
50 | AVFrame *out = ff_get_video_buffer(outlink, in->width, in->height); |
51 | |
52 | if (!out) { |
53 | av_frame_free(&in); |
54 | return AVERROR(ENOMEM); |
55 | } |
56 | av_frame_copy_props(out, in); |
57 | av_frame_copy(out, in); |
58 | av_frame_free(&in); |
59 | return ff_filter_frame(outlink, out); |
60 | } |
61 | |
62 | static const AVFilterPad avfilter_vf_copy_inputs[] = { |
63 | { |
64 | .name = "default", |
65 | .type = AVMEDIA_TYPE_VIDEO, |
66 | .filter_frame = filter_frame, |
67 | }, |
68 | { NULL } |
69 | }; |
70 | |
71 | static const AVFilterPad avfilter_vf_copy_outputs[] = { |
72 | { |
73 | .name = "default", |
74 | .type = AVMEDIA_TYPE_VIDEO, |
75 | }, |
76 | { NULL } |
77 | }; |
78 | |
79 | AVFilter ff_vf_copy = { |
80 | .name = "copy", |
81 | .description = NULL_IF_CONFIG_SMALL("Copy the input video unchanged to the output."), |
82 | .inputs = avfilter_vf_copy_inputs, |
83 | .outputs = avfilter_vf_copy_outputs, |
84 | .query_formats = query_formats, |
85 | }; |
86 |