ffmpeg / libavfilter / defaults.c @ 84cac86e
History | View | Annotate | Download (9.94 KB)
1 | bf4ce7a3 | Vitor Sessak | /*
|
---|---|---|---|
2 | * Filter layer - default implementations
|
||
3 | 3fa77bde | Stefano Sabatini | * Copyright (c) 2007 Bobby Bingham
|
4 | bf4ce7a3 | Vitor Sessak | *
|
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 | 63e8d976 | Stefano Sabatini | #include "libavcore/audioconvert.h" |
23 | 7be5b730 | Stefano Sabatini | #include "libavcore/imgutils.h" |
24 | ba7d6e79 | Stefano Sabatini | #include "libavcore/samplefmt.h" |
25 | bf4ce7a3 | Vitor Sessak | #include "avfilter.h" |
26 | 4723bc28 | Stefano Sabatini | #include "internal.h" |
27 | bf4ce7a3 | Vitor Sessak | |
28 | /* TODO: buffer pool. see comment for avfilter_default_get_video_buffer() */
|
||
29 | 4723bc28 | Stefano Sabatini | void ff_avfilter_default_free_buffer(AVFilterBuffer *ptr)
|
30 | bf4ce7a3 | Vitor Sessak | { |
31 | f0d77b20 | S.N. Hemanth Meenakshisundaram | av_free(ptr->data[0]);
|
32 | av_free(ptr); |
||
33 | bf4ce7a3 | Vitor Sessak | } |
34 | |||
35 | /* TODO: set the buffer's priv member to a context structure for the whole
|
||
36 | * filter chain. This will allow for a buffer pool instead of the constant
|
||
37 | * alloc & free cycle currently implemented. */
|
||
38 | ecc8dada | S.N. Hemanth Meenakshisundaram | AVFilterBufferRef *avfilter_default_get_video_buffer(AVFilterLink *link, int perms, int w, int h) |
39 | bf4ce7a3 | Vitor Sessak | { |
40 | 4da12e3b | Stefano Sabatini | int linesize[4]; |
41 | d38c340f | Stefano Sabatini | uint8_t *data[4];
|
42 | AVFilterBufferRef *picref = NULL;
|
||
43 | 65d4cab5 | Stefano Sabatini | |
44 | 4da12e3b | Stefano Sabatini | // +2 is needed for swscaler, +16 to be SIMD-friendly
|
45 | if (av_image_alloc(data, linesize, w, h, link->format, 16) < 0) |
||
46 | d38c340f | Stefano Sabatini | return NULL; |
47 | bf4ce7a3 | Vitor Sessak | |
48 | d38c340f | Stefano Sabatini | picref = avfilter_get_video_buffer_ref_from_arrays(data, linesize, |
49 | perms, w, h, link->format); |
||
50 | if (!picref) {
|
||
51 | 4da12e3b | Stefano Sabatini | av_free(data[0]);
|
52 | d38c340f | Stefano Sabatini | return NULL; |
53 | } |
||
54 | 65d4cab5 | Stefano Sabatini | |
55 | d38c340f | Stefano Sabatini | return picref;
|
56 | bf4ce7a3 | Vitor Sessak | } |
57 | |||
58 | ad2c9501 | S.N. Hemanth Meenakshisundaram | AVFilterBufferRef *avfilter_default_get_audio_buffer(AVFilterLink *link, int perms,
|
59 | 5d6e4c16 | Stefano Sabatini | enum AVSampleFormat sample_fmt, int size, |
60 | ad2c9501 | S.N. Hemanth Meenakshisundaram | int64_t channel_layout, int planar)
|
61 | { |
||
62 | AVFilterBuffer *samples = av_mallocz(sizeof(AVFilterBuffer));
|
||
63 | AVFilterBufferRef *ref = NULL;
|
||
64 | int i, sample_size, chans_nb, bufsize, per_channel_size, step_size = 0; |
||
65 | char *buf;
|
||
66 | |||
67 | if (!samples || !(ref = av_mallocz(sizeof(AVFilterBufferRef)))) |
||
68 | goto fail;
|
||
69 | |||
70 | ref->buf = samples; |
||
71 | ref->format = sample_fmt; |
||
72 | |||
73 | ref->audio = av_mallocz(sizeof(AVFilterBufferRefAudioProps));
|
||
74 | if (!ref->audio)
|
||
75 | goto fail;
|
||
76 | |||
77 | ref->audio->channel_layout = channel_layout; |
||
78 | ref->audio->size = size; |
||
79 | ref->audio->planar = planar; |
||
80 | |||
81 | /* make sure the buffer gets read permission or it's useless for output */
|
||
82 | ref->perms = perms | AV_PERM_READ; |
||
83 | |||
84 | samples->refcount = 1;
|
||
85 | 4723bc28 | Stefano Sabatini | samples->free = ff_avfilter_default_free_buffer; |
86 | ad2c9501 | S.N. Hemanth Meenakshisundaram | |
87 | ba7d6e79 | Stefano Sabatini | sample_size = av_get_bits_per_sample_fmt(sample_fmt) >>3;
|
88 | 63e8d976 | Stefano Sabatini | chans_nb = av_get_channel_layout_nb_channels(channel_layout); |
89 | ad2c9501 | S.N. Hemanth Meenakshisundaram | |
90 | per_channel_size = size/chans_nb; |
||
91 | a242ac36 | Stefano Sabatini | ref->audio->nb_samples = per_channel_size/sample_size; |
92 | ad2c9501 | S.N. Hemanth Meenakshisundaram | |
93 | /* Set the number of bytes to traverse to reach next sample of a particular channel:
|
||
94 | * For planar, this is simply the sample size.
|
||
95 | * For packed, this is the number of samples * sample_size.
|
||
96 | */
|
||
97 | for (i = 0; i < chans_nb; i++) |
||
98 | samples->linesize[i] = planar > 0 ? per_channel_size : sample_size;
|
||
99 | memset(&samples->linesize[chans_nb], 0, (8-chans_nb) * sizeof(samples->linesize[0])); |
||
100 | |||
101 | /* Calculate total buffer size, round to multiple of 16 to be SIMD friendly */
|
||
102 | bufsize = (size + 15)&~15; |
||
103 | buf = av_malloc(bufsize); |
||
104 | if (!buf)
|
||
105 | goto fail;
|
||
106 | |||
107 | /* For planar, set the start point of each channel's data within the buffer
|
||
108 | * For packed, set the start point of the entire buffer only
|
||
109 | */
|
||
110 | samples->data[0] = buf;
|
||
111 | if (buf && planar) {
|
||
112 | for (i = 1; i < chans_nb; i++) { |
||
113 | step_size += per_channel_size; |
||
114 | samples->data[i] = buf + step_size; |
||
115 | } |
||
116 | } else {
|
||
117 | for (i = 1; i < chans_nb; i++) |
||
118 | samples->data[i] = buf; |
||
119 | } |
||
120 | |||
121 | memset(&samples->data[chans_nb], 0, (8-chans_nb) * sizeof(samples->data[0])); |
||
122 | |||
123 | memcpy(ref->data, samples->data, sizeof(ref->data));
|
||
124 | memcpy(ref->linesize, samples->linesize, sizeof(ref->linesize));
|
||
125 | |||
126 | return ref;
|
||
127 | |||
128 | fail:
|
||
129 | if (ref && ref->audio)
|
||
130 | av_free(ref->audio); |
||
131 | av_free(ref); |
||
132 | av_free(samples); |
||
133 | return NULL; |
||
134 | } |
||
135 | |||
136 | f167a1a4 | Stefano Sabatini | void avfilter_default_start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref)
|
137 | bf4ce7a3 | Vitor Sessak | { |
138 | f167a1a4 | Stefano Sabatini | AVFilterLink *outlink = NULL;
|
139 | bf4ce7a3 | Vitor Sessak | |
140 | f167a1a4 | Stefano Sabatini | if (inlink->dst->output_count)
|
141 | outlink = inlink->dst->outputs[0];
|
||
142 | bf4ce7a3 | Vitor Sessak | |
143 | f167a1a4 | Stefano Sabatini | if (outlink) {
|
144 | outlink->out_buf = avfilter_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h); |
||
145 | avfilter_copy_buffer_ref_props(outlink->out_buf, picref); |
||
146 | avfilter_start_frame(outlink, avfilter_ref_buffer(outlink->out_buf, ~0));
|
||
147 | bf4ce7a3 | Vitor Sessak | } |
148 | } |
||
149 | |||
150 | f167a1a4 | Stefano Sabatini | void avfilter_default_draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) |
151 | b9609848 | Stefano Sabatini | { |
152 | f167a1a4 | Stefano Sabatini | AVFilterLink *outlink = NULL;
|
153 | b9609848 | Stefano Sabatini | |
154 | f167a1a4 | Stefano Sabatini | if (inlink->dst->output_count)
|
155 | outlink = inlink->dst->outputs[0];
|
||
156 | b9609848 | Stefano Sabatini | |
157 | f167a1a4 | Stefano Sabatini | if (outlink)
|
158 | avfilter_draw_slice(outlink, y, h, slice_dir); |
||
159 | b9609848 | Stefano Sabatini | } |
160 | |||
161 | f167a1a4 | Stefano Sabatini | void avfilter_default_end_frame(AVFilterLink *inlink)
|
162 | bf4ce7a3 | Vitor Sessak | { |
163 | f167a1a4 | Stefano Sabatini | AVFilterLink *outlink = NULL;
|
164 | bf4ce7a3 | Vitor Sessak | |
165 | f167a1a4 | Stefano Sabatini | if (inlink->dst->output_count)
|
166 | outlink = inlink->dst->outputs[0];
|
||
167 | bf4ce7a3 | Vitor Sessak | |
168 | f167a1a4 | Stefano Sabatini | avfilter_unref_buffer(inlink->cur_buf); |
169 | inlink->cur_buf = NULL;
|
||
170 | bf4ce7a3 | Vitor Sessak | |
171 | f167a1a4 | Stefano Sabatini | if (outlink) {
|
172 | if (outlink->out_buf) {
|
||
173 | avfilter_unref_buffer(outlink->out_buf); |
||
174 | outlink->out_buf = NULL;
|
||
175 | 552c0208 | Vitor Sessak | } |
176 | f167a1a4 | Stefano Sabatini | avfilter_end_frame(outlink); |
177 | bf4ce7a3 | Vitor Sessak | } |
178 | } |
||
179 | |||
180 | ad2c9501 | S.N. Hemanth Meenakshisundaram | /* FIXME: samplesref is same as link->cur_buf. Need to consider removing the redundant parameter. */
|
181 | f167a1a4 | Stefano Sabatini | void avfilter_default_filter_samples(AVFilterLink *inlink, AVFilterBufferRef *samplesref)
|
182 | ad2c9501 | S.N. Hemanth Meenakshisundaram | { |
183 | AVFilterLink *outlink = NULL;
|
||
184 | |||
185 | f167a1a4 | Stefano Sabatini | if (inlink->dst->output_count)
|
186 | outlink = inlink->dst->outputs[0];
|
||
187 | ad2c9501 | S.N. Hemanth Meenakshisundaram | |
188 | if (outlink) {
|
||
189 | f167a1a4 | Stefano Sabatini | outlink->out_buf = avfilter_default_get_audio_buffer(inlink, AV_PERM_WRITE, samplesref->format, |
190 | ad2c9501 | S.N. Hemanth Meenakshisundaram | samplesref->audio->size, |
191 | samplesref->audio->channel_layout, |
||
192 | samplesref->audio->planar); |
||
193 | outlink->out_buf->pts = samplesref->pts; |
||
194 | outlink->out_buf->audio->sample_rate = samplesref->audio->sample_rate; |
||
195 | avfilter_filter_samples(outlink, avfilter_ref_buffer(outlink->out_buf, ~0));
|
||
196 | avfilter_unref_buffer(outlink->out_buf); |
||
197 | outlink->out_buf = NULL;
|
||
198 | } |
||
199 | avfilter_unref_buffer(samplesref); |
||
200 | f167a1a4 | Stefano Sabatini | inlink->cur_buf = NULL;
|
201 | ad2c9501 | S.N. Hemanth Meenakshisundaram | } |
202 | |||
203 | bf4ce7a3 | Vitor Sessak | /**
|
204 | * default config_link() implementation for output video links to simplify
|
||
205 | * the implementation of one input one output video filters */
|
||
206 | int avfilter_default_config_output_link(AVFilterLink *link)
|
||
207 | { |
||
208 | 371cbff8 | Stefano Sabatini | if (link->src->input_count && link->src->inputs[0]) { |
209 | ad2c9501 | S.N. Hemanth Meenakshisundaram | if (link->type == AVMEDIA_TYPE_VIDEO) {
|
210 | link->w = link->src->inputs[0]->w;
|
||
211 | link->h = link->src->inputs[0]->h;
|
||
212 | 867ae7aa | Stefano Sabatini | link->time_base = link->src->inputs[0]->time_base;
|
213 | ad2c9501 | S.N. Hemanth Meenakshisundaram | } else if (link->type == AVMEDIA_TYPE_AUDIO) { |
214 | link->channel_layout = link->src->inputs[0]->channel_layout;
|
||
215 | link->sample_rate = link->src->inputs[0]->sample_rate;
|
||
216 | } |
||
217 | bf4ce7a3 | Vitor Sessak | } else {
|
218 | /* XXX: any non-simple filter which would cause this branch to be taken
|
||
219 | * really should implement its own config_props() for this link. */
|
||
220 | d0e4eba5 | Vitor Sessak | return -1; |
221 | bf4ce7a3 | Vitor Sessak | } |
222 | |||
223 | return 0; |
||
224 | } |
||
225 | |||
226 | /**
|
||
227 | e363730c | Vitor Sessak | * A helper for query_formats() which sets all links to the same list of
|
228 | * formats. If there are no links hooked to this filter, the list of formats is
|
||
229 | * freed.
|
||
230 | *
|
||
231 | * FIXME: this will need changed for filters with a mix of pad types
|
||
232 | * (video + audio, etc)
|
||
233 | */
|
||
234 | void avfilter_set_common_formats(AVFilterContext *ctx, AVFilterFormats *formats)
|
||
235 | bf4ce7a3 | Vitor Sessak | { |
236 | e363730c | Vitor Sessak | int count = 0, i; |
237 | |||
238 | 371cbff8 | Stefano Sabatini | for (i = 0; i < ctx->input_count; i++) { |
239 | if (ctx->inputs[i]) {
|
||
240 | e363730c | Vitor Sessak | avfilter_formats_ref(formats, &ctx->inputs[i]->out_formats); |
241 | 371cbff8 | Stefano Sabatini | count++; |
242 | e363730c | Vitor Sessak | } |
243 | } |
||
244 | 371cbff8 | Stefano Sabatini | for (i = 0; i < ctx->output_count; i++) { |
245 | if (ctx->outputs[i]) {
|
||
246 | e363730c | Vitor Sessak | avfilter_formats_ref(formats, &ctx->outputs[i]->in_formats); |
247 | 371cbff8 | Stefano Sabatini | count++; |
248 | e363730c | Vitor Sessak | } |
249 | } |
||
250 | |||
251 | 371cbff8 | Stefano Sabatini | if (!count) {
|
252 | e363730c | Vitor Sessak | av_free(formats->formats); |
253 | av_free(formats->refs); |
||
254 | av_free(formats); |
||
255 | } |
||
256 | } |
||
257 | |||
258 | int avfilter_default_query_formats(AVFilterContext *ctx)
|
||
259 | { |
||
260 | 12011922 | Stefano Sabatini | enum AVMediaType type = ctx->inputs && ctx->inputs [0] ? ctx->inputs [0]->type : |
261 | ctx->outputs && ctx->outputs[0] ? ctx->outputs[0]->type : |
||
262 | bdab614b | S.N. Hemanth Meenakshisundaram | AVMEDIA_TYPE_VIDEO; |
263 | |||
264 | avfilter_set_common_formats(ctx, avfilter_all_formats(type)); |
||
265 | e363730c | Vitor Sessak | return 0; |
266 | bf4ce7a3 | Vitor Sessak | } |
267 | |||
268 | ecc8dada | S.N. Hemanth Meenakshisundaram | void avfilter_null_start_frame(AVFilterLink *link, AVFilterBufferRef *picref)
|
269 | 91d1c741 | Bobby Bingham | { |
270 | avfilter_start_frame(link->dst->outputs[0], picref);
|
||
271 | } |
||
272 | |||
273 | void avfilter_null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir) |
||
274 | { |
||
275 | avfilter_draw_slice(link->dst->outputs[0], y, h, slice_dir);
|
||
276 | } |
||
277 | |||
278 | void avfilter_null_end_frame(AVFilterLink *link)
|
||
279 | { |
||
280 | avfilter_end_frame(link->dst->outputs[0]);
|
||
281 | } |
||
282 | |||
283 | ad2c9501 | S.N. Hemanth Meenakshisundaram | void avfilter_null_filter_samples(AVFilterLink *link, AVFilterBufferRef *samplesref)
|
284 | { |
||
285 | avfilter_filter_samples(link->dst->outputs[0], samplesref);
|
||
286 | } |
||
287 | |||
288 | ecc8dada | S.N. Hemanth Meenakshisundaram | AVFilterBufferRef *avfilter_null_get_video_buffer(AVFilterLink *link, int perms, int w, int h) |
289 | 91d1c741 | Bobby Bingham | { |
290 | return avfilter_get_video_buffer(link->dst->outputs[0], perms, w, h); |
||
291 | } |
||
292 | |||
293 | ad2c9501 | S.N. Hemanth Meenakshisundaram | AVFilterBufferRef *avfilter_null_get_audio_buffer(AVFilterLink *link, int perms,
|
294 | 5d6e4c16 | Stefano Sabatini | enum AVSampleFormat sample_fmt, int size, |
295 | ad2c9501 | S.N. Hemanth Meenakshisundaram | int64_t channel_layout, int packed)
|
296 | { |
||
297 | return avfilter_get_audio_buffer(link->dst->outputs[0], perms, sample_fmt, |
||
298 | size, channel_layout, packed); |
||
299 | } |