/* #define DEBUG */
-#include "libavcodec/audioconvert.c"
#include "libavutil/pixdesc.h"
+#include "libavutil/rational.h"
#include "libavcore/imgutils.h"
#include "avfilter.h"
#include "internal.h"
return LICENSE_PREFIX FFMPEG_LICENSE + sizeof(LICENSE_PREFIX) - 1;
}
-/** helper macros to get the in/out pad on the dst/src filter */
-#define link_dpad(link) link->dst-> input_pads[link->dstpad]
-#define link_spad(link) link->src->output_pads[link->srcpad]
-
AVFilterBufferRef *avfilter_ref_buffer(AVFilterBufferRef *ref, int pmask)
{
AVFilterBufferRef *ret = av_malloc(sizeof(AVFilterBufferRef));
link->src = src;
link->dst = dst;
- link->srcpad = srcpad;
- link->dstpad = dstpad;
+ link->srcpad = &src->output_pads[srcpad];
+ link->dstpad = &dst->input_pads[dstpad];
link->type = src->output_pads[srcpad].type;
assert(PIX_FMT_NONE == -1 && SAMPLE_FMT_NONE == -1);
link->format = -1;
}
int avfilter_insert_filter(AVFilterLink *link, AVFilterContext *filt,
- unsigned in, unsigned out)
+ unsigned filt_srcpad_idx, unsigned filt_dstpad_idx)
{
+ int ret;
+ unsigned dstpad_idx = link->dstpad - link->dst->input_pads;
+
av_log(link->dst, AV_LOG_INFO, "auto-inserting filter '%s' "
"between the filter '%s' and the filter '%s'\n",
filt->name, link->src->name, link->dst->name);
- link->dst->inputs[link->dstpad] = NULL;
- if (avfilter_link(filt, out, link->dst, link->dstpad)) {
+ link->dst->inputs[dstpad_idx] = NULL;
+ if ((ret = avfilter_link(filt, filt_dstpad_idx, link->dst, dstpad_idx)) < 0) {
/* failed to link output filter to new filter */
- link->dst->inputs[link->dstpad] = link;
- return -1;
+ link->dst->inputs[dstpad_idx] = link;
+ return ret;
}
/* re-hookup the link to the new destination filter we inserted */
link->dst = filt;
- link->dstpad = in;
- filt->inputs[in] = link;
+ link->dstpad = &filt->input_pads[filt_srcpad_idx];
+ filt->inputs[filt_srcpad_idx] = link;
/* if any information on supported media formats already exists on the
* link, we need to preserve that */
if (link->out_formats)
avfilter_formats_changeref(&link->out_formats,
- &filt->outputs[out]->out_formats);
+ &filt->outputs[filt_dstpad_idx]->out_formats);
return 0;
}
{
int (*config_link)(AVFilterLink *);
unsigned i;
+ int ret;
for (i = 0; i < filter->input_count; i ++) {
AVFilterLink *link = filter->inputs[i];
case AVLINK_UNINIT:
link->init_state = AVLINK_STARTINIT;
- if (avfilter_config_links(link->src))
- return -1;
+ if ((ret = avfilter_config_links(link->src)) < 0)
+ return ret;
- if (!(config_link = link_spad(link).config_props))
+ if (!(config_link = link->srcpad->config_props))
config_link = avfilter_default_config_output_link;
- if (config_link(link))
- return -1;
+ if ((ret = config_link(link)) < 0)
+ return ret;
+
+ if (link->time_base.num == 0 && link->time_base.den == 0)
+ link->time_base = link->src && link->src->input_count ?
+ link->src->inputs[0]->time_base : AV_TIME_BASE_Q;
- if ((config_link = link_dpad(link).config_props))
- if (config_link(link))
- return -1;
+ if ((config_link = link->dstpad->config_props))
+ if ((ret = config_link(link)) < 0)
+ return ret;
link->init_state = AVLINK_INIT;
}
return 0;
}
+char *ff_get_ref_perms_string(char *buf, size_t buf_size, int perms)
+{
+ snprintf(buf, buf_size, "%s%s%s%s%s",
+ perms & AV_PERM_READ ? "r" : "",
+ perms & AV_PERM_WRITE ? "w" : "",
+ perms & AV_PERM_PRESERVE ? "p" : "",
+ perms & AV_PERM_REUSE ? "r" : "",
+ perms & AV_PERM_REUSE2 ? "R" : "");
+ return buf;
+}
+
void ff_dprintf_ref(void *ctx, AVFilterBufferRef *ref, int end)
{
+ av_unused char buf[16];
dprintf(ctx,
- "ref[%p buf:%p refcount:%d perms:0x%x data:%p linesize[%d, %d, %d, %d] pts:%"PRId64" pos:%"PRId64,
- ref, ref->buf, ref->buf->refcount, ref->perms, ref->data[0],
+ "ref[%p buf:%p refcount:%d perms:%s data:%p linesize[%d, %d, %d, %d] pts:%"PRId64" pos:%"PRId64,
+ ref, ref->buf, ref->buf->refcount, ff_get_ref_perms_string(buf, sizeof(buf), ref->perms), ref->data[0],
ref->linesize[0], ref->linesize[1], ref->linesize[2], ref->linesize[3],
ref->pts, ref->pos);
{
AVFilterBufferRef *ret = NULL;
- FF_DPRINTF_START(NULL, get_video_buffer); ff_dprintf_link(NULL, link, 0); dprintf(NULL, " perms:%d w:%d h:%d\n", perms, w, h);
+ av_unused char buf[16];
+ FF_DPRINTF_START(NULL, get_video_buffer); ff_dprintf_link(NULL, link, 0);
+ dprintf(NULL, " perms:%s w:%d h:%d\n", ff_get_ref_perms_string(buf, sizeof(buf), perms), w, h);
- if (link_dpad(link).get_video_buffer)
- ret = link_dpad(link).get_video_buffer(link, perms, w, h);
+ if (link->dstpad->get_video_buffer)
+ ret = link->dstpad->get_video_buffer(link, perms, w, h);
if (!ret)
ret = avfilter_default_get_video_buffer(link, perms, w, h);
{
AVFilterBufferRef *ret = NULL;
- if (link_dpad(link).get_audio_buffer)
- ret = link_dpad(link).get_audio_buffer(link, perms, sample_fmt, size, channel_layout, planar);
+ if (link->dstpad->get_audio_buffer)
+ ret = link->dstpad->get_audio_buffer(link, perms, sample_fmt, size, channel_layout, planar);
if (!ret)
ret = avfilter_default_get_audio_buffer(link, perms, sample_fmt, size, channel_layout, planar);
{
FF_DPRINTF_START(NULL, request_frame); ff_dprintf_link(NULL, link, 1);
- if (link_spad(link).request_frame)
- return link_spad(link).request_frame(link);
+ if (link->srcpad->request_frame)
+ return link->srcpad->request_frame(link);
else if (link->src->inputs[0])
return avfilter_request_frame(link->src->inputs[0]);
else return -1;
{
int i, min = INT_MAX;
- if (link_spad(link).poll_frame)
- return link_spad(link).poll_frame(link);
+ if (link->srcpad->poll_frame)
+ return link->srcpad->poll_frame(link);
for (i = 0; i < link->src->input_count; i++) {
int val;
void avfilter_start_frame(AVFilterLink *link, AVFilterBufferRef *picref)
{
void (*start_frame)(AVFilterLink *, AVFilterBufferRef *);
- AVFilterPad *dst = &link_dpad(link);
+ AVFilterPad *dst = link->dstpad;
FF_DPRINTF_START(NULL, start_frame); ff_dprintf_link(NULL, link, 0); dprintf(NULL, " "); ff_dprintf_ref(NULL, picref, 1);
av_log(link->dst, AV_LOG_DEBUG,
"frame copy needed (have perms %x, need %x, reject %x)\n",
picref->perms,
- link_dpad(link).min_perms, link_dpad(link).rej_perms);
+ link->dstpad->min_perms, link->dstpad->rej_perms);
link->cur_buf = avfilter_get_video_buffer(link, dst->min_perms, link->w, link->h);
link->src_buf = picref;
{
void (*end_frame)(AVFilterLink *);
- if (!(end_frame = link_dpad(link).end_frame))
+ if (!(end_frame = link->dstpad->end_frame))
end_frame = avfilter_default_end_frame;
end_frame(link);
for (i = 0; i < 4; i++) {
int planew =
- av_get_image_linesize(link->format, link->cur_buf->video->w, i);
+ av_image_get_linesize(link->format, link->cur_buf->video->w, i);
if (!src[i]) continue;
}
}
- if (!(draw_slice = link_dpad(link).draw_slice))
+ if (!(draw_slice = link->dstpad->draw_slice))
draw_slice = avfilter_default_draw_slice;
draw_slice(link, y, h, slice_dir);
}
void avfilter_filter_samples(AVFilterLink *link, AVFilterBufferRef *samplesref)
{
void (*filter_samples)(AVFilterLink *, AVFilterBufferRef *);
- AVFilterPad *dst = &link_dpad(link);
+ AVFilterPad *dst = link->dstpad;
if (!(filter_samples = dst->filter_samples))
filter_samples = avfilter_default_filter_samples;
av_log(link->dst, AV_LOG_DEBUG,
"Copying audio data in avfilter (have perms %x, need %x, reject %x)\n",
- samplesref->perms, link_dpad(link).min_perms, link_dpad(link).rej_perms);
+ samplesref->perms, link->dstpad->min_perms, link->dstpad->rej_perms);
link->cur_buf = avfilter_default_get_audio_buffer(link, dst->min_perms,
samplesref->format,
return 0;
}
-void avfilter_destroy(AVFilterContext *filter)
+void avfilter_free(AVFilterContext *filter)
{
int i;
+ AVFilterLink *link;
if (filter->filter->uninit)
filter->filter->uninit(filter);
for (i = 0; i < filter->input_count; i++) {
- if (filter->inputs[i]) {
- if (filter->inputs[i]->src)
- filter->inputs[i]->src->outputs[filter->inputs[i]->srcpad] = NULL;
- avfilter_formats_unref(&filter->inputs[i]->in_formats);
- avfilter_formats_unref(&filter->inputs[i]->out_formats);
+ if ((link = filter->inputs[i])) {
+ if (link->src)
+ link->src->outputs[link->srcpad - link->src->output_pads] = NULL;
+ avfilter_formats_unref(&link->in_formats);
+ avfilter_formats_unref(&link->out_formats);
}
- av_freep(&filter->inputs[i]);
+ av_freep(&link);
}
for (i = 0; i < filter->output_count; i++) {
- if (filter->outputs[i]) {
- if (filter->outputs[i]->dst)
- filter->outputs[i]->dst->inputs[filter->outputs[i]->dstpad] = NULL;
- avfilter_formats_unref(&filter->outputs[i]->in_formats);
- avfilter_formats_unref(&filter->outputs[i]->out_formats);
+ if ((link = filter->outputs[i])) {
+ if (link->dst)
+ link->dst->inputs[link->dstpad - link->dst->input_pads] = NULL;
+ avfilter_formats_unref(&link->in_formats);
+ avfilter_formats_unref(&link->out_formats);
}
- av_freep(&filter->outputs[i]);
+ av_freep(&link);
}
av_freep(&filter->name);