[FFmpeg-devel] [PATCH v5 2/3] vf_find_rect.c: use the optimized sad function to improve the find performance
lance.lmwang at gmail.com
lance.lmwang at gmail.com
Wed Jun 12 13:57:30 EEST 2019
From: Limin Wang <lance.lmwang at gmail.com>
benchmark on x86_64: 6.4 -> 16 with below command:
./ffmpeg -i 1920x1080.mp4 -vf find_rect=./find.tif,cover_rect=./cover.jpg:mode=cover -f null -
6.4 fps -> 16fps
Signed-off-by: Limin Wang <lance.lmwang at gmail.com>
---
libavfilter/vf_find_rect.c | 53 +++++++++++++++-----------------------
1 file changed, 21 insertions(+), 32 deletions(-)
diff --git a/libavfilter/vf_find_rect.c b/libavfilter/vf_find_rect.c
index ee6c3f4b45..ed15885bc2 100644
--- a/libavfilter/vf_find_rect.c
+++ b/libavfilter/vf_find_rect.c
@@ -26,6 +26,7 @@
#include "libavutil/imgutils.h"
#include "libavutil/opt.h"
#include "internal.h"
+#include "scene_sad.h"
#include "lavfutils.h"
#include "lswsutils.h"
@@ -36,6 +37,8 @@ typedef struct FOCContext {
AVClass *class;
float threshold;
int mipmaps;
+ ff_scene_sad_fn sad;
+ int bitdepth;
int xmin, ymin, xmax, ymax;
char *obj_filename;
int last_x, last_y;
@@ -103,54 +106,40 @@ static AVFrame *downscale(AVFrame *in)
return frame;
}
-static float compare(const AVFrame *haystack, const AVFrame *obj, int offx, int offy)
+static float compare_sad(FOCContext *foc, AVFrame *haystack, AVFrame *obj, int offx, int offy)
{
- int x,y;
- int o_sum_v = 0;
- int h_sum_v = 0;
- int64_t oo_sum_v = 0;
- int64_t hh_sum_v = 0;
- int64_t oh_sum_v = 0;
- float c;
+ uint64_t sad = 0;
int n = obj->height * obj->width;
- const uint8_t *odat = obj ->data[0];
+ double mafd;
+ const uint8_t *odat = obj->data[0];
const uint8_t *hdat = haystack->data[0] + offx + offy * haystack->linesize[0];
- int64_t o_sigma, h_sigma;
-
- for(y = 0; y < obj->height; y++) {
- for(x = 0; x < obj->width; x++) {
- int o_v = odat[x];
- int h_v = hdat[x];
- o_sum_v += o_v;
- h_sum_v += h_v;
- oo_sum_v += o_v * o_v;
- hh_sum_v += h_v * h_v;
- oh_sum_v += o_v * h_v;
- }
- odat += obj->linesize[0];
- hdat += haystack->linesize[0];
- }
- o_sigma = n*oo_sum_v - o_sum_v*(int64_t)o_sum_v;
- h_sigma = n*hh_sum_v - h_sum_v*(int64_t)h_sum_v;
- if (o_sigma == 0 || h_sigma == 0)
- return 1.0;
+ foc->sad(hdat, haystack->linesize[0], odat, obj->linesize[0],
+ obj->width, obj->height, &sad);
+ emms_c();
+ mafd = (double)sad / n / (1ULL << foc->bitdepth);
- c = (n*oh_sum_v - o_sum_v*(int64_t)h_sum_v) / (sqrt(o_sigma)*sqrt(h_sigma));
-
- return 1 - fabs(c);
+ return mafd;
}
static int config_input(AVFilterLink *inlink)
{
AVFilterContext *ctx = inlink->dst;
FOCContext *foc = ctx->priv;
+ const AVPixFmtDescriptor *pix_desc = av_pix_fmt_desc_get(inlink->format);
if (foc->xmax <= 0)
foc->xmax = inlink->w - foc->obj_frame->width;
if (foc->ymax <= 0)
foc->ymax = inlink->h - foc->obj_frame->height;
+ foc->bitdepth = pix_desc->comp[0].depth;
+
+ foc->sad = ff_scene_sad_get_fn(foc->bitdepth == 8 ? 8 : 16);
+ if (!foc->sad)
+ return AVERROR(EINVAL);
+
+
return 0;
}
@@ -169,7 +158,7 @@ static float search(FOCContext *foc, int pass, int maxpass, int xmin, int xmax,
for (y = ymin; y <= ymax; y++) {
for (x = xmin; x <= xmax; x++) {
- float score = compare(foc->haystack_frame[pass], foc->needle_frame[pass], x, y);
+ float score = compare_sad(foc, foc->haystack_frame[pass], foc->needle_frame[pass], x, y);
av_assert0(score != 0);
if (score < best_score) {
best_score = score;
--
2.21.0
More information about the ffmpeg-devel
mailing list