|
|
|
@ -62,21 +62,21 @@ AVFILTER_DEFINE_CLASS(vidstabdetect); |
|
|
|
|
|
|
|
|
|
static av_cold int init(AVFilterContext *ctx) |
|
|
|
|
{ |
|
|
|
|
StabData *sd = ctx->priv; |
|
|
|
|
StabData *s = ctx->priv; |
|
|
|
|
ff_vs_init(); |
|
|
|
|
sd->class = &vidstabdetect_class; |
|
|
|
|
s->class = &vidstabdetect_class; |
|
|
|
|
av_log(ctx, AV_LOG_VERBOSE, "vidstabdetect filter: init %s\n", LIBVIDSTAB_VERSION); |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static av_cold void uninit(AVFilterContext *ctx) |
|
|
|
|
{ |
|
|
|
|
StabData *sd = ctx->priv; |
|
|
|
|
VSMotionDetect *md = &(sd->md); |
|
|
|
|
StabData *s = ctx->priv; |
|
|
|
|
VSMotionDetect *md = &(s->md); |
|
|
|
|
|
|
|
|
|
if (sd->f) { |
|
|
|
|
fclose(sd->f); |
|
|
|
|
sd->f = NULL; |
|
|
|
|
if (s->f) { |
|
|
|
|
fclose(s->f); |
|
|
|
|
s->f = NULL; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
vsMotionDetectionCleanup(md); |
|
|
|
@ -102,9 +102,9 @@ static int query_formats(AVFilterContext *ctx) |
|
|
|
|
static int config_input(AVFilterLink *inlink) |
|
|
|
|
{ |
|
|
|
|
AVFilterContext *ctx = inlink->dst; |
|
|
|
|
StabData *sd = ctx->priv; |
|
|
|
|
StabData *s = ctx->priv; |
|
|
|
|
|
|
|
|
|
VSMotionDetect* md = &(sd->md); |
|
|
|
|
VSMotionDetect* md = &(s->md); |
|
|
|
|
VSFrameInfo fi; |
|
|
|
|
const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format); |
|
|
|
|
|
|
|
|
@ -125,30 +125,30 @@ static int config_input(AVFilterLink *inlink) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// set values that are not initialized by the options
|
|
|
|
|
sd->conf.algo = 1; |
|
|
|
|
sd->conf.modName = "vidstabdetect"; |
|
|
|
|
if (vsMotionDetectInit(md, &sd->conf, &fi) != VS_OK) { |
|
|
|
|
s->conf.algo = 1; |
|
|
|
|
s->conf.modName = "vidstabdetect"; |
|
|
|
|
if (vsMotionDetectInit(md, &s->conf, &fi) != VS_OK) { |
|
|
|
|
av_log(ctx, AV_LOG_ERROR, "initialization of Motion Detection failed, please report a BUG"); |
|
|
|
|
return AVERROR(EINVAL); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
vsMotionDetectGetConfig(&sd->conf, md); |
|
|
|
|
vsMotionDetectGetConfig(&s->conf, md); |
|
|
|
|
av_log(ctx, AV_LOG_INFO, "Video stabilization settings (pass 1/2):\n"); |
|
|
|
|
av_log(ctx, AV_LOG_INFO, " shakiness = %d\n", sd->conf.shakiness); |
|
|
|
|
av_log(ctx, AV_LOG_INFO, " accuracy = %d\n", sd->conf.accuracy); |
|
|
|
|
av_log(ctx, AV_LOG_INFO, " stepsize = %d\n", sd->conf.stepSize); |
|
|
|
|
av_log(ctx, AV_LOG_INFO, " mincontrast = %f\n", sd->conf.contrastThreshold); |
|
|
|
|
av_log(ctx, AV_LOG_INFO, " tripod = %d\n", sd->conf.virtualTripod); |
|
|
|
|
av_log(ctx, AV_LOG_INFO, " show = %d\n", sd->conf.show); |
|
|
|
|
av_log(ctx, AV_LOG_INFO, " result = %s\n", sd->result); |
|
|
|
|
|
|
|
|
|
sd->f = fopen(sd->result, "w"); |
|
|
|
|
if (sd->f == NULL) { |
|
|
|
|
av_log(ctx, AV_LOG_ERROR, "cannot open transform file %s\n", sd->result); |
|
|
|
|
av_log(ctx, AV_LOG_INFO, " shakiness = %d\n", s->conf.shakiness); |
|
|
|
|
av_log(ctx, AV_LOG_INFO, " accuracy = %d\n", s->conf.accuracy); |
|
|
|
|
av_log(ctx, AV_LOG_INFO, " stepsize = %d\n", s->conf.stepSize); |
|
|
|
|
av_log(ctx, AV_LOG_INFO, " mincontrast = %f\n", s->conf.contrastThreshold); |
|
|
|
|
av_log(ctx, AV_LOG_INFO, " tripod = %d\n", s->conf.virtualTripod); |
|
|
|
|
av_log(ctx, AV_LOG_INFO, " show = %d\n", s->conf.show); |
|
|
|
|
av_log(ctx, AV_LOG_INFO, " result = %s\n", s->result); |
|
|
|
|
|
|
|
|
|
s->f = fopen(s->result, "w"); |
|
|
|
|
if (s->f == NULL) { |
|
|
|
|
av_log(ctx, AV_LOG_ERROR, "cannot open transform file %s\n", s->result); |
|
|
|
|
return AVERROR(EINVAL); |
|
|
|
|
} else { |
|
|
|
|
if (vsPrepareFile(md, sd->f) != VS_OK) { |
|
|
|
|
av_log(ctx, AV_LOG_ERROR, "cannot write to transform file %s\n", sd->result); |
|
|
|
|
if (vsPrepareFile(md, s->f) != VS_OK) { |
|
|
|
|
av_log(ctx, AV_LOG_ERROR, "cannot write to transform file %s\n", s->result); |
|
|
|
|
return AVERROR(EINVAL); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -158,15 +158,15 @@ static int config_input(AVFilterLink *inlink) |
|
|
|
|
static int filter_frame(AVFilterLink *inlink, AVFrame *in) |
|
|
|
|
{ |
|
|
|
|
AVFilterContext *ctx = inlink->dst; |
|
|
|
|
StabData *sd = ctx->priv; |
|
|
|
|
VSMotionDetect *md = &(sd->md); |
|
|
|
|
StabData *s = ctx->priv; |
|
|
|
|
VSMotionDetect *md = &(s->md); |
|
|
|
|
LocalMotions localmotions; |
|
|
|
|
|
|
|
|
|
AVFilterLink *outlink = inlink->dst->outputs[0]; |
|
|
|
|
VSFrame frame; |
|
|
|
|
int plane; |
|
|
|
|
|
|
|
|
|
if (sd->conf.show > 0 && !av_frame_is_writable(in)) |
|
|
|
|
if (s->conf.show > 0 && !av_frame_is_writable(in)) |
|
|
|
|
av_frame_make_writable(in); |
|
|
|
|
|
|
|
|
|
for (plane = 0; plane < md->fi.planes; plane++) { |
|
|
|
@ -177,7 +177,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) |
|
|
|
|
av_log(ctx, AV_LOG_ERROR, "motion detection failed"); |
|
|
|
|
return AVERROR(AVERROR_EXTERNAL); |
|
|
|
|
} else { |
|
|
|
|
if (vsWriteToFile(md, sd->f, &localmotions) != VS_OK) { |
|
|
|
|
if (vsWriteToFile(md, s->f, &localmotions) != VS_OK) { |
|
|
|
|
int ret = AVERROR(errno); |
|
|
|
|
av_log(ctx, AV_LOG_ERROR, "cannot write to transform file"); |
|
|
|
|
return ret; |
|
|
|
|