Home | History | Annotate | Download | only in common
      1 
      2 /*
      3  *  Copyright (c) 2012 The WebM project authors. All Rights Reserved.
      4  *
      5  *  Use of this source code is governed by a BSD-style license
      6  *  that can be found in the LICENSE file in the root of the source
      7  *  tree. An additional intellectual property rights grant can be found
      8  *  in the file PATENTS.  All contributing project authors may
      9  *  be found in the AUTHORS file in the root of the source tree.
     10  */
     11 
     12 #include <limits.h>
     13 
     14 #include "vp9/common/vp9_common.h"
     15 #include "vp9/common/vp9_pred_common.h"
     16 #include "vp9/common/vp9_seg_common.h"
     17 #include "vp9/common/vp9_treecoder.h"
     18 
     19 // Returns a context number for the given MB prediction signal
     20 unsigned char vp9_get_pred_context_switchable_interp(const MACROBLOCKD *xd) {
     21   const MODE_INFO * const above_mi = xd->mi_8x8[-xd->mode_info_stride];
     22   const MODE_INFO * const left_mi = xd->mi_8x8[-1];
     23   const int left_in_image = xd->left_available && left_mi;
     24   const int above_in_image = xd->up_available && above_mi;
     25   // Note:
     26   // The mode info data structure has a one element border above and to the
     27   // left of the entries correpsonding to real macroblocks.
     28   // The prediction flags in these dummy entries are initialised to 0.
     29   // left
     30   const int left_mv_pred = left_in_image ? is_inter_mode(left_mi->mbmi.mode)
     31                                          : 0;
     32   const int left_interp = left_in_image && left_mv_pred
     33                               ? left_mi->mbmi.interp_filter
     34                               : SWITCHABLE_FILTERS;
     35 
     36   // above
     37   const int above_mv_pred = above_in_image ? is_inter_mode(above_mi->mbmi.mode)
     38                                            : 0;
     39   const int above_interp = above_in_image && above_mv_pred
     40                                ? above_mi->mbmi.interp_filter
     41                                : SWITCHABLE_FILTERS;
     42 
     43   if (left_interp == above_interp)
     44     return left_interp;
     45   else if (left_interp == SWITCHABLE_FILTERS &&
     46            above_interp != SWITCHABLE_FILTERS)
     47     return above_interp;
     48   else if (left_interp != SWITCHABLE_FILTERS &&
     49            above_interp == SWITCHABLE_FILTERS)
     50     return left_interp;
     51   else
     52     return SWITCHABLE_FILTERS;
     53 }
     54 // Returns a context number for the given MB prediction signal
     55 unsigned char vp9_get_pred_context_intra_inter(const MACROBLOCKD *xd) {
     56   const MODE_INFO * const above_mi = xd->mi_8x8[-xd->mode_info_stride];
     57   const MODE_INFO * const left_mi = xd->mi_8x8[-1];
     58   const MB_MODE_INFO *const above_mbmi = above_mi ? &above_mi->mbmi : 0;
     59   const MB_MODE_INFO *const left_mbmi = left_mi ? &left_mi->mbmi : 0;
     60   const int left_in_image = xd->left_available && left_mi;
     61   const int above_in_image = xd->up_available && above_mi;
     62   const int left_intra = left_in_image ? !is_inter_block(left_mbmi) : 1;
     63   const int above_intra = above_in_image ? !is_inter_block(above_mbmi) : 1;
     64 
     65   // The mode info data structure has a one element border above and to the
     66   // left of the entries corresponding to real macroblocks.
     67   // The prediction flags in these dummy entries are initialized to 0.
     68   // 0 - inter/inter, inter/--, --/inter, --/--
     69   // 1 - intra/inter, inter/intra
     70   // 2 - intra/--, --/intra
     71   // 3 - intra/intra
     72   if (above_in_image && left_in_image)  // both edges available
     73     return left_intra && above_intra ? 3
     74                                      : left_intra || above_intra;
     75   else if (above_in_image || left_in_image)  // one edge available
     76     return 2 * (above_in_image ? above_intra : left_intra);
     77   else
     78     return 0;
     79 }
     80 // Returns a context number for the given MB prediction signal
     81 unsigned char vp9_get_pred_context_comp_inter_inter(const VP9_COMMON *cm,
     82                                                     const MACROBLOCKD *xd) {
     83   int pred_context;
     84   const MODE_INFO * const above_mi = xd->mi_8x8[-xd->mode_info_stride];
     85   const MODE_INFO * const left_mi = xd->mi_8x8[-1];
     86   const MB_MODE_INFO *const above_mbmi = above_mi ? &above_mi->mbmi : 0;
     87   const MB_MODE_INFO *const left_mbmi = left_mi ? &left_mi->mbmi : 0;
     88   const int left_in_image = xd->left_available && left_mi;
     89   const int above_in_image = xd->up_available && above_mi;
     90   // Note:
     91   // The mode info data structure has a one element border above and to the
     92   // left of the entries correpsonding to real macroblocks.
     93   // The prediction flags in these dummy entries are initialised to 0.
     94   if (above_in_image && left_in_image) {  // both edges available
     95     if (!has_second_ref(above_mbmi) && !has_second_ref(left_mbmi))
     96       // neither edge uses comp pred (0/1)
     97       pred_context = (above_mbmi->ref_frame[0] == cm->comp_fixed_ref) ^
     98                      (left_mbmi->ref_frame[0] == cm->comp_fixed_ref);
     99     else if (!has_second_ref(above_mbmi))
    100       // one of two edges uses comp pred (2/3)
    101       pred_context = 2 + (above_mbmi->ref_frame[0] == cm->comp_fixed_ref ||
    102                           !is_inter_block(above_mbmi));
    103     else if (!has_second_ref(left_mbmi))
    104       // one of two edges uses comp pred (2/3)
    105       pred_context = 2 + (left_mbmi->ref_frame[0] == cm->comp_fixed_ref ||
    106                           !is_inter_block(left_mbmi));
    107     else  // both edges use comp pred (4)
    108       pred_context = 4;
    109   } else if (above_in_image || left_in_image) {  // one edge available
    110     const MB_MODE_INFO *edge_mbmi = above_in_image ? above_mbmi : left_mbmi;
    111 
    112     if (!has_second_ref(edge_mbmi))
    113       // edge does not use comp pred (0/1)
    114       pred_context = edge_mbmi->ref_frame[0] == cm->comp_fixed_ref;
    115     else
    116       // edge uses comp pred (3)
    117       pred_context = 3;
    118   } else {  // no edges available (1)
    119     pred_context = 1;
    120   }
    121   assert(pred_context >= 0 && pred_context < COMP_INTER_CONTEXTS);
    122   return pred_context;
    123 }
    124 
    125 // Returns a context number for the given MB prediction signal
    126 unsigned char vp9_get_pred_context_comp_ref_p(const VP9_COMMON *cm,
    127                                               const MACROBLOCKD *xd) {
    128   int pred_context;
    129   const MODE_INFO * const above_mi = xd->mi_8x8[-cm->mode_info_stride];
    130   const MODE_INFO * const left_mi = xd->mi_8x8[-1];
    131   const MB_MODE_INFO *const above_mbmi = above_mi ? &above_mi->mbmi : 0;
    132   const MB_MODE_INFO *const left_mbmi = left_mi ? &left_mi->mbmi : 0;
    133   const int left_in_image = xd->left_available && left_mi;
    134   const int above_in_image = xd->up_available && above_mi;
    135   const int left_intra = left_in_image ? !is_inter_block(left_mbmi) : 1;
    136   const int above_intra = above_in_image ? !is_inter_block(above_mbmi) : 1;
    137   // Note:
    138   // The mode info data structure has a one element border above and to the
    139   // left of the entries correpsonding to real macroblocks.
    140   // The prediction flags in these dummy entries are initialised to 0.
    141   const int fix_ref_idx = cm->ref_frame_sign_bias[cm->comp_fixed_ref];
    142   const int var_ref_idx = !fix_ref_idx;
    143 
    144   if (above_in_image && left_in_image) {  // both edges available
    145     if (above_intra && left_intra) {  // intra/intra (2)
    146       pred_context = 2;
    147     } else if (above_intra || left_intra) {  // intra/inter
    148       const MB_MODE_INFO *edge_mbmi = above_intra ? left_mbmi : above_mbmi;
    149 
    150       if (!has_second_ref(edge_mbmi))  // single pred (1/3)
    151         pred_context = 1 + 2 * (edge_mbmi->ref_frame[0] != cm->comp_var_ref[1]);
    152       else  // comp pred (1/3)
    153         pred_context = 1 + 2 * (edge_mbmi->ref_frame[var_ref_idx]
    154                                     != cm->comp_var_ref[1]);
    155     } else {  // inter/inter
    156       const int l_sg = !has_second_ref(left_mbmi);
    157       const int a_sg = !has_second_ref(above_mbmi);
    158       MV_REFERENCE_FRAME vrfa = a_sg ? above_mbmi->ref_frame[0]
    159                                      : above_mbmi->ref_frame[var_ref_idx];
    160       MV_REFERENCE_FRAME vrfl = l_sg ? left_mbmi->ref_frame[0]
    161                                      : left_mbmi->ref_frame[var_ref_idx];
    162 
    163       if (vrfa == vrfl && cm->comp_var_ref[1] == vrfa) {
    164         pred_context = 0;
    165       } else if (l_sg && a_sg) {  // single/single
    166         if ((vrfa == cm->comp_fixed_ref && vrfl == cm->comp_var_ref[0]) ||
    167             (vrfl == cm->comp_fixed_ref && vrfa == cm->comp_var_ref[0]))
    168           pred_context = 4;
    169         else if (vrfa == vrfl)
    170           pred_context = 3;
    171         else
    172           pred_context = 1;
    173       } else if (l_sg || a_sg) {  // single/comp
    174         MV_REFERENCE_FRAME vrfc = l_sg ? vrfa : vrfl;
    175         MV_REFERENCE_FRAME rfs = a_sg ? vrfa : vrfl;
    176         if (vrfc == cm->comp_var_ref[1] && rfs != cm->comp_var_ref[1])
    177           pred_context = 1;
    178         else if (rfs == cm->comp_var_ref[1] && vrfc != cm->comp_var_ref[1])
    179           pred_context = 2;
    180         else
    181           pred_context = 4;
    182       } else if (vrfa == vrfl) {  // comp/comp
    183         pred_context = 4;
    184       } else {
    185         pred_context = 2;
    186       }
    187     }
    188   } else if (above_in_image || left_in_image) {  // one edge available
    189     const MB_MODE_INFO *edge_mbmi = above_in_image ? above_mbmi : left_mbmi;
    190 
    191     if (!is_inter_block(edge_mbmi)) {
    192       pred_context = 2;
    193     } else {
    194       if (has_second_ref(edge_mbmi))
    195         pred_context = 4 * (edge_mbmi->ref_frame[var_ref_idx]
    196                               != cm->comp_var_ref[1]);
    197       else
    198         pred_context = 3 * (edge_mbmi->ref_frame[0] != cm->comp_var_ref[1]);
    199     }
    200   } else {  // no edges available (2)
    201     pred_context = 2;
    202   }
    203   assert(pred_context >= 0 && pred_context < REF_CONTEXTS);
    204 
    205   return pred_context;
    206 }
    207 unsigned char vp9_get_pred_context_single_ref_p1(const MACROBLOCKD *xd) {
    208   int pred_context;
    209   const MODE_INFO * const above_mi = xd->mi_8x8[-xd->mode_info_stride];
    210   const MODE_INFO * const left_mi = xd->mi_8x8[-1];
    211   const MB_MODE_INFO *const above_mbmi = above_mi ? &above_mi->mbmi : 0;
    212   const MB_MODE_INFO *const left_mbmi = left_mi ? &left_mi->mbmi : 0;
    213   const int left_in_image = xd->left_available && left_mi;
    214   const int above_in_image = xd->up_available && above_mi;
    215   const int left_intra = left_in_image ? !is_inter_block(left_mbmi) : 1;
    216   const int above_intra = above_in_image ? !is_inter_block(above_mbmi) : 1;
    217   // Note:
    218   // The mode info data structure has a one element border above and to the
    219   // left of the entries correpsonding to real macroblocks.
    220   // The prediction flags in these dummy entries are initialised to 0.
    221   if (above_in_image && left_in_image) {  // both edges available
    222     if (above_intra && left_intra) {  // intra/intra
    223       pred_context = 2;
    224     } else if (above_intra || left_intra) {  // intra/inter or inter/intra
    225       const MB_MODE_INFO *edge_mbmi = above_intra ? left_mbmi : above_mbmi;
    226       if (!has_second_ref(edge_mbmi))
    227         pred_context = 4 * (edge_mbmi->ref_frame[0] == LAST_FRAME);
    228       else
    229         pred_context = 1 + (edge_mbmi->ref_frame[0] == LAST_FRAME ||
    230                             edge_mbmi->ref_frame[1] == LAST_FRAME);
    231     } else {  // inter/inter
    232       if (!has_second_ref(above_mbmi) && !has_second_ref(left_mbmi)) {
    233         pred_context = 2 * (above_mbmi->ref_frame[0] == LAST_FRAME) +
    234                        2 * (left_mbmi->ref_frame[0] == LAST_FRAME);
    235       } else if (has_second_ref(above_mbmi) && has_second_ref(left_mbmi)) {
    236         pred_context = 1 + (above_mbmi->ref_frame[0] == LAST_FRAME ||
    237                             above_mbmi->ref_frame[1] == LAST_FRAME ||
    238                             left_mbmi->ref_frame[0] == LAST_FRAME ||
    239                             left_mbmi->ref_frame[1] == LAST_FRAME);
    240       } else {
    241         const MV_REFERENCE_FRAME rfs = !has_second_ref(above_mbmi) ?
    242                   above_mbmi->ref_frame[0] : left_mbmi->ref_frame[0];
    243         const MV_REFERENCE_FRAME crf1 = has_second_ref(above_mbmi) ?
    244                   above_mbmi->ref_frame[0] : left_mbmi->ref_frame[0];
    245         const MV_REFERENCE_FRAME crf2 = has_second_ref(above_mbmi) ?
    246                   above_mbmi->ref_frame[1] : left_mbmi->ref_frame[1];
    247 
    248         if (rfs == LAST_FRAME)
    249           pred_context = 3 + (crf1 == LAST_FRAME || crf2 == LAST_FRAME);
    250         else
    251           pred_context = crf1 == LAST_FRAME || crf2 == LAST_FRAME;
    252       }
    253     }
    254   } else if (above_in_image || left_in_image) {  // one edge available
    255     const MB_MODE_INFO *edge_mbmi = above_in_image ? above_mbmi : left_mbmi;
    256     if (!is_inter_block(edge_mbmi)) {  // intra
    257       pred_context = 2;
    258     } else {  // inter
    259       if (!has_second_ref(edge_mbmi))
    260         pred_context = 4 * (edge_mbmi->ref_frame[0] == LAST_FRAME);
    261       else
    262         pred_context = 1 + (edge_mbmi->ref_frame[0] == LAST_FRAME ||
    263                             edge_mbmi->ref_frame[1] == LAST_FRAME);
    264     }
    265   } else {  // no edges available
    266     pred_context = 2;
    267   }
    268 
    269   assert(pred_context >= 0 && pred_context < REF_CONTEXTS);
    270   return pred_context;
    271 }
    272 
    273 unsigned char vp9_get_pred_context_single_ref_p2(const MACROBLOCKD *xd) {
    274   int pred_context;
    275   const MODE_INFO * const above_mi = xd->mi_8x8[-xd->mode_info_stride];
    276   const MODE_INFO * const left_mi = xd->mi_8x8[-1];
    277   const MB_MODE_INFO *const above_mbmi = above_mi ? &above_mi->mbmi : 0;
    278   const MB_MODE_INFO *const left_mbmi = left_mi ? &left_mi->mbmi : 0;
    279   const int left_in_image = xd->left_available && left_mi;
    280   const int above_in_image = xd->up_available && above_mi;
    281   const int left_intra = left_in_image ? !is_inter_block(left_mbmi) : 1;
    282   const int above_intra = above_in_image ? !is_inter_block(above_mbmi) : 1;
    283 
    284   // Note:
    285   // The mode info data structure has a one element border above and to the
    286   // left of the entries correpsonding to real macroblocks.
    287   // The prediction flags in these dummy entries are initialised to 0.
    288   if (above_in_image && left_in_image) {  // both edges available
    289     if (above_intra && left_intra) {  // intra/intra
    290       pred_context = 2;
    291     } else if (above_intra || left_intra) {  // intra/inter or inter/intra
    292       const MB_MODE_INFO *edge_mbmi = above_intra ? left_mbmi : above_mbmi;
    293       if (!has_second_ref(edge_mbmi)) {
    294         if (edge_mbmi->ref_frame[0] == LAST_FRAME)
    295           pred_context = 3;
    296         else
    297           pred_context = 4 * (edge_mbmi->ref_frame[0] == GOLDEN_FRAME);
    298       } else {
    299         pred_context = 1 + 2 * (edge_mbmi->ref_frame[0] == GOLDEN_FRAME ||
    300                                 edge_mbmi->ref_frame[1] == GOLDEN_FRAME);
    301       }
    302     } else {  // inter/inter
    303       if (!has_second_ref(above_mbmi) && !has_second_ref(left_mbmi)) {
    304         if (above_mbmi->ref_frame[0] == LAST_FRAME &&
    305             left_mbmi->ref_frame[0] == LAST_FRAME) {
    306           pred_context = 3;
    307         } else if (above_mbmi->ref_frame[0] == LAST_FRAME ||
    308                    left_mbmi->ref_frame[0] == LAST_FRAME) {
    309           const MB_MODE_INFO *edge_mbmi =
    310               above_mbmi->ref_frame[0] == LAST_FRAME ? left_mbmi : above_mbmi;
    311 
    312           pred_context = 4 * (edge_mbmi->ref_frame[0] == GOLDEN_FRAME);
    313         } else {
    314           pred_context = 2 * (above_mbmi->ref_frame[0] == GOLDEN_FRAME) +
    315                          2 * (left_mbmi->ref_frame[0] == GOLDEN_FRAME);
    316         }
    317       } else if (has_second_ref(above_mbmi) && has_second_ref(left_mbmi)) {
    318         if (above_mbmi->ref_frame[0] == left_mbmi->ref_frame[0] &&
    319             above_mbmi->ref_frame[1] == left_mbmi->ref_frame[1])
    320           pred_context = 3 * (above_mbmi->ref_frame[0] == GOLDEN_FRAME ||
    321                               above_mbmi->ref_frame[1] == GOLDEN_FRAME ||
    322                               left_mbmi->ref_frame[0] == GOLDEN_FRAME ||
    323                               left_mbmi->ref_frame[1] == GOLDEN_FRAME);
    324         else
    325           pred_context = 2;
    326       } else {
    327         const MV_REFERENCE_FRAME rfs = !has_second_ref(above_mbmi) ?
    328                   above_mbmi->ref_frame[0] : left_mbmi->ref_frame[0];
    329         const MV_REFERENCE_FRAME crf1 = has_second_ref(above_mbmi) ?
    330                   above_mbmi->ref_frame[0] : left_mbmi->ref_frame[0];
    331         const MV_REFERENCE_FRAME crf2 = has_second_ref(above_mbmi) ?
    332                   above_mbmi->ref_frame[1] : left_mbmi->ref_frame[1];
    333 
    334         if (rfs == GOLDEN_FRAME)
    335           pred_context = 3 + (crf1 == GOLDEN_FRAME || crf2 == GOLDEN_FRAME);
    336         else if (rfs == ALTREF_FRAME)
    337           pred_context = crf1 == GOLDEN_FRAME || crf2 == GOLDEN_FRAME;
    338         else
    339           pred_context = 1 + 2 * (crf1 == GOLDEN_FRAME || crf2 == GOLDEN_FRAME);
    340       }
    341     }
    342   } else if (above_in_image || left_in_image) {  // one edge available
    343     const MB_MODE_INFO *edge_mbmi = above_in_image ? above_mbmi : left_mbmi;
    344 
    345     if (!is_inter_block(edge_mbmi) ||
    346         (edge_mbmi->ref_frame[0] == LAST_FRAME && !has_second_ref(edge_mbmi)))
    347       pred_context = 2;
    348     else if (!has_second_ref(edge_mbmi))
    349       pred_context = 4 * (edge_mbmi->ref_frame[0] == GOLDEN_FRAME);
    350     else
    351       pred_context = 3 * (edge_mbmi->ref_frame[0] == GOLDEN_FRAME ||
    352                           edge_mbmi->ref_frame[1] == GOLDEN_FRAME);
    353   } else {  // no edges available (2)
    354     pred_context = 2;
    355   }
    356   assert(pred_context >= 0 && pred_context < REF_CONTEXTS);
    357   return pred_context;
    358 }
    359 // Returns a context number for the given MB prediction signal
    360 // The mode info data structure has a one element border above and to the
    361 // left of the entries corresponding to real blocks.
    362 // The prediction flags in these dummy entries are initialized to 0.
    363 unsigned char vp9_get_pred_context_tx_size(const MACROBLOCKD *xd) {
    364   const MODE_INFO * const above_mi = xd->mi_8x8[-xd->mode_info_stride];
    365   const MODE_INFO * const left_mi = xd->mi_8x8[-1];
    366   const MB_MODE_INFO *const above_mbmi = above_mi ? &above_mi->mbmi : 0;
    367   const MB_MODE_INFO *const left_mbmi = left_mi ? &left_mi->mbmi : 0;
    368   const int left_in_image = xd->left_available && left_mi;
    369   const int above_in_image = xd->up_available && above_mi;
    370   const int max_tx_size = max_txsize_lookup[xd->mi_8x8[0]->mbmi.sb_type];
    371   int above_context = max_tx_size;
    372   int left_context = max_tx_size;
    373 
    374   if (above_in_image)
    375     above_context = above_mbmi->skip_coeff ? max_tx_size
    376                                            : above_mbmi->tx_size;
    377 
    378   if (left_in_image)
    379     left_context = left_mbmi->skip_coeff ? max_tx_size
    380                                          : left_mbmi->tx_size;
    381 
    382   if (!left_in_image)
    383     left_context = above_context;
    384 
    385   if (!above_in_image)
    386     above_context = left_context;
    387 
    388   return above_context + left_context > max_tx_size;
    389 }
    390 
    391 void vp9_set_pred_flag_seg_id(MACROBLOCKD *xd, uint8_t pred_flag) {
    392   xd->this_mi->mbmi.seg_id_predicted = pred_flag;
    393 }
    394 
    395 void vp9_set_pred_flag_mbskip(MACROBLOCKD *xd, BLOCK_SIZE bsize,
    396                               uint8_t pred_flag) {
    397   xd->this_mi->mbmi.skip_coeff = pred_flag;
    398 }
    399 
    400 int vp9_get_segment_id(VP9_COMMON *cm, const uint8_t *segment_ids,
    401                        BLOCK_SIZE bsize, int mi_row, int mi_col) {
    402   const int mi_offset = mi_row * cm->mi_cols + mi_col;
    403   const int bw = 1 << mi_width_log2(bsize);
    404   const int bh = 1 << mi_height_log2(bsize);
    405   const int xmis = MIN(cm->mi_cols - mi_col, bw);
    406   const int ymis = MIN(cm->mi_rows - mi_row, bh);
    407   int x, y, segment_id = INT_MAX;
    408 
    409   for (y = 0; y < ymis; y++)
    410     for (x = 0; x < xmis; x++)
    411       segment_id = MIN(segment_id,
    412                        segment_ids[mi_offset + y * cm->mi_cols + x]);
    413 
    414   assert(segment_id >= 0 && segment_id < MAX_SEGMENTS);
    415   return segment_id;
    416 }
    417