| Index: source/libvpx/vp9/common/vp9_blockd.h
|
| ===================================================================
|
| --- source/libvpx/vp9/common/vp9_blockd.h (revision 240950)
|
| +++ source/libvpx/vp9/common/vp9_blockd.h (working copy)
|
| @@ -26,8 +26,9 @@
|
| #include "vp9/common/vp9_seg_common.h"
|
| #include "vp9/common/vp9_treecoder.h"
|
|
|
| -#define BLOCK_SIZE_GROUPS 4
|
| +#define BLOCK_SIZE_GROUPS 4
|
| #define MBSKIP_CONTEXTS 3
|
| +#define INTER_MODE_CONTEXTS 7
|
|
|
| /* Segment Feature Masks */
|
| #define MAX_MV_REF_CANDIDATES 2
|
| @@ -37,8 +38,9 @@
|
| #define REF_CONTEXTS 5
|
|
|
| typedef enum {
|
| - PLANE_TYPE_Y_WITH_DC,
|
| - PLANE_TYPE_UV,
|
| + PLANE_TYPE_Y = 0,
|
| + PLANE_TYPE_UV = 1,
|
| + PLANE_TYPES
|
| } PLANE_TYPE;
|
|
|
| typedef char ENTROPY_CONTEXT;
|
| @@ -74,10 +76,6 @@
|
| MB_MODE_COUNT
|
| } MB_PREDICTION_MODE;
|
|
|
| -static INLINE int is_intra_mode(MB_PREDICTION_MODE mode) {
|
| - return mode <= TM_PRED;
|
| -}
|
| -
|
| static INLINE int is_inter_mode(MB_PREDICTION_MODE mode) {
|
| return mode >= NEARESTMV && mode <= NEWMV;
|
| }
|
| @@ -86,10 +84,9 @@
|
|
|
| #define INTER_MODES (1 + NEWMV - NEARESTMV)
|
|
|
| -static INLINE int inter_mode_offset(MB_PREDICTION_MODE mode) {
|
| - return (mode - NEARESTMV);
|
| -}
|
| +#define INTER_OFFSET(mode) ((mode) - NEARESTMV)
|
|
|
| +
|
| /* For keyframes, intra block modes are predicted by the (already decoded)
|
| modes for the Y blocks to the left and above us; for interframes, there
|
| is a single probability table. */
|
| @@ -158,6 +155,34 @@
|
| return mbmi->ref_frame[1] > INTRA_FRAME;
|
| }
|
|
|
| +static MB_PREDICTION_MODE left_block_mode(const MODE_INFO *cur_mi,
|
| + const MODE_INFO *left_mi, int b) {
|
| + if (b == 0 || b == 2) {
|
| + if (!left_mi || is_inter_block(&left_mi->mbmi))
|
| + return DC_PRED;
|
| +
|
| + return left_mi->mbmi.sb_type < BLOCK_8X8 ? left_mi->bmi[b + 1].as_mode
|
| + : left_mi->mbmi.mode;
|
| + } else {
|
| + assert(b == 1 || b == 3);
|
| + return cur_mi->bmi[b - 1].as_mode;
|
| + }
|
| +}
|
| +
|
| +static MB_PREDICTION_MODE above_block_mode(const MODE_INFO *cur_mi,
|
| + const MODE_INFO *above_mi, int b) {
|
| + if (b == 0 || b == 1) {
|
| + if (!above_mi || is_inter_block(&above_mi->mbmi))
|
| + return DC_PRED;
|
| +
|
| + return above_mi->mbmi.sb_type < BLOCK_8X8 ? above_mi->bmi[b + 2].as_mode
|
| + : above_mi->mbmi.mode;
|
| + } else {
|
| + assert(b == 2 || b == 3);
|
| + return cur_mi->bmi[b - 2].as_mode;
|
| + }
|
| +}
|
| +
|
| enum mv_precision {
|
| MV_PRECISION_Q3,
|
| MV_PRECISION_Q4
|
| @@ -175,9 +200,7 @@
|
| };
|
|
|
| struct macroblockd_plane {
|
| - DECLARE_ALIGNED(16, int16_t, qcoeff[64 * 64]);
|
| - DECLARE_ALIGNED(16, int16_t, dqcoeff[64 * 64]);
|
| - DECLARE_ALIGNED(16, uint16_t, eobs[256]);
|
| + int16_t *dqcoeff;
|
| PLANE_TYPE plane_type;
|
| int subsampling_x;
|
| int subsampling_y;
|
| @@ -212,6 +235,9 @@
|
| int mb_to_top_edge;
|
| int mb_to_bottom_edge;
|
|
|
| + /* pointers to reference frames */
|
| + const YV12_BUFFER_CONFIG *ref_buf[2];
|
| +
|
| int lossless;
|
| /* Inverse transform function pointers. */
|
| void (*itxm_add)(const int16_t *input, uint8_t *dest, int stride, int eob);
|
| @@ -220,13 +246,6 @@
|
|
|
| int corrupted;
|
|
|
| - unsigned char sb_index; // index of 32x32 block inside the 64x64 block
|
| - unsigned char mb_index; // index of 16x16 block inside the 32x32 block
|
| - unsigned char b_index; // index of 8x8 block inside the 16x16 block
|
| - unsigned char ab_index; // index of 4x4 block inside the 8x8 block
|
| -
|
| - int q_index;
|
| -
|
| /* Y,U,V,(A) */
|
| ENTROPY_CONTEXT *above_context[MAX_MB_PLANE];
|
| ENTROPY_CONTEXT left_context[MAX_MB_PLANE][16];
|
| @@ -250,45 +269,53 @@
|
| const MODE_INFO *const mi = xd->mi_8x8[0];
|
| const MB_MODE_INFO *const mbmi = &mi->mbmi;
|
|
|
| - if (plane_type != PLANE_TYPE_Y_WITH_DC ||
|
| - xd->lossless ||
|
| - is_inter_block(mbmi))
|
| + if (plane_type != PLANE_TYPE_Y || xd->lossless || is_inter_block(mbmi))
|
| return DCT_DCT;
|
|
|
| - return mode2txfm_map[mbmi->sb_type < BLOCK_8X8 ?
|
| - mi->bmi[ib].as_mode : mbmi->mode];
|
| + return mode2txfm_map[mbmi->sb_type < BLOCK_8X8 ? mi->bmi[ib].as_mode
|
| + : mbmi->mode];
|
| }
|
|
|
| static INLINE TX_TYPE get_tx_type_8x8(PLANE_TYPE plane_type,
|
| const MACROBLOCKD *xd) {
|
| - return plane_type == PLANE_TYPE_Y_WITH_DC ?
|
| - mode2txfm_map[xd->mi_8x8[0]->mbmi.mode] : DCT_DCT;
|
| + return plane_type == PLANE_TYPE_Y ? mode2txfm_map[xd->mi_8x8[0]->mbmi.mode]
|
| + : DCT_DCT;
|
| }
|
|
|
| static INLINE TX_TYPE get_tx_type_16x16(PLANE_TYPE plane_type,
|
| const MACROBLOCKD *xd) {
|
| - return plane_type == PLANE_TYPE_Y_WITH_DC ?
|
| - mode2txfm_map[xd->mi_8x8[0]->mbmi.mode] : DCT_DCT;
|
| + return plane_type == PLANE_TYPE_Y ? mode2txfm_map[xd->mi_8x8[0]->mbmi.mode]
|
| + : DCT_DCT;
|
| }
|
|
|
| static void setup_block_dptrs(MACROBLOCKD *xd, int ss_x, int ss_y) {
|
| int i;
|
|
|
| for (i = 0; i < MAX_MB_PLANE; i++) {
|
| - xd->plane[i].plane_type = i ? PLANE_TYPE_UV : PLANE_TYPE_Y_WITH_DC;
|
| + xd->plane[i].plane_type = i ? PLANE_TYPE_UV : PLANE_TYPE_Y;
|
| xd->plane[i].subsampling_x = i ? ss_x : 0;
|
| xd->plane[i].subsampling_y = i ? ss_y : 0;
|
| }
|
| #if CONFIG_ALPHA
|
| // TODO(jkoleszar): Using the Y w/h for now
|
| + xd->plane[3].plane_type = PLANE_TYPE_Y;
|
| xd->plane[3].subsampling_x = 0;
|
| xd->plane[3].subsampling_y = 0;
|
| #endif
|
| }
|
|
|
| +static TX_SIZE get_uv_tx_size_impl(TX_SIZE y_tx_size, BLOCK_SIZE bsize) {
|
| + if (bsize < BLOCK_8X8) {
|
| + return TX_4X4;
|
| + } else {
|
| + // TODO(dkovalev): Assuming YUV420 (ss_x == 1, ss_y == 1)
|
| + const BLOCK_SIZE plane_bsize = ss_size_lookup[bsize][1][1];
|
| + return MIN(y_tx_size, max_txsize_lookup[plane_bsize]);
|
| + }
|
| +}
|
|
|
| -static INLINE TX_SIZE get_uv_tx_size(const MB_MODE_INFO *mbmi) {
|
| - return MIN(mbmi->tx_size, max_uv_txsize_lookup[mbmi->sb_type]);
|
| +static TX_SIZE get_uv_tx_size(const MB_MODE_INFO *mbmi) {
|
| + return get_uv_tx_size_impl(mbmi->tx_size, mbmi->sb_type);
|
| }
|
|
|
| static BLOCK_SIZE get_plane_block_size(BLOCK_SIZE bsize,
|
| @@ -298,16 +325,6 @@
|
| return bs;
|
| }
|
|
|
| -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 bsize,
|
| - const struct macroblockd_plane* plane) {
|
| - return 4 << (b_height_log2(bsize) - plane->subsampling_y);
|
| -}
|
| -
|
| typedef void (*foreach_transformed_block_visitor)(int plane, int block,
|
| BLOCK_SIZE plane_bsize,
|
| TX_SIZE tx_size,
|
| @@ -381,35 +398,6 @@
|
| foreach_transformed_block_in_plane(xd, bsize, plane, visit, arg);
|
| }
|
|
|
| -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(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(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(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 >> (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(BLOCK_SIZE plane_bsize,
|
| TX_SIZE tx_size, int block,
|
| int *x, int *y) {
|
| @@ -421,22 +409,19 @@
|
| *y = (raster_mb >> tx_cols_log2) << tx_size;
|
| }
|
|
|
| -static void extend_for_intra(MACROBLOCKD* const xd, BLOCK_SIZE plane_bsize,
|
| - int plane, int block, TX_SIZE tx_size) {
|
| +static void extend_for_intra(MACROBLOCKD *xd, BLOCK_SIZE plane_bsize,
|
| + int plane, int aoff, int loff) {
|
| 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(plane_bsize, tx_size, block, &x, &y);
|
| - x = x * 4 - 1;
|
| - y = y * 4 - 1;
|
| + const int x = aoff * 4 - 1;
|
| + const int y = loff * 4 - 1;
|
| // Copy a pixel into the umv if we are in a situation where the block size
|
| // extends into the UMV.
|
| // 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) {
|
| - const int bw = 4 << b_width_log2(plane_bsize);
|
| + const int bw = 4 * num_4x4_blocks_wide_lookup[plane_bsize];
|
| const int umv_border_start = bw + (xd->mb_to_right_edge >>
|
| (3 + pd->subsampling_x));
|
|
|
| @@ -447,7 +432,7 @@
|
|
|
| if (xd->mb_to_bottom_edge < 0) {
|
| if (xd->left_available || x >= 0) {
|
| - const int bh = 4 << b_height_log2(plane_bsize);
|
| + const int bh = 4 * num_4x4_blocks_high_lookup[plane_bsize];
|
| const int umv_border_start =
|
| bh + (xd->mb_to_bottom_edge >> (3 + pd->subsampling_y));
|
|
|
| @@ -461,58 +446,47 @@
|
| }
|
| }
|
| }
|
| -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 + 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 (left_contexts + loff > mi_blocks_high)
|
| - left_contexts = mi_blocks_high - loff;
|
| -
|
| - for (pt = 0; pt < above_contexts; 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] = 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,
|
| +static void set_contexts(const 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;
|
| + 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);
|
| + // above
|
| + if (has_eob && xd->mb_to_right_edge < 0) {
|
| + int i;
|
| + const int blocks_wide = num_4x4_blocks_wide_lookup[plane_bsize] +
|
| + (xd->mb_to_right_edge >> (5 + pd->subsampling_x));
|
| + int above_contexts = tx_size_in_blocks;
|
| + if (above_contexts + aoff > blocks_wide)
|
| + above_contexts = blocks_wide - aoff;
|
| +
|
| + for (i = 0; i < above_contexts; ++i)
|
| + a[i] = has_eob;
|
| + for (i = above_contexts; i < tx_size_in_blocks; ++i)
|
| + a[i] = 0;
|
| } 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);
|
| + vpx_memset(a, has_eob, sizeof(ENTROPY_CONTEXT) * tx_size_in_blocks);
|
| }
|
| +
|
| + // left
|
| + if (has_eob && xd->mb_to_bottom_edge < 0) {
|
| + int i;
|
| + const int blocks_high = num_4x4_blocks_high_lookup[plane_bsize] +
|
| + (xd->mb_to_bottom_edge >> (5 + pd->subsampling_y));
|
| + int left_contexts = tx_size_in_blocks;
|
| + if (left_contexts + loff > blocks_high)
|
| + left_contexts = blocks_high - loff;
|
| +
|
| + for (i = 0; i < left_contexts; ++i)
|
| + l[i] = has_eob;
|
| + for (i = left_contexts; i < tx_size_in_blocks; ++i)
|
| + l[i] = 0;
|
| + } else {
|
| + vpx_memset(l, has_eob, sizeof(ENTROPY_CONTEXT) * tx_size_in_blocks);
|
| + }
|
| }
|
|
|
| static int get_tx_eob(const struct segmentation *seg, int segment_id,
|
|
|