| 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,
 | 
| 
 |