You've already forked FFmpeg
mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-08-15 14:13:16 +02:00
avfilter/vf_zoompan: switch to activate
Fixes #5182. Signed-off-by: Paul B Mahol <onemda@gmail.com>
This commit is contained in:
@@ -23,6 +23,7 @@
|
|||||||
#include "libavutil/opt.h"
|
#include "libavutil/opt.h"
|
||||||
#include "libavutil/pixdesc.h"
|
#include "libavutil/pixdesc.h"
|
||||||
#include "avfilter.h"
|
#include "avfilter.h"
|
||||||
|
#include "filters.h"
|
||||||
#include "formats.h"
|
#include "formats.h"
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
#include "video.h"
|
#include "video.h"
|
||||||
@@ -217,97 +218,91 @@ static int output_single_frame(AVFilterContext *ctx, AVFrame *in, double *var_va
|
|||||||
sws_freeContext(s->sws);
|
sws_freeContext(s->sws);
|
||||||
s->sws = NULL;
|
s->sws = NULL;
|
||||||
s->current_frame++;
|
s->current_frame++;
|
||||||
|
|
||||||
|
if (s->current_frame >= s->nb_frames) {
|
||||||
|
if (*dx != -1)
|
||||||
|
s->x = *dx;
|
||||||
|
if (*dy != -1)
|
||||||
|
s->y = *dy;
|
||||||
|
if (*zoom != -1)
|
||||||
|
s->prev_zoom = *zoom;
|
||||||
|
s->prev_nb_frames = s->nb_frames;
|
||||||
|
s->nb_frames = 0;
|
||||||
|
s->current_frame = 0;
|
||||||
|
av_frame_free(&s->in);
|
||||||
|
s->finished = 1;
|
||||||
|
}
|
||||||
return ret;
|
return ret;
|
||||||
error:
|
error:
|
||||||
av_frame_free(&out);
|
av_frame_free(&out);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
|
static int activate(AVFilterContext *ctx)
|
||||||
{
|
{
|
||||||
AVFilterContext *ctx = inlink->dst;
|
ZPContext *s = ctx->priv;
|
||||||
|
AVFilterLink *inlink = ctx->inputs[0];
|
||||||
AVFilterLink *outlink = ctx->outputs[0];
|
AVFilterLink *outlink = ctx->outputs[0];
|
||||||
ZPContext *s = ctx->priv;
|
int status, ret = 0;
|
||||||
double nb_frames;
|
int64_t pts;
|
||||||
int ret;
|
|
||||||
|
|
||||||
av_assert0(s->in == NULL);
|
if (s->in && ff_outlink_frame_wanted(outlink)) {
|
||||||
|
double zoom = -1, dx = -1, dy = -1;
|
||||||
|
|
||||||
s->finished = 0;
|
ret = output_single_frame(ctx, s->in, s->var_values, s->current_frame,
|
||||||
s->var_values[VAR_IN_W] = s->var_values[VAR_IW] = in->width;
|
|
||||||
s->var_values[VAR_IN_H] = s->var_values[VAR_IH] = 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) in->width / 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(&in);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
s->var_values[VAR_DURATION] = s->nb_frames = nb_frames;
|
|
||||||
s->in = in;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int request_frame(AVFilterLink *outlink)
|
|
||||||
{
|
|
||||||
AVFilterContext *ctx = outlink->src;
|
|
||||||
ZPContext *s = ctx->priv;
|
|
||||||
AVFrame *in = s->in;
|
|
||||||
double zoom=-1, dx=-1, dy=-1;
|
|
||||||
int ret = -1;
|
|
||||||
|
|
||||||
if (in) {
|
|
||||||
ret = output_single_frame(ctx, in, s->var_values, s->current_frame,
|
|
||||||
&zoom, &dx, &dy);
|
&zoom, &dx, &dy);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto fail;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (s->current_frame >= s->nb_frames) {
|
if (!s->in && (ret = ff_inlink_consume_frame(inlink, &s->in)) > 0) {
|
||||||
if (dx != -1)
|
double zoom = -1, dx = -1, dy = -1, nb_frames;
|
||||||
s->x = dx;
|
|
||||||
if (dy != -1)
|
s->finished = 0;
|
||||||
s->y = dy;
|
s->var_values[VAR_IN_W] = s->var_values[VAR_IW] = s->in->width;
|
||||||
if (zoom != -1)
|
s->var_values[VAR_IN_H] = s->var_values[VAR_IH] = s->in->height;
|
||||||
s->prev_zoom = zoom;
|
s->var_values[VAR_OUT_W] = s->var_values[VAR_OW] = s->w;
|
||||||
s->prev_nb_frames = s->nb_frames;
|
s->var_values[VAR_OUT_H] = s->var_values[VAR_OH] = s->h;
|
||||||
s->nb_frames = 0;
|
s->var_values[VAR_IN] = inlink->frame_count_out + 1;
|
||||||
s->current_frame = 0;
|
s->var_values[VAR_ON] = outlink->frame_count_in + 1;
|
||||||
av_frame_free(&s->in);
|
s->var_values[VAR_PX] = s->x;
|
||||||
s->finished = 1;
|
s->var_values[VAR_PY] = s->y;
|
||||||
ret = ff_request_frame(ctx->inputs[0]);
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
fail:
|
|
||||||
sws_freeContext(s->sws);
|
|
||||||
s->sws = NULL;
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int poll_frame(AVFilterLink *link)
|
|
||||||
{
|
|
||||||
ZPContext *s = link->src->priv;
|
|
||||||
return s->nb_frames - s->current_frame;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int query_formats(AVFilterContext *ctx)
|
static int query_formats(AVFilterContext *ctx)
|
||||||
@@ -344,8 +339,6 @@ static const AVFilterPad inputs[] = {
|
|||||||
{
|
{
|
||||||
.name = "default",
|
.name = "default",
|
||||||
.type = AVMEDIA_TYPE_VIDEO,
|
.type = AVMEDIA_TYPE_VIDEO,
|
||||||
.filter_frame = filter_frame,
|
|
||||||
.needs_fifo = 1,
|
|
||||||
},
|
},
|
||||||
{ NULL }
|
{ NULL }
|
||||||
};
|
};
|
||||||
@@ -355,8 +348,6 @@ static const AVFilterPad outputs[] = {
|
|||||||
.name = "default",
|
.name = "default",
|
||||||
.type = AVMEDIA_TYPE_VIDEO,
|
.type = AVMEDIA_TYPE_VIDEO,
|
||||||
.config_props = config_output,
|
.config_props = config_output,
|
||||||
.poll_frame = poll_frame,
|
|
||||||
.request_frame = request_frame,
|
|
||||||
},
|
},
|
||||||
{ NULL }
|
{ NULL }
|
||||||
};
|
};
|
||||||
@@ -369,6 +360,7 @@ AVFilter ff_vf_zoompan = {
|
|||||||
.init = init,
|
.init = init,
|
||||||
.uninit = uninit,
|
.uninit = uninit,
|
||||||
.query_formats = query_formats,
|
.query_formats = query_formats,
|
||||||
|
.activate = activate,
|
||||||
.inputs = inputs,
|
.inputs = inputs,
|
||||||
.outputs = outputs,
|
.outputs = outputs,
|
||||||
.flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
|
.flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
|
||||||
|
Reference in New Issue
Block a user