Merge remote-tracking branch 'qatar/master'
* qatar/master: mss3: use standard zigzag table mss3: split DSP functions that are used in MTS2(MSS4) into separate file motion-test: do not use getopt() tcp: add initial timeout limit for incoming connections configure: Change the rdtsc check to a linker check avconv: propagate fatal errors from lavfi. lavfi: add error handling to filter_samples(). fate-run: make avconv() properly deal with multiple inputs. asplit: don't leak the input buffer. af_resample: fix request_frame() behavior. af_asyncts: fix request_frame() behavior. libx264: support aspect ratio switching matroskadec: honor error_recognition when encountering unknown elements. lavr: resampling: add support for s32p, fltp, and dblp internal sample formats lavr: resampling: add filter type and Kaiser window beta to AVOptions lavr: Use AV_SAMPLE_FMT_NONE to auto-select the internal sample format lavr: mix: validate internal sample format in ff_audio_mix_init() Conflicts: ffmpeg.c ffplay.c libavcodec/libx264.c libavfilter/audio.c libavfilter/split.c libavformat/tcp.c tests/fate-run.sh Merged-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
@@ -135,12 +135,13 @@ static int config_output(AVFilterLink *outlink)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *insamplesref)
|
||||
static int filter_samples(AVFilterLink *inlink, AVFilterBufferRef *insamplesref)
|
||||
{
|
||||
AConvertContext *aconvert = inlink->dst->priv;
|
||||
const int n = insamplesref->audio->nb_samples;
|
||||
AVFilterLink *const outlink = inlink->dst->outputs[0];
|
||||
AVFilterBufferRef *outsamplesref = ff_get_audio_buffer(outlink, AV_PERM_WRITE, n);
|
||||
int ret;
|
||||
|
||||
swr_convert(aconvert->swr, outsamplesref->data, n,
|
||||
(void *)insamplesref->data, n);
|
||||
@@ -148,8 +149,9 @@ static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *insamplesref
|
||||
avfilter_copy_buffer_ref_props(outsamplesref, insamplesref);
|
||||
outsamplesref->audio->channel_layout = outlink->channel_layout;
|
||||
|
||||
ff_filter_samples(outlink, outsamplesref);
|
||||
ret = ff_filter_samples(outlink, outsamplesref);
|
||||
avfilter_unref_buffer(insamplesref);
|
||||
return ret;
|
||||
}
|
||||
|
||||
AVFilter avfilter_af_aconvert = {
|
||||
|
@@ -212,7 +212,7 @@ static inline void copy_samples(int nb_inputs, struct amerge_input in[],
|
||||
}
|
||||
}
|
||||
|
||||
static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *insamples)
|
||||
static int filter_samples(AVFilterLink *inlink, AVFilterBufferRef *insamples)
|
||||
{
|
||||
AVFilterContext *ctx = inlink->dst;
|
||||
AMergeContext *am = ctx->priv;
|
||||
@@ -232,7 +232,7 @@ static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *insamples)
|
||||
for (i = 1; i < am->nb_inputs; i++)
|
||||
nb_samples = FFMIN(nb_samples, am->in[i].nb_samples);
|
||||
if (!nb_samples)
|
||||
return;
|
||||
return 0;
|
||||
|
||||
outbuf = ff_get_audio_buffer(ctx->outputs[0], AV_PERM_WRITE, nb_samples);
|
||||
outs = outbuf->data[0];
|
||||
@@ -285,7 +285,7 @@ static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *insamples)
|
||||
}
|
||||
}
|
||||
}
|
||||
ff_filter_samples(ctx->outputs[0], outbuf);
|
||||
return ff_filter_samples(ctx->outputs[0], outbuf);
|
||||
}
|
||||
|
||||
static av_cold int init(AVFilterContext *ctx, const char *args)
|
||||
|
@@ -305,9 +305,7 @@ static int output_frame(AVFilterLink *outlink, int nb_samples)
|
||||
if (s->next_pts != AV_NOPTS_VALUE)
|
||||
s->next_pts += nb_samples;
|
||||
|
||||
ff_filter_samples(outlink, out_buf);
|
||||
|
||||
return 0;
|
||||
return ff_filter_samples(outlink, out_buf);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -448,31 +446,37 @@ static int request_frame(AVFilterLink *outlink)
|
||||
return output_frame(outlink, available_samples);
|
||||
}
|
||||
|
||||
static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *buf)
|
||||
static int filter_samples(AVFilterLink *inlink, AVFilterBufferRef *buf)
|
||||
{
|
||||
AVFilterContext *ctx = inlink->dst;
|
||||
MixContext *s = ctx->priv;
|
||||
AVFilterLink *outlink = ctx->outputs[0];
|
||||
int i;
|
||||
int i, ret = 0;
|
||||
|
||||
for (i = 0; i < ctx->nb_inputs; i++)
|
||||
if (ctx->inputs[i] == inlink)
|
||||
break;
|
||||
if (i >= ctx->nb_inputs) {
|
||||
av_log(ctx, AV_LOG_ERROR, "unknown input link\n");
|
||||
return;
|
||||
ret = AVERROR(EINVAL);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (i == 0) {
|
||||
int64_t pts = av_rescale_q(buf->pts, inlink->time_base,
|
||||
outlink->time_base);
|
||||
frame_list_add_frame(s->frame_list, buf->audio->nb_samples, pts);
|
||||
ret = frame_list_add_frame(s->frame_list, buf->audio->nb_samples, pts);
|
||||
if (ret < 0)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
av_audio_fifo_write(s->fifos[i], (void **)buf->extended_data,
|
||||
buf->audio->nb_samples);
|
||||
ret = av_audio_fifo_write(s->fifos[i], (void **)buf->extended_data,
|
||||
buf->audio->nb_samples);
|
||||
|
||||
fail:
|
||||
avfilter_unref_buffer(buf);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int init(AVFilterContext *ctx, const char *args)
|
||||
|
@@ -168,13 +168,14 @@ static int config_output(AVFilterLink *outlink)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *insamplesref)
|
||||
static int filter_samples(AVFilterLink *inlink, AVFilterBufferRef *insamplesref)
|
||||
{
|
||||
AResampleContext *aresample = inlink->dst->priv;
|
||||
const int n_in = insamplesref->audio->nb_samples;
|
||||
int n_out = n_in * aresample->ratio * 2 ;
|
||||
AVFilterLink *const outlink = inlink->dst->outputs[0];
|
||||
AVFilterBufferRef *outsamplesref = ff_get_audio_buffer(outlink, AV_PERM_WRITE, n_out);
|
||||
int ret;
|
||||
|
||||
|
||||
avfilter_copy_buffer_ref_props(outsamplesref, insamplesref);
|
||||
@@ -193,15 +194,16 @@ static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *insamplesref
|
||||
if (n_out <= 0) {
|
||||
avfilter_unref_buffer(outsamplesref);
|
||||
avfilter_unref_buffer(insamplesref);
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
outsamplesref->audio->sample_rate = outlink->sample_rate;
|
||||
outsamplesref->audio->nb_samples = n_out;
|
||||
|
||||
ff_filter_samples(outlink, outsamplesref);
|
||||
ret = ff_filter_samples(outlink, outsamplesref);
|
||||
aresample->req_fullfilled= 1;
|
||||
avfilter_unref_buffer(insamplesref);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int request_frame(AVFilterLink *outlink)
|
||||
|
@@ -131,7 +131,7 @@ static int push_samples(AVFilterLink *outlink)
|
||||
return nb_out_samples;
|
||||
}
|
||||
|
||||
static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *insamples)
|
||||
static int filter_samples(AVFilterLink *inlink, AVFilterBufferRef *insamples)
|
||||
{
|
||||
AVFilterContext *ctx = inlink->dst;
|
||||
ASNSContext *asns = ctx->priv;
|
||||
@@ -145,7 +145,7 @@ static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *insamples)
|
||||
if (ret < 0) {
|
||||
av_log(ctx, AV_LOG_ERROR,
|
||||
"Stretching audio fifo failed, discarded %d samples\n", nb_samples);
|
||||
return;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
av_audio_fifo_write(asns->fifo, (void **)insamples->extended_data, nb_samples);
|
||||
@@ -155,6 +155,7 @@ static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *insamples)
|
||||
|
||||
if (av_audio_fifo_size(asns->fifo) >= asns->nb_out_samples)
|
||||
push_samples(outlink);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int request_frame(AVFilterLink *outlink)
|
||||
|
@@ -40,7 +40,7 @@ static av_cold int init(AVFilterContext *ctx, const char *args)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *samplesref)
|
||||
static int filter_samples(AVFilterLink *inlink, AVFilterBufferRef *samplesref)
|
||||
{
|
||||
AVFilterContext *ctx = inlink->dst;
|
||||
ShowInfoContext *showinfo = ctx->priv;
|
||||
@@ -83,7 +83,7 @@ static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *samplesref)
|
||||
av_log(ctx, AV_LOG_INFO, "]\n");
|
||||
|
||||
showinfo->frame++;
|
||||
ff_filter_samples(inlink->dst->outputs[0], samplesref);
|
||||
return ff_filter_samples(inlink->dst->outputs[0], samplesref);
|
||||
}
|
||||
|
||||
AVFilter avfilter_af_ashowinfo = {
|
||||
|
@@ -107,11 +107,12 @@ static int config_output(AVFilterLink *outlink)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void send_out(AVFilterContext *ctx, int out_id)
|
||||
static int send_out(AVFilterContext *ctx, int out_id)
|
||||
{
|
||||
AStreamSyncContext *as = ctx->priv;
|
||||
struct buf_queue *queue = &as->queue[out_id];
|
||||
AVFilterBufferRef *buf = queue->buf[queue->tail];
|
||||
int ret;
|
||||
|
||||
queue->buf[queue->tail] = NULL;
|
||||
as->var_values[VAR_B1 + out_id]++;
|
||||
@@ -121,11 +122,12 @@ static void send_out(AVFilterContext *ctx, int out_id)
|
||||
av_q2d(ctx->outputs[out_id]->time_base) * buf->pts;
|
||||
as->var_values[VAR_T1 + out_id] += buf->audio->nb_samples /
|
||||
(double)ctx->inputs[out_id]->sample_rate;
|
||||
ff_filter_samples(ctx->outputs[out_id], buf);
|
||||
ret = ff_filter_samples(ctx->outputs[out_id], buf);
|
||||
queue->nb--;
|
||||
queue->tail = (queue->tail + 1) % QUEUE_SIZE;
|
||||
if (as->req[out_id])
|
||||
as->req[out_id]--;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void send_next(AVFilterContext *ctx)
|
||||
@@ -165,7 +167,7 @@ static int request_frame(AVFilterLink *outlink)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *insamples)
|
||||
static int filter_samples(AVFilterLink *inlink, AVFilterBufferRef *insamples)
|
||||
{
|
||||
AVFilterContext *ctx = inlink->dst;
|
||||
AStreamSyncContext *as = ctx->priv;
|
||||
@@ -175,6 +177,7 @@ static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *insamples)
|
||||
insamples;
|
||||
as->eof &= ~(1 << id);
|
||||
send_next(ctx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
AVFilter avfilter_af_astreamsync = {
|
||||
|
@@ -37,6 +37,9 @@ typedef struct ASyncContext {
|
||||
int resample;
|
||||
float min_delta_sec;
|
||||
int max_comp;
|
||||
|
||||
/* set by filter_samples() to signal an output frame to request_frame() */
|
||||
int got_output;
|
||||
} ASyncContext;
|
||||
|
||||
#define OFFSET(x) offsetof(ASyncContext, x)
|
||||
@@ -112,9 +115,13 @@ static int request_frame(AVFilterLink *link)
|
||||
{
|
||||
AVFilterContext *ctx = link->src;
|
||||
ASyncContext *s = ctx->priv;
|
||||
int ret = ff_request_frame(ctx->inputs[0]);
|
||||
int ret = 0;
|
||||
int nb_samples;
|
||||
|
||||
s->got_output = 0;
|
||||
while (ret >= 0 && !s->got_output)
|
||||
ret = ff_request_frame(ctx->inputs[0]);
|
||||
|
||||
/* flush the fifo */
|
||||
if (ret == AVERROR_EOF && (nb_samples = avresample_get_delay(s->avr))) {
|
||||
AVFilterBufferRef *buf = ff_get_audio_buffer(link, AV_PERM_WRITE,
|
||||
@@ -124,18 +131,18 @@ static int request_frame(AVFilterLink *link)
|
||||
avresample_convert(s->avr, (void**)buf->extended_data, buf->linesize[0],
|
||||
nb_samples, NULL, 0, 0);
|
||||
buf->pts = s->pts;
|
||||
ff_filter_samples(link, buf);
|
||||
return 0;
|
||||
return ff_filter_samples(link, buf);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void write_to_fifo(ASyncContext *s, AVFilterBufferRef *buf)
|
||||
static int write_to_fifo(ASyncContext *s, AVFilterBufferRef *buf)
|
||||
{
|
||||
avresample_convert(s->avr, NULL, 0, 0, (void**)buf->extended_data,
|
||||
buf->linesize[0], buf->audio->nb_samples);
|
||||
int ret = avresample_convert(s->avr, NULL, 0, 0, (void**)buf->extended_data,
|
||||
buf->linesize[0], buf->audio->nb_samples);
|
||||
avfilter_unref_buffer(buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* get amount of data currently buffered, in samples */
|
||||
@@ -144,7 +151,7 @@ static int64_t get_delay(ASyncContext *s)
|
||||
return avresample_available(s->avr) + avresample_get_delay(s->avr);
|
||||
}
|
||||
|
||||
static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *buf)
|
||||
static int filter_samples(AVFilterLink *inlink, AVFilterBufferRef *buf)
|
||||
{
|
||||
AVFilterContext *ctx = inlink->dst;
|
||||
ASyncContext *s = ctx->priv;
|
||||
@@ -152,7 +159,7 @@ static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *buf)
|
||||
int nb_channels = av_get_channel_layout_nb_channels(buf->audio->channel_layout);
|
||||
int64_t pts = (buf->pts == AV_NOPTS_VALUE) ? buf->pts :
|
||||
av_rescale_q(buf->pts, inlink->time_base, outlink->time_base);
|
||||
int out_size;
|
||||
int out_size, ret;
|
||||
int64_t delta;
|
||||
|
||||
/* buffer data until we get the first timestamp */
|
||||
@@ -160,14 +167,12 @@ static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *buf)
|
||||
if (pts != AV_NOPTS_VALUE) {
|
||||
s->pts = pts - get_delay(s);
|
||||
}
|
||||
write_to_fifo(s, buf);
|
||||
return;
|
||||
return write_to_fifo(s, buf);
|
||||
}
|
||||
|
||||
/* now wait for the next timestamp */
|
||||
if (pts == AV_NOPTS_VALUE) {
|
||||
write_to_fifo(s, buf);
|
||||
return;
|
||||
return write_to_fifo(s, buf);
|
||||
}
|
||||
|
||||
/* when we have two timestamps, compute how many samples would we have
|
||||
@@ -190,8 +195,10 @@ static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *buf)
|
||||
if (out_size > 0) {
|
||||
AVFilterBufferRef *buf_out = ff_get_audio_buffer(outlink, AV_PERM_WRITE,
|
||||
out_size);
|
||||
if (!buf_out)
|
||||
return;
|
||||
if (!buf_out) {
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
avresample_read(s->avr, (void**)buf_out->extended_data, out_size);
|
||||
buf_out->pts = s->pts;
|
||||
@@ -200,7 +207,10 @@ static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *buf)
|
||||
av_samples_set_silence(buf_out->extended_data, out_size - delta,
|
||||
delta, nb_channels, buf->format);
|
||||
}
|
||||
ff_filter_samples(outlink, buf_out);
|
||||
ret = ff_filter_samples(outlink, buf_out);
|
||||
if (ret < 0)
|
||||
goto fail;
|
||||
s->got_output = 1;
|
||||
} else {
|
||||
av_log(ctx, AV_LOG_WARNING, "Non-monotonous timestamps, dropping "
|
||||
"whole buffer.\n");
|
||||
@@ -210,9 +220,13 @@ static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *buf)
|
||||
avresample_read(s->avr, NULL, avresample_available(s->avr));
|
||||
|
||||
s->pts = pts - avresample_get_delay(s->avr);
|
||||
avresample_convert(s->avr, NULL, 0, 0, (void**)buf->extended_data,
|
||||
buf->linesize[0], buf->audio->nb_samples);
|
||||
ret = avresample_convert(s->avr, NULL, 0, 0, (void**)buf->extended_data,
|
||||
buf->linesize[0], buf->audio->nb_samples);
|
||||
|
||||
fail:
|
||||
avfilter_unref_buffer(buf);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
AVFilter avfilter_af_asyncts = {
|
||||
|
@@ -1040,7 +1040,7 @@ static void push_samples(ATempoContext *atempo,
|
||||
atempo->nsamples_out += n_out;
|
||||
}
|
||||
|
||||
static void filter_samples(AVFilterLink *inlink,
|
||||
static int filter_samples(AVFilterLink *inlink,
|
||||
AVFilterBufferRef *src_buffer)
|
||||
{
|
||||
AVFilterContext *ctx = inlink->dst;
|
||||
@@ -1074,6 +1074,7 @@ static void filter_samples(AVFilterLink *inlink,
|
||||
|
||||
atempo->nsamples_in += n_in;
|
||||
avfilter_unref_bufferp(&src_buffer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int request_frame(AVFilterLink *outlink)
|
||||
|
@@ -313,7 +313,7 @@ static int channelmap_query_formats(AVFilterContext *ctx)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void channelmap_filter_samples(AVFilterLink *inlink, AVFilterBufferRef *buf)
|
||||
static int channelmap_filter_samples(AVFilterLink *inlink, AVFilterBufferRef *buf)
|
||||
{
|
||||
AVFilterContext *ctx = inlink->dst;
|
||||
AVFilterLink *outlink = ctx->outputs[0];
|
||||
@@ -330,8 +330,10 @@ static void channelmap_filter_samples(AVFilterLink *inlink, AVFilterBufferRef *b
|
||||
if (nch_out > FF_ARRAY_ELEMS(buf->data)) {
|
||||
uint8_t **new_extended_data =
|
||||
av_mallocz(nch_out * sizeof(*buf->extended_data));
|
||||
if (!new_extended_data)
|
||||
return;
|
||||
if (!new_extended_data) {
|
||||
avfilter_unref_buffer(buf);
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
if (buf->extended_data == buf->data) {
|
||||
buf->extended_data = new_extended_data;
|
||||
} else {
|
||||
@@ -353,7 +355,7 @@ static void channelmap_filter_samples(AVFilterLink *inlink, AVFilterBufferRef *b
|
||||
memcpy(buf->data, buf->extended_data,
|
||||
FFMIN(FF_ARRAY_ELEMS(buf->data), nch_out) * sizeof(buf->data[0]));
|
||||
|
||||
ff_filter_samples(outlink, buf);
|
||||
return ff_filter_samples(outlink, buf);
|
||||
}
|
||||
|
||||
static int channelmap_config_input(AVFilterLink *inlink)
|
||||
|
@@ -105,24 +105,29 @@ static int query_formats(AVFilterContext *ctx)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *buf)
|
||||
static int filter_samples(AVFilterLink *inlink, AVFilterBufferRef *buf)
|
||||
{
|
||||
AVFilterContext *ctx = inlink->dst;
|
||||
int i;
|
||||
int i, ret = 0;
|
||||
|
||||
for (i = 0; i < ctx->nb_outputs; i++) {
|
||||
AVFilterBufferRef *buf_out = avfilter_ref_buffer(buf, ~AV_PERM_WRITE);
|
||||
|
||||
if (!buf_out)
|
||||
return;
|
||||
if (!buf_out) {
|
||||
ret = AVERROR(ENOMEM);
|
||||
break;
|
||||
}
|
||||
|
||||
buf_out->data[0] = buf_out->extended_data[0] = buf_out->extended_data[i];
|
||||
buf_out->audio->channel_layout =
|
||||
av_channel_layout_extract_channel(buf->audio->channel_layout, i);
|
||||
|
||||
ff_filter_samples(ctx->outputs[i], buf_out);
|
||||
ret = ff_filter_samples(ctx->outputs[i], buf_out);
|
||||
if (ret < 0)
|
||||
break;
|
||||
}
|
||||
avfilter_unref_buffer(buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
AVFilter avfilter_af_channelsplit = {
|
||||
|
@@ -120,13 +120,15 @@ static inline int16_t *scalarproduct(const int16_t *in, const int16_t *endin, in
|
||||
return out;
|
||||
}
|
||||
|
||||
static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *insamples)
|
||||
static int filter_samples(AVFilterLink *inlink, AVFilterBufferRef *insamples)
|
||||
{
|
||||
AVFilterLink *outlink = inlink->dst->outputs[0];
|
||||
int16_t *taps, *endin, *in, *out;
|
||||
AVFilterBufferRef *outsamples =
|
||||
ff_get_audio_buffer(inlink, AV_PERM_WRITE,
|
||||
insamples->audio->nb_samples);
|
||||
int ret;
|
||||
|
||||
avfilter_copy_buffer_ref_props(outsamples, insamples);
|
||||
|
||||
taps = ((EarwaxContext *)inlink->dst->priv)->taps;
|
||||
@@ -144,8 +146,9 @@ static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *insamples)
|
||||
// save part of input for next round
|
||||
memcpy(taps, endin, NUMTAPS * sizeof(*taps));
|
||||
|
||||
ff_filter_samples(outlink, outsamples);
|
||||
ret = ff_filter_samples(outlink, outsamples);
|
||||
avfilter_unref_buffer(insamples);
|
||||
return ret;
|
||||
}
|
||||
|
||||
AVFilter avfilter_af_earwax = {
|
||||
|
@@ -92,7 +92,7 @@ static const AVClass join_class = {
|
||||
.version = LIBAVUTIL_VERSION_INT,
|
||||
};
|
||||
|
||||
static void filter_samples(AVFilterLink *link, AVFilterBufferRef *buf)
|
||||
static int filter_samples(AVFilterLink *link, AVFilterBufferRef *buf)
|
||||
{
|
||||
AVFilterContext *ctx = link->dst;
|
||||
JoinContext *s = ctx->priv;
|
||||
@@ -104,6 +104,8 @@ static void filter_samples(AVFilterLink *link, AVFilterBufferRef *buf)
|
||||
av_assert0(i < ctx->nb_inputs);
|
||||
av_assert0(!s->input_frames[i]);
|
||||
s->input_frames[i] = buf;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int parse_maps(AVFilterContext *ctx)
|
||||
@@ -468,11 +470,11 @@ static int join_request_frame(AVFilterLink *outlink)
|
||||
priv->nb_in_buffers = ctx->nb_inputs;
|
||||
buf->buf->priv = priv;
|
||||
|
||||
ff_filter_samples(outlink, buf);
|
||||
ret = ff_filter_samples(outlink, buf);
|
||||
|
||||
memset(s->input_frames, 0, sizeof(*s->input_frames) * ctx->nb_inputs);
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
|
||||
fail:
|
||||
avfilter_unref_buffer(buf);
|
||||
|
@@ -343,8 +343,9 @@ static int config_props(AVFilterLink *link)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *insamples)
|
||||
static int filter_samples(AVFilterLink *inlink, AVFilterBufferRef *insamples)
|
||||
{
|
||||
int ret;
|
||||
int n = insamples->audio->nb_samples;
|
||||
AVFilterLink *const outlink = inlink->dst->outputs[0];
|
||||
AVFilterBufferRef *outsamples = ff_get_audio_buffer(outlink, AV_PERM_WRITE, n);
|
||||
@@ -354,8 +355,9 @@ static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *insamples)
|
||||
avfilter_copy_buffer_ref_props(outsamples, insamples);
|
||||
outsamples->audio->channel_layout = outlink->channel_layout;
|
||||
|
||||
ff_filter_samples(outlink, outsamples);
|
||||
ret = ff_filter_samples(outlink, outsamples);
|
||||
avfilter_unref_buffer(insamples);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static av_cold void uninit(AVFilterContext *ctx)
|
||||
|
@@ -38,6 +38,9 @@ typedef struct ResampleContext {
|
||||
AVAudioResampleContext *avr;
|
||||
|
||||
int64_t next_pts;
|
||||
|
||||
/* set by filter_samples() to signal an output frame to request_frame() */
|
||||
int got_output;
|
||||
} ResampleContext;
|
||||
|
||||
static av_cold void uninit(AVFilterContext *ctx)
|
||||
@@ -102,12 +105,6 @@ static int config_output(AVFilterLink *outlink)
|
||||
av_opt_set_int(s->avr, "in_sample_rate", inlink ->sample_rate, 0);
|
||||
av_opt_set_int(s->avr, "out_sample_rate", outlink->sample_rate, 0);
|
||||
|
||||
/* if both the input and output formats are s16 or u8, use s16 as
|
||||
the internal sample format */
|
||||
if (av_get_bytes_per_sample(inlink->format) <= 2 &&
|
||||
av_get_bytes_per_sample(outlink->format) <= 2)
|
||||
av_opt_set_int(s->avr, "internal_sample_fmt", AV_SAMPLE_FMT_S16P, 0);
|
||||
|
||||
if ((ret = avresample_open(s->avr)) < 0)
|
||||
return ret;
|
||||
|
||||
@@ -130,7 +127,11 @@ static int request_frame(AVFilterLink *outlink)
|
||||
{
|
||||
AVFilterContext *ctx = outlink->src;
|
||||
ResampleContext *s = ctx->priv;
|
||||
int ret = ff_request_frame(ctx->inputs[0]);
|
||||
int ret = 0;
|
||||
|
||||
s->got_output = 0;
|
||||
while (ret >= 0 && !s->got_output)
|
||||
ret = ff_request_frame(ctx->inputs[0]);
|
||||
|
||||
/* flush the lavr delay buffer */
|
||||
if (ret == AVERROR_EOF && s->avr) {
|
||||
@@ -156,21 +157,21 @@ static int request_frame(AVFilterLink *outlink)
|
||||
}
|
||||
|
||||
buf->pts = s->next_pts;
|
||||
ff_filter_samples(outlink, buf);
|
||||
return 0;
|
||||
return ff_filter_samples(outlink, buf);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *buf)
|
||||
static int filter_samples(AVFilterLink *inlink, AVFilterBufferRef *buf)
|
||||
{
|
||||
AVFilterContext *ctx = inlink->dst;
|
||||
ResampleContext *s = ctx->priv;
|
||||
AVFilterLink *outlink = ctx->outputs[0];
|
||||
int ret;
|
||||
|
||||
if (s->avr) {
|
||||
AVFilterBufferRef *buf_out;
|
||||
int delay, nb_samples, ret;
|
||||
int delay, nb_samples;
|
||||
|
||||
/* maximum possible samples lavr can output */
|
||||
delay = avresample_get_delay(s->avr);
|
||||
@@ -179,10 +180,19 @@ static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *buf)
|
||||
AV_ROUND_UP);
|
||||
|
||||
buf_out = ff_get_audio_buffer(outlink, AV_PERM_WRITE, nb_samples);
|
||||
if (!buf_out) {
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ret = avresample_convert(s->avr, (void**)buf_out->extended_data,
|
||||
buf_out->linesize[0], nb_samples,
|
||||
(void**)buf->extended_data, buf->linesize[0],
|
||||
buf->audio->nb_samples);
|
||||
if (ret < 0) {
|
||||
avfilter_unref_buffer(buf_out);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
av_assert0(!avresample_available(s->avr));
|
||||
|
||||
@@ -208,11 +218,18 @@ static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *buf)
|
||||
|
||||
s->next_pts = buf_out->pts + buf_out->audio->nb_samples;
|
||||
|
||||
ff_filter_samples(outlink, buf_out);
|
||||
ret = ff_filter_samples(outlink, buf_out);
|
||||
s->got_output = 1;
|
||||
}
|
||||
|
||||
fail:
|
||||
avfilter_unref_buffer(buf);
|
||||
} else
|
||||
ff_filter_samples(outlink, buf);
|
||||
} else {
|
||||
ret = ff_filter_samples(outlink, buf);
|
||||
s->got_output = 1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
AVFilter avfilter_af_resample = {
|
||||
|
@@ -78,7 +78,7 @@ static av_cold int init(AVFilterContext *ctx, const char *args)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *insamples)
|
||||
static int filter_samples(AVFilterLink *inlink, AVFilterBufferRef *insamples)
|
||||
{
|
||||
int i;
|
||||
SilenceDetectContext *silence = inlink->dst->priv;
|
||||
@@ -118,7 +118,7 @@ static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *insamples)
|
||||
}
|
||||
}
|
||||
|
||||
ff_filter_samples(inlink->dst->outputs[0], insamples);
|
||||
return ff_filter_samples(inlink->dst->outputs[0], insamples);
|
||||
}
|
||||
|
||||
static int query_formats(AVFilterContext *ctx)
|
||||
|
@@ -110,7 +110,7 @@ static int query_formats(AVFilterContext *ctx)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *insamples)
|
||||
static int filter_samples(AVFilterLink *inlink, AVFilterBufferRef *insamples)
|
||||
{
|
||||
VolumeContext *vol = inlink->dst->priv;
|
||||
AVFilterLink *outlink = inlink->dst->outputs[0];
|
||||
@@ -169,7 +169,7 @@ static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *insamples)
|
||||
}
|
||||
}
|
||||
}
|
||||
ff_filter_samples(outlink, insamples);
|
||||
return ff_filter_samples(outlink, insamples);
|
||||
}
|
||||
|
||||
AVFilter avfilter_af_volume = {
|
||||
|
@@ -21,7 +21,10 @@
|
||||
#include "avfilter.h"
|
||||
#include "internal.h"
|
||||
|
||||
static void null_filter_samples(AVFilterLink *link, AVFilterBufferRef *samplesref) { }
|
||||
static int null_filter_samples(AVFilterLink *link, AVFilterBufferRef *samplesref)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
AVFilter avfilter_asink_anullsink = {
|
||||
.name = "anullsink",
|
||||
|
@@ -150,19 +150,19 @@ fail:
|
||||
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 *dst = link->dstpad;
|
||||
int64_t pts;
|
||||
AVFilterBufferRef *buf_out;
|
||||
int ret;
|
||||
|
||||
FF_TPRINTF_START(NULL, filter_samples); ff_tlog_link(NULL, link, 1);
|
||||
|
||||
@@ -193,21 +193,22 @@ void ff_filter_samples_framed(AVFilterLink *link,
|
||||
|
||||
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) {
|
||||
@@ -218,7 +219,7 @@ void ff_filter_samples(AVFilterLink *link, AVFilterBufferRef *samplesref)
|
||||
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 +
|
||||
@@ -234,10 +235,11 @@ void ff_filter_samples(AVFilterLink *link, AVFilterBufferRef *samplesref)
|
||||
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;
|
||||
}
|
||||
|
@@ -70,14 +70,17 @@ AVFilterBufferRef *ff_get_audio_buffer(AVFilterLink *link, int perms,
|
||||
* @param samplesref a reference to the buffer of audio samples being sent. The
|
||||
* receiving filter will free this reference when it no longer
|
||||
* needs it or pass it on to the next filter.
|
||||
*
|
||||
* @return >= 0 on success, a negative AVERROR on error. The receiving filter
|
||||
* is responsible for unreferencing samplesref in case of error.
|
||||
*/
|
||||
void ff_filter_samples(AVFilterLink *link, AVFilterBufferRef *samplesref);
|
||||
int ff_filter_samples(AVFilterLink *link, AVFilterBufferRef *samplesref);
|
||||
|
||||
/**
|
||||
* Send a buffer of audio samples to the next link, without checking
|
||||
* min_samples.
|
||||
*/
|
||||
void ff_filter_samples_framed(AVFilterLink *link,
|
||||
int ff_filter_samples_framed(AVFilterLink *link,
|
||||
AVFilterBufferRef *samplesref);
|
||||
|
||||
#endif /* AVFILTER_AUDIO_H */
|
||||
|
@@ -180,7 +180,7 @@ static int request_frame(AVFilterLink *outlink)
|
||||
|
||||
#define MAX_INT16 ((1<<15) -1)
|
||||
|
||||
static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *insamples)
|
||||
static int filter_samples(AVFilterLink *inlink, AVFilterBufferRef *insamples)
|
||||
{
|
||||
AVFilterContext *ctx = inlink->dst;
|
||||
AVFilterLink *outlink = ctx->outputs[0];
|
||||
@@ -225,6 +225,7 @@ static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *insamples)
|
||||
}
|
||||
|
||||
avfilter_unref_buffer(insamples);
|
||||
return 0;
|
||||
}
|
||||
|
||||
AVFilter avfilter_avf_showwaves = {
|
||||
|
@@ -301,8 +301,12 @@ struct AVFilterPad {
|
||||
* and should do its processing.
|
||||
*
|
||||
* Input audio pads only.
|
||||
*
|
||||
* @return >= 0 on success, a negative AVERROR on error. This function
|
||||
* must ensure that samplesref is properly unreferenced on error if it
|
||||
* hasn't been passed on to another filter.
|
||||
*/
|
||||
void (*filter_samples)(AVFilterLink *link, AVFilterBufferRef *samplesref);
|
||||
int (*filter_samples)(AVFilterLink *link, AVFilterBufferRef *samplesref);
|
||||
|
||||
/**
|
||||
* Frame poll callback. This returns the number of immediately available
|
||||
|
@@ -56,6 +56,12 @@ static void start_frame(AVFilterLink *link, AVFilterBufferRef *buf)
|
||||
link->cur_buf = NULL;
|
||||
};
|
||||
|
||||
static int filter_samples(AVFilterLink *link, AVFilterBufferRef *buf)
|
||||
{
|
||||
start_frame(link, buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int av_buffersink_read(AVFilterContext *ctx, AVFilterBufferRef **buf)
|
||||
{
|
||||
BufferSinkContext *s = ctx->priv;
|
||||
@@ -160,7 +166,7 @@ AVFilter avfilter_asink_abuffer = {
|
||||
|
||||
.inputs = (AVFilterPad[]) {{ .name = "default",
|
||||
.type = AVMEDIA_TYPE_AUDIO,
|
||||
.filter_samples = start_frame,
|
||||
.filter_samples = filter_samples,
|
||||
.min_perms = AV_PERM_READ,
|
||||
.needs_fifo = 1 },
|
||||
{ .name = NULL }},
|
||||
|
@@ -408,6 +408,7 @@ static int request_frame(AVFilterLink *link)
|
||||
{
|
||||
BufferSourceContext *c = link->src->priv;
|
||||
AVFilterBufferRef *buf;
|
||||
int ret = 0;
|
||||
|
||||
if (!av_fifo_size(c->fifo)) {
|
||||
if (c->eof)
|
||||
@@ -424,7 +425,7 @@ static int request_frame(AVFilterLink *link)
|
||||
ff_end_frame(link);
|
||||
break;
|
||||
case AVMEDIA_TYPE_AUDIO:
|
||||
ff_filter_samples(link, avfilter_ref_buffer(buf, ~0));
|
||||
ret = ff_filter_samples(link, avfilter_ref_buffer(buf, ~0));
|
||||
break;
|
||||
default:
|
||||
return AVERROR(EINVAL);
|
||||
@@ -432,7 +433,7 @@ static int request_frame(AVFilterLink *link)
|
||||
|
||||
avfilter_unref_buffer(buf);
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int poll_frame(AVFilterLink *link)
|
||||
|
@@ -117,7 +117,7 @@ static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref)
|
||||
ff_start_frame(outlink, picref2);
|
||||
}
|
||||
|
||||
static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *insamples)
|
||||
static int filter_samples(AVFilterLink *inlink, AVFilterBufferRef *insamples)
|
||||
{
|
||||
AVFilterContext *ctx = inlink->dst;
|
||||
AVFilterLink *outlink = ctx->outputs[0];
|
||||
@@ -132,7 +132,7 @@ static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *insamples)
|
||||
avfilter_unref_buffer(insamples);
|
||||
}
|
||||
|
||||
ff_filter_samples(outlink, outsamples);
|
||||
return ff_filter_samples(outlink, outsamples);
|
||||
}
|
||||
|
||||
#if CONFIG_SETTB_FILTER
|
||||
|
@@ -72,13 +72,25 @@ static av_cold void uninit(AVFilterContext *ctx)
|
||||
avfilter_unref_buffer(fifo->buf_out);
|
||||
}
|
||||
|
||||
static void add_to_queue(AVFilterLink *inlink, AVFilterBufferRef *buf)
|
||||
static int add_to_queue(AVFilterLink *inlink, AVFilterBufferRef *buf)
|
||||
{
|
||||
FifoContext *fifo = inlink->dst->priv;
|
||||
|
||||
fifo->last->next = av_mallocz(sizeof(Buf));
|
||||
if (!fifo->last->next) {
|
||||
avfilter_unref_buffer(buf);
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
|
||||
fifo->last = fifo->last->next;
|
||||
fifo->last->buf = buf;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *buf)
|
||||
{
|
||||
add_to_queue(inlink, buf);
|
||||
}
|
||||
|
||||
static void queue_pop(FifoContext *s)
|
||||
@@ -210,15 +222,13 @@ static int return_audio_frame(AVFilterContext *ctx)
|
||||
buf_out = s->buf_out;
|
||||
s->buf_out = NULL;
|
||||
}
|
||||
ff_filter_samples(link, buf_out);
|
||||
|
||||
return 0;
|
||||
return ff_filter_samples(link, buf_out);
|
||||
}
|
||||
|
||||
static int request_frame(AVFilterLink *outlink)
|
||||
{
|
||||
FifoContext *fifo = outlink->src->priv;
|
||||
int ret;
|
||||
int ret = 0;
|
||||
|
||||
if (!fifo->root.next) {
|
||||
if ((ret = ff_request_frame(outlink->src->inputs[0])) < 0)
|
||||
@@ -238,7 +248,7 @@ static int request_frame(AVFilterLink *outlink)
|
||||
if (outlink->request_samples) {
|
||||
return return_audio_frame(outlink->src);
|
||||
} else {
|
||||
ff_filter_samples(outlink, fifo->root.next->buf);
|
||||
ret = ff_filter_samples(outlink, fifo->root.next->buf);
|
||||
queue_pop(fifo);
|
||||
}
|
||||
break;
|
||||
@@ -246,7 +256,7 @@ static int request_frame(AVFilterLink *outlink)
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
AVFilter avfilter_vf_fifo = {
|
||||
@@ -261,7 +271,7 @@ AVFilter avfilter_vf_fifo = {
|
||||
.inputs = (const AVFilterPad[]) {{ .name = "default",
|
||||
.type = AVMEDIA_TYPE_VIDEO,
|
||||
.get_video_buffer= ff_null_get_video_buffer,
|
||||
.start_frame = add_to_queue,
|
||||
.start_frame = start_frame,
|
||||
.draw_slice = draw_slice,
|
||||
.end_frame = end_frame,
|
||||
.rej_perms = AV_PERM_REUSE2, },
|
||||
|
@@ -135,8 +135,12 @@ struct AVFilterPad {
|
||||
* and should do its processing.
|
||||
*
|
||||
* Input audio pads only.
|
||||
*
|
||||
* @return >= 0 on success, a negative AVERROR on error. This function
|
||||
* must ensure that samplesref is properly unreferenced on error if it
|
||||
* hasn't been passed on to another filter.
|
||||
*/
|
||||
void (*filter_samples)(AVFilterLink *link, AVFilterBufferRef *samplesref);
|
||||
int (*filter_samples)(AVFilterLink *link, AVFilterBufferRef *samplesref);
|
||||
|
||||
/**
|
||||
* Frame poll callback. This returns the number of immediately available
|
||||
|
@@ -244,9 +244,10 @@ AVFilter avfilter_vsink_buffersink = {
|
||||
|
||||
#if CONFIG_ABUFFERSINK_FILTER
|
||||
|
||||
static void filter_samples(AVFilterLink *link, AVFilterBufferRef *samplesref)
|
||||
static int filter_samples(AVFilterLink *link, AVFilterBufferRef *samplesref)
|
||||
{
|
||||
end_frame(link);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static av_cold int asink_init(AVFilterContext *ctx, const char *args)
|
||||
|
@@ -110,15 +110,19 @@ AVFilter avfilter_vf_split = {
|
||||
.outputs = (AVFilterPad[]) {{ .name = NULL}},
|
||||
};
|
||||
|
||||
static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *samplesref)
|
||||
static int filter_samples(AVFilterLink *inlink, AVFilterBufferRef *samplesref)
|
||||
{
|
||||
AVFilterContext *ctx = inlink->dst;
|
||||
int i;
|
||||
int i, ret = 0;
|
||||
|
||||
for (i = 0; i < ctx->nb_outputs; i++)
|
||||
ff_filter_samples(inlink->dst->outputs[i],
|
||||
avfilter_ref_buffer(samplesref, ~AV_PERM_WRITE));
|
||||
for (i = 0; i < ctx->nb_outputs; i++) {
|
||||
ret = ff_filter_samples(inlink->dst->outputs[i],
|
||||
avfilter_ref_buffer(samplesref, ~AV_PERM_WRITE));
|
||||
if (ret < 0)
|
||||
break;
|
||||
}
|
||||
avfilter_unref_buffer(samplesref);
|
||||
return ret;
|
||||
}
|
||||
|
||||
AVFilter avfilter_af_asplit = {
|
||||
|
Reference in New Issue
Block a user