vf_deshake: Avoid doing a malloc+free for every single frame.
authorReimar Döffinger <Reimar.Doeffinger@gmx.de>
Mon, 1 Sep 2014 21:47:12 +0000 (23:47 +0200)
committerReimar Döffinger <Reimar.Doeffinger@gmx.de>
Tue, 2 Sep 2014 17:20:28 +0000 (19:20 +0200)
Signed-off-by: Reimar Döffinger <Reimar.Doeffinger@gmx.de>
libavfilter/deshake.h
libavfilter/vf_deshake.c

index 20df88f4ec66681795814cd3461474d6a03325ce..62e81c3eaf254a9bac91ade1316b60b2d346dc66 100644 (file)
@@ -76,6 +76,8 @@ typedef struct {
 typedef struct {
     const AVClass *class;
     int counts[2*MAX_R+1][2*MAX_R+1]; /// < Scratch buffer for motion search
+    double *angles;            ///< Scratch buffer for block angles
+    unsigned angles_size;
     AVFrame *ref;              ///< Previous frame
     int rx;                    ///< Maximum horizontal shift
     int ry;                    ///< Maximum vertical shift
index 65144211b9133ab222d1e1cb3859db8b9de8c0a3..ccc263b5ce2425f6b3f3a3491317d6a83e45df68 100644 (file)
@@ -244,10 +244,11 @@ static void find_motion(DeshakeContext *deshake, uint8_t *src1, uint8_t *src2,
     int contrast;
 
     int pos;
-    double *angles = av_malloc_array(width * height / (16 * deshake->blocksize), sizeof(*angles));
     int center_x = 0, center_y = 0;
     double p_x, p_y;
 
+    av_fast_malloc(&deshake->angles, &deshake->angles_size, width * height / (16 * deshake->blocksize) * sizeof(*deshake->angles));
+
     // Reset counts to zero
     for (x = 0; x < deshake->rx * 2 + 1; x++) {
         for (y = 0; y < deshake->ry * 2 + 1; y++) {
@@ -269,7 +270,7 @@ static void find_motion(DeshakeContext *deshake, uint8_t *src1, uint8_t *src2,
                 if (mv.x != -1 && mv.y != -1) {
                     deshake->counts[mv.x + deshake->rx][mv.y + deshake->ry] += 1;
                     if (x > deshake->rx && y > deshake->ry)
-                        angles[pos++] = block_angle(x, y, 0, 0, &mv);
+                        deshake->angles[pos++] = block_angle(x, y, 0, 0, &mv);
 
                     center_x += mv.x;
                     center_y += mv.y;
@@ -281,7 +282,7 @@ static void find_motion(DeshakeContext *deshake, uint8_t *src1, uint8_t *src2,
     if (pos) {
          center_x /= pos;
          center_y /= pos;
-         t->angle = clean_mean(angles, pos);
+         t->angle = clean_mean(deshake->angles, pos);
          if (t->angle < 0.001)
               t->angle = 0;
     } else {
@@ -312,7 +313,6 @@ static void find_motion(DeshakeContext *deshake, uint8_t *src1, uint8_t *src2,
     t->angle = av_clipf(t->angle, -0.1, 0.1);
 
     //av_log(NULL, AV_LOG_ERROR, "%d x %d\n", avg->x, avg->y);
-    av_free(angles);
 }
 
 static int deshake_transform_c(AVFilterContext *ctx,
@@ -422,6 +422,8 @@ static av_cold void uninit(AVFilterContext *ctx)
         ff_opencl_deshake_uninit(ctx);
     }
     av_frame_free(&deshake->ref);
+    av_freep(&deshake->angles);
+    deshake->angles_size = 0;
     if (deshake->fp)
         fclose(deshake->fp);
 }