X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fh264_mvpred.h;h=5e8f237f633f4091bad12d9abf2da6abb3abe496;hb=ea4d46e72945cba37feb7aa154eb970732f513e4;hp=6c29bb7e49c264a1cd24b0853ab0ae5737219e2b;hpb=64c81b2cd0dcf1fe66c381a5d2c707dddcf35a7e;p=ffmpeg diff --git a/libavcodec/h264_mvpred.h b/libavcodec/h264_mvpred.h index 6c29bb7e49c..5e8f237f633 100644 --- a/libavcodec/h264_mvpred.h +++ b/libavcodec/h264_mvpred.h @@ -35,11 +35,11 @@ #include -static av_always_inline int fetch_diagonal_mv(H264Context *h, H264SliceContext *sl, +static av_always_inline int fetch_diagonal_mv(const H264Context *h, H264SliceContext *sl, 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,23 +50,23 @@ 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])) { + if (!MB_FIELD(sl) && IS_INTERLACED(sl->left_type[0])) { SET_DIAG_MV(* 2, >> 1, sl->left_mb_xy[0] + h->mb_stride, - (h->mb_y & 1) * 2 + (i >> 5)); + (sl->mb_y & 1) * 2 + (i >> 5)); } - if (MB_FIELD(h) && !IS_INTERLACED(sl->left_type[0])) { + if (MB_FIELD(sl) && !IS_INTERLACED(sl->left_type[0])) { // left shift will turn LIST_NOT_USED into PART_NOT_AVAILABLE, but that's OK. SET_DIAG_MV(/ 2, << 1, sl->left_mb_xy[i >= 36], ((i >> 2)) & 3); } @@ -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"); + ff_tlog(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]; } } @@ -92,17 +92,17 @@ static av_always_inline int fetch_diagonal_mv(H264Context *h, H264SliceContext * * @param mx the x component of the predicted motion vector * @param my the y component of the predicted motion vector */ -static av_always_inline void pred_motion(H264Context *const h, +static av_always_inline void pred_motion(const H264Context *const h, H264SliceContext *sl, int n, int part_width, int list, int ref, 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; @@ -118,7 +118,7 @@ static av_always_inline void pred_motion(H264Context *const h, diagonal_ref = fetch_diagonal_mv(h, sl, &C, index8, list, part_width); match_count = (diagonal_ref == ref) + (top_ref == ref) + (left_ref == ref); - tprintf(h->avctx, "pred_motion match_count=%d\n", match_count); + ff_tlog(h->avctx, "pred_motion match_count=%d\n", match_count); if (match_count > 1) { //most common *mx = mid_pred(A[0], B[0], C[0]); *my = mid_pred(A[1], B[1], C[1]); @@ -145,10 +145,10 @@ static av_always_inline void pred_motion(H264Context *const h, } } - tprintf(h->avctx, + ff_tlog(h->avctx, "pred_motion (%2d %2d %2d) (%2d %2d %2d) (%2d %2d %2d) -> (%2d %2d %2d) at %2d %2d %d list %d\n", top_ref, B[0], B[1], diagonal_ref, C[0], C[1], left_ref, - A[0], A[1], ref, *mx, *my, h->mb_x, h->mb_y, n, list); + A[0], A[1], ref, *mx, *my, sl->mb_x, sl->mb_y, n, list); } /** @@ -157,17 +157,17 @@ static av_always_inline void pred_motion(H264Context *const h, * @param mx the x component of the predicted motion vector * @param my the y component of the predicted motion vector */ -static av_always_inline void pred_16x8_motion(H264Context *const h, +static av_always_inline void pred_16x8_motion(const H264Context *const h, H264SliceContext *sl, int n, int list, int ref, 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); + ff_tlog(h->avctx, "pred_16x8: (%2d %2d %2d) at %2d %2d %d list %d\n", + top_ref, B[0], B[1], sl->mb_x, sl->mb_y, n, list); if (top_ref == ref) { *mx = B[0]; @@ -175,11 +175,11 @@ 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); + ff_tlog(h->avctx, "pred_16x8: (%2d %2d %2d) at %2d %2d %d list %d\n", + left_ref, A[0], A[1], sl->mb_x, sl->mb_y, n, list); if (left_ref == ref) { *mx = A[0]; @@ -198,17 +198,17 @@ static av_always_inline void pred_16x8_motion(H264Context *const h, * @param mx the x component of the predicted motion vector * @param my the y component of the predicted motion vector */ -static av_always_inline void pred_8x16_motion(H264Context *const h, +static av_always_inline void pred_8x16_motion(const H264Context *const h, H264SliceContext *sl, int n, int list, int ref, 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); + ff_tlog(h->avctx, "pred_8x16: (%2d %2d %2d) at %2d %2d %d list %d\n", + left_ref, A[0], A[1], sl->mb_x, sl->mb_y, n, list); if (left_ref == ref) { *mx = A[0]; @@ -221,8 +221,8 @@ static av_always_inline void pred_8x16_motion(H264Context *const h, diagonal_ref = fetch_diagonal_mv(h, sl, &C, scan8[4], list, 2); - tprintf(h->avctx, "pred_8x16: (%2d %2d %2d) at %2d %2d %d list %d\n", - diagonal_ref, C[0], C[1], h->mb_x, h->mb_y, n, list); + ff_tlog(h->avctx, "pred_8x16: (%2d %2d %2d) at %2d %2d %d list %d\n", + diagonal_ref, C[0], C[1], sl->mb_x, sl->mb_y, n, list); if (diagonal_ref == ref) { *mx = C[0]; @@ -237,7 +237,7 @@ static av_always_inline void pred_8x16_motion(H264Context *const h, #define FIX_MV_MBAFF(type, refn, mvn, idx) \ if (FRAME_MBAFF(h)) { \ - if (MB_FIELD(h)) { \ + if (MB_FIELD(sl)) { \ if (!IS_INTERLACED(type)) { \ refn <<= 1; \ AV_COPY32(mvbuf[idx], mvn); \ @@ -254,7 +254,7 @@ static av_always_inline void pred_8x16_motion(H264Context *const h, } \ } -static av_always_inline void pred_pskip_motion(H264Context *const h, +static av_always_inline void pred_pskip_motion(const H264Context *const h, H264SliceContext *sl) { DECLARE_ALIGNED(4, static const int16_t, zeromv)[2] = { 0 }; @@ -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. @@ -298,8 +298,8 @@ static av_always_inline void pred_pskip_motion(H264Context *const h, goto zeromv; } - tprintf(h->avctx, "pred_pskip: (%d) (%d) at %2d %2d\n", - top_ref, left_ref, h->mb_x, h->mb_y); + ff_tlog(h->avctx, "pred_pskip: (%d) (%d) at %2d %2d\n", + top_ref, left_ref, sl->mb_x, sl->mb_y); if (USES_LIST(sl->topright_type, 0)) { diagonal_ref = ref[4 * sl->topright_mb_xy + 2]; @@ -325,7 +325,7 @@ static av_always_inline void pred_pskip_motion(H264Context *const h, } match_count = !diagonal_ref + !top_ref + !left_ref; - tprintf(h->avctx, "pred_pskip_motion match_count=%d\n", match_count); + ff_tlog(h->avctx, "pred_pskip_motion match_count=%d\n", match_count); if (match_count > 1) { mx = mid_pred(A[0], B[0], C[0]); my = mid_pred(A[1], B[1], C[1]); @@ -345,17 +345,17 @@ 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; } -static void fill_decode_neighbors(H264Context *h, H264SliceContext *sl, int mb_type) +static void fill_decode_neighbors(const H264Context *h, H264SliceContext *sl, int mb_type) { - const int mb_xy = h->mb_xy; + const int mb_xy = sl->mb_xy; int topleft_xy, top_xy, topright_xy, left_xy[LEFT_MBS]; static const uint8_t left_block_options[4][32] = { { 0, 1, 2, 3, 7, 10, 8, 11, 3 + 0 * 4, 3 + 1 * 4, 3 + 2 * 4, 3 + 3 * 4, 1 + 4 * 4, 1 + 8 * 4, 1 + 5 * 4, 1 + 9 * 4 }, @@ -366,7 +366,7 @@ static void fill_decode_neighbors(H264Context *h, H264SliceContext *sl, int mb_t sl->topleft_partition = -1; - top_xy = mb_xy - (h->mb_stride << MB_FIELD(h)); + top_xy = mb_xy - (h->mb_stride << MB_FIELD(sl)); /* Wow, what a mess, why didn't they simplify the interlacing & intra * stuff, I can't imagine that these complex rules are worth it. */ @@ -378,7 +378,7 @@ static void fill_decode_neighbors(H264Context *h, H264SliceContext *sl, int mb_t if (FRAME_MBAFF(h)) { const int left_mb_field_flag = IS_INTERLACED(h->cur_pic.mb_type[mb_xy - 1]); const int curr_mb_field_flag = IS_INTERLACED(mb_type); - if (h->mb_y & 1) { + if (sl->mb_y & 1) { if (left_mb_field_flag != curr_mb_field_flag) { left_xy[LBOT] = left_xy[LTOP] = mb_xy - h->mb_stride - 1; if (curr_mb_field_flag) { @@ -423,26 +423,26 @@ static void fill_decode_neighbors(H264Context *h, H264SliceContext *sl, int mb_t sl->left_type[LBOT] = h->cur_pic.mb_type[left_xy[LBOT]]; if (FMO) { - if (h->slice_table[topleft_xy] != h->slice_num) + if (h->slice_table[topleft_xy] != sl->slice_num) sl->topleft_type = 0; - if (h->slice_table[top_xy] != h->slice_num) + if (h->slice_table[top_xy] != sl->slice_num) sl->top_type = 0; - if (h->slice_table[left_xy[LTOP]] != h->slice_num) + if (h->slice_table[left_xy[LTOP]] != sl->slice_num) sl->left_type[LTOP] = sl->left_type[LBOT] = 0; } else { - if (h->slice_table[topleft_xy] != h->slice_num) { + if (h->slice_table[topleft_xy] != sl->slice_num) { sl->topleft_type = 0; - if (h->slice_table[top_xy] != h->slice_num) + if (h->slice_table[top_xy] != sl->slice_num) sl->top_type = 0; - if (h->slice_table[left_xy[LTOP]] != h->slice_num) + if (h->slice_table[left_xy[LTOP]] != sl->slice_num) sl->left_type[LTOP] = sl->left_type[LBOT] = 0; } } - if (h->slice_table[topright_xy] != h->slice_num) + if (h->slice_table[topright_xy] != sl->slice_num) sl->topright_type = 0; } -static void fill_decode_caches(H264Context *h, H264SliceContext *sl, int mb_type) +static void fill_decode_caches(const H264Context *h, H264SliceContext *sl, int mb_type) { int topleft_xy, top_xy, topright_xy, left_xy[LEFT_MBS]; int topleft_type, top_type, topright_type, left_type[LEFT_MBS]; @@ -539,7 +539,7 @@ static void fill_decode_caches(H264Context *h, H264SliceContext *sl, int mb_type */ /* FIXME: constraint_intra_pred & partitioning & nnz * (let us hope this is just a typo in the spec) */ - nnz_cache = h->non_zero_count_cache; + nnz_cache = sl->non_zero_count_cache; if (top_type) { nnz = h->non_zero_count[top_xy]; AV_COPY32(&nnz_cache[4 + 8 * 0], &nnz[4 * 3]); @@ -589,31 +589,31 @@ static void fill_decode_caches(H264Context *h, H264SliceContext *sl, int mb_type if (CABAC(h)) { // top_cbp if (top_type) - h->top_cbp = h->cbp_table[top_xy]; + sl->top_cbp = h->cbp_table[top_xy]; else - h->top_cbp = IS_INTRA(mb_type) ? 0x7CF : 0x00F; + sl->top_cbp = IS_INTRA(mb_type) ? 0x7CF : 0x00F; // left_cbp if (left_type[LTOP]) { - h->left_cbp = (h->cbp_table[left_xy[LTOP]] & 0x7F0) | + sl->left_cbp = (h->cbp_table[left_xy[LTOP]] & 0x7F0) | ((h->cbp_table[left_xy[LTOP]] >> (left_block[0] & (~1))) & 2) | (((h->cbp_table[left_xy[LBOT]] >> (left_block[2] & (~1))) & 2) << 2); } else { - h->left_cbp = IS_INTRA(mb_type) ? 0x7CF : 0x00F; + sl->left_cbp = IS_INTRA(mb_type) ? 0x7CF : 0x00F; } } } - if (IS_INTER(mb_type) || (IS_DIRECT(mb_type) && h->direct_spatial_mv_pred)) { + if (IS_INTER(mb_type) || (IS_DIRECT(mb_type) && sl->direct_spatial_mv_pred)) { 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]]; + for (list = 0; list < sl->list_count; list++) { + 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; - assert(!(IS_DIRECT(mb_type) && !h->direct_spatial_mv_pred)); + assert(!(IS_DIRECT(mb_type) && !sl->direct_spatial_mv_pred)); if (USES_LIST(top_type, list)) { const int b_xy = h->mb2b_xy[top_xy] + 3 * b_stride; @@ -688,8 +688,8 @@ static void fill_decode_caches(H264Context *h, H264SliceContext *sl, int mb_type continue; if (!(mb_type & (MB_TYPE_SKIP | MB_TYPE_DIRECT2))) { - uint8_t(*mvd_cache)[2] = &h->mvd_cache[list][scan8[0]]; - uint8_t(*mvd)[2] = h->mvd_table[list]; + uint8_t(*mvd_cache)[2] = &sl->mvd_cache[list][scan8[0]]; + uint8_t(*mvd)[2] = sl->mvd_table[list]; ref_cache[2 + 8 * 0] = ref_cache[2 + 8 * 2] = PART_NOT_AVAILABLE; AV_ZERO32(mv_cache[2 + 8 * 0]); @@ -720,8 +720,8 @@ static void fill_decode_caches(H264Context *h, H264SliceContext *sl, int mb_type } AV_ZERO16(mvd_cache[2 + 8 * 0]); AV_ZERO16(mvd_cache[2 + 8 * 2]); - if (h->slice_type_nos == AV_PICTURE_TYPE_B) { - uint8_t *direct_cache = &h->direct_cache[scan8[0]]; + if (sl->slice_type_nos == AV_PICTURE_TYPE_B) { + uint8_t *direct_cache = &sl->direct_cache[scan8[0]]; uint8_t *direct_table = h->direct_table; fill_rectangle(direct_cache, 4, 4, 8, MB_TYPE_16x16 >> 1, 1); @@ -767,13 +767,13 @@ static void fill_decode_caches(H264Context *h, H264SliceContext *sl, int mb_type MAP_F2F(scan8[0] - 1 + 3 * 8, left_type[LBOT]) if (FRAME_MBAFF(h)) { - if (MB_FIELD(h)) { + if (MB_FIELD(sl)) { #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; \ - h->mvd_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] /= 2; \ + sl->mvd_cache[list][idx][1] >>= 1; \ } MAP_MVS @@ -781,10 +781,10 @@ 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; \ - h->mvd_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; \ + sl->mvd_cache[list][idx][1] <<= 1; \ } MAP_MVS @@ -794,30 +794,30 @@ static void fill_decode_caches(H264Context *h, H264SliceContext *sl, int mb_type } } - h->neighbor_transform_size = !!IS_8x8DCT(top_type) + !!IS_8x8DCT(left_type[LTOP]); + sl->neighbor_transform_size = !!IS_8x8DCT(top_type) + !!IS_8x8DCT(left_type[LTOP]); } /** * decodes a P_SKIP or B_SKIP macroblock */ -static void av_unused decode_mb_skip(H264Context *h, H264SliceContext *sl) +static void av_unused decode_mb_skip(const H264Context *h, H264SliceContext *sl) { - const int mb_xy = h->mb_xy; + const int mb_xy = sl->mb_xy; int mb_type = 0; memset(h->non_zero_count[mb_xy], 0, 48); - if (MB_FIELD(h)) + if (MB_FIELD(sl)) mb_type |= MB_TYPE_INTERLACED; - if (h->slice_type_nos == AV_PICTURE_TYPE_B) { + if (sl->slice_type_nos == AV_PICTURE_TYPE_B) { // just for fill_caches. pred_direct_motion will set the real mb_type mb_type |= MB_TYPE_L0L1 | MB_TYPE_DIRECT2 | MB_TYPE_SKIP; - if (h->direct_spatial_mv_pred) { + if (sl->direct_spatial_mv_pred) { 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,10 +826,10 @@ 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; + h->slice_table[mb_xy] = sl->slice_num; sl->prev_mb_skipped = 1; }