static int filter_frame(AVFilterLink *inlink, AVFrame *buf) { AVFilterContext *ctx = inlink->dst; MixContext *s = ctx->priv; AVFilterLink *outlink = ctx->outputs[0]; 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"); ret = AVERROR(EINVAL); goto fail; } if (i == 0) { int64_t pts = av_rescale_q(buf->pts, inlink->time_base, outlink->time_base); ret = frame_list_add_frame(s->frame_list, buf->nb_samples, pts); if (ret < 0) goto fail; } ret = av_audio_fifo_write(s->fifos[i], (void **)buf->extended_data, buf->nb_samples); fail: av_frame_free(&buf); return ret; }
static int activate(AVFilterContext *ctx) { AVFilterLink *outlink = ctx->outputs[0]; MixContext *s = ctx->priv; AVFrame *buf = NULL; int i, ret; for (i = 0; i < s->nb_inputs; i++) { AVFilterLink *inlink = ctx->inputs[i]; if ((ret = ff_inlink_consume_frame(ctx->inputs[i], &buf)) > 0) { if (i == 0) { int64_t pts = av_rescale_q(buf->pts, inlink->time_base, outlink->time_base); ret = frame_list_add_frame(s->frame_list, buf->nb_samples, pts); if (ret < 0) { av_frame_free(&buf); return ret; } } ret = av_audio_fifo_write(s->fifos[i], (void **)buf->extended_data, buf->nb_samples); if (ret < 0) { av_frame_free(&buf); return ret; } av_frame_free(&buf); ret = output_frame(outlink); if (ret < 0) return ret; } } for (i = 0; i < s->nb_inputs; i++) { int64_t pts; int status; if (ff_inlink_acknowledge_status(ctx->inputs[i], &status, &pts)) { if (status == AVERROR_EOF) { if (i == 0) { s->input_state[i] = 0; if (s->nb_inputs == 1) { ff_outlink_set_status(outlink, status, pts); return 0; } } else { s->input_state[i] |= INPUT_EOF; if (av_audio_fifo_size(s->fifos[i]) == 0) { s->input_state[i] = 0; } } } } } if (calc_active_inputs(s)) { ff_outlink_set_status(outlink, AVERROR_EOF, s->next_pts); return 0; } if (ff_outlink_frame_wanted(outlink)) { int wanted_samples; if (!(s->input_state[0] & INPUT_ON)) return request_samples(ctx, 1); if (s->frame_list->nb_frames == 0) { ff_inlink_request_frame(ctx->inputs[0]); return 0; } av_assert0(s->frame_list->nb_frames > 0); wanted_samples = frame_list_next_frame_size(s->frame_list); return request_samples(ctx, wanted_samples); } return 0; }