Also change the method for allocating to the same one as used by edge_emu_buffer.tags/n2.7
@@ -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] = | |||
@@ -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]; | |||
@@ -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 { | |||
@@ -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); | |||