X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavfilter%2Fvf_deshake.c;h=7013f6ccc1d254b72e2425d5ce89aa776d47f05b;hb=5226be0dd5167581277857fa267c7ad32a1aefaa;hp=6128cb9b6057600ada7aa9d0a6ede475e118cb82;hpb=52673ab18a8f241e37aea83236ffe0fa84b78655;p=ffmpeg diff --git a/libavfilter/vf_deshake.c b/libavfilter/vf_deshake.c index 6128cb9b605..7013f6ccc1d 100644 --- a/libavfilter/vf_deshake.c +++ b/libavfilter/vf_deshake.c @@ -92,12 +92,14 @@ typedef struct { int refcount; ///< Number of reference frames (defines averaging window) FILE *fp; Transform avg; + int cw; ///< Crop motion search to this box + int ch; + int cx; + int cy; } DeshakeContext; -static int cmp(void const *ca, void const *cb) +static int cmp(const double *a, const double *b) { - double *a = (double *) ca; - double *b = (double *) cb; return *a < *b ? -1 : ( *a > *b ? 1 : 0 ); } @@ -110,7 +112,7 @@ static double clean_mean(double *values, int count) int cut = count / 5; int x; - qsort(values, count, sizeof(double), cmp); + qsort(values, count, sizeof(double), (void*)cmp); for (x = cut; x < count - cut; x++) { mean += values[x]; @@ -343,8 +345,15 @@ static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque) deshake->search = EXHAUSTIVE; deshake->refcount = 20; + deshake->cw = -1; + deshake->ch = -1; + deshake->cx = -1; + deshake->cy = -1; + if (args) { - sscanf(args, "%d:%d:%d:%d:%d:%d:%255s", &deshake->rx, &deshake->ry, (int *)&deshake->edge, + sscanf(args, "%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%255s", + &deshake->cx, &deshake->cy, &deshake->cw, &deshake->ch, + &deshake->rx, &deshake->ry, (int *)&deshake->edge, &deshake->blocksize, &deshake->contrast, (int *)&deshake->search, filename); deshake->blocksize /= 2; @@ -355,13 +364,22 @@ static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque) deshake->blocksize = av_clip(deshake->blocksize, 4, 128); deshake->contrast = av_clip(deshake->contrast, 1, 255); deshake->search = av_clip(deshake->search, EXHAUSTIVE, SEARCH_COUNT - 1); + } if (*filename) deshake->fp = fopen(filename, "w"); if (deshake->fp) fwrite("Ori x, Avg x, Fin x, Ori y, Avg y, Fin y, Ori angle, Avg angle, Fin angle, Ori zoom, Avg zoom, Fin zoom\n", sizeof(char), 104, deshake->fp); - av_log(ctx, AV_LOG_INFO, "rx: %d, ry: %d, edge: %d blocksize: %d contrast: %d search: %d\n", + // Quadword align left edge of box for MMX code, adjust width if necessary + // to keep right margin + if (deshake->cx > 0) { + deshake->cw += deshake->cx - (deshake->cx & ~15); + deshake->cx &= ~15; + } + + av_log(ctx, AV_LOG_INFO, "cx: %d, cy: %d, cw: %d, ch: %d, rx: %d, ry: %d, edge: %d blocksize: %d contrast: %d search: %d\n", + deshake->cx, deshake->cy, deshake->cw, deshake->ch, deshake->rx, deshake->ry, deshake->edge, deshake->blocksize * 2, deshake->contrast, deshake->search); return 0; @@ -416,8 +434,28 @@ static void end_frame(AVFilterLink *link) char tmp[256]; Transform orig; - // Find the most likely global motion for the current frame - find_motion(deshake, (deshake->ref == NULL) ? in->data[0] : deshake->ref->data[0], in->data[0], link->w, link->h, in->linesize[0], &t); + if (deshake->cx < 0 || deshake->cy < 0 || deshake->cw < 0 || deshake->ch < 0) { + // Find the most likely global motion for the current frame + find_motion(deshake, (deshake->ref == NULL) ? in->data[0] : deshake->ref->data[0], in->data[0], link->w, link->h, in->linesize[0], &t); + } else { + uint8_t *src1 = (deshake->ref == NULL) ? in->data[0] : deshake->ref->data[0]; + uint8_t *src2 = in->data[0]; + + deshake->cx = FFMIN(deshake->cx, link->w); + deshake->cy = FFMIN(deshake->cy, link->h); + + if ((unsigned)deshake->cx + (unsigned)deshake->cw > link->w) deshake->cw = link->w - deshake->cx; + if ((unsigned)deshake->cy + (unsigned)deshake->ch > link->h) deshake->ch = link->h - deshake->cy; + + // Quadword align right margin + deshake->cw &= ~15; + + src1 += deshake->cy * in->linesize[0] + deshake->cx; + src2 += deshake->cy * in->linesize[0] + deshake->cx; + + find_motion(deshake, src1, src2, deshake->cw, deshake->ch, in->linesize[0], &t); + } + // Copy transform so we can output it later to compare to the smoothed value orig.vector.x = t.vector.x; @@ -508,7 +546,7 @@ AVFilter avfilter_vf_deshake = { .uninit = uninit, .query_formats = query_formats, - .inputs = (AVFilterPad[]) {{ .name = "default", + .inputs = (const AVFilterPad[]) {{ .name = "default", .type = AVMEDIA_TYPE_VIDEO, .draw_slice = draw_slice, .end_frame = end_frame, @@ -516,7 +554,7 @@ AVFilter avfilter_vf_deshake = { .min_perms = AV_PERM_READ, }, { .name = NULL}}, - .outputs = (AVFilterPad[]) {{ .name = "default", + .outputs = (const AVFilterPad[]) {{ .name = "default", .type = AVMEDIA_TYPE_VIDEO, }, { .name = NULL}}, };