From e6287f077c3e8e4aca11e61dd4bade1351439e6b Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sat, 17 Jan 2015 22:28:46 +0100 Subject: [PATCH] h264: move {mv,ref}_cache into the per-slice context --- libavcodec/h264.c | 18 +++--- libavcodec/h264.h | 27 +++++---- libavcodec/h264_cabac.c | 67 +++++++++++---------- libavcodec/h264_cavlc.c | 44 +++++++------- libavcodec/h264_direct.c | 109 +++++++++++++++++----------------- libavcodec/h264_loopfilter.c | 39 ++++++------ libavcodec/h264_mb.c | 81 +++++++++++++------------ libavcodec/h264_mb_template.c | 12 ++-- libavcodec/h264_mc_template.c | 10 ++-- libavcodec/h264_mvpred.h | 64 ++++++++++---------- libavcodec/h264_slice.c | 9 +-- libavcodec/svq3.c | 35 +++++------ 12 files changed, 267 insertions(+), 248 deletions(-) diff --git a/libavcodec/h264.c b/libavcodec/h264.c index 2b29389d60..ee6d86334b 100644 --- a/libavcodec/h264.c +++ b/libavcodec/h264.c @@ -71,8 +71,8 @@ static void h264_er_decode_mb(void *opaque, int ref, int mv_dir, int mv_type, ref = 0; fill_rectangle(&h->cur_pic.ref_index[0][4 * h->mb_xy], 2, 2, 2, ref, 1); - fill_rectangle(&h->ref_cache[0][scan8[0]], 4, 4, 8, ref, 1); - fill_rectangle(h->mv_cache[0][scan8[0]], 4, 4, 8, + fill_rectangle(&sl->ref_cache[0][scan8[0]], 4, 4, 8, ref, 1); + fill_rectangle(sl->mv_cache[0][scan8[0]], 4, 4, 8, pack16to32((*mv)[0][0][0], (*mv)[0][0][1]), 4); assert(!FRAME_MBAFF(h)); ff_h264_hl_decode_mb(h, &h->slice_ctx[0]); @@ -484,12 +484,14 @@ int ff_h264_context_init(H264Context *h) FF_ALLOCZ_OR_GOTO(h->avctx, h->top_borders[1], h->mb_width * 16 * 3 * sizeof(uint8_t) * 2, fail) - h->ref_cache[0][scan8[5] + 1] = - h->ref_cache[0][scan8[7] + 1] = - h->ref_cache[0][scan8[13] + 1] = - h->ref_cache[1][scan8[5] + 1] = - h->ref_cache[1][scan8[7] + 1] = - h->ref_cache[1][scan8[13] + 1] = PART_NOT_AVAILABLE; + 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] = + h->slice_ctx[i].ref_cache[0][scan8[13] + 1] = + h->slice_ctx[i].ref_cache[1][scan8[5] + 1] = + h->slice_ctx[i].ref_cache[1][scan8[7] + 1] = + h->slice_ctx[i].ref_cache[1][scan8[13] + 1] = PART_NOT_AVAILABLE; + } if (CONFIG_ERROR_RESILIENCE) { /* init ER */ diff --git a/libavcodec/h264.h b/libavcodec/h264.h index 521ceebe70..189825a301 100644 --- a/libavcodec/h264.h +++ b/libavcodec/h264.h @@ -347,6 +347,12 @@ typedef struct H264SliceContext { * is 64 if not available. */ DECLARE_ALIGNED(8, uint8_t, non_zero_count_cache)[15 * 8]; + + /** + * Motion vector cache. + */ + DECLARE_ALIGNED(16, int16_t, mv_cache)[2][5 * 8][2]; + DECLARE_ALIGNED(8, int8_t, ref_cache)[2][5 * 8]; } H264SliceContext; /** @@ -389,11 +395,6 @@ typedef struct H264Context { uint8_t (*non_zero_count)[48]; - /** - * Motion vector cache. - */ - DECLARE_ALIGNED(16, int16_t, mv_cache)[2][5 * 8][2]; - DECLARE_ALIGNED(8, int8_t, ref_cache)[2][5 * 8]; #define LIST_NOT_USED -1 // FIXME rename? #define PART_NOT_AVAILABLE -2 @@ -821,7 +822,8 @@ void h264_init_dequant_tables(H264Context *h); void ff_h264_direct_dist_scale_factor(H264Context *const h); void ff_h264_direct_ref_list_init(H264Context *const h); -void ff_h264_pred_direct_motion(H264Context *const h, int *mb_type); +void ff_h264_pred_direct_motion(H264Context *const h, H264SliceContext *sl, + int *mb_type); void ff_h264_filter_mb_fast(H264Context *h, H264SliceContext *sl, int mb_x, int mb_y, uint8_t *img_y, uint8_t *img_cb, uint8_t *img_cr, @@ -969,12 +971,13 @@ static av_always_inline void write_back_non_zero_count(H264Context *h, } static av_always_inline void write_back_motion_list(H264Context *h, + H264SliceContext *sl, int b_stride, int b_xy, int b8_xy, int mb_type, int list) { int16_t(*mv_dst)[2] = &h->cur_pic.motion_val[list][b_xy]; - int16_t(*mv_src)[2] = &h->mv_cache[list][scan8[0]]; + int16_t(*mv_src)[2] = &sl->mv_cache[list][scan8[0]]; AV_COPY128(mv_dst + 0 * b_stride, mv_src + 8 * 0); AV_COPY128(mv_dst + 1 * b_stride, mv_src + 8 * 1); AV_COPY128(mv_dst + 2 * b_stride, mv_src + 8 * 2); @@ -995,7 +998,7 @@ static av_always_inline void write_back_motion_list(H264Context *h, { int8_t *ref_index = &h->cur_pic.ref_index[list][b8_xy]; - int8_t *ref_cache = h->ref_cache[list]; + int8_t *ref_cache = sl->ref_cache[list]; ref_index[0 + 0 * 2] = ref_cache[scan8[0]]; ref_index[1 + 0 * 2] = ref_cache[scan8[4]]; ref_index[0 + 1 * 2] = ref_cache[scan8[8]]; @@ -1003,20 +1006,22 @@ static av_always_inline void write_back_motion_list(H264Context *h, } } -static av_always_inline void write_back_motion(H264Context *h, int mb_type) +static av_always_inline void write_back_motion(H264Context *h, + H264SliceContext *sl, + int mb_type) { const int b_stride = h->b_stride; const int b_xy = 4 * h->mb_x + 4 * h->mb_y * h->b_stride; // try mb2b(8)_xy const int b8_xy = 4 * h->mb_xy; if (USES_LIST(mb_type, 0)) { - write_back_motion_list(h, b_stride, b_xy, b8_xy, mb_type, 0); + write_back_motion_list(h, sl, b_stride, b_xy, b8_xy, mb_type, 0); } else { fill_rectangle(&h->cur_pic.ref_index[0][b8_xy], 2, 2, 2, (uint8_t)LIST_NOT_USED, 1); } if (USES_LIST(mb_type, 1)) - write_back_motion_list(h, b_stride, b_xy, b8_xy, mb_type, 1); + write_back_motion_list(h, sl, b_stride, b_xy, b8_xy, mb_type, 1); if (h->slice_type_nos == AV_PICTURE_TYPE_B && CABAC(h)) { if (IS_8X8(mb_type)) { diff --git a/libavcodec/h264_cabac.c b/libavcodec/h264_cabac.c index bf80455781..7fa1ae6f24 100644 --- a/libavcodec/h264_cabac.c +++ b/libavcodec/h264_cabac.c @@ -1459,9 +1459,10 @@ static int decode_cabac_b_mb_sub_type( H264Context *h ) { return type; } -static int decode_cabac_mb_ref( H264Context *h, int list, int n ) { - int refa = h->ref_cache[list][scan8[n] - 1]; - int refb = h->ref_cache[list][scan8[n] - 8]; +static int decode_cabac_mb_ref(H264Context *h, H264SliceContext *sl, int list, int n) +{ + int refa = sl->ref_cache[list][scan8[n] - 1]; + int refb = sl->ref_cache[list][scan8[n] - 8]; int ref = 0; int ctx = 0; @@ -2092,11 +2093,11 @@ decode_intra_mb: } if( IS_DIRECT(h->sub_mb_type[0] | h->sub_mb_type[1] | h->sub_mb_type[2] | h->sub_mb_type[3]) ) { - ff_h264_pred_direct_motion(h, &mb_type); - h->ref_cache[0][scan8[4]] = - h->ref_cache[1][scan8[4]] = - h->ref_cache[0][scan8[12]] = - h->ref_cache[1][scan8[12]] = PART_NOT_AVAILABLE; + ff_h264_pred_direct_motion(h, sl, &mb_type); + sl->ref_cache[0][scan8[4]] = + sl->ref_cache[1][scan8[4]] = + sl->ref_cache[0][scan8[12]] = + sl->ref_cache[1][scan8[12]] = PART_NOT_AVAILABLE; for( i = 0; i < 4; i++ ) fill_rectangle( &h->direct_cache[scan8[4*i]], 2, 2, 8, (h->sub_mb_type[i]>>1)&0xFF, 1 ); } @@ -2114,7 +2115,7 @@ decode_intra_mb: if(IS_DIR(h->sub_mb_type[i], 0, list)){ int rc = h->ref_count[list] << MB_MBAFF(h); if (rc > 1) { - ref[list][i] = decode_cabac_mb_ref( h, list, 4*i ); + ref[list][i] = decode_cabac_mb_ref(h, sl, list, 4 * i); if (ref[list][i] >= (unsigned) rc) { av_log(h->avctx, AV_LOG_ERROR, "Reference %d >= %d\n", ref[list][i], rc); return -1; @@ -2124,8 +2125,8 @@ decode_intra_mb: } else { ref[list][i] = -1; } - h->ref_cache[list][ scan8[4*i]+1 ]= - h->ref_cache[list][ scan8[4*i]+8 ]=h->ref_cache[list][ scan8[4*i]+9 ]= ref[list][i]; + sl->ref_cache[list][scan8[4 * i] + 1] = + sl->ref_cache[list][scan8[4 * i] + 8] = sl->ref_cache[list][scan8[4 * i] + 9] = ref[list][i]; } } @@ -2134,7 +2135,7 @@ decode_intra_mb: for(list=0; listlist_count; list++){ for(i=0; i<4; i++){ - h->ref_cache[list][ scan8[4*i] ]=h->ref_cache[list][ scan8[4*i]+1 ]; + sl->ref_cache[list][scan8[4 * i]] = sl->ref_cache[list][scan8[4 * i] + 1]; if(IS_DIRECT(h->sub_mb_type[i])){ fill_rectangle(h->mvd_cache[list][scan8[4*i]], 2, 2, 8, 0, 2); continue; @@ -2147,9 +2148,9 @@ decode_intra_mb: int mpx, mpy; int mx, my; const int index= 4*i + block_width*j; - int16_t (* mv_cache)[2]= &h->mv_cache[list][ scan8[index] ]; + int16_t (* mv_cache)[2] = &sl->mv_cache[list][ scan8[index] ]; uint8_t (* mvd_cache)[2]= &h->mvd_cache[list][ scan8[index] ]; - pred_motion(h, sl, index, block_width, list, h->ref_cache[list][ scan8[index] ], &mx, &my); + pred_motion(h, sl, index, block_width, list, sl->ref_cache[list][ scan8[index] ], &mx, &my); DECODE_CABAC_MB_MVD( h, list, index) tprintf(h->avctx, "final mv:%d %d\n", mx, my); @@ -2183,13 +2184,13 @@ decode_intra_mb: mvd_cache[ 0 ][1]= mpy; } }else{ - fill_rectangle(h->mv_cache [list][ scan8[4*i] ], 2, 2, 8, 0, 4); + fill_rectangle(sl->mv_cache [list][ scan8[4*i] ], 2, 2, 8, 0, 4); fill_rectangle(h->mvd_cache[list][ scan8[4*i] ], 2, 2, 8, 0, 2); } } } } else if( IS_DIRECT(mb_type) ) { - ff_h264_pred_direct_motion(h, &mb_type); + ff_h264_pred_direct_motion(h, sl, &mb_type); fill_rectangle(h->mvd_cache[0][scan8[0]], 4, 4, 8, 0, 2); fill_rectangle(h->mvd_cache[1][scan8[0]], 4, 4, 8, 0, 2); dct8x8_allowed &= h->sps.direct_8x8_inference_flag; @@ -2200,25 +2201,25 @@ decode_intra_mb: if(IS_DIR(mb_type, 0, list)){ int ref, rc = h->ref_count[list] << MB_MBAFF(h); if (rc > 1) { - ref= decode_cabac_mb_ref(h, list, 0); + ref= decode_cabac_mb_ref(h, sl, list, 0); if (ref >= (unsigned) rc) { av_log(h->avctx, AV_LOG_ERROR, "Reference %d >= %d\n", ref, rc); return -1; } }else ref=0; - fill_rectangle(&h->ref_cache[list][ scan8[0] ], 4, 4, 8, ref, 1); + fill_rectangle(&sl->ref_cache[list][ scan8[0] ], 4, 4, 8, ref, 1); } } for(list=0; listlist_count; list++){ if(IS_DIR(mb_type, 0, list)){ int mx,my,mpx,mpy; - pred_motion(h, sl, 0, 4, list, h->ref_cache[list][ scan8[0] ], &mx, &my); + pred_motion(h, sl, 0, 4, list, sl->ref_cache[list][ scan8[0] ], &mx, &my); DECODE_CABAC_MB_MVD( h, list, 0) tprintf(h->avctx, "final mv:%d %d\n", mx, my); fill_rectangle(h->mvd_cache[list][ scan8[0] ], 4, 4, 8, pack8to16(mpx,mpy), 2); - fill_rectangle(h->mv_cache[list][ scan8[0] ], 4, 4, 8, pack16to32(mx,my), 4); + fill_rectangle(sl->mv_cache[list][ scan8[0] ], 4, 4, 8, pack16to32(mx,my), 4); } } } @@ -2228,31 +2229,31 @@ decode_intra_mb: if(IS_DIR(mb_type, i, list)){ int ref, rc = h->ref_count[list] << MB_MBAFF(h); if (rc > 1) { - ref= decode_cabac_mb_ref( h, list, 8*i ); + ref= decode_cabac_mb_ref(h, sl, list, 8 * i); if (ref >= (unsigned) rc) { av_log(h->avctx, AV_LOG_ERROR, "Reference %d >= %d\n", ref, rc); return -1; } }else ref=0; - fill_rectangle(&h->ref_cache[list][ scan8[0] + 16*i ], 4, 2, 8, ref, 1); + fill_rectangle(&sl->ref_cache[list][ scan8[0] + 16*i ], 4, 2, 8, ref, 1); }else - fill_rectangle(&h->ref_cache[list][ scan8[0] + 16*i ], 4, 2, 8, (LIST_NOT_USED&0xFF), 1); + fill_rectangle(&sl->ref_cache[list][ scan8[0] + 16*i ], 4, 2, 8, (LIST_NOT_USED&0xFF), 1); } } for(list=0; listlist_count; list++){ for(i=0; i<2; i++){ if(IS_DIR(mb_type, i, list)){ int mx,my,mpx,mpy; - pred_16x8_motion(h, sl, 8*i, list, h->ref_cache[list][scan8[0] + 16*i], &mx, &my); + pred_16x8_motion(h, sl, 8*i, list, sl->ref_cache[list][scan8[0] + 16*i], &mx, &my); DECODE_CABAC_MB_MVD( h, list, 8*i) tprintf(h->avctx, "final mv:%d %d\n", mx, my); fill_rectangle(h->mvd_cache[list][ scan8[0] + 16*i ], 4, 2, 8, pack8to16(mpx,mpy), 2); - fill_rectangle(h->mv_cache[list][ scan8[0] + 16*i ], 4, 2, 8, pack16to32(mx,my), 4); + fill_rectangle(sl->mv_cache[list][ scan8[0] + 16*i ], 4, 2, 8, pack16to32(mx,my), 4); }else{ fill_rectangle(h->mvd_cache[list][ scan8[0] + 16*i ], 4, 2, 8, 0, 2); - fill_rectangle(h-> mv_cache[list][ scan8[0] + 16*i ], 4, 2, 8, 0, 4); + fill_rectangle(sl->mv_cache[list][ scan8[0] + 16*i ], 4, 2, 8, 0, 4); } } } @@ -2263,31 +2264,31 @@ decode_intra_mb: if(IS_DIR(mb_type, i, list)){ //FIXME optimize int ref, rc = h->ref_count[list] << MB_MBAFF(h); if (rc > 1) { - ref= decode_cabac_mb_ref( h, list, 4*i ); + ref= decode_cabac_mb_ref(h, sl, list, 4 * i); if (ref >= (unsigned) rc) { av_log(h->avctx, AV_LOG_ERROR, "Reference %d >= %d\n", ref, rc); return -1; } }else ref=0; - fill_rectangle(&h->ref_cache[list][ scan8[0] + 2*i ], 2, 4, 8, ref, 1); + fill_rectangle(&sl->ref_cache[list][ scan8[0] + 2*i ], 2, 4, 8, ref, 1); }else - fill_rectangle(&h->ref_cache[list][ scan8[0] + 2*i ], 2, 4, 8, (LIST_NOT_USED&0xFF), 1); + fill_rectangle(&sl->ref_cache[list][ scan8[0] + 2*i ], 2, 4, 8, (LIST_NOT_USED&0xFF), 1); } } for(list=0; listlist_count; list++){ for(i=0; i<2; i++){ if(IS_DIR(mb_type, i, list)){ int mx,my,mpx,mpy; - pred_8x16_motion(h, sl, i*4, list, h->ref_cache[list][ scan8[0] + 2*i ], &mx, &my); + pred_8x16_motion(h, sl, i*4, list, sl->ref_cache[list][ scan8[0] + 2*i ], &mx, &my); DECODE_CABAC_MB_MVD( h, list, 4*i) tprintf(h->avctx, "final mv:%d %d\n", mx, my); fill_rectangle(h->mvd_cache[list][ scan8[0] + 2*i ], 2, 4, 8, pack8to16(mpx,mpy), 2); - fill_rectangle(h->mv_cache[list][ scan8[0] + 2*i ], 2, 4, 8, pack16to32(mx,my), 4); + fill_rectangle(sl->mv_cache[list][ scan8[0] + 2*i ], 2, 4, 8, pack16to32(mx,my), 4); }else{ fill_rectangle(h->mvd_cache[list][ scan8[0] + 2*i ], 2, 4, 8, 0, 2); - fill_rectangle(h-> mv_cache[list][ scan8[0] + 2*i ], 2, 4, 8, 0, 4); + fill_rectangle(sl->mv_cache[list][ scan8[0] + 2*i ], 2, 4, 8, 0, 4); } } } @@ -2296,7 +2297,7 @@ decode_intra_mb: if( IS_INTER( mb_type ) ) { h->chroma_pred_mode_table[mb_xy] = 0; - write_back_motion( h, mb_type ); + write_back_motion(h, sl, mb_type); } if( !IS_INTRA16x16( mb_type ) ) { diff --git a/libavcodec/h264_cavlc.c b/libavcodec/h264_cavlc.c index 08580ed7e2..37647b9e83 100644 --- a/libavcodec/h264_cavlc.c +++ b/libavcodec/h264_cavlc.c @@ -845,11 +845,11 @@ decode_intra_mb: h->sub_mb_type[i]= b_sub_mb_type_info[ h->sub_mb_type[i] ].type; } if( IS_DIRECT(h->sub_mb_type[0]|h->sub_mb_type[1]|h->sub_mb_type[2]|h->sub_mb_type[3])) { - ff_h264_pred_direct_motion(h, &mb_type); - h->ref_cache[0][scan8[4]] = - h->ref_cache[1][scan8[4]] = - h->ref_cache[0][scan8[12]] = - h->ref_cache[1][scan8[12]] = PART_NOT_AVAILABLE; + ff_h264_pred_direct_motion(h, sl, &mb_type); + sl->ref_cache[0][scan8[4]] = + sl->ref_cache[1][scan8[4]] = + sl->ref_cache[0][scan8[12]] = + sl->ref_cache[1][scan8[12]] = PART_NOT_AVAILABLE; } }else{ assert(h->slice_type_nos == AV_PICTURE_TYPE_P); //FIXME SP correct ? @@ -895,11 +895,11 @@ decode_intra_mb: for(list=0; listlist_count; list++){ for(i=0; i<4; i++){ if(IS_DIRECT(h->sub_mb_type[i])) { - h->ref_cache[list][ scan8[4*i] ] = h->ref_cache[list][ scan8[4*i]+1 ]; + sl->ref_cache[list][ scan8[4*i] ] = sl->ref_cache[list][ scan8[4*i]+1 ]; continue; } - h->ref_cache[list][ scan8[4*i] ]=h->ref_cache[list][ scan8[4*i]+1 ]= - h->ref_cache[list][ scan8[4*i]+8 ]=h->ref_cache[list][ scan8[4*i]+9 ]= ref[list][i]; + sl->ref_cache[list][ scan8[4*i] ]=sl->ref_cache[list][ scan8[4*i]+1 ]= + sl->ref_cache[list][ scan8[4*i]+8 ]=sl->ref_cache[list][ scan8[4*i]+9 ]= ref[list][i]; if(IS_DIR(h->sub_mb_type[i], 0, list)){ const int sub_mb_type= h->sub_mb_type[i]; @@ -907,8 +907,8 @@ decode_intra_mb: for(j=0; jmv_cache[list][ scan8[index] ]; - pred_motion(h, sl, index, block_width, list, h->ref_cache[list][ scan8[index] ], &mx, &my); + int16_t (* mv_cache)[2]= &sl->mv_cache[list][ scan8[index] ]; + pred_motion(h, sl, index, block_width, list, sl->ref_cache[list][ scan8[index] ], &mx, &my); mx += get_se_golomb(&h->gb); my += get_se_golomb(&h->gb); tprintf(h->avctx, "final mv:%d %d\n", mx, my); @@ -929,14 +929,14 @@ decode_intra_mb: mv_cache[ 0 ][1]= my; } }else{ - uint32_t *p= (uint32_t *)&h->mv_cache[list][ scan8[4*i] ][0]; + uint32_t *p= (uint32_t *)&sl->mv_cache[list][ scan8[4*i] ][0]; p[0] = p[1]= p[8] = p[9]= 0; } } } }else if(IS_DIRECT(mb_type)){ - ff_h264_pred_direct_motion(h, &mb_type); + ff_h264_pred_direct_motion(h, sl, &mb_type); dct8x8_allowed &= h->sps.direct_8x8_inference_flag; }else{ int list, mx, my, i; @@ -957,17 +957,17 @@ decode_intra_mb: return -1; } } - fill_rectangle(&h->ref_cache[list][ scan8[0] ], 4, 4, 8, val, 1); + fill_rectangle(&sl->ref_cache[list][ scan8[0] ], 4, 4, 8, val, 1); } } for(list=0; listlist_count; list++){ if(IS_DIR(mb_type, 0, list)){ - pred_motion(h, sl, 0, 4, list, h->ref_cache[list][ scan8[0] ], &mx, &my); + pred_motion(h, sl, 0, 4, list, sl->ref_cache[list][ scan8[0] ], &mx, &my); mx += get_se_golomb(&h->gb); my += get_se_golomb(&h->gb); tprintf(h->avctx, "final mv:%d %d\n", mx, my); - fill_rectangle(h->mv_cache[list][ scan8[0] ], 4, 4, 8, pack16to32(mx,my), 4); + fill_rectangle(sl->mv_cache[list][ scan8[0] ], 4, 4, 8, pack16to32(mx,my), 4); } } } @@ -990,14 +990,14 @@ decode_intra_mb: } }else val= LIST_NOT_USED&0xFF; - fill_rectangle(&h->ref_cache[list][ scan8[0] + 16*i ], 4, 2, 8, val, 1); + fill_rectangle(&sl->ref_cache[list][ scan8[0] + 16*i ], 4, 2, 8, val, 1); } } for(list=0; listlist_count; list++){ for(i=0; i<2; i++){ unsigned int val; if(IS_DIR(mb_type, i, list)){ - pred_16x8_motion(h, sl, 8*i, list, h->ref_cache[list][scan8[0] + 16*i], &mx, &my); + pred_16x8_motion(h, sl, 8*i, list, sl->ref_cache[list][scan8[0] + 16*i], &mx, &my); mx += get_se_golomb(&h->gb); my += get_se_golomb(&h->gb); tprintf(h->avctx, "final mv:%d %d\n", mx, my); @@ -1005,7 +1005,7 @@ decode_intra_mb: val= pack16to32(mx,my); }else val=0; - fill_rectangle(h->mv_cache[list][ scan8[0] + 16*i ], 4, 2, 8, val, 4); + fill_rectangle(sl->mv_cache[list][ scan8[0] + 16*i ], 4, 2, 8, val, 4); } } }else{ @@ -1028,14 +1028,14 @@ decode_intra_mb: } }else val= LIST_NOT_USED&0xFF; - fill_rectangle(&h->ref_cache[list][ scan8[0] + 2*i ], 2, 4, 8, val, 1); + fill_rectangle(&sl->ref_cache[list][ scan8[0] + 2*i ], 2, 4, 8, val, 1); } } for(list=0; listlist_count; list++){ for(i=0; i<2; i++){ unsigned int val; if(IS_DIR(mb_type, i, list)){ - pred_8x16_motion(h, sl, i*4, list, h->ref_cache[list][ scan8[0] + 2*i ], &mx, &my); + pred_8x16_motion(h, sl, i*4, list, sl->ref_cache[list][ scan8[0] + 2*i ], &mx, &my); mx += get_se_golomb(&h->gb); my += get_se_golomb(&h->gb); tprintf(h->avctx, "final mv:%d %d\n", mx, my); @@ -1043,14 +1043,14 @@ decode_intra_mb: val= pack16to32(mx,my); }else val=0; - fill_rectangle(h->mv_cache[list][ scan8[0] + 2*i ], 2, 4, 8, val, 4); + fill_rectangle(sl->mv_cache[list][ scan8[0] + 2*i ], 2, 4, 8, val, 4); } } } } if(IS_INTER(mb_type)) - write_back_motion(h, mb_type); + write_back_motion(h, sl, mb_type); if(!IS_INTRA16x16(mb_type)){ cbp= get_ue_golomb(&h->gb); diff --git a/libavcodec/h264_direct.c b/libavcodec/h264_direct.c index 855526ed03..559b8ab257 100644 --- a/libavcodec/h264_direct.c +++ b/libavcodec/h264_direct.c @@ -171,7 +171,8 @@ static void await_reference_mb_row(H264Context *const h, H264Picture *ref, ref_field_picture && ref_field); } -static void pred_spatial_direct_motion(H264Context *const h, int *mb_type) +static void pred_spatial_direct_motion(H264Context *const h, H264SliceContext *sl, + int *mb_type) { int b8_stride = 2; int b4_stride = h->b_stride; @@ -196,13 +197,13 @@ static void pred_spatial_direct_motion(H264Context *const h, int *mb_type) /* ref = min(neighbors) */ for (list = 0; list < 2; list++) { - int left_ref = h->ref_cache[list][scan8[0] - 1]; - int top_ref = h->ref_cache[list][scan8[0] - 8]; - int refc = h->ref_cache[list][scan8[0] - 8 + 4]; - const int16_t *C = h->mv_cache[list][scan8[0] - 8 + 4]; + int left_ref = sl->ref_cache[list][scan8[0] - 1]; + int top_ref = sl->ref_cache[list][scan8[0] - 8]; + int refc = sl->ref_cache[list][scan8[0] - 8 + 4]; + const int16_t *C = sl->mv_cache[list][scan8[0] - 8 + 4]; if (refc == PART_NOT_AVAILABLE) { - refc = h->ref_cache[list][scan8[0] - 8 - 1]; - C = h->mv_cache[list][scan8[0] - 8 - 1]; + refc = sl->ref_cache[list][scan8[0] - 8 - 1]; + C = sl->mv_cache[list][scan8[0] - 8 - 1]; } ref[list] = FFMIN3((unsigned)left_ref, (unsigned)top_ref, @@ -210,8 +211,8 @@ static void pred_spatial_direct_motion(H264Context *const h, int *mb_type) if (ref[list] >= 0) { /* This is just pred_motion() but with the cases removed that * cannot happen for direct blocks. */ - const int16_t *const A = h->mv_cache[list][scan8[0] - 1]; - const int16_t *const B = h->mv_cache[list][scan8[0] - 8]; + const int16_t *const A = sl->mv_cache[list][scan8[0] - 1]; + const int16_t *const B = sl->mv_cache[list][scan8[0] - 8]; int match_count = (left_ref == ref[list]) + (top_ref == ref[list]) + @@ -246,10 +247,10 @@ static void pred_spatial_direct_motion(H264Context *const h, int *mb_type) } if (!(is_b8x8 | mv[0] | mv[1])) { - fill_rectangle(&h->ref_cache[0][scan8[0]], 4, 4, 8, (uint8_t)ref[0], 1); - fill_rectangle(&h->ref_cache[1][scan8[0]], 4, 4, 8, (uint8_t)ref[1], 1); - fill_rectangle(&h->mv_cache[0][scan8[0]], 4, 4, 8, 0, 4); - fill_rectangle(&h->mv_cache[1][scan8[0]], 4, 4, 8, 0, 4); + fill_rectangle(&sl->ref_cache[0][scan8[0]], 4, 4, 8, (uint8_t)ref[0], 1); + fill_rectangle(&sl->ref_cache[1][scan8[0]], 4, 4, 8, (uint8_t)ref[1], 1); + fill_rectangle(&sl->mv_cache[0][scan8[0]], 4, 4, 8, 0, 4); + fill_rectangle(&sl->mv_cache[1][scan8[0]], 4, 4, 8, 0, 4); *mb_type = (*mb_type & ~(MB_TYPE_8x8 | MB_TYPE_16x8 | MB_TYPE_8x16 | MB_TYPE_P1L0 | MB_TYPE_P1L1)) | MB_TYPE_16x16 | MB_TYPE_DIRECT2; @@ -340,9 +341,9 @@ single_col: continue; h->sub_mb_type[i8] = sub_mb_type; - fill_rectangle(&h->ref_cache[0][scan8[i8 * 4]], 2, 2, 8, + fill_rectangle(&sl->ref_cache[0][scan8[i8 * 4]], 2, 2, 8, (uint8_t)ref[0], 1); - fill_rectangle(&h->ref_cache[1][scan8[i8 * 4]], 2, 2, 8, + fill_rectangle(&sl->ref_cache[1][scan8[i8 * 4]], 2, 2, 8, (uint8_t)ref[1], 1); if (!IS_INTRA(mb_type_col[y8]) && !h->ref_list[1][0].long_ref && ((l1ref0[xy8] == 0 && @@ -363,8 +364,8 @@ single_col: a = mv[0]; b = mv[1]; } - fill_rectangle(&h->mv_cache[0][scan8[i8 * 4]], 2, 2, 8, a, 4); - fill_rectangle(&h->mv_cache[1][scan8[i8 * 4]], 2, 2, 8, b, 4); + fill_rectangle(&sl->mv_cache[0][scan8[i8 * 4]], 2, 2, 8, a, 4); + fill_rectangle(&sl->mv_cache[1][scan8[i8 * 4]], 2, 2, 8, b, 4); } if (!is_b8x8 && !(n & 3)) *mb_type = (*mb_type & ~(MB_TYPE_8x8 | MB_TYPE_16x8 | MB_TYPE_8x16 | @@ -373,8 +374,8 @@ single_col: } else if (IS_16X16(*mb_type)) { int a, b; - fill_rectangle(&h->ref_cache[0][scan8[0]], 4, 4, 8, (uint8_t)ref[0], 1); - fill_rectangle(&h->ref_cache[1][scan8[0]], 4, 4, 8, (uint8_t)ref[1], 1); + fill_rectangle(&sl->ref_cache[0][scan8[0]], 4, 4, 8, (uint8_t)ref[0], 1); + fill_rectangle(&sl->ref_cache[1][scan8[0]], 4, 4, 8, (uint8_t)ref[1], 1); if (!IS_INTRA(mb_type_col[0]) && !h->ref_list[1][0].long_ref && ((l1ref0[0] == 0 && FFABS(l1mv0[0][0]) <= 1 && @@ -392,8 +393,8 @@ single_col: a = mv[0]; b = mv[1]; } - fill_rectangle(&h->mv_cache[0][scan8[0]], 4, 4, 8, a, 4); - fill_rectangle(&h->mv_cache[1][scan8[0]], 4, 4, 8, b, 4); + fill_rectangle(&sl->mv_cache[0][scan8[0]], 4, 4, 8, a, 4); + fill_rectangle(&sl->mv_cache[1][scan8[0]], 4, 4, 8, b, 4); } else { int n = 0; for (i8 = 0; i8 < 4; i8++) { @@ -404,11 +405,11 @@ single_col: continue; h->sub_mb_type[i8] = sub_mb_type; - fill_rectangle(&h->mv_cache[0][scan8[i8 * 4]], 2, 2, 8, mv[0], 4); - fill_rectangle(&h->mv_cache[1][scan8[i8 * 4]], 2, 2, 8, mv[1], 4); - fill_rectangle(&h->ref_cache[0][scan8[i8 * 4]], 2, 2, 8, + fill_rectangle(&sl->mv_cache[0][scan8[i8 * 4]], 2, 2, 8, mv[0], 4); + fill_rectangle(&sl->mv_cache[1][scan8[i8 * 4]], 2, 2, 8, mv[1], 4); + fill_rectangle(&sl->ref_cache[0][scan8[i8 * 4]], 2, 2, 8, (uint8_t)ref[0], 1); - fill_rectangle(&h->ref_cache[1][scan8[i8 * 4]], 2, 2, 8, + fill_rectangle(&sl->ref_cache[1][scan8[i8 * 4]], 2, 2, 8, (uint8_t)ref[1], 1); assert(b8_stride == 2); @@ -423,10 +424,10 @@ single_col: const int16_t *mv_col = l1mv[x8 * 3 + y8 * 3 * b4_stride]; if (FFABS(mv_col[0]) <= 1 && FFABS(mv_col[1]) <= 1) { if (ref[0] == 0) - fill_rectangle(&h->mv_cache[0][scan8[i8 * 4]], 2, 2, + fill_rectangle(&sl->mv_cache[0][scan8[i8 * 4]], 2, 2, 8, 0, 4); if (ref[1] == 0) - fill_rectangle(&h->mv_cache[1][scan8[i8 * 4]], 2, 2, + fill_rectangle(&sl->mv_cache[1][scan8[i8 * 4]], 2, 2, 8, 0, 4); n += 4; } @@ -437,9 +438,9 @@ single_col: (y8 * 2 + (i4 >> 1)) * b4_stride]; if (FFABS(mv_col[0]) <= 1 && FFABS(mv_col[1]) <= 1) { if (ref[0] == 0) - AV_ZERO32(h->mv_cache[0][scan8[i8 * 4 + i4]]); + AV_ZERO32(sl->mv_cache[0][scan8[i8 * 4 + i4]]); if (ref[1] == 0) - AV_ZERO32(h->mv_cache[1][scan8[i8 * 4 + i4]]); + AV_ZERO32(sl->mv_cache[1][scan8[i8 * 4 + i4]]); m++; } } @@ -456,7 +457,8 @@ single_col: } } -static void pred_temp_direct_motion(H264Context *const h, int *mb_type) +static void pred_temp_direct_motion(H264Context *const h, H264SliceContext *sl, + int *mb_type) { int b8_stride = 2; int b4_stride = h->b_stride; @@ -577,11 +579,11 @@ single_col: continue; h->sub_mb_type[i8] = sub_mb_type; - fill_rectangle(&h->ref_cache[1][scan8[i8 * 4]], 2, 2, 8, 0, 1); + fill_rectangle(&sl->ref_cache[1][scan8[i8 * 4]], 2, 2, 8, 0, 1); if (IS_INTRA(mb_type_col[y8])) { - fill_rectangle(&h->ref_cache[0][scan8[i8 * 4]], 2, 2, 8, 0, 1); - fill_rectangle(&h->mv_cache[0][scan8[i8 * 4]], 2, 2, 8, 0, 4); - fill_rectangle(&h->mv_cache[1][scan8[i8 * 4]], 2, 2, 8, 0, 4); + fill_rectangle(&sl->ref_cache[0][scan8[i8 * 4]], 2, 2, 8, 0, 1); + fill_rectangle(&sl->mv_cache[0][scan8[i8 * 4]], 2, 2, 8, 0, 4); + fill_rectangle(&sl->mv_cache[1][scan8[i8 * 4]], 2, 2, 8, 0, 4); continue; } @@ -594,7 +596,7 @@ single_col: l1mv = l1mv1; } scale = dist_scale_factor[ref0]; - fill_rectangle(&h->ref_cache[0][scan8[i8 * 4]], 2, 2, 8, + fill_rectangle(&sl->ref_cache[0][scan8[i8 * 4]], 2, 2, 8, ref0, 1); { @@ -602,9 +604,9 @@ single_col: int my_col = (mv_col[1] << y_shift) / 2; int mx = (scale * mv_col[0] + 128) >> 8; int my = (scale * my_col + 128) >> 8; - fill_rectangle(&h->mv_cache[0][scan8[i8 * 4]], 2, 2, 8, + fill_rectangle(&sl->mv_cache[0][scan8[i8 * 4]], 2, 2, 8, pack16to32(mx, my), 4); - fill_rectangle(&h->mv_cache[1][scan8[i8 * 4]], 2, 2, 8, + fill_rectangle(&sl->mv_cache[1][scan8[i8 * 4]], 2, 2, 8, pack16to32(mx - mv_col[0], my - my_col), 4); } } @@ -616,7 +618,7 @@ single_col: if (IS_16X16(*mb_type)) { int ref, mv0, mv1; - fill_rectangle(&h->ref_cache[1][scan8[0]], 4, 4, 8, 0, 1); + fill_rectangle(&sl->ref_cache[1][scan8[0]], 4, 4, 8, 0, 1); if (IS_INTRA(mb_type_col[0])) { ref = mv0 = mv1 = 0; } else { @@ -631,9 +633,9 @@ single_col: mv0 = pack16to32(mv_l0[0], mv_l0[1]); mv1 = pack16to32(mv_l0[0] - mv_col[0], mv_l0[1] - mv_col[1]); } - fill_rectangle(&h->ref_cache[0][scan8[0]], 4, 4, 8, ref, 1); - fill_rectangle(&h->mv_cache[0][scan8[0]], 4, 4, 8, mv0, 4); - fill_rectangle(&h->mv_cache[1][scan8[0]], 4, 4, 8, mv1, 4); + fill_rectangle(&sl->ref_cache[0][scan8[0]], 4, 4, 8, ref, 1); + fill_rectangle(&sl->mv_cache[0][scan8[0]], 4, 4, 8, mv0, 4); + fill_rectangle(&sl->mv_cache[1][scan8[0]], 4, 4, 8, mv1, 4); } else { for (i8 = 0; i8 < 4; i8++) { const int x8 = i8 & 1; @@ -644,11 +646,11 @@ single_col: if (is_b8x8 && !IS_DIRECT(h->sub_mb_type[i8])) continue; h->sub_mb_type[i8] = sub_mb_type; - fill_rectangle(&h->ref_cache[1][scan8[i8 * 4]], 2, 2, 8, 0, 1); + fill_rectangle(&sl->ref_cache[1][scan8[i8 * 4]], 2, 2, 8, 0, 1); if (IS_INTRA(mb_type_col[0])) { - fill_rectangle(&h->ref_cache[0][scan8[i8 * 4]], 2, 2, 8, 0, 1); - fill_rectangle(&h->mv_cache[0][scan8[i8 * 4]], 2, 2, 8, 0, 4); - fill_rectangle(&h->mv_cache[1][scan8[i8 * 4]], 2, 2, 8, 0, 4); + fill_rectangle(&sl->ref_cache[0][scan8[i8 * 4]], 2, 2, 8, 0, 1); + fill_rectangle(&sl->mv_cache[0][scan8[i8 * 4]], 2, 2, 8, 0, 4); + fill_rectangle(&sl->mv_cache[1][scan8[i8 * 4]], 2, 2, 8, 0, 4); continue; } @@ -662,24 +664,24 @@ single_col: } scale = dist_scale_factor[ref0]; - fill_rectangle(&h->ref_cache[0][scan8[i8 * 4]], 2, 2, 8, + fill_rectangle(&sl->ref_cache[0][scan8[i8 * 4]], 2, 2, 8, ref0, 1); if (IS_SUB_8X8(sub_mb_type)) { const int16_t *mv_col = l1mv[x8 * 3 + y8 * 3 * b4_stride]; int mx = (scale * mv_col[0] + 128) >> 8; int my = (scale * mv_col[1] + 128) >> 8; - fill_rectangle(&h->mv_cache[0][scan8[i8 * 4]], 2, 2, 8, + fill_rectangle(&sl->mv_cache[0][scan8[i8 * 4]], 2, 2, 8, pack16to32(mx, my), 4); - fill_rectangle(&h->mv_cache[1][scan8[i8 * 4]], 2, 2, 8, + fill_rectangle(&sl->mv_cache[1][scan8[i8 * 4]], 2, 2, 8, pack16to32(mx - mv_col[0], my - mv_col[1]), 4); } else { for (i4 = 0; i4 < 4; i4++) { const int16_t *mv_col = l1mv[x8 * 2 + (i4 & 1) + (y8 * 2 + (i4 >> 1)) * b4_stride]; - int16_t *mv_l0 = h->mv_cache[0][scan8[i8 * 4 + i4]]; + int16_t *mv_l0 = sl->mv_cache[0][scan8[i8 * 4 + i4]]; mv_l0[0] = (scale * mv_col[0] + 128) >> 8; mv_l0[1] = (scale * mv_col[1] + 128) >> 8; - AV_WN32A(h->mv_cache[1][scan8[i8 * 4 + i4]], + AV_WN32A(sl->mv_cache[1][scan8[i8 * 4 + i4]], pack16to32(mv_l0[0] - mv_col[0], mv_l0[1] - mv_col[1])); } @@ -689,10 +691,11 @@ single_col: } } -void ff_h264_pred_direct_motion(H264Context *const h, int *mb_type) +void ff_h264_pred_direct_motion(H264Context *const h, H264SliceContext *sl, + int *mb_type) { if (h->direct_spatial_mv_pred) - pred_spatial_direct_motion(h, mb_type); + pred_spatial_direct_motion(h, sl, mb_type); else - pred_temp_direct_motion(h, mb_type); + pred_temp_direct_motion(h, sl, mb_type); } diff --git a/libavcodec/h264_loopfilter.c b/libavcodec/h264_loopfilter.c index a33a66fc36..4d34a29eb2 100644 --- a/libavcodec/h264_loopfilter.c +++ b/libavcodec/h264_loopfilter.c @@ -371,7 +371,7 @@ static av_always_inline void h264_filter_mb_fast_internal(H264Context *h, int mask_edge0 = 3*((mask_edge1>>1) & ((5*left_type)>>5)&1); // (mb_type & (MB_TYPE_16x16 | MB_TYPE_8x16)) && (h->left_type[LTOP] & (MB_TYPE_16x16 | MB_TYPE_8x16)) ? 3 : 0; int step = 1+(mb_type>>24); //IS_8x8DCT(mb_type) ? 2 : 1; edges = 4 - 3*((mb_type>>3) & !(h->cbp & 15)); //(mb_type & MB_TYPE_16x16) && !(h->cbp & 15) ? 1 : 4; - h->h264dsp.h264_loop_filter_strength(bS, sl->non_zero_count_cache, h->ref_cache, h->mv_cache, + h->h264dsp.h264_loop_filter_strength(bS, sl->non_zero_count_cache, sl->ref_cache, sl->mv_cache, h->list_count==2, edges, step, mask_edge0, mask_edge1, FIELD_PICTURE(h)); } if( IS_INTRA(left_type) ) @@ -438,29 +438,30 @@ void ff_h264_filter_mb_fast(H264Context *h, H264SliceContext *sl, #endif } -static int check_mv(H264Context *h, long b_idx, long bn_idx, int mvy_limit){ +static int check_mv(H264Context *h, H264SliceContext *sl, long b_idx, long bn_idx, int mvy_limit) +{ int v; - v= h->ref_cache[0][b_idx] != h->ref_cache[0][bn_idx]; - if(!v && h->ref_cache[0][b_idx]!=-1) - v= h->mv_cache[0][b_idx][0] - h->mv_cache[0][bn_idx][0] + 3 >= 7U | - FFABS( h->mv_cache[0][b_idx][1] - h->mv_cache[0][bn_idx][1] ) >= mvy_limit; + v = sl->ref_cache[0][b_idx] != sl->ref_cache[0][bn_idx]; + if (!v && sl->ref_cache[0][b_idx] != -1) + v = sl->mv_cache[0][b_idx][0] - sl->mv_cache[0][bn_idx][0] + 3 >= 7U | + FFABS(sl->mv_cache[0][b_idx][1] - sl->mv_cache[0][bn_idx][1]) >= mvy_limit; if(h->list_count==2){ if(!v) - v = h->ref_cache[1][b_idx] != h->ref_cache[1][bn_idx] | - h->mv_cache[1][b_idx][0] - h->mv_cache[1][bn_idx][0] + 3 >= 7U | - FFABS( h->mv_cache[1][b_idx][1] - h->mv_cache[1][bn_idx][1] ) >= mvy_limit; + v = sl->ref_cache[1][b_idx] != sl->ref_cache[1][bn_idx] | + sl->mv_cache[1][b_idx][0] - sl->mv_cache[1][bn_idx][0] + 3 >= 7U | + FFABS(sl->mv_cache[1][b_idx][1] - sl->mv_cache[1][bn_idx][1]) >= mvy_limit; if(v){ - if(h->ref_cache[0][b_idx] != h->ref_cache[1][bn_idx] | - h->ref_cache[1][b_idx] != h->ref_cache[0][bn_idx]) + if (sl->ref_cache[0][b_idx] != sl->ref_cache[1][bn_idx] | + sl->ref_cache[1][b_idx] != sl->ref_cache[0][bn_idx]) return 1; return - h->mv_cache[0][b_idx][0] - h->mv_cache[1][bn_idx][0] + 3 >= 7U | - FFABS( h->mv_cache[0][b_idx][1] - h->mv_cache[1][bn_idx][1] ) >= mvy_limit | - h->mv_cache[1][b_idx][0] - h->mv_cache[0][bn_idx][0] + 3 >= 7U | - FFABS( h->mv_cache[1][b_idx][1] - h->mv_cache[0][bn_idx][1] ) >= mvy_limit; + sl->mv_cache[0][b_idx][0] - sl->mv_cache[1][bn_idx][0] + 3 >= 7U | + FFABS(sl->mv_cache[0][b_idx][1] - sl->mv_cache[1][bn_idx][1]) >= mvy_limit | + sl->mv_cache[1][b_idx][0] - sl->mv_cache[0][bn_idx][0] + 3 >= 7U | + FFABS(sl->mv_cache[1][b_idx][1] - sl->mv_cache[0][bn_idx][1]) >= mvy_limit; } } @@ -564,7 +565,7 @@ static av_always_inline void filter_mb_dir(H264Context *h, H264SliceContext *sl, int b_idx= 8 + 4; int bn_idx= b_idx - (dir ? 8:1); - bS[0] = bS[1] = bS[2] = bS[3] = check_mv(h, 8 + 4, bn_idx, mvy_limit); + bS[0] = bS[1] = bS[2] = bS[3] = check_mv(h, sl, 8 + 4, bn_idx, mvy_limit); mv_done = 1; } else @@ -582,7 +583,7 @@ static av_always_inline void filter_mb_dir(H264Context *h, H264SliceContext *sl, } else if(!mv_done) { - bS[i] = check_mv(h, b_idx, bn_idx, mvy_limit); + bS[i] = check_mv(h, sl, b_idx, bn_idx, mvy_limit); } } } @@ -645,7 +646,7 @@ static av_always_inline void filter_mb_dir(H264Context *h, H264SliceContext *sl, int b_idx= 8 + 4 + edge * (dir ? 8:1); int bn_idx= b_idx - (dir ? 8:1); - bS[0] = bS[1] = bS[2] = bS[3] = check_mv(h, b_idx, bn_idx, mvy_limit); + bS[0] = bS[1] = bS[2] = bS[3] = check_mv(h, sl, b_idx, bn_idx, mvy_limit); mv_done = 1; } else @@ -663,7 +664,7 @@ static av_always_inline void filter_mb_dir(H264Context *h, H264SliceContext *sl, } else if(!mv_done) { - bS[i] = check_mv(h, b_idx, bn_idx, mvy_limit); + bS[i] = check_mv(h, sl, b_idx, bn_idx, mvy_limit); } } diff --git a/libavcodec/h264_mb.c b/libavcodec/h264_mb.c index 44dd598534..0e48befc8b 100644 --- a/libavcodec/h264_mb.c +++ b/libavcodec/h264_mb.c @@ -36,10 +36,11 @@ #include "svq3.h" #include "thread.h" -static inline int get_lowest_part_list_y(H264Context *h, H264Picture *pic, int n, +static inline int get_lowest_part_list_y(H264Context *h, H264SliceContext *sl, + H264Picture *pic, int n, int height, int y_offset, int list) { - int raw_my = h->mv_cache[list][scan8[n]][1]; + int raw_my = sl->mv_cache[list][scan8[n]][1]; int filter_height_up = (raw_my & 3) ? 2 : 0; int filter_height_down = (raw_my & 3) ? 3 : 0; int full_my = (raw_my >> 2) + y_offset; @@ -49,7 +50,8 @@ static inline int get_lowest_part_list_y(H264Context *h, H264Picture *pic, int n return FFMAX(abs(top), bottom); } -static inline void get_lowest_part_y(H264Context *h, int refs[2][48], int n, +static inline void get_lowest_part_y(H264Context *h, H264SliceContext *sl, + int refs[2][48], int n, int height, int y_offset, int list0, int list1, int *nrefs) { @@ -58,7 +60,7 @@ static inline void get_lowest_part_y(H264Context *h, int refs[2][48], int n, y_offset += 16 * (h->mb_y >> MB_FIELD(h)); if (list0) { - int ref_n = h->ref_cache[0][scan8[n]]; + int ref_n = sl->ref_cache[0][scan8[n]]; H264Picture *ref = &h->ref_list[0][ref_n]; // Error resilience puts the current picture in the ref list. @@ -66,7 +68,7 @@ static inline void get_lowest_part_y(H264Context *h, int refs[2][48], int n, // Fields can wait on each other, though. if (ref->tf.progress->data != h->cur_pic.tf.progress->data || (ref->reference & 3) != h->picture_structure) { - my = get_lowest_part_list_y(h, ref, n, height, y_offset, 0); + my = get_lowest_part_list_y(h, sl, ref, n, height, y_offset, 0); if (refs[0][ref_n] < 0) nrefs[0] += 1; refs[0][ref_n] = FFMAX(refs[0][ref_n], my); @@ -74,12 +76,12 @@ static inline void get_lowest_part_y(H264Context *h, int refs[2][48], int n, } if (list1) { - int ref_n = h->ref_cache[1][scan8[n]]; + int ref_n = sl->ref_cache[1][scan8[n]]; H264Picture *ref = &h->ref_list[1][ref_n]; if (ref->tf.progress->data != h->cur_pic.tf.progress->data || (ref->reference & 3) != h->picture_structure) { - my = get_lowest_part_list_y(h, ref, n, height, y_offset, 1); + my = get_lowest_part_list_y(h, sl, ref, n, height, y_offset, 1); if (refs[1][ref_n] < 0) nrefs[1] += 1; refs[1][ref_n] = FFMAX(refs[1][ref_n], my); @@ -92,7 +94,7 @@ static inline void get_lowest_part_y(H264Context *h, int refs[2][48], int n, * * @param h the H264 context */ -static void await_references(H264Context *h) +static void await_references(H264Context *h, H264SliceContext *sl) { const int mb_xy = h->mb_xy; const int mb_type = h->cur_pic.mb_type[mb_xy]; @@ -103,17 +105,17 @@ static void await_references(H264Context *h) memset(refs, -1, sizeof(refs)); if (IS_16X16(mb_type)) { - get_lowest_part_y(h, refs, 0, 16, 0, + get_lowest_part_y(h, sl, refs, 0, 16, 0, IS_DIR(mb_type, 0, 0), IS_DIR(mb_type, 0, 1), nrefs); } else if (IS_16X8(mb_type)) { - get_lowest_part_y(h, refs, 0, 8, 0, + get_lowest_part_y(h, sl, refs, 0, 8, 0, IS_DIR(mb_type, 0, 0), IS_DIR(mb_type, 0, 1), nrefs); - get_lowest_part_y(h, refs, 8, 8, 8, + get_lowest_part_y(h, sl, refs, 8, 8, 8, IS_DIR(mb_type, 1, 0), IS_DIR(mb_type, 1, 1), nrefs); } else if (IS_8X16(mb_type)) { - get_lowest_part_y(h, refs, 0, 16, 0, + get_lowest_part_y(h, sl, refs, 0, 16, 0, IS_DIR(mb_type, 0, 0), IS_DIR(mb_type, 0, 1), nrefs); - get_lowest_part_y(h, refs, 4, 16, 0, + get_lowest_part_y(h, sl, refs, 4, 16, 0, IS_DIR(mb_type, 1, 0), IS_DIR(mb_type, 1, 1), nrefs); } else { int i; @@ -126,25 +128,25 @@ static void await_references(H264Context *h) int y_offset = (i & 2) << 2; if (IS_SUB_8X8(sub_mb_type)) { - get_lowest_part_y(h, refs, n, 8, y_offset, + get_lowest_part_y(h, sl, refs, n, 8, y_offset, IS_DIR(sub_mb_type, 0, 0), IS_DIR(sub_mb_type, 0, 1), nrefs); } else if (IS_SUB_8X4(sub_mb_type)) { - get_lowest_part_y(h, refs, n, 4, y_offset, + get_lowest_part_y(h, sl, refs, n, 4, y_offset, IS_DIR(sub_mb_type, 0, 0), IS_DIR(sub_mb_type, 0, 1), nrefs); - get_lowest_part_y(h, refs, n + 2, 4, y_offset + 4, + get_lowest_part_y(h, sl, refs, n + 2, 4, y_offset + 4, IS_DIR(sub_mb_type, 0, 0), IS_DIR(sub_mb_type, 0, 1), nrefs); } else if (IS_SUB_4X8(sub_mb_type)) { - get_lowest_part_y(h, refs, n, 8, y_offset, + get_lowest_part_y(h, sl, refs, n, 8, y_offset, IS_DIR(sub_mb_type, 0, 0), IS_DIR(sub_mb_type, 0, 1), nrefs); - get_lowest_part_y(h, refs, n + 1, 8, y_offset, + get_lowest_part_y(h, sl, refs, n + 1, 8, y_offset, IS_DIR(sub_mb_type, 0, 0), IS_DIR(sub_mb_type, 0, 1), nrefs); @@ -153,7 +155,7 @@ static void await_references(H264Context *h) assert(IS_SUB_4X4(sub_mb_type)); for (j = 0; j < 4; j++) { int sub_y_offset = y_offset + 2 * (j & 2); - get_lowest_part_y(h, refs, n + j, 4, sub_y_offset, + get_lowest_part_y(h, sl, refs, n + j, 4, sub_y_offset, IS_DIR(sub_mb_type, 0, 0), IS_DIR(sub_mb_type, 0, 1), nrefs); @@ -200,7 +202,8 @@ static void await_references(H264Context *h) } } -static av_always_inline void mc_dir_part(H264Context *h, H264Picture *pic, +static av_always_inline void mc_dir_part(H264Context *h, H264SliceContext *sl, + H264Picture *pic, int n, int square, int height, int delta, int list, uint8_t *dest_y, uint8_t *dest_cb, @@ -210,8 +213,8 @@ static av_always_inline void mc_dir_part(H264Context *h, H264Picture *pic, h264_chroma_mc_func chroma_op, int pixel_shift, int chroma_idc) { - const int mx = h->mv_cache[list][scan8[n]][0] + src_x_offset * 8; - int my = h->mv_cache[list][scan8[n]][1] + src_y_offset * 8; + const int mx = sl->mv_cache[list][scan8[n]][0] + src_x_offset * 8; + int my = sl->mv_cache[list][scan8[n]][1] + src_y_offset * 8; const int luma_xy = (mx & 3) + ((my & 3) << 2); ptrdiff_t offset = ((mx >> 2) << pixel_shift) + (my >> 2) * h->mb_linesize; uint8_t *src_y = pic->f.data[0] + offset; @@ -315,7 +318,8 @@ static av_always_inline void mc_dir_part(H264Context *h, H264Picture *pic, mx & 7, (my << (chroma_idc == 2 /* yuv422 */)) & 7); } -static av_always_inline void mc_part_std(H264Context *h, int n, int square, +static av_always_inline void mc_part_std(H264Context *h, H264SliceContext *sl, + int n, int square, int height, int delta, uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr, @@ -345,8 +349,8 @@ static av_always_inline void mc_part_std(H264Context *h, int n, int square, y_offset += 8 * (h->mb_y >> MB_FIELD(h)); if (list0) { - H264Picture *ref = &h->ref_list[0][h->ref_cache[0][scan8[n]]]; - mc_dir_part(h, ref, n, square, height, delta, 0, + H264Picture *ref = &h->ref_list[0][sl->ref_cache[0][scan8[n]]]; + mc_dir_part(h, sl, ref, n, square, height, delta, 0, dest_y, dest_cb, dest_cr, x_offset, y_offset, qpix_op, chroma_op, pixel_shift, chroma_idc); @@ -355,8 +359,8 @@ static av_always_inline void mc_part_std(H264Context *h, int n, int square, } if (list1) { - H264Picture *ref = &h->ref_list[1][h->ref_cache[1][scan8[n]]]; - mc_dir_part(h, ref, n, square, height, delta, 1, + H264Picture *ref = &h->ref_list[1][sl->ref_cache[1][scan8[n]]]; + mc_dir_part(h, sl, ref, n, square, height, delta, 1, dest_y, dest_cb, dest_cr, x_offset, y_offset, qpix_op, chroma_op, pixel_shift, chroma_idc); } @@ -404,14 +408,14 @@ static av_always_inline void mc_part_weighted(H264Context *h, H264SliceContext * uint8_t *tmp_cb = h->bipred_scratchpad; uint8_t *tmp_cr = h->bipred_scratchpad + (16 << pixel_shift); uint8_t *tmp_y = h->bipred_scratchpad + 16 * h->mb_uvlinesize; - int refn0 = h->ref_cache[0][scan8[n]]; - int refn1 = h->ref_cache[1][scan8[n]]; + int refn0 = sl->ref_cache[0][scan8[n]]; + int refn1 = sl->ref_cache[1][scan8[n]]; - mc_dir_part(h, &h->ref_list[0][refn0], n, square, height, delta, 0, + mc_dir_part(h, sl, &h->ref_list[0][refn0], n, square, height, delta, 0, dest_y, dest_cb, dest_cr, x_offset, y_offset, qpix_put, chroma_put, pixel_shift, chroma_idc); - mc_dir_part(h, &h->ref_list[1][refn1], n, square, height, delta, 1, + mc_dir_part(h, sl, &h->ref_list[1][refn1], n, square, height, delta, 1, tmp_y, tmp_cb, tmp_cr, x_offset, y_offset, qpix_put, chroma_put, pixel_shift, chroma_idc); @@ -447,9 +451,9 @@ static av_always_inline void mc_part_weighted(H264Context *h, H264SliceContext * } } else { int list = list1 ? 1 : 0; - int refn = h->ref_cache[list][scan8[n]]; + int refn = sl->ref_cache[list][scan8[n]]; H264Picture *ref = &h->ref_list[list][refn]; - mc_dir_part(h, ref, n, square, height, delta, list, + mc_dir_part(h, sl, ref, n, square, height, delta, list, dest_y, dest_cb, dest_cr, x_offset, y_offset, qpix_put, chroma_put, pixel_shift, chroma_idc); @@ -470,15 +474,16 @@ static av_always_inline void mc_part_weighted(H264Context *h, H264SliceContext * } } -static av_always_inline void prefetch_motion(H264Context *h, int list, - int pixel_shift, int chroma_idc) +static av_always_inline void prefetch_motion(H264Context *h, H264SliceContext *sl, + int list, int pixel_shift, + int chroma_idc) { /* fetch pixels for estimated mv 4 macroblocks ahead * optimized for 64byte cache lines */ - const int refn = h->ref_cache[list][scan8[0]]; + const int refn = sl->ref_cache[list][scan8[0]]; if (refn >= 0) { - const int mx = (h->mv_cache[list][scan8[0]][0] >> 2) + 16 * h->mb_x + 8; - const int my = (h->mv_cache[list][scan8[0]][1] >> 2) + 16 * h->mb_y; + const int mx = (sl->mv_cache[list][scan8[0]][0] >> 2) + 16 * h->mb_x + 8; + const int my = (sl->mv_cache[list][scan8[0]][1] >> 2) + 16 * h->mb_y; uint8_t **src = h->ref_list[list][refn].f.data; int off = (mx << pixel_shift) + (my + (h->mb_x & 3) * 4) * h->mb_linesize + diff --git a/libavcodec/h264_mb_template.c b/libavcodec/h264_mb_template.c index fcd17e843c..6235c1136f 100644 --- a/libavcodec/h264_mb_template.c +++ b/libavcodec/h264_mb_template.c @@ -81,13 +81,13 @@ static av_noinline void FUNC(hl_decode_mb)(H264Context *h, H264SliceContext *sl) if (!USES_LIST(mb_type, list)) continue; if (IS_16X16(mb_type)) { - int8_t *ref = &h->ref_cache[list][scan8[0]]; + int8_t *ref = &sl->ref_cache[list][scan8[0]]; fill_rectangle(ref, 4, 4, 8, (16 + *ref) ^ (h->mb_y & 1), 1); } else { for (i = 0; i < 16; i += 4) { - int ref = h->ref_cache[list][scan8[i]]; + int ref = sl->ref_cache[list][scan8[i]]; if (ref >= 0) - fill_rectangle(&h->ref_cache[list][scan8[i]], 2, 2, + fill_rectangle(&sl->ref_cache[list][scan8[i]], 2, 2, 8, (16 + ref) ^ (h->mb_y & 1), 1); } } @@ -306,13 +306,13 @@ static av_noinline void FUNC(hl_decode_mb_444)(H264Context *h, H264SliceContext if (!USES_LIST(mb_type, list)) continue; if (IS_16X16(mb_type)) { - int8_t *ref = &h->ref_cache[list][scan8[0]]; + int8_t *ref = &sl->ref_cache[list][scan8[0]]; fill_rectangle(ref, 4, 4, 8, (16 + *ref) ^ (h->mb_y & 1), 1); } else { for (i = 0; i < 16; i += 4) { - int ref = h->ref_cache[list][scan8[i]]; + int ref = sl->ref_cache[list][scan8[i]]; if (ref >= 0) - fill_rectangle(&h->ref_cache[list][scan8[i]], 2, 2, + fill_rectangle(&sl->ref_cache[list][scan8[i]], 2, 2, 8, (16 + ref) ^ (h->mb_y & 1), 1); } } diff --git a/libavcodec/h264_mc_template.c b/libavcodec/h264_mc_template.c index 0e58eb3a87..11d7d1f831 100644 --- a/libavcodec/h264_mc_template.c +++ b/libavcodec/h264_mc_template.c @@ -49,14 +49,14 @@ static void mc_part(H264Context *h, H264SliceContext *sl, int list0, int list1) { if ((sl->use_weight == 2 && list0 && list1 && - (sl->implicit_weight[h->ref_cache[0][scan8[n]]][h->ref_cache[1][scan8[n]]][h->mb_y & 1] != 32)) || + (sl->implicit_weight[sl->ref_cache[0][scan8[n]]][sl->ref_cache[1][scan8[n]]][h->mb_y & 1] != 32)) || sl->use_weight == 1) mc_part_weighted(h, sl, n, square, height, delta, dest_y, dest_cb, dest_cr, x_offset, y_offset, qpix_put, chroma_put, weight_op[0], weight_op[1], weight_avg[0], weight_avg[1], list0, list1, PIXEL_SHIFT, CHROMA_IDC); else - mc_part_std(h, n, square, height, delta, dest_y, dest_cb, dest_cr, + mc_part_std(h, sl, n, square, height, delta, dest_y, dest_cb, dest_cr, x_offset, y_offset, qpix_put, chroma_put, qpix_avg, chroma_avg, list0, list1, PIXEL_SHIFT, CHROMA_IDC); } @@ -77,8 +77,8 @@ static void MCFUNC(hl_motion)(H264Context *h, H264SliceContext *sl, assert(IS_INTER(mb_type)); if (HAVE_THREADS && (h->avctx->active_thread_type & FF_THREAD_FRAME)) - await_references(h); - prefetch_motion(h, 0, PIXEL_SHIFT, CHROMA_IDC); + await_references(h, sl); + prefetch_motion(h, sl, 0, PIXEL_SHIFT, CHROMA_IDC); if (IS_16X16(mb_type)) { mc_part(h, sl, 0, 1, 16, 0, dest_y, dest_cb, dest_cr, 0, 0, @@ -158,6 +158,6 @@ static void MCFUNC(hl_motion)(H264Context *h, H264SliceContext *sl, } } - prefetch_motion(h, 1, PIXEL_SHIFT, CHROMA_IDC); + prefetch_motion(h, sl, 1, PIXEL_SHIFT, CHROMA_IDC); } diff --git a/libavcodec/h264_mvpred.h b/libavcodec/h264_mvpred.h index 78810dfc5e..3d4ffa0168 100644 --- a/libavcodec/h264_mvpred.h +++ b/libavcodec/h264_mvpred.h @@ -39,7 +39,7 @@ static av_always_inline int fetch_diagonal_mv(H264Context *h, H264SliceContext * const int16_t **C, int i, int list, int part_width) { - const int topright_ref = h->ref_cache[list][i - 8 + part_width]; + const int topright_ref = sl->ref_cache[list][i - 8 + part_width]; /* there is no consistent mapping of mvs to neighboring locations that will * make mbaff happy, so we can't move all this logic to fill_caches */ @@ -50,17 +50,17 @@ static av_always_inline int fetch_diagonal_mv(H264Context *h, H264SliceContext * if (!USES_LIST(mb_type, list)) \ return LIST_NOT_USED; \ mv = h->cur_pic_ptr->motion_val[list][h->mb2b_xy[xy] + 3 + y4 * h->b_stride]; \ - h->mv_cache[list][scan8[0] - 2][0] = mv[0]; \ - h->mv_cache[list][scan8[0] - 2][1] = mv[1] MV_OP; \ + sl->mv_cache[list][scan8[0] - 2][0] = mv[0]; \ + sl->mv_cache[list][scan8[0] - 2][1] = mv[1] MV_OP; \ return h->cur_pic_ptr->ref_index[list][4 * xy + 1 + (y4 & ~1)] REF_OP; if (topright_ref == PART_NOT_AVAILABLE && i >= scan8[0] + 8 && (i & 7) == 4 - && h->ref_cache[list][scan8[0] - 1] != PART_NOT_AVAILABLE) { + && sl->ref_cache[list][scan8[0] - 1] != PART_NOT_AVAILABLE) { const uint32_t *mb_types = h->cur_pic_ptr->mb_type; const int16_t *mv; - AV_ZERO32(h->mv_cache[list][scan8[0] - 2]); - *C = h->mv_cache[list][scan8[0] - 2]; + AV_ZERO32(sl->mv_cache[list][scan8[0] - 2]); + *C = sl->mv_cache[list][scan8[0] - 2]; if (!MB_FIELD(h) && IS_INTERLACED(sl->left_type[0])) { SET_DIAG_MV(* 2, >> 1, sl->left_mb_xy[0] + h->mb_stride, @@ -75,13 +75,13 @@ static av_always_inline int fetch_diagonal_mv(H264Context *h, H264SliceContext * } if (topright_ref != PART_NOT_AVAILABLE) { - *C = h->mv_cache[list][i - 8 + part_width]; + *C = sl->mv_cache[list][i - 8 + part_width]; return topright_ref; } else { tprintf(h->avctx, "topright MV not available\n"); - *C = h->mv_cache[list][i - 8 - 1]; - return h->ref_cache[list][i - 8 - 1]; + *C = sl->mv_cache[list][i - 8 - 1]; + return sl->ref_cache[list][i - 8 - 1]; } } @@ -99,10 +99,10 @@ static av_always_inline void pred_motion(H264Context *const h, int *const mx, int *const my) { const int index8 = scan8[n]; - const int top_ref = h->ref_cache[list][index8 - 8]; - const int left_ref = h->ref_cache[list][index8 - 1]; - const int16_t *const A = h->mv_cache[list][index8 - 1]; - const int16_t *const B = h->mv_cache[list][index8 - 8]; + const int top_ref = sl->ref_cache[list][index8 - 8]; + const int left_ref = sl->ref_cache[list][index8 - 1]; + const int16_t *const A = sl->mv_cache[list][index8 - 1]; + const int16_t *const B = sl->mv_cache[list][index8 - 8]; const int16_t *C; int diagonal_ref, match_count; @@ -163,8 +163,8 @@ static av_always_inline void pred_16x8_motion(H264Context *const h, int *const mx, int *const my) { if (n == 0) { - const int top_ref = h->ref_cache[list][scan8[0] - 8]; - const int16_t *const B = h->mv_cache[list][scan8[0] - 8]; + const int top_ref = sl->ref_cache[list][scan8[0] - 8]; + const int16_t *const B = sl->mv_cache[list][scan8[0] - 8]; tprintf(h->avctx, "pred_16x8: (%2d %2d %2d) at %2d %2d %d list %d\n", top_ref, B[0], B[1], h->mb_x, h->mb_y, n, list); @@ -175,8 +175,8 @@ static av_always_inline void pred_16x8_motion(H264Context *const h, return; } } else { - const int left_ref = h->ref_cache[list][scan8[8] - 1]; - const int16_t *const A = h->mv_cache[list][scan8[8] - 1]; + const int left_ref = sl->ref_cache[list][scan8[8] - 1]; + const int16_t *const A = sl->mv_cache[list][scan8[8] - 1]; tprintf(h->avctx, "pred_16x8: (%2d %2d %2d) at %2d %2d %d list %d\n", left_ref, A[0], A[1], h->mb_x, h->mb_y, n, list); @@ -204,8 +204,8 @@ static av_always_inline void pred_8x16_motion(H264Context *const h, int *const mx, int *const my) { if (n == 0) { - const int left_ref = h->ref_cache[list][scan8[0] - 1]; - const int16_t *const A = h->mv_cache[list][scan8[0] - 1]; + const int left_ref = sl->ref_cache[list][scan8[0] - 1]; + const int16_t *const A = sl->mv_cache[list][scan8[0] - 1]; tprintf(h->avctx, "pred_8x16: (%2d %2d %2d) at %2d %2d %d list %d\n", left_ref, A[0], A[1], h->mb_x, h->mb_y, n, list); @@ -265,7 +265,7 @@ static av_always_inline void pred_pskip_motion(H264Context *const h, const int16_t *A, *B, *C; int b_stride = h->b_stride; - fill_rectangle(&h->ref_cache[0][scan8[0]], 4, 4, 8, 0, 1); + fill_rectangle(&sl->ref_cache[0][scan8[0]], 4, 4, 8, 0, 1); /* To avoid doing an entire fill_decode_caches, we inline the relevant * parts here. @@ -345,11 +345,11 @@ static av_always_inline void pred_pskip_motion(H264Context *const h, my = mid_pred(A[1], B[1], C[1]); } - fill_rectangle(h->mv_cache[0][scan8[0]], 4, 4, 8, pack16to32(mx, my), 4); + fill_rectangle(sl->mv_cache[0][scan8[0]], 4, 4, 8, pack16to32(mx, my), 4); return; zeromv: - fill_rectangle(h->mv_cache[0][scan8[0]], 4, 4, 8, 0, 4); + fill_rectangle(sl->mv_cache[0][scan8[0]], 4, 4, 8, 0, 4); return; } @@ -607,9 +607,9 @@ static void fill_decode_caches(H264Context *h, H264SliceContext *sl, int mb_type int list; int b_stride = h->b_stride; for (list = 0; list < h->list_count; list++) { - int8_t *ref_cache = &h->ref_cache[list][scan8[0]]; + int8_t *ref_cache = &sl->ref_cache[list][scan8[0]]; int8_t *ref = h->cur_pic.ref_index[list]; - int16_t(*mv_cache)[2] = &h->mv_cache[list][scan8[0]]; + int16_t(*mv_cache)[2] = &sl->mv_cache[list][scan8[0]]; int16_t(*mv)[2] = h->cur_pic.motion_val[list]; if (!USES_LIST(mb_type, list)) continue; @@ -770,9 +770,9 @@ static void fill_decode_caches(H264Context *h, H264SliceContext *sl, int mb_type if (MB_FIELD(h)) { #define MAP_F2F(idx, mb_type) \ - if (!IS_INTERLACED(mb_type) && h->ref_cache[list][idx] >= 0) { \ - h->ref_cache[list][idx] <<= 1; \ - h->mv_cache[list][idx][1] /= 2; \ + if (!IS_INTERLACED(mb_type) && sl->ref_cache[list][idx] >= 0) { \ + sl->ref_cache[list][idx] <<= 1; \ + sl->mv_cache[list][idx][1] /= 2; \ h->mvd_cache[list][idx][1] >>= 1; \ } @@ -781,9 +781,9 @@ static void fill_decode_caches(H264Context *h, H264SliceContext *sl, int mb_type #undef MAP_F2F #define MAP_F2F(idx, mb_type) \ - if (IS_INTERLACED(mb_type) && h->ref_cache[list][idx] >= 0) { \ - h->ref_cache[list][idx] >>= 1; \ - h->mv_cache[list][idx][1] <<= 1; \ + if (IS_INTERLACED(mb_type) && sl->ref_cache[list][idx] >= 0) { \ + sl->ref_cache[list][idx] >>= 1; \ + sl->mv_cache[list][idx][1] <<= 1; \ h->mvd_cache[list][idx][1] <<= 1; \ } @@ -817,7 +817,7 @@ static void av_unused decode_mb_skip(H264Context *h, H264SliceContext *sl) fill_decode_neighbors(h, sl, mb_type); fill_decode_caches(h, sl, mb_type); //FIXME check what is needed and what not ... } - ff_h264_pred_direct_motion(h, &mb_type); + ff_h264_pred_direct_motion(h, sl, &mb_type); mb_type |= MB_TYPE_SKIP; } else { mb_type |= MB_TYPE_16x16 | MB_TYPE_P0L0 | MB_TYPE_P1L0 | MB_TYPE_SKIP; @@ -826,7 +826,7 @@ static void av_unused decode_mb_skip(H264Context *h, H264SliceContext *sl) pred_pskip_motion(h, sl); } - write_back_motion(h, mb_type); + write_back_motion(h, sl, mb_type); h->cur_pic.mb_type[mb_xy] = mb_type; h->cur_pic.qscale_table[mb_xy] = sl->qscale; h->slice_table[mb_xy] = h->slice_num; diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c index 11dc98478d..925538970b 100644 --- a/libavcodec/h264_slice.c +++ b/libavcodec/h264_slice.c @@ -1822,6 +1822,7 @@ int ff_h264_get_slice_type(const H264Context *h) } static av_always_inline void fill_filter_caches_inter(H264Context *h, + H264SliceContext *sl, int mb_type, int top_xy, int left_xy[LEFT_MBS], int top_type, @@ -1829,8 +1830,8 @@ static av_always_inline void fill_filter_caches_inter(H264Context *h, int mb_xy, int list) { int b_stride = h->b_stride; - int16_t(*mv_dst)[2] = &h->mv_cache[list][scan8[0]]; - int8_t *ref_cache = &h->ref_cache[list][scan8[0]]; + int16_t(*mv_dst)[2] = &sl->mv_cache[list][scan8[0]]; + int8_t *ref_cache = &sl->ref_cache[list][scan8[0]]; if (IS_INTER(mb_type) || IS_DIRECT(mb_type)) { if (USES_LIST(top_type, list)) { const int b_xy = h->mb2b_xy[top_xy] + 3 * b_stride; @@ -1979,10 +1980,10 @@ static int fill_filter_caches(H264Context *h, H264SliceContext *sl, int mb_type) if (IS_INTRA(mb_type)) return 0; - fill_filter_caches_inter(h, mb_type, top_xy, left_xy, + fill_filter_caches_inter(h, sl, mb_type, top_xy, left_xy, top_type, left_type, mb_xy, 0); if (h->list_count == 2) - fill_filter_caches_inter(h, mb_type, top_xy, left_xy, + fill_filter_caches_inter(h, sl, mb_type, top_xy, left_xy, top_type, left_type, mb_xy, 1); nnz = h->non_zero_count[mb_xy]; diff --git a/libavcodec/svq3.c b/libavcodec/svq3.c index 499c35d6d5..163a49eeda 100644 --- a/libavcodec/svq3.c +++ b/libavcodec/svq3.c @@ -459,15 +459,15 @@ static inline int svq3_mc_dir(SVQ3Context *s, int size, int mode, int32_t mv = pack16to32(mx, my); if (part_height == 8 && i < 8) { - AV_WN32A(h->mv_cache[dir][scan8[k] + 1 * 8], mv); + AV_WN32A(sl->mv_cache[dir][scan8[k] + 1 * 8], mv); if (part_width == 8 && j < 8) - AV_WN32A(h->mv_cache[dir][scan8[k] + 1 + 1 * 8], mv); + AV_WN32A(sl->mv_cache[dir][scan8[k] + 1 + 1 * 8], mv); } if (part_width == 8 && j < 8) - AV_WN32A(h->mv_cache[dir][scan8[k] + 1], mv); + AV_WN32A(sl->mv_cache[dir][scan8[k] + 1], mv); if (part_width == 4 || part_height == 4) - AV_WN32A(h->mv_cache[dir][scan8[k]], mv); + AV_WN32A(sl->mv_cache[dir][scan8[k]], mv); } /* write back motion vectors */ @@ -535,36 +535,36 @@ static int svq3_decode_mb(SVQ3Context *s, unsigned int mb_type) for (m = 0; m < 2; m++) { if (h->mb_x > 0 && sl->intra4x4_pred_mode[h->mb2br_xy[mb_xy - 1] + 6] != -1) { for (i = 0; i < 4; i++) - AV_COPY32(h->mv_cache[m][scan8[0] - 1 + i * 8], + AV_COPY32(sl->mv_cache[m][scan8[0] - 1 + i * 8], h->cur_pic.motion_val[m][b_xy - 1 + i * h->b_stride]); } else { for (i = 0; i < 4; i++) - AV_ZERO32(h->mv_cache[m][scan8[0] - 1 + i * 8]); + AV_ZERO32(sl->mv_cache[m][scan8[0] - 1 + i * 8]); } if (h->mb_y > 0) { - memcpy(h->mv_cache[m][scan8[0] - 1 * 8], + memcpy(sl->mv_cache[m][scan8[0] - 1 * 8], h->cur_pic.motion_val[m][b_xy - h->b_stride], 4 * 2 * sizeof(int16_t)); - memset(&h->ref_cache[m][scan8[0] - 1 * 8], + memset(&sl->ref_cache[m][scan8[0] - 1 * 8], (sl->intra4x4_pred_mode[h->mb2br_xy[mb_xy - h->mb_stride]] == -1) ? PART_NOT_AVAILABLE : 1, 4); if (h->mb_x < h->mb_width - 1) { - AV_COPY32(h->mv_cache[m][scan8[0] + 4 - 1 * 8], + AV_COPY32(sl->mv_cache[m][scan8[0] + 4 - 1 * 8], h->cur_pic.motion_val[m][b_xy - h->b_stride + 4]); - h->ref_cache[m][scan8[0] + 4 - 1 * 8] = + sl->ref_cache[m][scan8[0] + 4 - 1 * 8] = (sl->intra4x4_pred_mode[h->mb2br_xy[mb_xy - h->mb_stride + 1] + 6] == -1 || sl->intra4x4_pred_mode[h->mb2br_xy[mb_xy - h->mb_stride]] == -1) ? PART_NOT_AVAILABLE : 1; } else - h->ref_cache[m][scan8[0] + 4 - 1 * 8] = PART_NOT_AVAILABLE; + sl->ref_cache[m][scan8[0] + 4 - 1 * 8] = PART_NOT_AVAILABLE; if (h->mb_x > 0) { - AV_COPY32(h->mv_cache[m][scan8[0] - 1 - 1 * 8], + AV_COPY32(sl->mv_cache[m][scan8[0] - 1 - 1 * 8], h->cur_pic.motion_val[m][b_xy - h->b_stride - 1]); - h->ref_cache[m][scan8[0] - 1 - 1 * 8] = + sl->ref_cache[m][scan8[0] - 1 - 1 * 8] = (sl->intra4x4_pred_mode[h->mb2br_xy[mb_xy - h->mb_stride - 1] + 3] == -1) ? PART_NOT_AVAILABLE : 1; } else - h->ref_cache[m][scan8[0] - 1 - 1 * 8] = PART_NOT_AVAILABLE; + sl->ref_cache[m][scan8[0] - 1 - 1 * 8] = PART_NOT_AVAILABLE; } else - memset(&h->ref_cache[m][scan8[0] - 1 * 8 - 1], + memset(&sl->ref_cache[m][scan8[0] - 1 * 8 - 1], PART_NOT_AVAILABLE, 8); if (h->pict_type != AV_PICTURE_TYPE_B) @@ -1111,6 +1111,7 @@ static int svq3_decode_frame(AVCodecContext *avctx, void *data, const uint8_t *buf = avpkt->data; SVQ3Context *s = avctx->priv_data; H264Context *h = &s->h; + H264SliceContext *sl = &h->slice_ctx[0]; int buf_size = avpkt->size; int ret, m, i; @@ -1235,9 +1236,9 @@ static int svq3_decode_frame(AVCodecContext *avctx, void *data, for (i = 0; i < 4; i++) { int j; for (j = -1; j < 4; j++) - h->ref_cache[m][scan8[0] + 8 * i + j] = 1; + sl->ref_cache[m][scan8[0] + 8 * i + j] = 1; if (i < 3) - h->ref_cache[m][scan8[0] + 8 * i + j] = PART_NOT_AVAILABLE; + sl->ref_cache[m][scan8[0] + 8 * i + j] = PART_NOT_AVAILABLE; } }