While it is a per-frame variable, it is only really used in the low-level decoding code, so it is more efficient to store it in the slice context.tags/n2.7
@@ -366,6 +366,7 @@ typedef struct H264SliceContext { | |||||
unsigned int topright_samples_available; | unsigned int topright_samples_available; | ||||
unsigned int left_samples_available; | unsigned int left_samples_available; | ||||
ptrdiff_t linesize, uvlinesize; | |||||
ptrdiff_t mb_linesize; ///< may be equal to s->linesize or s->linesize * 2, for mbaff | ptrdiff_t mb_linesize; ///< may be equal to s->linesize or s->linesize * 2, for mbaff | ||||
ptrdiff_t mb_uvlinesize; | ptrdiff_t mb_uvlinesize; | ||||
@@ -478,7 +479,6 @@ typedef struct H264Context { | |||||
/* coded dimensions -- 16 * mb w/h */ | /* coded dimensions -- 16 * mb w/h */ | ||||
int width, height; | int width, height; | ||||
ptrdiff_t linesize, uvlinesize; | |||||
int chroma_x_shift, chroma_y_shift; | int chroma_x_shift, chroma_y_shift; | ||||
int droppable; | int droppable; | ||||
@@ -487,13 +487,13 @@ static av_always_inline void prefetch_motion(const H264Context *h, H264SliceCont | |||||
int off = (mx << pixel_shift) + | int off = (mx << pixel_shift) + | ||||
(my + (sl->mb_x & 3) * 4) * sl->mb_linesize + | (my + (sl->mb_x & 3) * 4) * sl->mb_linesize + | ||||
(64 << pixel_shift); | (64 << pixel_shift); | ||||
h->vdsp.prefetch(src[0] + off, h->linesize, 4); | |||||
h->vdsp.prefetch(src[0] + off, sl->linesize, 4); | |||||
if (chroma_idc == 3 /* yuv444 */) { | if (chroma_idc == 3 /* yuv444 */) { | ||||
h->vdsp.prefetch(src[1] + off, h->linesize, 4); | |||||
h->vdsp.prefetch(src[2] + off, h->linesize, 4); | |||||
h->vdsp.prefetch(src[1] + off, sl->linesize, 4); | |||||
h->vdsp.prefetch(src[2] + off, sl->linesize, 4); | |||||
} else { | } else { | ||||
off = ((mx >> 1) << pixel_shift) + | off = ((mx >> 1) << pixel_shift) + | ||||
((my >> 1) + (sl->mb_x & 7)) * h->uvlinesize + | |||||
((my >> 1) + (sl->mb_x & 7)) * sl->uvlinesize + | |||||
(64 << pixel_shift); | (64 << pixel_shift); | ||||
h->vdsp.prefetch(src[1] + off, src[2] - src[1], 2); | h->vdsp.prefetch(src[1] + off, src[2] - src[1], 2); | ||||
} | } | ||||
@@ -57,23 +57,23 @@ static av_noinline void FUNC(hl_decode_mb)(const H264Context *h, H264SliceContex | |||||
const int block_h = 16 >> h->chroma_y_shift; | const int block_h = 16 >> h->chroma_y_shift; | ||||
const int chroma422 = CHROMA422(h); | const int chroma422 = CHROMA422(h); | ||||
dest_y = h->cur_pic.f.data[0] + ((mb_x << PIXEL_SHIFT) + mb_y * h->linesize) * 16; | |||||
dest_cb = h->cur_pic.f.data[1] + (mb_x << PIXEL_SHIFT) * 8 + mb_y * h->uvlinesize * block_h; | |||||
dest_cr = h->cur_pic.f.data[2] + (mb_x << PIXEL_SHIFT) * 8 + mb_y * h->uvlinesize * block_h; | |||||
dest_y = h->cur_pic.f.data[0] + ((mb_x << PIXEL_SHIFT) + mb_y * sl->linesize) * 16; | |||||
dest_cb = h->cur_pic.f.data[1] + (mb_x << PIXEL_SHIFT) * 8 + mb_y * sl->uvlinesize * block_h; | |||||
dest_cr = h->cur_pic.f.data[2] + (mb_x << PIXEL_SHIFT) * 8 + mb_y * sl->uvlinesize * block_h; | |||||
h->vdsp.prefetch(dest_y + (sl->mb_x & 3) * 4 * h->linesize + (64 << PIXEL_SHIFT), h->linesize, 4); | |||||
h->vdsp.prefetch(dest_cb + (sl->mb_x & 7) * h->uvlinesize + (64 << PIXEL_SHIFT), dest_cr - dest_cb, 2); | |||||
h->vdsp.prefetch(dest_y + (sl->mb_x & 3) * 4 * sl->linesize + (64 << PIXEL_SHIFT), sl->linesize, 4); | |||||
h->vdsp.prefetch(dest_cb + (sl->mb_x & 7) * sl->uvlinesize + (64 << PIXEL_SHIFT), dest_cr - dest_cb, 2); | |||||
h->list_counts[mb_xy] = sl->list_count; | h->list_counts[mb_xy] = sl->list_count; | ||||
if (!SIMPLE && MB_FIELD(sl)) { | if (!SIMPLE && MB_FIELD(sl)) { | ||||
linesize = sl->mb_linesize = h->linesize * 2; | |||||
uvlinesize = sl->mb_uvlinesize = h->uvlinesize * 2; | |||||
linesize = sl->mb_linesize = sl->linesize * 2; | |||||
uvlinesize = sl->mb_uvlinesize = sl->uvlinesize * 2; | |||||
block_offset = &h->block_offset[48]; | block_offset = &h->block_offset[48]; | ||||
if (mb_y & 1) { // FIXME move out of this function? | if (mb_y & 1) { // FIXME move out of this function? | ||||
dest_y -= h->linesize * 15; | |||||
dest_cb -= h->uvlinesize * (block_h - 1); | |||||
dest_cr -= h->uvlinesize * (block_h - 1); | |||||
dest_y -= sl->linesize * 15; | |||||
dest_cb -= sl->uvlinesize * (block_h - 1); | |||||
dest_cr -= sl->uvlinesize * (block_h - 1); | |||||
} | } | ||||
if (FRAME_MBAFF(h)) { | if (FRAME_MBAFF(h)) { | ||||
int list; | int list; | ||||
@@ -94,8 +94,8 @@ static av_noinline void FUNC(hl_decode_mb)(const H264Context *h, H264SliceContex | |||||
} | } | ||||
} | } | ||||
} else { | } else { | ||||
linesize = sl->mb_linesize = h->linesize; | |||||
uvlinesize = sl->mb_uvlinesize = h->uvlinesize; | |||||
linesize = sl->mb_linesize = sl->linesize; | |||||
uvlinesize = sl->mb_uvlinesize = sl->uvlinesize; | |||||
// dct_offset = s->linesize * 16; | // dct_offset = s->linesize * 16; | ||||
} | } | ||||
@@ -287,19 +287,19 @@ static av_noinline void FUNC(hl_decode_mb_444)(const H264Context *h, H264SliceCo | |||||
for (p = 0; p < plane_count; p++) { | for (p = 0; p < plane_count; p++) { | ||||
dest[p] = h->cur_pic.f.data[p] + | dest[p] = h->cur_pic.f.data[p] + | ||||
((mb_x << PIXEL_SHIFT) + mb_y * h->linesize) * 16; | |||||
h->vdsp.prefetch(dest[p] + (sl->mb_x & 3) * 4 * h->linesize + (64 << PIXEL_SHIFT), | |||||
h->linesize, 4); | |||||
((mb_x << PIXEL_SHIFT) + mb_y * sl->linesize) * 16; | |||||
h->vdsp.prefetch(dest[p] + (sl->mb_x & 3) * 4 * sl->linesize + (64 << PIXEL_SHIFT), | |||||
sl->linesize, 4); | |||||
} | } | ||||
h->list_counts[mb_xy] = sl->list_count; | h->list_counts[mb_xy] = sl->list_count; | ||||
if (!SIMPLE && MB_FIELD(sl)) { | if (!SIMPLE && MB_FIELD(sl)) { | ||||
linesize = sl->mb_linesize = sl->mb_uvlinesize = h->linesize * 2; | |||||
linesize = sl->mb_linesize = sl->mb_uvlinesize = sl->linesize * 2; | |||||
block_offset = &h->block_offset[48]; | block_offset = &h->block_offset[48]; | ||||
if (mb_y & 1) // FIXME move out of this function? | if (mb_y & 1) // FIXME move out of this function? | ||||
for (p = 0; p < 3; p++) | for (p = 0; p < 3; p++) | ||||
dest[p] -= h->linesize * 15; | |||||
dest[p] -= sl->linesize * 15; | |||||
if (FRAME_MBAFF(h)) { | if (FRAME_MBAFF(h)) { | ||||
int list; | int list; | ||||
for (list = 0; list < sl->list_count; list++) { | for (list = 0; list < sl->list_count; list++) { | ||||
@@ -319,7 +319,7 @@ static av_noinline void FUNC(hl_decode_mb_444)(const H264Context *h, H264SliceCo | |||||
} | } | ||||
} | } | ||||
} else { | } else { | ||||
linesize = sl->mb_linesize = sl->mb_uvlinesize = h->linesize; | |||||
linesize = sl->mb_linesize = sl->mb_uvlinesize = sl->linesize; | |||||
} | } | ||||
if (!SIMPLE && IS_INTRA_PCM(mb_type)) { | if (!SIMPLE && IS_INTRA_PCM(mb_type)) { | ||||
@@ -228,9 +228,6 @@ static int alloc_picture(H264Context *h, H264Picture *pic) | |||||
if (ret < 0) | if (ret < 0) | ||||
goto fail; | goto fail; | ||||
h->linesize = pic->f.linesize[0]; | |||||
h->uvlinesize = pic->f.linesize[1]; | |||||
if (h->avctx->hwaccel) { | if (h->avctx->hwaccel) { | ||||
const AVHWAccel *hwaccel = h->avctx->hwaccel; | const AVHWAccel *hwaccel = h->avctx->hwaccel; | ||||
av_assert0(!pic->hwaccel_picture_private); | av_assert0(!pic->hwaccel_picture_private); | ||||
@@ -458,11 +455,6 @@ int ff_h264_update_thread_context(AVCodecContext *dst, | |||||
} | } | ||||
context_reinitialized = 1; | context_reinitialized = 1; | ||||
/* update linesize on resize. The decoder doesn't | |||||
* necessarily call h264_frame_start in the new thread */ | |||||
h->linesize = h1->linesize; | |||||
h->uvlinesize = h1->uvlinesize; | |||||
/* copy block_offset since frame_start may not be called */ | /* copy block_offset since frame_start may not be called */ | ||||
memcpy(h->block_offset, h1->block_offset, sizeof(h->block_offset)); | memcpy(h->block_offset, h1->block_offset, sizeof(h->block_offset)); | ||||
} | } | ||||
@@ -644,17 +636,15 @@ static int h264_frame_start(H264Context *h) | |||||
if (CONFIG_ERROR_RESILIENCE) | if (CONFIG_ERROR_RESILIENCE) | ||||
ff_er_frame_start(&h->slice_ctx[0].er); | ff_er_frame_start(&h->slice_ctx[0].er); | ||||
assert(h->linesize && h->uvlinesize); | |||||
for (i = 0; i < 16; i++) { | for (i = 0; i < 16; i++) { | ||||
h->block_offset[i] = (4 * ((scan8[i] - scan8[0]) & 7) << pixel_shift) + 4 * h->linesize * ((scan8[i] - scan8[0]) >> 3); | |||||
h->block_offset[48 + i] = (4 * ((scan8[i] - scan8[0]) & 7) << pixel_shift) + 8 * h->linesize * ((scan8[i] - scan8[0]) >> 3); | |||||
h->block_offset[i] = (4 * ((scan8[i] - scan8[0]) & 7) << pixel_shift) + 4 * pic->f.linesize[0] * ((scan8[i] - scan8[0]) >> 3); | |||||
h->block_offset[48 + i] = (4 * ((scan8[i] - scan8[0]) & 7) << pixel_shift) + 8 * pic->f.linesize[0] * ((scan8[i] - scan8[0]) >> 3); | |||||
} | } | ||||
for (i = 0; i < 16; i++) { | for (i = 0; i < 16; i++) { | ||||
h->block_offset[16 + i] = | h->block_offset[16 + i] = | ||||
h->block_offset[32 + i] = (4 * ((scan8[i] - scan8[0]) & 7) << pixel_shift) + 4 * h->uvlinesize * ((scan8[i] - scan8[0]) >> 3); | |||||
h->block_offset[32 + i] = (4 * ((scan8[i] - scan8[0]) & 7) << pixel_shift) + 4 * pic->f.linesize[1] * ((scan8[i] - scan8[0]) >> 3); | |||||
h->block_offset[48 + 16 + i] = | h->block_offset[48 + 16 + i] = | ||||
h->block_offset[48 + 32 + i] = (4 * ((scan8[i] - scan8[0]) & 7) << pixel_shift) + 8 * h->uvlinesize * ((scan8[i] - scan8[0]) >> 3); | |||||
h->block_offset[48 + 32 + i] = (4 * ((scan8[i] - scan8[0]) & 7) << pixel_shift) + 8 * pic->f.linesize[1] * ((scan8[i] - scan8[0]) >> 3); | |||||
} | } | ||||
/* Some macroblocks can be accessed before they're available in case | /* Some macroblocks can be accessed before they're available in case | ||||
@@ -1976,26 +1966,26 @@ static void loop_filter(const H264Context *h, H264SliceContext *sl, int start_x, | |||||
sl->mb_x = mb_x; | sl->mb_x = mb_x; | ||||
sl->mb_y = mb_y; | sl->mb_y = mb_y; | ||||
dest_y = h->cur_pic.f.data[0] + | dest_y = h->cur_pic.f.data[0] + | ||||
((mb_x << pixel_shift) + mb_y * h->linesize) * 16; | |||||
((mb_x << pixel_shift) + mb_y * sl->linesize) * 16; | |||||
dest_cb = h->cur_pic.f.data[1] + | dest_cb = h->cur_pic.f.data[1] + | ||||
(mb_x << pixel_shift) * (8 << CHROMA444(h)) + | (mb_x << pixel_shift) * (8 << CHROMA444(h)) + | ||||
mb_y * h->uvlinesize * block_h; | |||||
mb_y * sl->uvlinesize * block_h; | |||||
dest_cr = h->cur_pic.f.data[2] + | dest_cr = h->cur_pic.f.data[2] + | ||||
(mb_x << pixel_shift) * (8 << CHROMA444(h)) + | (mb_x << pixel_shift) * (8 << CHROMA444(h)) + | ||||
mb_y * h->uvlinesize * block_h; | |||||
mb_y * sl->uvlinesize * block_h; | |||||
// FIXME simplify above | // FIXME simplify above | ||||
if (MB_FIELD(sl)) { | if (MB_FIELD(sl)) { | ||||
linesize = sl->mb_linesize = h->linesize * 2; | |||||
uvlinesize = sl->mb_uvlinesize = h->uvlinesize * 2; | |||||
linesize = sl->mb_linesize = sl->linesize * 2; | |||||
uvlinesize = sl->mb_uvlinesize = sl->uvlinesize * 2; | |||||
if (mb_y & 1) { // FIXME move out of this function? | if (mb_y & 1) { // FIXME move out of this function? | ||||
dest_y -= h->linesize * 15; | |||||
dest_cb -= h->uvlinesize * (block_h - 1); | |||||
dest_cr -= h->uvlinesize * (block_h - 1); | |||||
dest_y -= sl->linesize * 15; | |||||
dest_cb -= sl->uvlinesize * (block_h - 1); | |||||
dest_cr -= sl->uvlinesize * (block_h - 1); | |||||
} | } | ||||
} else { | } else { | ||||
linesize = sl->mb_linesize = h->linesize; | |||||
uvlinesize = sl->mb_uvlinesize = h->uvlinesize; | |||||
linesize = sl->mb_linesize = sl->linesize; | |||||
uvlinesize = sl->mb_uvlinesize = sl->uvlinesize; | |||||
} | } | ||||
backup_mb_border(h, sl, dest_y, dest_cb, dest_cr, linesize, | backup_mb_border(h, sl, dest_y, dest_cb, dest_cr, linesize, | ||||
uvlinesize, 0); | uvlinesize, 0); | ||||
@@ -2083,7 +2073,10 @@ static int decode_slice(struct AVCodecContext *avctx, void *arg) | |||||
int lf_x_start = sl->mb_x; | int lf_x_start = sl->mb_x; | ||||
int ret; | int ret; | ||||
ret = alloc_scratch_buffers(sl, h->linesize); | |||||
sl->linesize = h->cur_pic_ptr->f.linesize[0]; | |||||
sl->uvlinesize = h->cur_pic_ptr->f.linesize[1]; | |||||
ret = alloc_scratch_buffers(sl, sl->linesize); | |||||
if (ret < 0) | if (ret < 0) | ||||
return ret; | return ret; | ||||
@@ -313,23 +313,23 @@ static inline void svq3_mc_dir_part(SVQ3Context *s, | |||||
} | } | ||||
/* form component predictions */ | /* form component predictions */ | ||||
dest = h->cur_pic.f.data[0] + x + y * h->linesize; | |||||
src = pic->f.data[0] + mx + my * h->linesize; | |||||
dest = h->cur_pic.f.data[0] + x + y * sl->linesize; | |||||
src = pic->f.data[0] + mx + my * sl->linesize; | |||||
if (emu) { | if (emu) { | ||||
h->vdsp.emulated_edge_mc(sl->edge_emu_buffer, src, | h->vdsp.emulated_edge_mc(sl->edge_emu_buffer, src, | ||||
h->linesize, h->linesize, | |||||
sl->linesize, sl->linesize, | |||||
width + 1, height + 1, | width + 1, height + 1, | ||||
mx, my, s->h_edge_pos, s->v_edge_pos); | mx, my, s->h_edge_pos, s->v_edge_pos); | ||||
src = sl->edge_emu_buffer; | src = sl->edge_emu_buffer; | ||||
} | } | ||||
if (thirdpel) | if (thirdpel) | ||||
(avg ? s->tdsp.avg_tpel_pixels_tab | (avg ? s->tdsp.avg_tpel_pixels_tab | ||||
: s->tdsp.put_tpel_pixels_tab)[dxy](dest, src, h->linesize, | |||||
: s->tdsp.put_tpel_pixels_tab)[dxy](dest, src, sl->linesize, | |||||
width, height); | width, height); | ||||
else | else | ||||
(avg ? s->hdsp.avg_pixels_tab | (avg ? s->hdsp.avg_pixels_tab | ||||
: s->hdsp.put_pixels_tab)[blocksize][dxy](dest, src, h->linesize, | |||||
: s->hdsp.put_pixels_tab)[blocksize][dxy](dest, src, sl->linesize, | |||||
height); | height); | ||||
if (!(h->flags & CODEC_FLAG_GRAY)) { | if (!(h->flags & CODEC_FLAG_GRAY)) { | ||||
@@ -340,12 +340,12 @@ static inline void svq3_mc_dir_part(SVQ3Context *s, | |||||
blocksize++; | blocksize++; | ||||
for (i = 1; i < 3; i++) { | for (i = 1; i < 3; i++) { | ||||
dest = h->cur_pic.f.data[i] + (x >> 1) + (y >> 1) * h->uvlinesize; | |||||
src = pic->f.data[i] + mx + my * h->uvlinesize; | |||||
dest = h->cur_pic.f.data[i] + (x >> 1) + (y >> 1) * sl->uvlinesize; | |||||
src = pic->f.data[i] + mx + my * sl->uvlinesize; | |||||
if (emu) { | if (emu) { | ||||
h->vdsp.emulated_edge_mc(sl->edge_emu_buffer, src, | h->vdsp.emulated_edge_mc(sl->edge_emu_buffer, src, | ||||
h->uvlinesize, h->uvlinesize, | |||||
sl->uvlinesize, sl->uvlinesize, | |||||
width + 1, height + 1, | width + 1, height + 1, | ||||
mx, my, (s->h_edge_pos >> 1), | mx, my, (s->h_edge_pos >> 1), | ||||
s->v_edge_pos >> 1); | s->v_edge_pos >> 1); | ||||
@@ -354,12 +354,12 @@ static inline void svq3_mc_dir_part(SVQ3Context *s, | |||||
if (thirdpel) | if (thirdpel) | ||||
(avg ? s->tdsp.avg_tpel_pixels_tab | (avg ? s->tdsp.avg_tpel_pixels_tab | ||||
: s->tdsp.put_tpel_pixels_tab)[dxy](dest, src, | : s->tdsp.put_tpel_pixels_tab)[dxy](dest, src, | ||||
h->uvlinesize, | |||||
sl->uvlinesize, | |||||
width, height); | width, height); | ||||
else | else | ||||
(avg ? s->hdsp.avg_pixels_tab | (avg ? s->hdsp.avg_pixels_tab | ||||
: s->hdsp.put_pixels_tab)[blocksize][dxy](dest, src, | : s->hdsp.put_pixels_tab)[blocksize][dxy](dest, src, | ||||
h->uvlinesize, | |||||
sl->uvlinesize, | |||||
height); | height); | ||||
} | } | ||||
} | } | ||||
@@ -1101,8 +1101,8 @@ static int get_buffer(AVCodecContext *avctx, H264Picture *pic) | |||||
return AVERROR(ENOMEM); | return AVERROR(ENOMEM); | ||||
} | } | ||||
h->linesize = pic->f.linesize[0]; | |||||
h->uvlinesize = pic->f.linesize[1]; | |||||
sl->linesize = pic->f.linesize[0]; | |||||
sl->uvlinesize = pic->f.linesize[1]; | |||||
return 0; | return 0; | ||||
fail: | fail: | ||||
@@ -1162,14 +1162,14 @@ static int svq3_decode_frame(AVCodecContext *avctx, void *data, | |||||
return ret; | return ret; | ||||
for (i = 0; i < 16; i++) { | for (i = 0; i < 16; i++) { | ||||
h->block_offset[i] = (4 * ((scan8[i] - scan8[0]) & 7)) + 4 * h->linesize * ((scan8[i] - scan8[0]) >> 3); | |||||
h->block_offset[48 + i] = (4 * ((scan8[i] - scan8[0]) & 7)) + 8 * h->linesize * ((scan8[i] - scan8[0]) >> 3); | |||||
h->block_offset[i] = (4 * ((scan8[i] - scan8[0]) & 7)) + 4 * sl->linesize * ((scan8[i] - scan8[0]) >> 3); | |||||
h->block_offset[48 + i] = (4 * ((scan8[i] - scan8[0]) & 7)) + 8 * sl->linesize * ((scan8[i] - scan8[0]) >> 3); | |||||
} | } | ||||
for (i = 0; i < 16; i++) { | for (i = 0; i < 16; i++) { | ||||
h->block_offset[16 + i] = | h->block_offset[16 + i] = | ||||
h->block_offset[32 + i] = (4 * ((scan8[i] - scan8[0]) & 7)) + 4 * h->uvlinesize * ((scan8[i] - scan8[0]) >> 3); | |||||
h->block_offset[32 + i] = (4 * ((scan8[i] - scan8[0]) & 7)) + 4 * sl->uvlinesize * ((scan8[i] - scan8[0]) >> 3); | |||||
h->block_offset[48 + 16 + i] = | h->block_offset[48 + 16 + i] = | ||||
h->block_offset[48 + 32 + i] = (4 * ((scan8[i] - scan8[0]) & 7)) + 8 * h->uvlinesize * ((scan8[i] - scan8[0]) >> 3); | |||||
h->block_offset[48 + 32 + i] = (4 * ((scan8[i] - scan8[0]) & 7)) + 8 * sl->uvlinesize * ((scan8[i] - scan8[0]) >> 3); | |||||
} | } | ||||
if (h->pict_type != AV_PICTURE_TYPE_I) { | if (h->pict_type != AV_PICTURE_TYPE_I) { | ||||