Reduces the amount of allocations and frees.

Signed-off-by: Andreas Rheinhardt <andreas.rheinha...@outlook.com>
---
 libavcodec/mpegvideo.c | 46 ++++++++++++++++++++++++++----------------
 libavcodec/mpegvideo.h |  8 ++++----
 2 files changed, 33 insertions(+), 21 deletions(-)

diff --git a/libavcodec/mpegvideo.c b/libavcodec/mpegvideo.c
index e2cdba8bb1..be47ccb8ed 100644
--- a/libavcodec/mpegvideo.c
+++ b/libavcodec/mpegvideo.c
@@ -769,34 +769,44 @@ static int init_context_frame(MpegEncContext *s)
             !FF_ALLOC_TYPED_ARRAY (s->bits_tab,     mb_array_size))
             return AVERROR(ENOMEM);
 
+#define ALLOCZ_ARRAYS(p, mult, numb) ((p) = av_calloc(numb, mult * 
sizeof(*(p))))
     if (s->codec_id == AV_CODEC_ID_MPEG4 ||
         (s->avctx->flags & AV_CODEC_FLAG_INTERLACED_ME)) {
+            int16_t (*tmp1)[2];
+            uint8_t *tmp2;
+            if (!(tmp1 = ALLOCZ_ARRAYS(s->b_field_mv_table_base, 8, 
mv_table_size)) ||
+                !(tmp2 = ALLOCZ_ARRAYS(s->b_field_select_table[0][0], 2 * 4, 
mv_table_size)) ||
+                !ALLOCZ_ARRAYS(s->p_field_select_table[0], 2 * 2, 
mv_table_size))
+                return AVERROR(ENOMEM);
+
+            s->p_field_select_table[1] = s->p_field_select_table[0] + 2 * 
mv_table_size;
+            tmp1 += s->mb_stride + 1;
+
         for (i = 0; i < 2; i++) {
             int j, k;
             for (j = 0; j < 2; j++) {
                 for (k = 0; k < 2; k++) {
-                    if 
(!FF_ALLOCZ_TYPED_ARRAY(s->b_field_mv_table_base[i][j][k], mv_table_size))
-                        return AVERROR(ENOMEM);
-                    s->b_field_mv_table[i][j][k] = 
s->b_field_mv_table_base[i][j][k] +
-                                                   s->mb_stride + 1;
+                        s->b_field_mv_table[i][j][k] = tmp1;
+                        tmp1 += mv_table_size;
                 }
-                if (!FF_ALLOCZ_TYPED_ARRAY(s->b_field_select_table [i][j], 
mv_table_size * 2))
-                    return AVERROR(ENOMEM);
+                    s->b_field_select_table[i][j] = tmp2;
+                    tmp2 += 2 * mv_table_size;
             }
-            if (!FF_ALLOCZ_TYPED_ARRAY(s->p_field_select_table[i], 
mv_table_size * 2))
-                return AVERROR(ENOMEM);
         }
     }
     }
 
     if (s->codec_id == AV_CODEC_ID_MPEG4 ||
         (s->avctx->flags & AV_CODEC_FLAG_INTERLACED_ME)) {
+        int16_t (*tmp)[2];
         /* interlaced direct mode decoding tables */
+        if (!(tmp = ALLOCZ_ARRAYS(s->p_field_mv_table_base, 4, mv_table_size)))
+            return AVERROR(ENOMEM);
+        tmp += s->mb_stride + 1;
         for (int i = 0; i < 2; i++) {
             for (int j = 0; j < 2; j++) {
-                if (!FF_ALLOCZ_TYPED_ARRAY(s->p_field_mv_table_base[i][j], 
mv_table_size))
-                    return AVERROR(ENOMEM);
-                s->p_field_mv_table[i][j] = s->p_field_mv_table_base[i][j] + 
s->mb_stride + 1;
+                s->p_field_mv_table[i][j] = tmp;
+                tmp += mv_table_size;
             }
         }
     }
