#include "libavutil/avassert.h"
#include "libavutil/audioconvert.h"
+#include "libavutil/common.h"
#include "audio.h"
#include "avfilter.h"
return NULL;
}
-static void default_filter_samples(AVFilterLink *link,
- AVFilterBufferRef *samplesref)
+static int default_filter_samples(AVFilterLink *link,
+ AVFilterBufferRef *samplesref)
{
- ff_filter_samples(link->dst->outputs[0], samplesref);
+ return ff_filter_samples(link->dst->outputs[0], samplesref);
}
-void ff_filter_samples_framed(AVFilterLink *link,
- AVFilterBufferRef *samplesref)
+int ff_filter_samples_framed(AVFilterLink *link, AVFilterBufferRef *samplesref)
{
- void (*filter_samples)(AVFilterLink *, AVFilterBufferRef *);
+ int (*filter_samples)(AVFilterLink *, AVFilterBufferRef *);
+ AVFilterPad *src = link->srcpad;
AVFilterPad *dst = link->dstpad;
int64_t pts;
AVFilterBufferRef *buf_out;
+ int ret;
FF_TPRINTF_START(NULL, filter_samples); ff_tlog_link(NULL, link, 1);
if (!(filter_samples = dst->filter_samples))
filter_samples = default_filter_samples;
+ av_assert1((samplesref->perms & src->min_perms) == src->min_perms);
+ samplesref->perms &= ~ src->rej_perms;
+
/* prepare to copy the samples if the buffer has insufficient permissions */
if ((dst->min_perms & samplesref->perms) != dst->min_perms ||
dst->rej_perms & samplesref->perms) {
buf_out = ff_default_get_audio_buffer(link, dst->min_perms,
samplesref->audio->nb_samples);
+ if (!buf_out) {
+ avfilter_unref_buffer(samplesref);
+ return AVERROR(ENOMEM);
+ }
buf_out->pts = samplesref->pts;
buf_out->audio->sample_rate = samplesref->audio->sample_rate;
link->cur_buf = buf_out;
pts = buf_out->pts;
- filter_samples(link, buf_out);
+ ret = filter_samples(link, buf_out);
ff_update_link_current_pts(link, pts);
+ return ret;
}
-void ff_filter_samples(AVFilterLink *link, AVFilterBufferRef *samplesref)
+int ff_filter_samples(AVFilterLink *link, AVFilterBufferRef *samplesref)
{
int insamples = samplesref->audio->nb_samples, inpos = 0, nb_samples;
AVFilterBufferRef *pbuf = link->partial_buf;
int nb_channels = av_get_channel_layout_nb_channels(link->channel_layout);
+ int ret = 0;
if (!link->min_samples ||
(!pbuf &&
insamples >= link->min_samples && insamples <= link->max_samples)) {
- ff_filter_samples_framed(link, samplesref);
- return;
+ return ff_filter_samples_framed(link, samplesref);
}
/* Handle framing (min_samples, max_samples) */
while (insamples) {
if (!pbuf) {
av_log(link->dst, AV_LOG_WARNING,
"Samples dropped due to memory allocation failure.\n");
- return;
+ return 0;
}
avfilter_copy_buffer_ref_props(pbuf, samplesref);
pbuf->pts = samplesref->pts +
insamples -= nb_samples;
pbuf->audio->nb_samples += nb_samples;
if (pbuf->audio->nb_samples >= link->min_samples) {
- ff_filter_samples_framed(link, pbuf);
+ ret = ff_filter_samples_framed(link, pbuf);
pbuf = NULL;
}
}
avfilter_unref_buffer(samplesref);
link->partial_buf = pbuf;
+ return ret;
}