3 * Copyright (c) 2007 Bobby Bingham
5 * This file is part of FFmpeg.
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.
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.
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
24 #include "libavutil/pixdesc.h"
25 #include "libavutil/rational.h"
26 #include "libavutil/audioconvert.h"
27 #include "libavutil/imgutils.h"
31 unsigned avfilter_version(void) {
32 return LIBAVFILTER_VERSION_INT
;
35 const char *avfilter_configuration(void)
37 return LIBAV_CONFIGURATION
;
40 const char *avfilter_license(void)
42 #define LICENSE_PREFIX "libavfilter license: "
43 return LICENSE_PREFIX LIBAV_LICENSE
+ sizeof(LICENSE_PREFIX
) - 1;
46 AVFilterBufferRef
*avfilter_ref_buffer(AVFilterBufferRef
*ref
, int pmask
)
48 AVFilterBufferRef
*ret
= av_malloc(sizeof(AVFilterBufferRef
));
52 if (ref
->type
== AVMEDIA_TYPE_VIDEO
) {
53 ret
->video
= av_malloc(sizeof(AVFilterBufferRefVideoProps
));
58 *ret
->video
= *ref
->video
;
59 } else if (ref
->type
== AVMEDIA_TYPE_AUDIO
) {
60 ret
->audio
= av_malloc(sizeof(AVFilterBufferRefAudioProps
));
65 *ret
->audio
= *ref
->audio
;
68 ret
->buf
->refcount
++;
72 void avfilter_unref_buffer(AVFilterBufferRef
*ref
)
76 if (!(--ref
->buf
->refcount
))
77 ref
->buf
->free(ref
->buf
);
83 void avfilter_insert_pad(unsigned idx
, unsigned *count
, size_t padidx_off
,
84 AVFilterPad
**pads
, AVFilterLink
***links
,
89 idx
= FFMIN(idx
, *count
);
91 *pads
= av_realloc(*pads
, sizeof(AVFilterPad
) * (*count
+ 1));
92 *links
= av_realloc(*links
, sizeof(AVFilterLink
*) * (*count
+ 1));
93 memmove(*pads
+idx
+1, *pads
+idx
, sizeof(AVFilterPad
) * (*count
-idx
));
94 memmove(*links
+idx
+1, *links
+idx
, sizeof(AVFilterLink
*) * (*count
-idx
));
95 memcpy(*pads
+idx
, newpad
, sizeof(AVFilterPad
));
99 for (i
= idx
+1; i
< *count
; i
++)
101 (*(unsigned *)((uint8_t *) *links
[i
] + padidx_off
))++;
104 int avfilter_link(AVFilterContext
*src
, unsigned srcpad
,
105 AVFilterContext
*dst
, unsigned dstpad
)
109 if (src
->output_count
<= srcpad
|| dst
->input_count
<= dstpad
||
110 src
->outputs
[srcpad
] || dst
->inputs
[dstpad
])
113 if (src
->output_pads
[srcpad
].type
!= dst
->input_pads
[dstpad
].type
) {
114 av_log(src
, AV_LOG_ERROR
,
115 "Media type mismatch between the '%s' filter output pad %d and the '%s' filter input pad %d\n",
116 src
->name
, srcpad
, dst
->name
, dstpad
);
117 return AVERROR(EINVAL
);
120 src
->outputs
[srcpad
] =
121 dst
-> inputs
[dstpad
] = link
= av_mallocz(sizeof(AVFilterLink
));
125 link
->srcpad
= &src
->output_pads
[srcpad
];
126 link
->dstpad
= &dst
->input_pads
[dstpad
];
127 link
->type
= src
->output_pads
[srcpad
].type
;
128 assert(PIX_FMT_NONE
== -1 && AV_SAMPLE_FMT_NONE
== -1);
134 int avfilter_insert_filter(AVFilterLink
*link
, AVFilterContext
*filt
,
135 unsigned filt_srcpad_idx
, unsigned filt_dstpad_idx
)
138 unsigned dstpad_idx
= link
->dstpad
- link
->dst
->input_pads
;
140 av_log(link
->dst
, AV_LOG_INFO
, "auto-inserting filter '%s' "
141 "between the filter '%s' and the filter '%s'\n",
142 filt
->name
, link
->src
->name
, link
->dst
->name
);
144 link
->dst
->inputs
[dstpad_idx
] = NULL
;
145 if ((ret
= avfilter_link(filt
, filt_dstpad_idx
, link
->dst
, dstpad_idx
)) < 0) {
146 /* failed to link output filter to new filter */
147 link
->dst
->inputs
[dstpad_idx
] = link
;
151 /* re-hookup the link to the new destination filter we inserted */
153 link
->dstpad
= &filt
->input_pads
[filt_srcpad_idx
];
154 filt
->inputs
[filt_srcpad_idx
] = link
;
156 /* if any information on supported media formats already exists on the
157 * link, we need to preserve that */
158 if (link
->out_formats
)
159 avfilter_formats_changeref(&link
->out_formats
,
160 &filt
->outputs
[filt_dstpad_idx
]->out_formats
);
165 int avfilter_config_links(AVFilterContext
*filter
)
167 int (*config_link
)(AVFilterLink
*);
171 for (i
= 0; i
< filter
->input_count
; i
++) {
172 AVFilterLink
*link
= filter
->inputs
[i
];
176 switch (link
->init_state
) {
179 case AVLINK_STARTINIT
:
180 av_log(filter
, AV_LOG_INFO
, "circular filter chain detected\n");
183 link
->init_state
= AVLINK_STARTINIT
;
185 if ((ret
= avfilter_config_links(link
->src
)) < 0)
188 if (!(config_link
= link
->srcpad
->config_props
))
189 config_link
= avfilter_default_config_output_link
;
190 if ((ret
= config_link(link
)) < 0)
193 if (link
->time_base
.num
== 0 && link
->time_base
.den
== 0)
194 link
->time_base
= link
->src
&& link
->src
->input_count ?
195 link
->src
->inputs
[0]->time_base
: AV_TIME_BASE_Q
;
197 if (link
->sample_aspect_ratio
.num
== 0 && link
->sample_aspect_ratio
.den
== 0)
198 link
->sample_aspect_ratio
= link
->src
->input_count ?
199 link
->src
->inputs
[0]->sample_aspect_ratio
: (AVRational
){1,1};
201 if (link
->sample_rate
== 0 && link
->src
&& link
->src
->input_count
)
202 link
->sample_rate
= link
->src
->inputs
[0]->sample_rate
;
204 if (link
->channel_layout
== 0 && link
->src
&& link
->src
->input_count
)
205 link
->channel_layout
= link
->src
->inputs
[0]->channel_layout
;
207 if ((config_link
= link
->dstpad
->config_props
))
208 if ((ret
= config_link(link
)) < 0)
211 link
->init_state
= AVLINK_INIT
;
218 static char *ff_get_ref_perms_string(char *buf
, size_t buf_size
, int perms
)
220 snprintf(buf
, buf_size
, "%s%s%s%s%s%s",
221 perms
& AV_PERM_READ ?
"r" : "",
222 perms
& AV_PERM_WRITE ?
"w" : "",
223 perms
& AV_PERM_PRESERVE ?
"p" : "",
224 perms
& AV_PERM_REUSE ?
"u" : "",
225 perms
& AV_PERM_REUSE2 ?
"U" : "",
226 perms
& AV_PERM_NEG_LINESIZES ?
"n" : "");
230 static void ff_dlog_ref(void *ctx
, AVFilterBufferRef
*ref
, int end
)
232 av_unused
char buf
[16];
234 "ref[%p buf:%p refcount:%d perms:%s data:%p linesize[%d, %d, %d, %d] pts:%"PRId64
" pos:%"PRId64
,
235 ref
, ref
->buf
, ref
->buf
->refcount
, ff_get_ref_perms_string(buf
, sizeof(buf
), ref
->perms
), ref
->data
[0],
236 ref
->linesize
[0], ref
->linesize
[1], ref
->linesize
[2], ref
->linesize
[3],
240 av_dlog(ctx
, " a:%d/%d s:%dx%d i:%c",
241 ref
->video
->pixel_aspect
.num
, ref
->video
->pixel_aspect
.den
,
242 ref
->video
->w
, ref
->video
->h
,
243 !ref
->video
->interlaced ?
'P' : /* Progressive */
244 ref
->video
->top_field_first ?
'T' : 'B'); /* Top / Bottom */
247 av_dlog(ctx
, " cl:%"PRId64
"d sn:%d s:%d sr:%d p:%d",
248 ref
->audio
->channel_layout
,
249 ref
->audio
->nb_samples
,
251 ref
->audio
->sample_rate
,
255 av_dlog(ctx
, "]%s", end ?
"\n" : "");
258 static void ff_dlog_link(void *ctx
, AVFilterLink
*link
, int end
)
260 if (link
->type
== AVMEDIA_TYPE_VIDEO
) {
262 "link[%p s:%dx%d fmt:%-16s %-16s->%-16s]%s",
263 link
, link
->w
, link
->h
,
264 av_pix_fmt_descriptors
[link
->format
].name
,
265 link
->src ? link
->src
->filter
->name
: "",
266 link
->dst ? link
->dst
->filter
->name
: "",
270 av_get_channel_layout_string(buf
, sizeof(buf
), -1, link
->channel_layout
);
273 "link[%p r:%"PRId64
" cl:%s fmt:%-16s %-16s->%-16s]%s",
274 link
, link
->sample_rate
, buf
,
275 av_get_sample_fmt_name(link
->format
),
276 link
->src ? link
->src
->filter
->name
: "",
277 link
->dst ? link
->dst
->filter
->name
: "",
282 #define FF_DPRINTF_START(ctx, func) av_dlog(NULL, "%-16s: ", #func)
284 AVFilterBufferRef
*avfilter_get_video_buffer(AVFilterLink
*link
, int perms
, int w
, int h
)
286 AVFilterBufferRef
*ret
= NULL
;
288 av_unused
char buf
[16];
289 FF_DPRINTF_START(NULL
, get_video_buffer
); ff_dlog_link(NULL
, link
, 0);
290 av_dlog(NULL
, " perms:%s w:%d h:%d\n", ff_get_ref_perms_string(buf
, sizeof(buf
), perms
), w
, h
);
292 if (link
->dstpad
->get_video_buffer
)
293 ret
= link
->dstpad
->get_video_buffer(link
, perms
, w
, h
);
296 ret
= avfilter_default_get_video_buffer(link
, perms
, w
, h
);
299 ret
->type
= AVMEDIA_TYPE_VIDEO
;
301 FF_DPRINTF_START(NULL
, get_video_buffer
); ff_dlog_link(NULL
, link
, 0); av_dlog(NULL
, " returning "); ff_dlog_ref(NULL
, ret
, 1);
307 avfilter_get_video_buffer_ref_from_arrays(uint8_t *data
[4], int linesize
[4], int perms
,
308 int w
, int h
, enum PixelFormat format
)
310 AVFilterBuffer
*pic
= av_mallocz(sizeof(AVFilterBuffer
));
311 AVFilterBufferRef
*picref
= av_mallocz(sizeof(AVFilterBufferRef
));
317 picref
->buf
->free
= ff_avfilter_default_free_buffer
;
318 if (!(picref
->video
= av_mallocz(sizeof(AVFilterBufferRefVideoProps
))))
321 pic
->w
= picref
->video
->w
= w
;
322 pic
->h
= picref
->video
->h
= h
;
324 /* make sure the buffer gets read permission or it's useless for output */
325 picref
->perms
= perms
| AV_PERM_READ
;
328 picref
->type
= AVMEDIA_TYPE_VIDEO
;
329 pic
->format
= picref
->format
= format
;
331 memcpy(pic
->data
, data
, sizeof(pic
->data
));
332 memcpy(pic
->linesize
, linesize
, sizeof(pic
->linesize
));
333 memcpy(picref
->data
, pic
->data
, sizeof(picref
->data
));
334 memcpy(picref
->linesize
, pic
->linesize
, sizeof(picref
->linesize
));
339 if (picref
&& picref
->video
)
340 av_free(picref
->video
);
346 AVFilterBufferRef
*avfilter_get_audio_buffer(AVFilterLink
*link
, int perms
,
347 enum AVSampleFormat sample_fmt
, int size
,
348 int64_t channel_layout
, int planar
)
350 AVFilterBufferRef
*ret
= NULL
;
352 if (link
->dstpad
->get_audio_buffer
)
353 ret
= link
->dstpad
->get_audio_buffer(link
, perms
, sample_fmt
, size
, channel_layout
, planar
);
356 ret
= avfilter_default_get_audio_buffer(link
, perms
, sample_fmt
, size
, channel_layout
, planar
);
359 ret
->type
= AVMEDIA_TYPE_AUDIO
;
364 int avfilter_request_frame(AVFilterLink
*link
)
366 FF_DPRINTF_START(NULL
, request_frame
); ff_dlog_link(NULL
, link
, 1);
368 if (link
->srcpad
->request_frame
)
369 return link
->srcpad
->request_frame(link
);
370 else if (link
->src
->inputs
[0])
371 return avfilter_request_frame(link
->src
->inputs
[0]);
375 int avfilter_poll_frame(AVFilterLink
*link
)
377 int i
, min
= INT_MAX
;
379 if (link
->srcpad
->poll_frame
)
380 return link
->srcpad
->poll_frame(link
);
382 for (i
= 0; i
< link
->src
->input_count
; i
++) {
384 if (!link
->src
->inputs
[i
])
386 val
= avfilter_poll_frame(link
->src
->inputs
[i
]);
387 min
= FFMIN(min
, val
);
393 /* XXX: should we do the duplicating of the picture ref here, instead of
394 * forcing the source filter to do it? */
395 void avfilter_start_frame(AVFilterLink
*link
, AVFilterBufferRef
*picref
)
397 void (*start_frame
)(AVFilterLink
*, AVFilterBufferRef
*);
398 AVFilterPad
*dst
= link
->dstpad
;
399 int perms
= picref
->perms
;
401 FF_DPRINTF_START(NULL
, start_frame
); ff_dlog_link(NULL
, link
, 0); av_dlog(NULL
, " "); ff_dlog_ref(NULL
, picref
, 1);
403 if (!(start_frame
= dst
->start_frame
))
404 start_frame
= avfilter_default_start_frame
;
406 if (picref
->linesize
[0] < 0)
407 perms
|= AV_PERM_NEG_LINESIZES
;
408 /* prepare to copy the picture if it has insufficient permissions */
409 if ((dst
->min_perms
& perms
) != dst
->min_perms
|| dst
->rej_perms
& perms
) {
410 av_log(link
->dst
, AV_LOG_DEBUG
,
411 "frame copy needed (have perms %x, need %x, reject %x)\n",
413 link
->dstpad
->min_perms
, link
->dstpad
->rej_perms
);
415 link
->cur_buf
= avfilter_get_video_buffer(link
, dst
->min_perms
, link
->w
, link
->h
);
416 link
->src_buf
= picref
;
417 avfilter_copy_buffer_ref_props(link
->cur_buf
, link
->src_buf
);
420 link
->cur_buf
= picref
;
422 start_frame(link
, link
->cur_buf
);
425 void avfilter_end_frame(AVFilterLink
*link
)
427 void (*end_frame
)(AVFilterLink
*);
429 if (!(end_frame
= link
->dstpad
->end_frame
))
430 end_frame
= avfilter_default_end_frame
;
434 /* unreference the source picture if we're feeding the destination filter
435 * a copied version dues to permission issues */
437 avfilter_unref_buffer(link
->src_buf
);
438 link
->src_buf
= NULL
;
442 void avfilter_draw_slice(AVFilterLink
*link
, int y
, int h
, int slice_dir
)
444 uint8_t *src
[4], *dst
[4];
446 void (*draw_slice
)(AVFilterLink
*, int, int, int);
448 FF_DPRINTF_START(NULL
, draw_slice
); ff_dlog_link(NULL
, link
, 0); av_dlog(NULL
, " y:%d h:%d dir:%d\n", y
, h
, slice_dir
);
450 /* copy the slice if needed for permission reasons */
452 vsub
= av_pix_fmt_descriptors
[link
->format
].log2_chroma_h
;
454 for (i
= 0; i
< 4; i
++) {
455 if (link
->src_buf
->data
[i
]) {
456 src
[i
] = link
->src_buf
-> data
[i
] +
457 (y
>> (i
==1 || i
==2 ? vsub
: 0)) * link
->src_buf
-> linesize
[i
];
458 dst
[i
] = link
->cur_buf
->data
[i
] +
459 (y
>> (i
==1 || i
==2 ? vsub
: 0)) * link
->cur_buf
->linesize
[i
];
461 src
[i
] = dst
[i
] = NULL
;
464 for (i
= 0; i
< 4; i
++) {
466 av_image_get_linesize(link
->format
, link
->cur_buf
->video
->w
, i
);
468 if (!src
[i
]) continue;
470 for (j
= 0; j
< h
>> (i
==1 || i
==2 ? vsub
: 0); j
++) {
471 memcpy(dst
[i
], src
[i
], planew
);
472 src
[i
] += link
->src_buf
->linesize
[i
];
473 dst
[i
] += link
->cur_buf
->linesize
[i
];
478 if (!(draw_slice
= link
->dstpad
->draw_slice
))
479 draw_slice
= avfilter_default_draw_slice
;
480 draw_slice(link
, y
, h
, slice_dir
);
483 void avfilter_filter_samples(AVFilterLink
*link
, AVFilterBufferRef
*samplesref
)
485 void (*filter_samples
)(AVFilterLink
*, AVFilterBufferRef
*);
486 AVFilterPad
*dst
= link
->dstpad
;
488 FF_DPRINTF_START(NULL
, filter_samples
); ff_dlog_link(NULL
, link
, 1);
490 if (!(filter_samples
= dst
->filter_samples
))
491 filter_samples
= avfilter_default_filter_samples
;
493 /* prepare to copy the samples if the buffer has insufficient permissions */
494 if ((dst
->min_perms
& samplesref
->perms
) != dst
->min_perms
||
495 dst
->rej_perms
& samplesref
->perms
) {
497 av_log(link
->dst
, AV_LOG_DEBUG
,
498 "Copying audio data in avfilter (have perms %x, need %x, reject %x)\n",
499 samplesref
->perms
, link
->dstpad
->min_perms
, link
->dstpad
->rej_perms
);
501 link
->cur_buf
= avfilter_default_get_audio_buffer(link
, dst
->min_perms
,
503 samplesref
->audio
->size
,
504 samplesref
->audio
->channel_layout
,
505 samplesref
->audio
->planar
);
506 link
->cur_buf
->pts
= samplesref
->pts
;
507 link
->cur_buf
->audio
->sample_rate
= samplesref
->audio
->sample_rate
;
509 /* Copy actual data into new samples buffer */
510 memcpy(link
->cur_buf
->data
[0], samplesref
->data
[0], samplesref
->audio
->size
);
512 avfilter_unref_buffer(samplesref
);
514 link
->cur_buf
= samplesref
;
516 filter_samples(link
, link
->cur_buf
);
519 #define MAX_REGISTERED_AVFILTERS_NB 64
521 static AVFilter
*registered_avfilters
[MAX_REGISTERED_AVFILTERS_NB
+ 1];
523 static int next_registered_avfilter_idx
= 0;
525 AVFilter
*avfilter_get_by_name(const char *name
)
529 for (i
= 0; registered_avfilters
[i
]; i
++)
530 if (!strcmp(registered_avfilters
[i
]->name
, name
))
531 return registered_avfilters
[i
];
536 int avfilter_register(AVFilter
*filter
)
538 if (next_registered_avfilter_idx
== MAX_REGISTERED_AVFILTERS_NB
)
541 registered_avfilters
[next_registered_avfilter_idx
++] = filter
;
545 AVFilter
**av_filter_next(AVFilter
**filter
)
547 return filter ?
++filter
: ®istered_avfilters
[0];
550 void avfilter_uninit(void)
552 memset(registered_avfilters
, 0, sizeof(registered_avfilters
));
553 next_registered_avfilter_idx
= 0;
556 static int pad_count(const AVFilterPad
*pads
)
560 for(count
= 0; pads
->name
; count
++) pads
++;
564 static const char *filter_name(void *p
)
566 AVFilterContext
*filter
= p
;
567 return filter
->filter
->name
;
570 static const AVClass avfilter_class
= {
574 LIBAVUTIL_VERSION_INT
,
577 int avfilter_open(AVFilterContext
**filter_ctx
, AVFilter
*filter
, const char *inst_name
)
579 AVFilterContext
*ret
;
583 return AVERROR(EINVAL
);
585 ret
= av_mallocz(sizeof(AVFilterContext
));
587 ret
->av_class
= &avfilter_class
;
588 ret
->filter
= filter
;
589 ret
->name
= inst_name ?
av_strdup(inst_name
) : NULL
;
590 ret
->priv
= av_mallocz(filter
->priv_size
);
592 ret
->input_count
= pad_count(filter
->inputs
);
593 if (ret
->input_count
) {
594 ret
->input_pads
= av_malloc(sizeof(AVFilterPad
) * ret
->input_count
);
595 memcpy(ret
->input_pads
, filter
->inputs
, sizeof(AVFilterPad
) * ret
->input_count
);
596 ret
->inputs
= av_mallocz(sizeof(AVFilterLink
*) * ret
->input_count
);
599 ret
->output_count
= pad_count(filter
->outputs
);
600 if (ret
->output_count
) {
601 ret
->output_pads
= av_malloc(sizeof(AVFilterPad
) * ret
->output_count
);
602 memcpy(ret
->output_pads
, filter
->outputs
, sizeof(AVFilterPad
) * ret
->output_count
);
603 ret
->outputs
= av_mallocz(sizeof(AVFilterLink
*) * ret
->output_count
);
610 void avfilter_free(AVFilterContext
*filter
)
615 if (filter
->filter
->uninit
)
616 filter
->filter
->uninit(filter
);
618 for (i
= 0; i
< filter
->input_count
; i
++) {
619 if ((link
= filter
->inputs
[i
])) {
621 link
->src
->outputs
[link
->srcpad
- link
->src
->output_pads
] = NULL
;
622 avfilter_formats_unref(&link
->in_formats
);
623 avfilter_formats_unref(&link
->out_formats
);
627 for (i
= 0; i
< filter
->output_count
; i
++) {
628 if ((link
= filter
->outputs
[i
])) {
630 link
->dst
->inputs
[link
->dstpad
- link
->dst
->input_pads
] = NULL
;
631 avfilter_formats_unref(&link
->in_formats
);
632 avfilter_formats_unref(&link
->out_formats
);
637 av_freep(&filter
->name
);
638 av_freep(&filter
->input_pads
);
639 av_freep(&filter
->output_pads
);
640 av_freep(&filter
->inputs
);
641 av_freep(&filter
->outputs
);
642 av_freep(&filter
->priv
);
646 int avfilter_init_filter(AVFilterContext
*filter
, const char *args
, void *opaque
)
650 if (filter
->filter
->init
)
651 ret
= filter
->filter
->init(filter
, args
, opaque
);