h264: move top_borders into the per-slice context
authorAnton Khirnov <anton@khirnov.net>
Sat, 17 Jan 2015 21:28:46 +0000 (22:28 +0100)
committerAnton Khirnov <anton@khirnov.net>
Sat, 21 Mar 2015 10:27:15 +0000 (11:27 +0100)
Also change the method for allocating to the same one as used by
edge_emu_buffer.

libavcodec/h264.c
libavcodec/h264.h
libavcodec/h264_mb.c
libavcodec/h264_slice.c

index e60d1fc..b711c64 100644 (file)
@@ -379,8 +379,6 @@ void ff_h264_free_tables(H264Context *h, int free_rbsp)
         hx = h->thread_context[i];
         if (!hx)
             continue;
-        av_freep(&hx->top_borders[1]);
-        av_freep(&hx->top_borders[0]);
         av_freep(&hx->dc_val_base);
         av_freep(&hx->er.mb_index2xy);
         av_freep(&hx->er.error_status_table);
@@ -401,9 +399,13 @@ void ff_h264_free_tables(H264Context *h, int free_rbsp)
 
         av_freep(&sl->bipred_scratchpad);
         av_freep(&sl->edge_emu_buffer);
+        av_freep(&sl->top_borders[0]);
+        av_freep(&sl->top_borders[1]);
 
         sl->bipred_scratchpad_allocated = 0;
         sl->edge_emu_buffer_allocated   = 0;
+        sl->top_borders_allocated[0]    = 0;
+        sl->top_borders_allocated[1]    = 0;
     }
 }
 
@@ -486,11 +488,6 @@ int ff_h264_context_init(H264Context *h)
     int yc_size = y_size + 2   * c_size;
     int x, y, i;
 
