static int activate(AVFilterContext *ctx) { AVFilterLink *inlink = ctx->inputs[0]; AVFilterLink *outlink = ctx->outputs[0]; CueContext *s = ctx->priv; int64_t pts; AVFrame *frame = NULL; FF_FILTER_FORWARD_STATUS_BACK(outlink, inlink); if (s->status < 3 || s->status == 5) { int ret = ff_inlink_consume_frame(inlink, &frame); if (ret < 0) return ret; if (frame) pts = av_rescale_q(frame->pts, inlink->time_base, AV_TIME_BASE_Q); } if (!s->status && frame) { s->first_pts = pts; s->status++; } if (s->status == 1 && frame) { if (pts - s->first_pts < s->preroll) return ff_filter_frame(outlink, frame); s->first_pts = pts; s->status++; } if (s->status == 2 && frame) { int ret = ff_framequeue_add(&s->queue, frame); if (ret < 0) { av_frame_free(&frame); return ret; } frame = NULL; if (!(pts - s->first_pts < s->buffer && (av_gettime() - s->cue) < 0)) s->status++; } if (s->status == 3) { int64_t diff; while ((diff = (av_gettime() - s->cue)) < 0) av_usleep(av_clip(-diff / 2, 100, 1000000)); s->status++; } if (s->status == 4) { if (ff_framequeue_queued_frames(&s->queue)) return ff_filter_frame(outlink, ff_framequeue_take(&s->queue)); s->status++; } if (s->status == 5 && frame) return ff_filter_frame(outlink, frame); FF_FILTER_FORWARD_STATUS(inlink, outlink); FF_FILTER_FORWARD_WANTED(outlink, inlink); return FFERROR_NOT_READY; }
int ff_filter_frame(AVFilterLink *link, AVFrame *frame) { int ret; FF_TPRINTF_START(NULL, filter_frame); ff_tlog_link(NULL, link, 1); ff_tlog(NULL, " "); ff_tlog_ref(NULL, frame, 1); /* Consistency checks */ if (link->type == AVMEDIA_TYPE_VIDEO) { if (strcmp(link->dst->filter->name, "buffersink") && strcmp(link->dst->filter->name, "format") && strcmp(link->dst->filter->name, "idet") && strcmp(link->dst->filter->name, "null") && strcmp(link->dst->filter->name, "scale")) { av_assert1(frame->format == link->format); av_assert1(frame->width == link->w); av_assert1(frame->height == link->h); } } else { if (frame->format != link->format) { av_log(link->dst, AV_LOG_ERROR, "Format change is not supported\n"); goto error; } if (av_frame_get_channels(frame) != link->channels) { av_log(link->dst, AV_LOG_ERROR, "Channel count change is not supported\n"); goto error; } if (frame->channel_layout != link->channel_layout) { av_log(link->dst, AV_LOG_ERROR, "Channel layout change is not supported\n"); goto error; } if (frame->sample_rate != link->sample_rate) { av_log(link->dst, AV_LOG_ERROR, "Sample rate change is not supported\n"); goto error; } } link->frame_blocked_in = link->frame_wanted_out = 0; link->frame_count_in++; filter_unblock(link->dst); ret = ff_framequeue_add(&link->fifo, frame); if (ret < 0) { av_frame_free(&frame); return ret; } ff_filter_set_ready(link->dst, 300); return 0; error: av_frame_free(&frame); return AVERROR_PATCHWELCOME; }