Index: source/libvpx/vp9/common/vp9_blockd.h |
=================================================================== |
--- source/libvpx/vp9/common/vp9_blockd.h (revision 219822) |
+++ source/libvpx/vp9/common/vp9_blockd.h (working copy) |
@@ -19,16 +19,13 @@ |
#include "vp9/common/vp9_common.h" |
#include "vp9/common/vp9_common_data.h" |
-#include "vp9/common/vp9_convolve.h" |
#include "vp9/common/vp9_enums.h" |
#include "vp9/common/vp9_mv.h" |
+#include "vp9/common/vp9_scale.h" |
#include "vp9/common/vp9_seg_common.h" |
#include "vp9/common/vp9_treecoder.h" |
#define BLOCK_SIZE_GROUPS 4 |
- |
-#define PREDICTION_PROBS 3 |
- |
#define MBSKIP_CONTEXTS 3 |
/* Segment Feature Masks */ |
@@ -59,11 +56,11 @@ |
} FRAME_TYPE; |
typedef enum { |
- EIGHTTAP_SMOOTH, |
- EIGHTTAP, |
- EIGHTTAP_SHARP, |
- BILINEAR, |
- SWITCHABLE /* should be the last one */ |
+ EIGHTTAP = 0, |
+ EIGHTTAP_SMOOTH = 1, |
+ EIGHTTAP_SHARP = 2, |
+ BILINEAR = 3, |
+ SWITCHABLE = 4 /* should be the last one */ |
} INTERPOLATIONFILTERTYPE; |
typedef enum { |
@@ -74,7 +71,7 @@ |
D135_PRED, // Directional 135 deg = 180 - 45 |
D117_PRED, // Directional 117 deg = 180 - 63 |
D153_PRED, // Directional 153 deg = 180 - 27 |
- D27_PRED, // Directional 27 deg = round(arctan(1/2) * 180/pi) |
+ D207_PRED, // Directional 207 deg = 180 + 27 |
D63_PRED, // Directional 63 deg = round(arctan(2/1) * 180/pi) |
TM_PRED, // True-motion |
NEARESTMV, |
@@ -92,9 +89,9 @@ |
return mode >= NEARESTMV && mode <= NEWMV; |
} |
-#define VP9_INTRA_MODES (TM_PRED + 1) |
+#define INTRA_MODES (TM_PRED + 1) |
-#define VP9_INTER_MODES (1 + NEWMV - NEARESTMV) |
+#define INTER_MODES (1 + NEWMV - NEARESTMV) |
static INLINE int inter_mode_offset(MB_PREDICTION_MODE mode) { |
return (mode - NEARESTMV); |
@@ -118,45 +115,45 @@ |
MAX_REF_FRAMES = 4 |
} MV_REFERENCE_FRAME; |
-static INLINE int b_width_log2(BLOCK_SIZE_TYPE sb_type) { |
+static INLINE int b_width_log2(BLOCK_SIZE sb_type) { |
return b_width_log2_lookup[sb_type]; |
} |
-static INLINE int b_height_log2(BLOCK_SIZE_TYPE sb_type) { |
+static INLINE int b_height_log2(BLOCK_SIZE sb_type) { |
return b_height_log2_lookup[sb_type]; |
} |
-static INLINE int mi_width_log2(BLOCK_SIZE_TYPE sb_type) { |
+static INLINE int mi_width_log2(BLOCK_SIZE sb_type) { |
return mi_width_log2_lookup[sb_type]; |
} |
-static INLINE int mi_height_log2(BLOCK_SIZE_TYPE sb_type) { |
+static INLINE int mi_height_log2(BLOCK_SIZE sb_type) { |
return mi_height_log2_lookup[sb_type]; |
} |
+// This structure now relates to 8x8 block regions. |
typedef struct { |
MB_PREDICTION_MODE mode, uv_mode; |
MV_REFERENCE_FRAME ref_frame[2]; |
TX_SIZE txfm_size; |
- int_mv mv[2]; // for each reference frame used |
+ int_mv mv[2]; // for each reference frame used |
int_mv ref_mvs[MAX_REF_FRAMES][MAX_MV_REF_CANDIDATES]; |
int_mv best_mv, best_second_mv; |
- uint8_t mb_mode_context[MAX_REF_FRAMES]; |
+ uint8_t mode_context[MAX_REF_FRAMES]; |
- unsigned char mb_skip_coeff; /* does this mb has coefficients at all, 1=no coefficients, 0=need decode tokens */ |
- unsigned char segment_id; // Segment id for current frame |
+ unsigned char skip_coeff; // 0=need to decode coeffs, 1=no coefficients |
+ unsigned char segment_id; // Segment id for this block. |
- // Flags used for prediction status of various bistream signals |
+ // Flags used for prediction status of various bit-stream signals |
unsigned char seg_id_predicted; |
- // Indicates if the mb is part of the image (1) vs border (0) |
- // This can be useful in determining whether the MB provides |
- // a valid predictor |
- unsigned char mb_in_image; |
+ // Indicates if the block is part of the image (1) vs border (0) |
+ // This can be useful in determining whether it provides a valid predictor |
+ unsigned char in_image; |
INTERPOLATIONFILTERTYPE interp_filter; |
- BLOCK_SIZE_TYPE sb_type; |
+ BLOCK_SIZE sb_type; |
} MB_MODE_INFO; |
typedef struct { |
@@ -164,31 +161,19 @@ |
union b_mode_info bmi[4]; |
} MODE_INFO; |
+static INLINE int is_inter_block(const MB_MODE_INFO *mbmi) { |
+ return mbmi->ref_frame[0] > INTRA_FRAME; |
+} |
+ |
+static INLINE int has_second_ref(const MB_MODE_INFO *mbmi) { |
+ return mbmi->ref_frame[1] > INTRA_FRAME; |
+} |
+ |
enum mv_precision { |
MV_PRECISION_Q3, |
MV_PRECISION_Q4 |
}; |
-#define VP9_REF_SCALE_SHIFT 14 |
-#define VP9_REF_NO_SCALE (1 << VP9_REF_SCALE_SHIFT) |
- |
-struct scale_factors { |
- int x_scale_fp; // horizontal fixed point scale factor |
- int y_scale_fp; // vertical fixed point scale factor |
- int x_offset_q4; |
- int x_step_q4; |
- int y_offset_q4; |
- int y_step_q4; |
- |
- int (*scale_value_x)(int val, const struct scale_factors *scale); |
- int (*scale_value_y)(int val, const struct scale_factors *scale); |
- void (*set_scaled_offsets)(struct scale_factors *scale, int row, int col); |
- MV32 (*scale_mv_q3_to_q4)(const MV *mv, const struct scale_factors *scale); |
- MV32 (*scale_mv_q4)(const MV *mv, const struct scale_factors *scale); |
- |
- convolve_fn_t predict[2][2][2]; // horiz, vert, avg |
-}; |
- |
#if CONFIG_ALPHA |
enum { MAX_MB_PLANE = 4 }; |
#else |
@@ -214,29 +199,8 @@ |
ENTROPY_CONTEXT *left_context; |
}; |
-#define BLOCK_OFFSET(x, i, n) ((x) + (i) * (n)) |
+#define BLOCK_OFFSET(x, i) ((x) + (i) * 16) |
-#define MAX_REF_LF_DELTAS 4 |
-#define MAX_MODE_LF_DELTAS 2 |
- |
-struct loopfilter { |
- int filter_level; |
- |
- int sharpness_level; |
- int last_sharpness_level; |
- |
- uint8_t mode_ref_delta_enabled; |
- uint8_t mode_ref_delta_update; |
- |
- // 0 = Intra, Last, GF, ARF |
- signed char ref_deltas[MAX_REF_LF_DELTAS]; |
- signed char last_ref_deltas[MAX_REF_LF_DELTAS]; |
- |
- // 0 = ZERO_MV, MV |
- signed char mode_deltas[MAX_MODE_LF_DELTAS]; |
- signed char last_mode_deltas[MAX_MODE_LF_DELTAS]; |
-}; |
- |
typedef struct macroblockd { |
struct macroblockd_plane plane[MAX_MB_PLANE]; |
@@ -250,9 +214,6 @@ |
int left_available; |
int right_available; |
- struct segmentation seg; |
- struct loopfilter lf; |
- |
// partition contexts |
PARTITION_CONTEXT *above_seg_context; |
PARTITION_CONTEXT *left_seg_context; |
@@ -284,24 +245,24 @@ |
} MACROBLOCKD; |
-static INLINE unsigned char *get_sb_index(MACROBLOCKD *xd, BLOCK_SIZE_TYPE subsize) { |
+static INLINE unsigned char *get_sb_index(MACROBLOCKD *xd, BLOCK_SIZE subsize) { |
switch (subsize) { |
- case BLOCK_SIZE_SB64X64: |
- case BLOCK_SIZE_SB64X32: |
- case BLOCK_SIZE_SB32X64: |
- case BLOCK_SIZE_SB32X32: |
+ case BLOCK_64X64: |
+ case BLOCK_64X32: |
+ case BLOCK_32X64: |
+ case BLOCK_32X32: |
return &xd->sb_index; |
- case BLOCK_SIZE_SB32X16: |
- case BLOCK_SIZE_SB16X32: |
- case BLOCK_SIZE_MB16X16: |
+ case BLOCK_32X16: |
+ case BLOCK_16X32: |
+ case BLOCK_16X16: |
return &xd->mb_index; |
- case BLOCK_SIZE_SB16X8: |
- case BLOCK_SIZE_SB8X16: |
- case BLOCK_SIZE_SB8X8: |
+ case BLOCK_16X8: |
+ case BLOCK_8X16: |
+ case BLOCK_8X8: |
return &xd->b_index; |
- case BLOCK_SIZE_SB8X4: |
- case BLOCK_SIZE_SB4X8: |
- case BLOCK_SIZE_AB4X4: |
+ case BLOCK_8X4: |
+ case BLOCK_4X8: |
+ case BLOCK_4X4: |
return &xd->ab_index; |
default: |
assert(0); |
@@ -309,13 +270,12 @@ |
} |
} |
-static INLINE void update_partition_context(MACROBLOCKD *xd, |
- BLOCK_SIZE_TYPE sb_type, |
- BLOCK_SIZE_TYPE sb_size) { |
+static INLINE void update_partition_context(MACROBLOCKD *xd, BLOCK_SIZE sb_type, |
+ BLOCK_SIZE sb_size) { |
const int bsl = b_width_log2(sb_size), bs = (1 << bsl) / 2; |
const int bwl = b_width_log2(sb_type); |
const int bhl = b_height_log2(sb_type); |
- const int boffset = b_width_log2(BLOCK_SIZE_SB64X64) - bsl; |
+ const int boffset = b_width_log2(BLOCK_64X64) - bsl; |
const char pcval0 = ~(0xe << boffset); |
const char pcval1 = ~(0xf << boffset); |
const char pcvalue[2] = {pcval0, pcval1}; |
@@ -329,11 +289,10 @@ |
vpx_memset(xd->left_seg_context, pcvalue[bhl == bsl], bs); |
} |
-static INLINE int partition_plane_context(MACROBLOCKD *xd, |
- BLOCK_SIZE_TYPE sb_type) { |
+static INLINE int partition_plane_context(MACROBLOCKD *xd, BLOCK_SIZE sb_type) { |
int bsl = mi_width_log2(sb_type), bs = 1 << bsl; |
int above = 0, left = 0, i; |
- int boffset = mi_width_log2(BLOCK_SIZE_SB64X64) - bsl; |
+ int boffset = mi_width_log2(BLOCK_64X64) - bsl; |
assert(mi_width_log2(sb_type) == mi_height_log2(sb_type)); |
assert(bsl >= 0); |
@@ -350,10 +309,9 @@ |
return (left * 2 + above) + bsl * PARTITION_PLOFFSET; |
} |
-static BLOCK_SIZE_TYPE get_subsize(BLOCK_SIZE_TYPE bsize, |
- PARTITION_TYPE partition) { |
- BLOCK_SIZE_TYPE subsize = subsize_lookup[partition][bsize]; |
- assert(subsize != BLOCK_SIZE_TYPES); |
+static BLOCK_SIZE get_subsize(BLOCK_SIZE bsize, PARTITION_TYPE partition) { |
+ const BLOCK_SIZE subsize = subsize_lookup[partition][bsize]; |
+ assert(subsize < BLOCK_SIZES); |
return subsize; |
} |
@@ -366,10 +324,10 @@ |
if (plane_type != PLANE_TYPE_Y_WITH_DC || |
xd->lossless || |
- mbmi->ref_frame[0] != INTRA_FRAME) |
+ is_inter_block(mbmi)) |
return DCT_DCT; |
- return mode2txfm_map[mbmi->sb_type < BLOCK_SIZE_SB8X8 ? |
+ return mode2txfm_map[mbmi->sb_type < BLOCK_8X8 ? |
mi->bmi[ib].as_mode : mbmi->mode]; |
} |
@@ -405,256 +363,144 @@ |
return MIN(mbmi->txfm_size, max_uv_txsize_lookup[mbmi->sb_type]); |
} |
-struct plane_block_idx { |
- int plane; |
- int block; |
-}; |
- |
-// TODO(jkoleszar): returning a struct so it can be used in a const context, |
-// expect to refactor this further later. |
-static INLINE struct plane_block_idx plane_block_idx(int y_blocks, |
- int b_idx) { |
- const int v_offset = y_blocks * 5 / 4; |
- struct plane_block_idx res; |
- |
- if (b_idx < y_blocks) { |
- res.plane = 0; |
- res.block = b_idx; |
- } else if (b_idx < v_offset) { |
- res.plane = 1; |
- res.block = b_idx - y_blocks; |
- } else { |
- assert(b_idx < y_blocks * 3 / 2); |
- res.plane = 2; |
- res.block = b_idx - v_offset; |
- } |
- return res; |
+static BLOCK_SIZE get_plane_block_size(BLOCK_SIZE bsize, |
+ const struct macroblockd_plane *pd) { |
+ BLOCK_SIZE bs = ss_size_lookup[bsize][pd->subsampling_x][pd->subsampling_y]; |
+ assert(bs < BLOCK_SIZES); |
+ return bs; |
} |
-static INLINE int plane_block_width(BLOCK_SIZE_TYPE bsize, |
+static INLINE int plane_block_width(BLOCK_SIZE bsize, |
const struct macroblockd_plane* plane) { |
return 4 << (b_width_log2(bsize) - plane->subsampling_x); |
} |
-static INLINE int plane_block_height(BLOCK_SIZE_TYPE bsize, |
+static INLINE int plane_block_height(BLOCK_SIZE bsize, |
const struct macroblockd_plane* plane) { |
return 4 << (b_height_log2(bsize) - plane->subsampling_y); |
} |
-static INLINE int plane_block_width_log2by4( |
- BLOCK_SIZE_TYPE bsize, const struct macroblockd_plane* plane) { |
- return (b_width_log2(bsize) - plane->subsampling_x); |
-} |
- |
-static INLINE int plane_block_height_log2by4( |
- BLOCK_SIZE_TYPE bsize, const struct macroblockd_plane* plane) { |
- return (b_height_log2(bsize) - plane->subsampling_y); |
-} |
- |
typedef void (*foreach_transformed_block_visitor)(int plane, int block, |
- BLOCK_SIZE_TYPE bsize, |
- int ss_txfrm_size, |
+ BLOCK_SIZE plane_bsize, |
+ TX_SIZE tx_size, |
void *arg); |
static INLINE void foreach_transformed_block_in_plane( |
- const MACROBLOCKD* const xd, BLOCK_SIZE_TYPE bsize, int plane, |
+ const MACROBLOCKD *const xd, BLOCK_SIZE bsize, int plane, |
foreach_transformed_block_visitor visit, void *arg) { |
- const int bw = b_width_log2(bsize), bh = b_height_log2(bsize); |
- |
+ const struct macroblockd_plane *const pd = &xd->plane[plane]; |
+ const MB_MODE_INFO* mbmi = &xd->mode_info_context->mbmi; |
// block and transform sizes, in number of 4x4 blocks log 2 ("*_b") |
// 4x4=0, 8x8=2, 16x16=4, 32x32=6, 64x64=8 |
// transform size varies per plane, look it up in a common way. |
- const MB_MODE_INFO* mbmi = &xd->mode_info_context->mbmi; |
const TX_SIZE tx_size = plane ? get_uv_tx_size(mbmi) |
: mbmi->txfm_size; |
- const int block_size_b = bw + bh; |
- const int txfrm_size_b = tx_size * 2; |
- |
- // subsampled size of the block |
- const int ss_sum = xd->plane[plane].subsampling_x |
- + xd->plane[plane].subsampling_y; |
- const int ss_block_size = block_size_b - ss_sum; |
- |
- const int step = 1 << txfrm_size_b; |
- |
+ const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd); |
+ const int num_4x4_w = num_4x4_blocks_wide_lookup[plane_bsize]; |
+ const int num_4x4_h = num_4x4_blocks_high_lookup[plane_bsize]; |
+ const int step = 1 << (tx_size << 1); |
int i; |
- assert(txfrm_size_b <= block_size_b); |
- assert(txfrm_size_b <= ss_block_size); |
- |
// If mb_to_right_edge is < 0 we are in a situation in which |
// the current block size extends into the UMV and we won't |
// visit the sub blocks that are wholly within the UMV. |
if (xd->mb_to_right_edge < 0 || xd->mb_to_bottom_edge < 0) { |
int r, c; |
- const int sw = bw - xd->plane[plane].subsampling_x; |
- const int sh = bh - xd->plane[plane].subsampling_y; |
- int max_blocks_wide = 1 << sw; |
- int max_blocks_high = 1 << sh; |
+ int max_blocks_wide = num_4x4_w; |
+ int max_blocks_high = num_4x4_h; |
+ |
// xd->mb_to_right_edge is in units of pixels * 8. This converts |
// it to 4x4 block sizes. |
if (xd->mb_to_right_edge < 0) |
- max_blocks_wide += |
- + (xd->mb_to_right_edge >> (5 + xd->plane[plane].subsampling_x)); |
+ max_blocks_wide += (xd->mb_to_right_edge >> (5 + pd->subsampling_x)); |
if (xd->mb_to_bottom_edge < 0) |
- max_blocks_high += |
- + (xd->mb_to_bottom_edge >> (5 + xd->plane[plane].subsampling_y)); |
+ max_blocks_high += (xd->mb_to_bottom_edge >> (5 + pd->subsampling_y)); |
i = 0; |
// Unlike the normal case - in here we have to keep track of the |
// row and column of the blocks we use so that we know if we are in |
- // the unrestricted motion border.. |
- for (r = 0; r < (1 << sh); r += (1 << tx_size)) { |
- for (c = 0; c < (1 << sw); c += (1 << tx_size)) { |
+ // the unrestricted motion border. |
+ for (r = 0; r < num_4x4_h; r += (1 << tx_size)) { |
+ for (c = 0; c < num_4x4_w; c += (1 << tx_size)) { |
if (r < max_blocks_high && c < max_blocks_wide) |
- visit(plane, i, bsize, txfrm_size_b, arg); |
+ visit(plane, i, plane_bsize, tx_size, arg); |
i += step; |
} |
} |
} else { |
- for (i = 0; i < (1 << ss_block_size); i += step) { |
- visit(plane, i, bsize, txfrm_size_b, arg); |
- } |
+ for (i = 0; i < num_4x4_w * num_4x4_h; i += step) |
+ visit(plane, i, plane_bsize, tx_size, arg); |
} |
} |
static INLINE void foreach_transformed_block( |
- const MACROBLOCKD* const xd, BLOCK_SIZE_TYPE bsize, |
+ const MACROBLOCKD* const xd, BLOCK_SIZE bsize, |
foreach_transformed_block_visitor visit, void *arg) { |
int plane; |
- for (plane = 0; plane < MAX_MB_PLANE; plane++) { |
- foreach_transformed_block_in_plane(xd, bsize, plane, |
- visit, arg); |
- } |
+ for (plane = 0; plane < MAX_MB_PLANE; plane++) |
+ foreach_transformed_block_in_plane(xd, bsize, plane, visit, arg); |
} |
static INLINE void foreach_transformed_block_uv( |
- const MACROBLOCKD* const xd, BLOCK_SIZE_TYPE bsize, |
+ const MACROBLOCKD* const xd, BLOCK_SIZE bsize, |
foreach_transformed_block_visitor visit, void *arg) { |
int plane; |
- for (plane = 1; plane < MAX_MB_PLANE; plane++) { |
- foreach_transformed_block_in_plane(xd, bsize, plane, |
- visit, arg); |
- } |
+ for (plane = 1; plane < MAX_MB_PLANE; plane++) |
+ foreach_transformed_block_in_plane(xd, bsize, plane, visit, arg); |
} |
-// TODO(jkoleszar): In principle, pred_w, pred_h are unnecessary, as we could |
-// calculate the subsampled BLOCK_SIZE_TYPE, but that type isn't defined for |
-// sizes smaller than 16x16 yet. |
-typedef void (*foreach_predicted_block_visitor)(int plane, int block, |
- BLOCK_SIZE_TYPE bsize, |
- int pred_w, int pred_h, |
- void *arg); |
-static INLINE void foreach_predicted_block_in_plane( |
- const MACROBLOCKD* const xd, BLOCK_SIZE_TYPE bsize, int plane, |
- foreach_predicted_block_visitor visit, void *arg) { |
- int i, x, y; |
- |
- // block sizes in number of 4x4 blocks log 2 ("*_b") |
- // 4x4=0, 8x8=2, 16x16=4, 32x32=6, 64x64=8 |
- // subsampled size of the block |
- const int bwl = b_width_log2(bsize) - xd->plane[plane].subsampling_x; |
- const int bhl = b_height_log2(bsize) - xd->plane[plane].subsampling_y; |
- |
- // size of the predictor to use. |
- int pred_w, pred_h; |
- |
- if (xd->mode_info_context->mbmi.sb_type < BLOCK_SIZE_SB8X8) { |
- assert(bsize == BLOCK_SIZE_SB8X8); |
- pred_w = 0; |
- pred_h = 0; |
- } else { |
- pred_w = bwl; |
- pred_h = bhl; |
- } |
- assert(pred_w <= bwl); |
- assert(pred_h <= bhl); |
- |
- // visit each subblock in raster order |
- i = 0; |
- for (y = 0; y < 1 << bhl; y += 1 << pred_h) { |
- for (x = 0; x < 1 << bwl; x += 1 << pred_w) { |
- visit(plane, i, bsize, pred_w, pred_h, arg); |
- i += 1 << pred_w; |
- } |
- i += (1 << (bwl + pred_h)) - (1 << bwl); |
- } |
-} |
-static INLINE void foreach_predicted_block( |
- const MACROBLOCKD* const xd, BLOCK_SIZE_TYPE bsize, |
- foreach_predicted_block_visitor visit, void *arg) { |
- int plane; |
- |
- for (plane = 0; plane < MAX_MB_PLANE; plane++) { |
- foreach_predicted_block_in_plane(xd, bsize, plane, visit, arg); |
- } |
-} |
-static INLINE void foreach_predicted_block_uv( |
- const MACROBLOCKD* const xd, BLOCK_SIZE_TYPE bsize, |
- foreach_predicted_block_visitor visit, void *arg) { |
- int plane; |
- |
- for (plane = 1; plane < MAX_MB_PLANE; plane++) { |
- foreach_predicted_block_in_plane(xd, bsize, plane, visit, arg); |
- } |
-} |
-static int raster_block_offset(MACROBLOCKD *xd, BLOCK_SIZE_TYPE bsize, |
- int plane, int block, int stride) { |
- const int bw = b_width_log2(bsize) - xd->plane[plane].subsampling_x; |
- const int y = 4 * (block >> bw), x = 4 * (block & ((1 << bw) - 1)); |
+static int raster_block_offset(BLOCK_SIZE plane_bsize, |
+ int raster_block, int stride) { |
+ const int bw = b_width_log2(plane_bsize); |
+ const int y = 4 * (raster_block >> bw); |
+ const int x = 4 * (raster_block & ((1 << bw) - 1)); |
return y * stride + x; |
} |
-static int16_t* raster_block_offset_int16(MACROBLOCKD *xd, |
- BLOCK_SIZE_TYPE bsize, |
- int plane, int block, int16_t *base) { |
- const int stride = plane_block_width(bsize, &xd->plane[plane]); |
- return base + raster_block_offset(xd, bsize, plane, block, stride); |
+static int16_t* raster_block_offset_int16(BLOCK_SIZE plane_bsize, |
+ int raster_block, int16_t *base) { |
+ const int stride = 4 << b_width_log2(plane_bsize); |
+ return base + raster_block_offset(plane_bsize, raster_block, stride); |
} |
-static uint8_t* raster_block_offset_uint8(MACROBLOCKD *xd, |
- BLOCK_SIZE_TYPE bsize, |
- int plane, int block, |
- uint8_t *base, int stride) { |
- return base + raster_block_offset(xd, bsize, plane, block, stride); |
+static uint8_t* raster_block_offset_uint8(BLOCK_SIZE plane_bsize, |
+ int raster_block, uint8_t *base, |
+ int stride) { |
+ return base + raster_block_offset(plane_bsize, raster_block, stride); |
} |
-static int txfrm_block_to_raster_block(MACROBLOCKD *xd, |
- BLOCK_SIZE_TYPE bsize, |
- int plane, int block, |
- int ss_txfrm_size) { |
- const int bwl = b_width_log2(bsize) - xd->plane[plane].subsampling_x; |
- const int txwl = ss_txfrm_size / 2; |
- const int tx_cols_log2 = bwl - txwl; |
+static int txfrm_block_to_raster_block(BLOCK_SIZE plane_bsize, |
+ TX_SIZE tx_size, int block) { |
+ const int bwl = b_width_log2(plane_bsize); |
+ const int tx_cols_log2 = bwl - tx_size; |
const int tx_cols = 1 << tx_cols_log2; |
- const int raster_mb = block >> ss_txfrm_size; |
- const int x = (raster_mb & (tx_cols - 1)) << (txwl); |
- const int y = raster_mb >> tx_cols_log2 << (txwl); |
+ const int raster_mb = block >> (tx_size << 1); |
+ const int x = (raster_mb & (tx_cols - 1)) << tx_size; |
+ const int y = (raster_mb >> tx_cols_log2) << tx_size; |
return x + (y << bwl); |
} |
-static void txfrm_block_to_raster_xy(MACROBLOCKD *xd, |
- BLOCK_SIZE_TYPE bsize, |
- int plane, int block, |
- int ss_txfrm_size, |
+static void txfrm_block_to_raster_xy(BLOCK_SIZE plane_bsize, |
+ TX_SIZE tx_size, int block, |
int *x, int *y) { |
- const int bwl = b_width_log2(bsize) - xd->plane[plane].subsampling_x; |
- const int txwl = ss_txfrm_size / 2; |
- const int tx_cols_log2 = bwl - txwl; |
+ const int bwl = b_width_log2(plane_bsize); |
+ const int tx_cols_log2 = bwl - tx_size; |
const int tx_cols = 1 << tx_cols_log2; |
- const int raster_mb = block >> ss_txfrm_size; |
- *x = (raster_mb & (tx_cols - 1)) << (txwl); |
- *y = raster_mb >> tx_cols_log2 << (txwl); |
+ const int raster_mb = block >> (tx_size << 1); |
+ *x = (raster_mb & (tx_cols - 1)) << tx_size; |
+ *y = (raster_mb >> tx_cols_log2) << tx_size; |
} |
-static void extend_for_intra(MACROBLOCKD* const xd, int plane, int block, |
- BLOCK_SIZE_TYPE bsize, int ss_txfrm_size) { |
- const int bw = plane_block_width(bsize, &xd->plane[plane]); |
- const int bh = plane_block_height(bsize, &xd->plane[plane]); |
+static void extend_for_intra(MACROBLOCKD* const xd, BLOCK_SIZE plane_bsize, |
+ int plane, int block, TX_SIZE tx_size) { |
+ struct macroblockd_plane *const pd = &xd->plane[plane]; |
+ uint8_t *const buf = pd->dst.buf; |
+ const int stride = pd->dst.stride; |
+ |
int x, y; |
- txfrm_block_to_raster_xy(xd, bsize, plane, block, ss_txfrm_size, &x, &y); |
+ txfrm_block_to_raster_xy(plane_bsize, tx_size, block, &x, &y); |
x = x * 4 - 1; |
y = y * 4 - 1; |
// Copy a pixel into the umv if we are in a situation where the block size |
@@ -662,75 +508,80 @@ |
// TODO(JBB): Should be able to do the full extend in place so we don't have |
// to do this multiple times. |
if (xd->mb_to_right_edge < 0) { |
- int umv_border_start = bw |
- + (xd->mb_to_right_edge >> (3 + xd->plane[plane].subsampling_x)); |
+ const int bw = 4 << b_width_log2(plane_bsize); |
+ const int umv_border_start = bw + (xd->mb_to_right_edge >> |
+ (3 + pd->subsampling_x)); |
if (x + bw > umv_border_start) |
- vpx_memset( |
- xd->plane[plane].dst.buf + y * xd->plane[plane].dst.stride |
- + umv_border_start, |
- *(xd->plane[plane].dst.buf + y * xd->plane[plane].dst.stride |
- + umv_border_start - 1), |
- bw); |
+ vpx_memset(&buf[y * stride + umv_border_start], |
+ buf[y * stride + umv_border_start - 1], bw); |
} |
+ |
if (xd->mb_to_bottom_edge < 0) { |
- int umv_border_start = bh |
- + (xd->mb_to_bottom_edge >> (3 + xd->plane[plane].subsampling_y)); |
+ const int bh = 4 << b_height_log2(plane_bsize); |
+ const int umv_border_start = bh + (xd->mb_to_bottom_edge >> |
+ (3 + pd->subsampling_y)); |
int i; |
- uint8_t c = *(xd->plane[plane].dst.buf |
- + (umv_border_start - 1) * xd->plane[plane].dst.stride + x); |
+ const uint8_t c = buf[(umv_border_start - 1) * stride + x]; |
+ uint8_t *d = &buf[umv_border_start * stride + x]; |
- uint8_t *d = xd->plane[plane].dst.buf |
- + umv_border_start * xd->plane[plane].dst.stride + x; |
- |
if (y + bh > umv_border_start) |
- for (i = 0; i < bh; i++, d += xd->plane[plane].dst.stride) |
+ for (i = 0; i < bh; ++i, d += stride) |
*d = c; |
} |
} |
-static void set_contexts_on_border(MACROBLOCKD *xd, BLOCK_SIZE_TYPE bsize, |
- int plane, int ss_tx_size, int eob, int aoff, |
- int loff, ENTROPY_CONTEXT *A, |
- ENTROPY_CONTEXT *L) { |
- const int bw = b_width_log2(bsize), bh = b_height_log2(bsize); |
- const int sw = bw - xd->plane[plane].subsampling_x; |
- const int sh = bh - xd->plane[plane].subsampling_y; |
- int mi_blocks_wide = 1 << sw; |
- int mi_blocks_high = 1 << sh; |
- int tx_size_in_blocks = (1 << ss_tx_size); |
+static void set_contexts_on_border(MACROBLOCKD *xd, |
+ struct macroblockd_plane *pd, |
+ BLOCK_SIZE plane_bsize, |
+ int tx_size_in_blocks, int has_eob, |
+ int aoff, int loff, |
+ ENTROPY_CONTEXT *A, ENTROPY_CONTEXT *L) { |
+ int mi_blocks_wide = num_4x4_blocks_wide_lookup[plane_bsize]; |
+ int mi_blocks_high = num_4x4_blocks_high_lookup[plane_bsize]; |
int above_contexts = tx_size_in_blocks; |
int left_contexts = tx_size_in_blocks; |
int pt; |
// xd->mb_to_right_edge is in units of pixels * 8. This converts |
// it to 4x4 block sizes. |
- if (xd->mb_to_right_edge < 0) { |
- mi_blocks_wide += (xd->mb_to_right_edge |
- >> (5 + xd->plane[plane].subsampling_x)); |
- } |
+ if (xd->mb_to_right_edge < 0) |
+ mi_blocks_wide += (xd->mb_to_right_edge >> (5 + pd->subsampling_x)); |
+ if (xd->mb_to_bottom_edge < 0) |
+ mi_blocks_high += (xd->mb_to_bottom_edge >> (5 + pd->subsampling_y)); |
+ |
// this code attempts to avoid copying into contexts that are outside |
// our border. Any blocks that do are set to 0... |
if (above_contexts + aoff > mi_blocks_wide) |
above_contexts = mi_blocks_wide - aoff; |
- if (xd->mb_to_bottom_edge < 0) { |
- mi_blocks_high += (xd->mb_to_bottom_edge |
- >> (5 + xd->plane[plane].subsampling_y)); |
- } |
- if (left_contexts + loff > mi_blocks_high) { |
+ if (left_contexts + loff > mi_blocks_high) |
left_contexts = mi_blocks_high - loff; |
- } |
for (pt = 0; pt < above_contexts; pt++) |
- A[pt] = eob > 0; |
- for (pt = above_contexts; pt < (1 << ss_tx_size); pt++) |
+ A[pt] = has_eob; |
+ for (pt = above_contexts; pt < tx_size_in_blocks; pt++) |
A[pt] = 0; |
for (pt = 0; pt < left_contexts; pt++) |
- L[pt] = eob > 0; |
- for (pt = left_contexts; pt < (1 << ss_tx_size); pt++) |
+ L[pt] = has_eob; |
+ for (pt = left_contexts; pt < tx_size_in_blocks; pt++) |
L[pt] = 0; |
} |
+static void set_contexts(MACROBLOCKD *xd, struct macroblockd_plane *pd, |
+ BLOCK_SIZE plane_bsize, TX_SIZE tx_size, |
+ int has_eob, int aoff, int loff) { |
+ ENTROPY_CONTEXT *const A = pd->above_context + aoff; |
+ ENTROPY_CONTEXT *const L = pd->left_context + loff; |
+ const int tx_size_in_blocks = 1 << tx_size; |
+ if (xd->mb_to_right_edge < 0 || xd->mb_to_bottom_edge < 0) { |
+ set_contexts_on_border(xd, pd, plane_bsize, tx_size_in_blocks, has_eob, |
+ aoff, loff, A, L); |
+ } else { |
+ vpx_memset(A, has_eob, sizeof(ENTROPY_CONTEXT) * tx_size_in_blocks); |
+ vpx_memset(L, has_eob, sizeof(ENTROPY_CONTEXT) * tx_size_in_blocks); |
+ } |
+} |
+ |
#endif // VP9_COMMON_VP9_BLOCKD_H_ |