static int request_frame(AVFilterLink *outlink) { AVFilterContext *ctx = outlink->src; MixContext *s = ctx->priv; int ret; int wanted_samples; ret = calc_active_inputs(s); if (ret < 0) return ret; if (!(s->input_state[0] & INPUT_ON)) return request_samples(ctx, 1); if (s->frame_list->nb_frames == 0) { ret = ff_request_frame(ctx->inputs[0]); if (ret == AVERROR_EOF) { s->input_state[0] = 0; if (s->nb_inputs == 1) return AVERROR_EOF; return output_frame(ctx->outputs[0]); } return ret; } av_assert0(s->frame_list->nb_frames > 0); wanted_samples = frame_list_next_frame_size(s->frame_list); return request_samples(ctx, wanted_samples); }
static int request_frame(AVFilterLink *outlink) { AVFilterContext *ctx = outlink->src; MixContext *s = ctx->priv; int ret; int wanted_samples, available_samples; ret = calc_active_inputs(s); if (ret < 0) return ret; if (s->input_state[0] == INPUT_OFF) { ret = request_samples(ctx, 1); if (ret < 0) return ret; ret = calc_active_inputs(s); if (ret < 0) return ret; available_samples = get_available_samples(s); if (!available_samples) return AVERROR(EAGAIN); return output_frame(outlink, available_samples); } if (s->frame_list->nb_frames == 0) { ret = ff_request_frame(ctx->inputs[0]); if (ret == AVERROR_EOF) { s->input_state[0] = INPUT_OFF; if (s->nb_inputs == 1) return AVERROR_EOF; else return AVERROR(EAGAIN); } else if (ret < 0) return ret; } av_assert0(s->frame_list->nb_frames > 0); wanted_samples = frame_list_next_frame_size(s->frame_list); if (s->active_inputs > 1) { ret = request_samples(ctx, wanted_samples); if (ret < 0) return ret; ret = calc_active_inputs(s); if (ret < 0) return ret; } if (s->active_inputs > 1) { available_samples = get_available_samples(s); if (!available_samples) return AVERROR(EAGAIN); available_samples = FFMIN(available_samples, wanted_samples); } else { available_samples = wanted_samples; } s->next_pts = frame_list_next_pts(s->frame_list); frame_list_remove_samples(s->frame_list, available_samples); return output_frame(outlink, available_samples); }
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; }