@@ -880,14 +890,14 @@ static void clear_context(MpegEncContext *s)
     s->b_bidir_forw_mv_table = NULL;
     s->b_bidir_back_mv_table = NULL;
     s->b_direct_mv_table     = NULL;
+    s->b_field_mv_table_base = NULL;
+    s->p_field_mv_table_base = NULL;
     for (i = 0; i < 2; i++) {
         for (j = 0; j < 2; j++) {
             for (k = 0; k < 2; k++) {
-                s->b_field_mv_table_base[i][j][k] = NULL;
                 s->b_field_mv_table[i][j][k] = NULL;
             }
             s->b_field_select_table[i][j] = NULL;
-            s->p_field_mv_table_base[i][j] = NULL;
             s->p_field_mv_table[i][j] = NULL;
         }
         s->p_field_select_table[i] = NULL;
@@ -1026,17 +1036,19 @@ static void free_context_frame(MpegEncContext *s)
     s->b_bidir_forw_mv_table = NULL;
     s->b_bidir_back_mv_table = NULL;
     s->b_direct_mv_table     = NULL;
+    av_freep(&s->b_field_mv_table_base);
+    av_freep(&s->b_field_select_table[0][0]);
+    av_freep(&s->p_field_mv_table_base);
+    av_freep(&s->p_field_select_table[0]);
     for (i = 0; i < 2; i++) {
         for (j = 0; j < 2; j++) {
             for (k = 0; k < 2; k++) {
-                av_freep(&s->b_field_mv_table_base[i][j][k]);
                 s->b_field_mv_table[i][j][k] = NULL;
             }
-            av_freep(&s->b_field_select_table[i][j]);
-            av_freep(&s->p_field_mv_table_base[i][j]);
+            s->b_field_select_table[i][j] = NULL;
             s->p_field_mv_table[i][j] = NULL;
         }
-        av_freep(&s->p_field_select_table[i]);
+        s->p_field_select_table[i] = NULL;
     }
 
     av_freep(&s->dc_val_base);
diff --git a/libavcodec/mpegvideo.h b/libavcodec/mpegvideo.h
index 85f02b1355..879b019ffc 100644
--- a/libavcodec/mpegvideo.h
+++ b/libavcodec/mpegvideo.h
@@ -232,8 +232,8 @@ typedef struct MpegEncContext {
     int16_t (*b_bidir_forw_mv_table_base)[2];
     int16_t (*b_bidir_back_mv_table_base)[2];
     int16_t (*b_direct_mv_table_base)[2];
-    int16_t (*p_field_mv_table_base[2][2])[2];
-    int16_t (*b_field_mv_table_base[2][2][2])[2];
+    int16_t (*p_field_mv_table_base)[2];
+    int16_t (*b_field_mv_table_base)[2];
     int16_t (*p_mv_table)[2];            ///< MV table (1MV per MB) P-frame 
encoding
     int16_t (*b_forw_mv_table)[2];       ///< MV table (1MV per MB) forward 
mode B-frame encoding
     int16_t (*b_back_mv_table)[2];       ///< MV table (1MV per MB) backward 
mode B-frame encoding
@@ -242,8 +242,8 @@ typedef struct MpegEncContext {
     int16_t (*b_direct_mv_table)[2];     ///< MV table (1MV per MB) direct 
mode B-frame encoding
     int16_t (*p_field_mv_table[2][2])[2];   ///< MV table (2MV per MB) 
interlaced P-frame encoding
     int16_t (*b_field_mv_table[2][2][2])[2];///< MV table (4MV per MB) 
interlaced B-frame encoding
-    uint8_t (*p_field_select_table[2]);
-    uint8_t (*b_field_select_table[2][2]);
+    uint8_t (*p_field_select_table[2]);  ///< Only the first element is 
allocated
+    uint8_t (*b_field_select_table[2][2]); ///< Only the first element is 
allocated
     int motion_est;                      ///< ME algorithm
     int me_penalty_compensation;
     int me_pre;                          ///< prepass for motion estimation
-- 
2.32.0

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

Reply via email to