-    FF_ALLOCZ_OR_GOTO(h->avctx, h->top_borders[0],
-                      h->mb_width * 16 * 3 * sizeof(uint8_t) * 2, fail)
-    FF_ALLOCZ_OR_GOTO(h->avctx, h->top_borders[1],
-                      h->mb_width * 16 * 3 * sizeof(uint8_t) * 2, fail)
-
     for (i = 0; i < h->nb_slice_ctx; i++) {
         h->slice_ctx[i].ref_cache[0][scan8[5]  + 1] =
         h->slice_ctx[i].ref_cache[0][scan8[7]  + 1] =
index 2c41584..ba4ee39 100644 (file)
@@ -401,8 +401,10 @@ typedef struct H264SliceContext {
 
     uint8_t *bipred_scratchpad;
     uint8_t *edge_emu_buffer;
+    uint8_t (*top_borders[2])[(16 * 3) * 2];
     int bipred_scratchpad_allocated;
     int edge_emu_buffer_allocated;
+    int top_borders_allocated[2];
 
     /**
      * non zero coeff count cache.
@@ -473,7 +475,6 @@ typedef struct H264Context {
 
     int8_t(*intra4x4_pred_mode);
     H264PredContext hpc;
-    uint8_t (*top_borders[2])[(16 * 3) * 2];
 
     uint8_t (*non_zero_count)[48];
 
index 23aa684..2eaf55a 100644 (file)
@@ -535,8 +535,8 @@ static av_always_inline void xchg_mb_border(const H264Context *h, H264SliceConte
     src_cb -= uvlinesize + 1 + pixel_shift;
     src_cr -= uvlinesize + 1 + pixel_shift;
 
-    top_border_m1 = h->top_borders[top_idx][sl->mb_x - 1];
-    top_border    = h->top_borders[top_idx][sl->mb_x];
+    top_border_m1 = sl->top_borders[top_idx][sl->mb_x - 1];
+    top_border    = sl->top_borders[top_idx][sl->mb_x];
 
 #define XCHG(a, b, xchg)                        \
     if (pixel_shift) {                          \
@@ -559,7 +559,7 @@ static av_always_inline void xchg_mb_border(const H264Context *h, H264SliceConte
         XCHG(top_border + (0 << pixel_shift), src_y + (1 << pixel_shift), xchg);
         XCHG(top_border + (8 << pixel_shift), src_y + (9 << pixel_shift), 1);
         if (sl->mb_x + 1 < h->mb_width) {
-            XCHG(h->top_borders[top_idx][sl->mb_x + 1],
+            XCHG(sl->top_borders[top_idx][sl->mb_x + 1],
                  src_y + (17 << pixel_shift), 1);
         }
     }
@@ -575,8 +575,8 @@ static av_always_inline void xchg_mb_border(const H264Context *h, H264SliceConte
                 XCHG(top_border + (32 << pixel_shift), src_cr + (1 << pixel_shift), xchg);
                 XCHG(top_border + (40 << pixel_shift), src_cr + (9 << pixel_shift), 1);
                 if (sl->mb_x + 1 < h->mb_width) {
-                    XCHG(h->top_borders[top_idx][sl->mb_x + 1] + (16 << pixel_shift), src_cb + (17 << pixel_shift), 1);
-                    XCHG(h->top_borders[top_idx][sl->mb_x + 1] + (32 << pixel_shift), src_cr + (17 << pixel_shift), 1);
+                    XCHG(sl->top_borders[top_idx][sl->mb_x + 1] + (16 << pixel_shift), src_cb + (17 << pixel_shift), 1);
+                    XCHG(sl->top_borders[top_idx][sl->mb_x + 1] + (32 << pixel_shift), src_cr + (17 << pixel_shift), 1);
                 }
             }
         } else {
index 30dd5c3..0c99523 100644 (file)
@@ -159,6 +159,7 @@ static void release_unused_pictures(H264Context *h, int remove_current)
 
 static int alloc_scratch_buffers(H264SliceContext *sl, int linesize)
 {
+    const H264Context *h = sl->h264;
     int alloc_size = FFALIGN(FFABS(linesize) + 32, 32);
 
     av_fast_malloc(&sl->bipred_scratchpad, &sl->bipred_scratchpad_allocated, 16 * 6 * alloc_size);
@@ -166,11 +167,22 @@ static int alloc_scratch_buffers(H264SliceContext *sl, int linesize)
     // (= 21x21 for  h264)
     av_fast_malloc(&sl->edge_emu_buffer, &sl->edge_emu_buffer_allocated, alloc_size * 2 * 21);
 
-    if (!sl->bipred_scratchpad || !sl->edge_emu_buffer) {
+    av_fast_malloc(&sl->top_borders[0], &sl->top_borders_allocated[0],
+                   h->mb_width * 16 * 3 * sizeof(uint8_t) * 2);
+    av_fast_malloc(&sl->top_borders[1], &sl->top_borders_allocated[1],
+                   h->mb_width * 16 * 3 * sizeof(uint8_t) * 2);
+
+    if (!sl->bipred_scratchpad || !sl->edge_emu_buffer ||
+        !sl->top_borders[0]    || !sl->top_borders[1]) {
         av_freep(&sl->bipred_scratchpad);
         av_freep(&sl->edge_emu_buffer);
+        av_freep(&sl->top_borders[0]);
+        av_freep(&sl->top_borders[1]);
+
         sl->bipred_scratchpad_allocated = 0;
         sl->edge_emu_buffer_allocated   = 0;
+        sl->top_borders_allocated[0]    = 0;
+        sl->top_borders_allocated[1]    = 0;
         return AVERROR(ENOMEM);
     }
 
@@ -714,7 +726,7 @@ static av_always_inline void backup_mb_border(H264Context *h, H264SliceContext *
     if (!simple && FRAME_MBAFF(h)) {
         if (sl->mb_y & 1) {
             if (!MB_MBAFF(sl)) {
-                top_border = h->top_borders[0][sl->mb_x];
+                top_border = sl->top_borders[0][sl->mb_x];
                 AV_COPY128(top_border, src_y + 15 * linesize);
                 if (pixel_shift)
                     AV_COPY128(top_border + 16, src_y + 15 * linesize + 16);
@@ -754,7 +766,7 @@ static av_always_inline void backup_mb_border(H264Context *h, H264SliceContext *
             return;
     }
 
-    top_border = h->top_borders[top_idx][sl->mb_x];
+    top_border = sl->top_borders[top_idx][sl->mb_x];
     /* There are two lines saved, the line above the top macroblock
      * of a pair, and the line above the bottom macroblock. */
     AV_COPY128(top_border, src_y + 16 * linesize);