static int request_frame(AVFilterLink *outlink) { AVFilterContext *ctx = outlink->src; ZPContext *s = ctx->priv; AVFrame *in = s->in; double zoom, dx, dy; int ret; if (in) { ret = output_single_frame(ctx, in, s->var_values, s->current_frame, &zoom, &dx, &dy); if (ret < 0) goto fail; } if (s->current_frame >= s->nb_frames) { s->x = dx; s->y = dy; s->prev_zoom = zoom; s->prev_nb_frames = s->nb_frames; s->nb_frames = 0; s->current_frame = 0; av_frame_free(&s->in); ret = 0; s->finished = 1; ret = ff_request_frame(ctx->inputs[0]); } fail: sws_freeContext(s->sws); s->sws = NULL; return ret; }
static int activate(AVFilterContext *ctx) { ZPContext *s = ctx->priv; AVFilterLink *inlink = ctx->inputs[0]; AVFilterLink *outlink = ctx->outputs[0]; int status, ret = 0; int64_t pts; if (s->in && ff_outlink_frame_wanted(outlink)) { double zoom = -1, dx = -1, dy = -1; ret = output_single_frame(ctx, s->in, s->var_values, s->current_frame, &zoom, &dx, &dy); if (ret < 0) return ret; } if (!s->in && (ret = ff_inlink_consume_frame(inlink, &s->in)) > 0) { double zoom = -1, dx = -1, dy = -1, nb_frames; s->finished = 0; s->var_values[VAR_IN_W] = s->var_values[VAR_IW] = s->in->width; s->var_values[VAR_IN_H] = s->var_values[VAR_IH] = s->in->height; s->var_values[VAR_OUT_W] = s->var_values[VAR_OW] = s->w; s->var_values[VAR_OUT_H] = s->var_values[VAR_OH] = s->h; s->var_values[VAR_IN] = inlink->frame_count_out + 1; s->var_values[VAR_ON] = outlink->frame_count_in + 1; s->var_values[VAR_PX] = s->x; s->var_values[VAR_PY] = s->y; s->var_values[VAR_X] = 0; s->var_values[VAR_Y] = 0; s->var_values[VAR_PZOOM] = s->prev_zoom; s->var_values[VAR_ZOOM] = 1; s->var_values[VAR_PDURATION] = s->prev_nb_frames; s->var_values[VAR_A] = (double) s->in->width / s->in->height; s->var_values[VAR_SAR] = inlink->sample_aspect_ratio.num ? (double) inlink->sample_aspect_ratio.num / inlink->sample_aspect_ratio.den : 1; s->var_values[VAR_DAR] = s->var_values[VAR_A] * s->var_values[VAR_SAR]; s->var_values[VAR_HSUB] = 1 << s->desc->log2_chroma_w; s->var_values[VAR_VSUB] = 1 << s->desc->log2_chroma_h; if ((ret = av_expr_parse_and_eval(&nb_frames, s->duration_expr_str, var_names, s->var_values, NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0) { av_frame_free(&s->in); return ret; } s->var_values[VAR_DURATION] = s->nb_frames = nb_frames; ret = output_single_frame(ctx, s->in, s->var_values, s->current_frame, &zoom, &dx, &dy); if (ret < 0) return ret; } if (ret < 0) { return ret; } else if (s->finished && ff_inlink_acknowledge_status(inlink, &status, &pts)) { ff_outlink_set_status(outlink, status, pts); return 0; } else { if (ff_outlink_frame_wanted(outlink) && s->finished) ff_inlink_request_frame(inlink); return 0; } }