Пример #1
0
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;
}
Пример #2
0
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;
}