Home | History | Annotate | Download | only in common
      1 /*
      2  *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
      3  *
      4  *  Use of this source code is governed by a BSD-style license
      5  *  that can be found in the LICENSE file in the root of the source
      6  *  tree. An additional intellectual property rights grant can be found
      7  *  in the file PATENTS.  All contributing project authors may
      8  *  be found in the AUTHORS file in the root of the source tree.
      9  */
     10 
     11 
     12 #ifndef VP9_COMMON_VP9_BLOCKD_H_
     13 #define VP9_COMMON_VP9_BLOCKD_H_
     14 
     15 #include "./vpx_config.h"
     16 
     17 #include "vpx_ports/mem.h"
     18 #include "vpx_scale/yv12config.h"
     19 
     20 #include "vp9/common/vp9_common.h"
     21 #include "vp9/common/vp9_common_data.h"
     22 #include "vp9/common/vp9_enums.h"
     23 #include "vp9/common/vp9_filter.h"
     24 #include "vp9/common/vp9_idct.h"
     25 #include "vp9/common/vp9_mv.h"
     26 #include "vp9/common/vp9_scale.h"
     27 #include "vp9/common/vp9_seg_common.h"
     28 
     29 #ifdef __cplusplus
     30 extern "C" {
     31 #endif
     32 
     33 #define BLOCK_SIZE_GROUPS 4
     34 #define SKIP_CONTEXTS 3
     35 #define INTER_MODE_CONTEXTS 7
     36 
     37 /* Segment Feature Masks */
     38 #define MAX_MV_REF_CANDIDATES 2
     39 
     40 #define INTRA_INTER_CONTEXTS 4
     41 #define COMP_INTER_CONTEXTS 5
     42 #define REF_CONTEXTS 5
     43 
     44 typedef enum {
     45   PLANE_TYPE_Y  = 0,
     46   PLANE_TYPE_UV = 1,
     47   PLANE_TYPES
     48 } PLANE_TYPE;
     49 
     50 typedef char ENTROPY_CONTEXT;
     51 
     52 typedef char PARTITION_CONTEXT;
     53 
     54 static INLINE int combine_entropy_contexts(ENTROPY_CONTEXT a,
     55                                            ENTROPY_CONTEXT b) {
     56   return (a != 0) + (b != 0);
     57 }
     58 
     59 typedef enum {
     60   KEY_FRAME = 0,
     61   INTER_FRAME = 1,
     62   FRAME_TYPES,
     63 } FRAME_TYPE;
     64 
     65 typedef enum {
     66   DC_PRED,         // Average of above and left pixels
     67   V_PRED,          // Vertical
     68   H_PRED,          // Horizontal
     69   D45_PRED,        // Directional 45  deg = round(arctan(1/1) * 180/pi)
     70   D135_PRED,       // Directional 135 deg = 180 - 45
     71   D117_PRED,       // Directional 117 deg = 180 - 63
     72   D153_PRED,       // Directional 153 deg = 180 - 27
     73   D207_PRED,       // Directional 207 deg = 180 + 27
     74   D63_PRED,        // Directional 63  deg = round(arctan(2/1) * 180/pi)
     75   TM_PRED,         // True-motion
     76   NEARESTMV,
     77   NEARMV,
     78   ZEROMV,
     79   NEWMV,
     80   MB_MODE_COUNT
     81 } PREDICTION_MODE;
     82 
     83 static INLINE int is_inter_mode(PREDICTION_MODE mode) {
     84   return mode >= NEARESTMV && mode <= NEWMV;
     85 }
     86 
     87 #define INTRA_MODES (TM_PRED + 1)
     88 
     89 #define INTER_MODES (1 + NEWMV - NEARESTMV)
     90 
     91 #define INTER_OFFSET(mode) ((mode) - NEARESTMV)
     92 
     93 /* For keyframes, intra block modes are predicted by the (already decoded)
     94    modes for the Y blocks to the left and above us; for interframes, there
     95    is a single probability table. */
     96 
     97 typedef struct {
     98   PREDICTION_MODE as_mode;
     99   int_mv as_mv[2];  // first, second inter predictor motion vectors
    100 } b_mode_info;
    101 
    102 // Note that the rate-distortion optimization loop, bit-stream writer, and
    103 // decoder implementation modules critically rely on the enum entry values
    104 // specified herein. They should be refactored concurrently.
    105 typedef enum {
    106   NONE = -1,
    107   INTRA_FRAME = 0,
    108   LAST_FRAME = 1,
    109   GOLDEN_FRAME = 2,
    110   ALTREF_FRAME = 3,
    111   MAX_REF_FRAMES = 4
    112 } MV_REFERENCE_FRAME;
    113 
    114 static INLINE int b_width_log2(BLOCK_SIZE sb_type) {
    115   return b_width_log2_lookup[sb_type];
    116 }
    117 static INLINE int b_height_log2(BLOCK_SIZE sb_type) {
    118   return b_height_log2_lookup[sb_type];
    119 }
    120 
    121 static INLINE int mi_width_log2(BLOCK_SIZE sb_type) {
    122   return mi_width_log2_lookup[sb_type];
    123 }
    124 
    125 // This structure now relates to 8x8 block regions.
    126 typedef struct {
    127   // Common for both INTER and INTRA blocks
    128   BLOCK_SIZE sb_type;
    129   PREDICTION_MODE mode;
    130   TX_SIZE tx_size;
    131   int8_t skip;
    132   int8_t segment_id;
    133   int8_t seg_id_predicted;  // valid only when temporal_update is enabled
    134 
    135   // Only for INTRA blocks
    136   PREDICTION_MODE uv_mode;
    137 
    138   // Only for INTER blocks
    139   MV_REFERENCE_FRAME ref_frame[2];
    140   int_mv mv[2];
    141   int_mv ref_mvs[MAX_REF_FRAMES][MAX_MV_REF_CANDIDATES];
    142   uint8_t mode_context[MAX_REF_FRAMES];
    143   INTERP_FILTER interp_filter;
    144 } MB_MODE_INFO;
    145 
    146 typedef struct MODE_INFO {
    147   struct MODE_INFO *src_mi;
    148   MB_MODE_INFO mbmi;
    149   b_mode_info bmi[4];
    150 } MODE_INFO;
    151 
    152 static INLINE PREDICTION_MODE get_y_mode(const MODE_INFO *mi, int block) {
    153   return mi->mbmi.sb_type < BLOCK_8X8 ? mi->bmi[block].as_mode
    154                                       : mi->mbmi.mode;
    155 }
    156 
    157 static INLINE int is_inter_block(const MB_MODE_INFO *mbmi) {
    158   return mbmi->ref_frame[0] > INTRA_FRAME;
    159 }
    160 
    161 static INLINE int has_second_ref(const MB_MODE_INFO *mbmi) {
    162   return mbmi->ref_frame[1] > INTRA_FRAME;
    163 }
    164 
    165 PREDICTION_MODE vp9_left_block_mode(const MODE_INFO *cur_mi,
    166                                     const MODE_INFO *left_mi, int b);
    167 
    168 PREDICTION_MODE vp9_above_block_mode(const MODE_INFO *cur_mi,
    169                                      const MODE_INFO *above_mi, int b);
    170 
    171 enum mv_precision {
    172   MV_PRECISION_Q3,
    173   MV_PRECISION_Q4
    174 };
    175 
    176 enum { MAX_MB_PLANE = 3 };
    177 
    178 struct buf_2d {
    179   uint8_t *buf;
    180   int stride;
    181 };
    182 
    183 struct macroblockd_plane {
    184   tran_low_t *dqcoeff;
    185   PLANE_TYPE plane_type;
    186   int subsampling_x;
    187   int subsampling_y;
    188   struct buf_2d dst;
    189   struct buf_2d pre[2];
    190   const int16_t *dequant;
    191   ENTROPY_CONTEXT *above_context;
    192   ENTROPY_CONTEXT *left_context;
    193 };
    194 
    195 #define BLOCK_OFFSET(x, i) ((x) + (i) * 16)
    196 
    197 typedef struct RefBuffer {
    198   // TODO(dkovalev): idx is not really required and should be removed, now it
    199   // is used in vp9_onyxd_if.c
    200   int idx;
    201   YV12_BUFFER_CONFIG *buf;
    202   struct scale_factors sf;
    203 } RefBuffer;
    204 
    205 typedef struct macroblockd {
    206   struct macroblockd_plane plane[MAX_MB_PLANE];
    207 
    208   int mi_stride;
    209 
    210   MODE_INFO *mi;
    211 
    212   int up_available;
    213   int left_available;
    214 
    215   /* Distance of MB away from frame edges */
    216   int mb_to_left_edge;
    217   int mb_to_right_edge;
    218   int mb_to_top_edge;
    219   int mb_to_bottom_edge;
    220 
    221   /* pointers to reference frames */
    222   RefBuffer *block_refs[2];
    223 
    224   /* pointer to current frame */
    225   const YV12_BUFFER_CONFIG *cur_buf;
    226 
    227   /* mc buffer */
    228   DECLARE_ALIGNED(16, uint8_t, mc_buf[80 * 2 * 80 * 2]);
    229 
    230 #if CONFIG_VP9_HIGHBITDEPTH
    231   /* Bit depth: 8, 10, 12 */
    232   int bd;
    233   DECLARE_ALIGNED(16, uint16_t, mc_buf_high[80 * 2 * 80 * 2]);
    234 #endif
    235 
    236   int lossless;
    237 
    238   int corrupted;
    239 
    240   DECLARE_ALIGNED(16, tran_low_t, dqcoeff[MAX_MB_PLANE][64 * 64]);
    241 
    242   ENTROPY_CONTEXT *above_context[MAX_MB_PLANE];
    243   ENTROPY_CONTEXT left_context[MAX_MB_PLANE][16];
    244 
    245   PARTITION_CONTEXT *above_seg_context;
    246   PARTITION_CONTEXT left_seg_context[8];
    247 } MACROBLOCKD;
    248 
    249 static INLINE BLOCK_SIZE get_subsize(BLOCK_SIZE bsize,
    250                                      PARTITION_TYPE partition) {
    251   return subsize_lookup[partition][bsize];
    252 }
    253 
    254 extern const TX_TYPE intra_mode_to_tx_type_lookup[INTRA_MODES];
    255 
    256 static INLINE TX_TYPE get_tx_type(PLANE_TYPE plane_type,
    257                                   const MACROBLOCKD *xd) {
    258   const MB_MODE_INFO *const mbmi = &xd->mi[0].src_mi->mbmi;
    259 
    260   if (plane_type != PLANE_TYPE_Y || is_inter_block(mbmi))
    261     return DCT_DCT;
    262   return intra_mode_to_tx_type_lookup[mbmi->mode];
    263 }
    264 
    265 static INLINE TX_TYPE get_tx_type_4x4(PLANE_TYPE plane_type,
    266                                       const MACROBLOCKD *xd, int ib) {
    267   const MODE_INFO *const mi = xd->mi[0].src_mi;
    268 
    269   if (plane_type != PLANE_TYPE_Y || xd->lossless || is_inter_block(&mi->mbmi))
    270     return DCT_DCT;
    271 
    272   return intra_mode_to_tx_type_lookup[get_y_mode(mi, ib)];
    273 }
    274 
    275 void vp9_setup_block_planes(MACROBLOCKD *xd, int ss_x, int ss_y);
    276 
    277 static INLINE TX_SIZE get_uv_tx_size_impl(TX_SIZE y_tx_size, BLOCK_SIZE bsize,
    278                                           int xss, int yss) {
    279   if (bsize < BLOCK_8X8) {
    280     return TX_4X4;
    281   } else {
    282     const BLOCK_SIZE plane_bsize = ss_size_lookup[bsize][xss][yss];
    283     return MIN(y_tx_size, max_txsize_lookup[plane_bsize]);
    284   }
    285 }
    286 
    287 static INLINE TX_SIZE get_uv_tx_size(const MB_MODE_INFO *mbmi,
    288                                      const struct macroblockd_plane *pd) {
    289   return get_uv_tx_size_impl(mbmi->tx_size, mbmi->sb_type, pd->subsampling_x,
    290                              pd->subsampling_y);
    291 }
    292 
    293 static INLINE BLOCK_SIZE get_plane_block_size(BLOCK_SIZE bsize,
    294     const struct macroblockd_plane *pd) {
    295   return ss_size_lookup[bsize][pd->subsampling_x][pd->subsampling_y];
    296 }
    297 
    298 typedef void (*foreach_transformed_block_visitor)(int plane, int block,
    299                                                   BLOCK_SIZE plane_bsize,
    300                                                   TX_SIZE tx_size,
    301                                                   void *arg);
    302 
    303 void vp9_foreach_transformed_block_in_plane(
    304     const MACROBLOCKD *const xd, BLOCK_SIZE bsize, int plane,
    305     foreach_transformed_block_visitor visit, void *arg);
    306 
    307 
    308 void vp9_foreach_transformed_block(
    309     const MACROBLOCKD* const xd, BLOCK_SIZE bsize,
    310     foreach_transformed_block_visitor visit, void *arg);
    311 
    312 static INLINE void txfrm_block_to_raster_xy(BLOCK_SIZE plane_bsize,
    313                                             TX_SIZE tx_size, int block,
    314                                             int *x, int *y) {
    315   const int bwl = b_width_log2(plane_bsize);
    316   const int tx_cols_log2 = bwl - tx_size;
    317   const int tx_cols = 1 << tx_cols_log2;
    318   const int raster_mb = block >> (tx_size << 1);
    319   *x = (raster_mb & (tx_cols - 1)) << tx_size;
    320   *y = (raster_mb >> tx_cols_log2) << tx_size;
    321 }
    322 
    323 void vp9_set_contexts(const MACROBLOCKD *xd, struct macroblockd_plane *pd,
    324                       BLOCK_SIZE plane_bsize, TX_SIZE tx_size, int has_eob,
    325                       int aoff, int loff);
    326 
    327 #ifdef __cplusplus
    328 }  // extern "C"
    329 #endif
    330 
    331 #endif  // VP9_COMMON_VP9_BLOCKD_H_
    332