diff options
author | Derek Buitenhuis <derek.buitenhuis@gmail.com> | 2016-04-27 18:48:20 +0300 |
---|---|---|
committer | Derek Buitenhuis <derek.buitenhuis@gmail.com> | 2016-04-27 18:48:30 +0300 |
commit | c0b51aa2d2c66cb52577a287b3b821e89f214514 (patch) | |
tree | 473a1c27cc3232fd8e50bb9972ffe7d87fd55a7a /libavcodec/svq3.c | |
parent | fed686af232487dad6ec46294b3e5018f11943f1 (diff) | |
parent | 89a13998a1b5074411dff5a461dce3837057b0b8 (diff) |
Merge commit '89a13998a1b5074411dff5a461dce3837057b0b8'
* commit '89a13998a1b5074411dff5a461dce3837057b0b8':
svq3: rip out the svq3-relevant parts of pred_motion() out of h264
Merged-by: Derek Buitenhuis <derek.buitenhuis@gmail.com>
Diffstat (limited to 'libavcodec/svq3.c')
-rw-r--r-- | libavcodec/svq3.c | 75 |
1 files changed, 74 insertions, 1 deletions
diff --git a/libavcodec/svq3.c b/libavcodec/svq3.c index d5ed6925a7..26fc7c5cec 100644 --- a/libavcodec/svq3.c +++ b/libavcodec/svq3.c @@ -318,6 +318,79 @@ static inline int svq3_decode_block(GetBitContext *gb, int16_t *block, return 0; } +static av_always_inline int +svq3_fetch_diagonal_mv(const H264Context *h, H264SliceContext *sl, + const int16_t **C, + int i, int list, int part_width) +{ + const int topright_ref = sl->ref_cache[list][i - 8 + part_width]; + + if (topright_ref != PART_NOT_AVAILABLE) { + *C = sl->mv_cache[list][i - 8 + part_width]; + return topright_ref; + } else { + *C = sl->mv_cache[list][i - 8 - 1]; + return sl->ref_cache[list][i - 8 - 1]; + } +} + +/** + * Get the predicted MV. + * @param n the block index + * @param part_width the width of the partition (4, 8,16) -> (1, 2, 4) + * @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 svq3_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 = 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; + +/* mv_cache + * B . . A T T T T + * U . . L . . , . + * U . . L . . . . + * U . . L . . , . + * . . . L . . . . + */ + + diagonal_ref = svq3_fetch_diagonal_mv(h, sl, &C, index8, list, part_width); + match_count = (diagonal_ref == ref) + (top_ref == ref) + (left_ref == ref); + if (match_count > 1) { //most common + *mx = mid_pred(A[0], B[0], C[0]); + *my = mid_pred(A[1], B[1], C[1]); + } else if (match_count == 1) { + if (left_ref == ref) { + *mx = A[0]; + *my = A[1]; + } else if (top_ref == ref) { + *mx = B[0]; + *my = B[1]; + } else { + *mx = C[0]; + *my = C[1]; + } + } else { + if (top_ref == PART_NOT_AVAILABLE && + diagonal_ref == PART_NOT_AVAILABLE && + left_ref != PART_NOT_AVAILABLE) { + *mx = A[0]; + *my = A[1]; + } else { + *mx = mid_pred(A[0], B[0], C[0]); + *my = mid_pred(A[1], B[1], C[1]); + } + } +} + static inline void svq3_mc_dir_part(SVQ3Context *s, int x, int y, int width, int height, int mx, int my, int dxy, @@ -416,7 +489,7 @@ static inline int svq3_mc_dir(SVQ3Context *s, int size, int mode, (j >> 1 & 4) + (i & 8); if (mode != PREDICT_MODE) { - pred_motion(h, sl, k, part_width >> 2, dir, 1, &mx, &my); + svq3_pred_motion(h, sl, k, part_width >> 2, dir, 1, &mx, &my); } else { mx = s->next_pic->motion_val[0][b_xy][0] << 1; my = s->next_pic->motion_val[0][b_xy][1] << 1; |