forked from FFmpeg/FFmpeg
avfilter/vf_scale: switch to FFFrameSync
Preliminary commit, in anticipation of adding support for multiple inputs (with proper synchronization and activate() callback).
This commit is contained in:
parent
a5032dc12a
commit
e82a3997cd
2 changed files with 63 additions and 6 deletions
|
@ -20989,8 +20989,8 @@ the next filter, the scale filter will convert the input to the
|
|||
requested format.
|
||||
|
||||
@subsection Options
|
||||
The filter accepts the following options, or any of the options
|
||||
supported by the libswscale scaler.
|
||||
The filter accepts the following options, any of the options supported
|
||||
by the libswscale scaler, as well as any of the @ref{framesync} options.
|
||||
|
||||
See @ref{scaler_options,,the ffmpeg-scaler manual,ffmpeg-scaler} for
|
||||
the complete list of scaler options.
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
|
||||
#include "avfilter.h"
|
||||
#include "formats.h"
|
||||
#include "framesync.h"
|
||||
#include "internal.h"
|
||||
#include "scale_eval.h"
|
||||
#include "video.h"
|
||||
|
@ -113,6 +114,7 @@ typedef struct ScaleContext {
|
|||
struct SwsContext *isws[2]; ///< software scaler context for interlaced material
|
||||
// context used for forwarding options to sws
|
||||
struct SwsContext *sws_opts;
|
||||
FFFrameSync fs;
|
||||
|
||||
/**
|
||||
* New dimensions. Special values are:
|
||||
|
@ -287,6 +289,8 @@ static av_cold int preinit(AVFilterContext *ctx)
|
|||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ff_framesync_preinit(&scale->fs);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -302,6 +306,8 @@ static const int sws_colorspaces[] = {
|
|||
-1
|
||||
};
|
||||
|
||||
static int do_scale(FFFrameSync *fs);
|
||||
|
||||
static av_cold int init(AVFilterContext *ctx)
|
||||
{
|
||||
ScaleContext *scale = ctx->priv;
|
||||
|
@ -388,6 +394,7 @@ static av_cold void uninit(AVFilterContext *ctx)
|
|||
av_expr_free(scale->w_pexpr);
|
||||
av_expr_free(scale->h_pexpr);
|
||||
scale->w_pexpr = scale->h_pexpr = NULL;
|
||||
ff_framesync_uninit(&scale->fs);
|
||||
sws_freeContext(scale->sws_opts);
|
||||
sws_freeContext(scale->sws);
|
||||
sws_freeContext(scale->isws[0]);
|
||||
|
@ -677,6 +684,21 @@ static int config_props(AVFilterLink *outlink)
|
|||
flags_val);
|
||||
av_freep(&flags_val);
|
||||
|
||||
if (ctx->filter != &ff_vf_scale2ref) {
|
||||
ret = ff_framesync_init(&scale->fs, ctx, ctx->nb_inputs);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
scale->fs.on_event = do_scale;
|
||||
scale->fs.in[0].time_base = ctx->inputs[0]->time_base;
|
||||
scale->fs.in[0].sync = 1;
|
||||
scale->fs.in[0].before = EXT_STOP;
|
||||
scale->fs.in[0].after = EXT_STOP;
|
||||
|
||||
ret = ff_framesync_configure(&scale->fs);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
|
@ -894,6 +916,26 @@ scale:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int do_scale(FFFrameSync *fs)
|
||||
{
|
||||
AVFilterContext *ctx = fs->parent;
|
||||
AVFilterLink *outlink = ctx->outputs[0];
|
||||
AVFrame *in, *out;
|
||||
int ret;
|
||||
|
||||
ret = ff_framesync_get_frame(fs, 0, &in, 1);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = scale_frame(ctx->inputs[0], in, &out);
|
||||
if (out) {
|
||||
out->pts = av_rescale_q(fs->pts, fs->time_base, outlink->time_base);
|
||||
return ff_filter_frame(outlink, out);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int filter_frame(AVFilterLink *link, AVFrame *in)
|
||||
{
|
||||
AVFilterContext *ctx = link->dst;
|
||||
|
@ -972,11 +1014,24 @@ static int process_command(AVFilterContext *ctx, const char *cmd, const char *ar
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int activate(AVFilterContext *ctx)
|
||||
{
|
||||
ScaleContext *scale = ctx->priv;
|
||||
return ff_framesync_activate(&scale->fs);
|
||||
}
|
||||
|
||||
static const AVClass *child_class_iterate(void **iter)
|
||||
{
|
||||
const AVClass *c = *iter ? NULL : sws_get_class();
|
||||
*iter = (void*)(uintptr_t)c;
|
||||
return c;
|
||||
switch ((uintptr_t) *iter) {
|
||||
case 0:
|
||||
*iter = (void*)(uintptr_t) 1;
|
||||
return sws_get_class();
|
||||
case 1:
|
||||
*iter = (void*)(uintptr_t) 2;
|
||||
return &ff_framesync_class;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void *child_next(void *obj, void *prev)
|
||||
|
@ -984,6 +1039,8 @@ static void *child_next(void *obj, void *prev)
|
|||
ScaleContext *s = obj;
|
||||
if (!prev)
|
||||
return s->sws_opts;
|
||||
if (prev == s->sws_opts)
|
||||
return &s->fs;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -1051,7 +1108,6 @@ static const AVFilterPad avfilter_vf_scale_inputs[] = {
|
|||
{
|
||||
.name = "default",
|
||||
.type = AVMEDIA_TYPE_VIDEO,
|
||||
.filter_frame = filter_frame,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -1074,6 +1130,7 @@ const AVFilter ff_vf_scale = {
|
|||
FILTER_INPUTS(avfilter_vf_scale_inputs),
|
||||
FILTER_OUTPUTS(avfilter_vf_scale_outputs),
|
||||
FILTER_QUERY_FUNC(query_formats),
|
||||
.activate = activate,
|
||||
.process_command = process_command,
|
||||
};
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue