pred_common.h 8.76 KB
Newer Older
Jingning Han's avatar
Jingning Han committed
1
2
3
4
5
6
7
8
9
10
/*
 *  Copyright (c) 2012 The WebM project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

11
12
#ifndef VP10_COMMON_PRED_COMMON_H_
#define VP10_COMMON_PRED_COMMON_H_
Jingning Han's avatar
Jingning Han committed
13

14
15
#include "vp10/common/blockd.h"
#include "vp10/common/onyxc_int.h"
16
#include "vpx_dsp/vpx_dsp_common.h"
Jingning Han's avatar
Jingning Han committed
17
18
19
20
21

#ifdef __cplusplus
extern "C" {
#endif

Yaowu Xu's avatar
Yaowu Xu committed
22
static INLINE int get_segment_id(const VP10_COMMON *cm,
Jingning Han's avatar
Jingning Han committed
23
24
25
26
27
                                 const uint8_t *segment_ids,
                                 BLOCK_SIZE bsize, int mi_row, int mi_col) {
  const int mi_offset = mi_row * cm->mi_cols + mi_col;
  const int bw = num_8x8_blocks_wide_lookup[bsize];
  const int bh = num_8x8_blocks_high_lookup[bsize];
28
29
  const int xmis = VPXMIN(cm->mi_cols - mi_col, bw);
  const int ymis = VPXMIN(cm->mi_rows - mi_row, bh);
Jingning Han's avatar
Jingning Han committed
30
31
32
33
  int x, y, segment_id = MAX_SEGMENTS;

  for (y = 0; y < ymis; ++y)
    for (x = 0; x < xmis; ++x)
34
35
      segment_id =
          VPXMIN(segment_id, segment_ids[mi_offset + y * cm->mi_cols + x]);
Jingning Han's avatar
Jingning Han committed
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63

  assert(segment_id >= 0 && segment_id < MAX_SEGMENTS);
  return segment_id;
}

static INLINE int vp10_get_pred_context_seg_id(const MACROBLOCKD *xd) {
  const MODE_INFO *const above_mi = xd->above_mi;
  const MODE_INFO *const left_mi = xd->left_mi;
  const int above_sip = (above_mi != NULL) ?
                        above_mi->mbmi.seg_id_predicted : 0;
  const int left_sip = (left_mi != NULL) ? left_mi->mbmi.seg_id_predicted : 0;

  return above_sip + left_sip;
}

static INLINE vpx_prob vp10_get_pred_prob_seg_id(const struct segmentation *seg,
                                                const MACROBLOCKD *xd) {
  return seg->pred_probs[vp10_get_pred_context_seg_id(xd)];
}

static INLINE int vp10_get_skip_context(const MACROBLOCKD *xd) {
  const MODE_INFO *const above_mi = xd->above_mi;
  const MODE_INFO *const left_mi = xd->left_mi;
  const int above_skip = (above_mi != NULL) ? above_mi->mbmi.skip : 0;
  const int left_skip = (left_mi != NULL) ? left_mi->mbmi.skip : 0;
  return above_skip + left_skip;
}

Yaowu Xu's avatar
Yaowu Xu committed
64
static INLINE vpx_prob vp10_get_skip_prob(const VP10_COMMON *cm,
Jingning Han's avatar
Jingning Han committed
65
66
67
68
69
70
71
72
                                         const MACROBLOCKD *xd) {
  return cm->fc->skip_probs[vp10_get_skip_context(xd)];
}

int vp10_get_pred_context_switchable_interp(const MACROBLOCKD *xd);

int vp10_get_intra_inter_context(const MACROBLOCKD *xd);

Yaowu Xu's avatar
Yaowu Xu committed
73
static INLINE vpx_prob vp10_get_intra_inter_prob(const VP10_COMMON *cm,
Jingning Han's avatar
Jingning Han committed
74
75
76
77
                                                const MACROBLOCKD *xd) {
  return cm->fc->intra_inter_prob[vp10_get_intra_inter_context(xd)];
}

Yaowu Xu's avatar
Yaowu Xu committed
78
79
int vp10_get_reference_mode_context(const VP10_COMMON *cm,
                                    const MACROBLOCKD *xd);
Jingning Han's avatar
Jingning Han committed
80

Yaowu Xu's avatar
Yaowu Xu committed
81
static INLINE vpx_prob vp10_get_reference_mode_prob(const VP10_COMMON *cm,
Jingning Han's avatar
Jingning Han committed
82
83
84
85
                                                   const MACROBLOCKD *xd) {
  return cm->fc->comp_inter_prob[vp10_get_reference_mode_context(cm, xd)];
}

Yaowu Xu's avatar
Yaowu Xu committed
86
int vp10_get_pred_context_comp_ref_p(const VP10_COMMON *cm,
Jingning Han's avatar
Jingning Han committed
87
88
                                    const MACROBLOCKD *xd);

Yaowu Xu's avatar
Yaowu Xu committed
89
static INLINE vpx_prob vp10_get_pred_prob_comp_ref_p(const VP10_COMMON *cm,
Jingning Han's avatar
Jingning Han committed
90
91
92
93
94
95
96
                                                    const MACROBLOCKD *xd) {
  const int pred_context = vp10_get_pred_context_comp_ref_p(cm, xd);
  return cm->fc->comp_ref_prob[pred_context];
}

int vp10_get_pred_context_single_ref_p1(const MACROBLOCKD *xd);

Yaowu Xu's avatar
Yaowu Xu committed
97
static INLINE vpx_prob vp10_get_pred_prob_single_ref_p1(const VP10_COMMON *cm,
Jingning Han's avatar
Jingning Han committed
98
99
100
101
102
103
                                                       const MACROBLOCKD *xd) {
  return cm->fc->single_ref_prob[vp10_get_pred_context_single_ref_p1(xd)][0];
}

int vp10_get_pred_context_single_ref_p2(const MACROBLOCKD *xd);

Yaowu Xu's avatar
Yaowu Xu committed
104
static INLINE vpx_prob vp10_get_pred_prob_single_ref_p2(const VP10_COMMON *cm,
Jingning Han's avatar
Jingning Han committed
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
                                                       const MACROBLOCKD *xd) {
  return cm->fc->single_ref_prob[vp10_get_pred_context_single_ref_p2(xd)][1];
}

// Returns a context number for the given MB prediction signal
// The mode info data structure has a one element border above and to the
// left of the entries corresponding to real blocks.
// The prediction flags in these dummy entries are initialized to 0.
static INLINE int get_tx_size_context(const MACROBLOCKD *xd) {
  const int max_tx_size = max_txsize_lookup[xd->mi[0]->mbmi.sb_type];
  const MB_MODE_INFO *const above_mbmi = xd->above_mbmi;
  const MB_MODE_INFO *const left_mbmi = xd->left_mbmi;
  const int has_above = xd->up_available;
  const int has_left = xd->left_available;
  int above_ctx = (has_above && !above_mbmi->skip) ? (int)above_mbmi->tx_size
                                                   : max_tx_size;
  int left_ctx = (has_left && !left_mbmi->skip) ? (int)left_mbmi->tx_size
                                                : max_tx_size;
  if (!has_left)
    left_ctx = above_ctx;

  if (!has_above)
    above_ctx = left_ctx;

  return (above_ctx + left_ctx) > max_tx_size;
}

static INLINE const vpx_prob *get_tx_probs(TX_SIZE max_tx_size, int ctx,
                                           const struct tx_probs *tx_probs) {
  switch (max_tx_size) {
    case TX_8X8:
      return tx_probs->p8x8[ctx];
    case TX_16X16:
      return tx_probs->p16x16[ctx];
    case TX_32X32:
      return tx_probs->p32x32[ctx];
    default:
      assert(0 && "Invalid max_tx_size.");
      return NULL;
  }
}

static INLINE const vpx_prob *get_tx_probs2(TX_SIZE max_tx_size,
                                            const MACROBLOCKD *xd,
                                            const struct tx_probs *tx_probs) {
  return get_tx_probs(max_tx_size, get_tx_size_context(xd), tx_probs);
}

static INLINE unsigned int *get_tx_counts(TX_SIZE max_tx_size, int ctx,
                                          struct tx_counts *tx_counts) {
  switch (max_tx_size) {
    case TX_8X8:
      return tx_counts->p8x8[ctx];
    case TX_16X16:
      return tx_counts->p16x16[ctx];
    case TX_32X32:
      return tx_counts->p32x32[ctx];
    default:
      assert(0 && "Invalid max_tx_size.");
      return NULL;
  }
}

168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
#if CONFIG_VAR_TX
static void update_tx_counts(VP10_COMMON *cm, MACROBLOCKD *xd,
                             MB_MODE_INFO *mbmi, BLOCK_SIZE plane_bsize,
                             TX_SIZE tx_size, int blk_row, int blk_col,
                             TX_SIZE max_tx_size, int ctx,
                             struct tx_counts *tx_counts) {
  const struct macroblockd_plane *const pd = &xd->plane[0];
  const BLOCK_SIZE bsize = txsize_to_bsize[tx_size];
  int tx_idx = (blk_row >> (1 - pd->subsampling_y)) * 8 +
               (blk_col >> (1 - pd->subsampling_x));
  TX_SIZE plane_tx_size = mbmi->inter_tx_size[tx_idx];
  int max_blocks_high = num_4x4_blocks_high_lookup[plane_bsize];
  int max_blocks_wide = num_4x4_blocks_wide_lookup[plane_bsize];

  if (xd->mb_to_bottom_edge < 0)
    max_blocks_high += xd->mb_to_bottom_edge >> (5 + pd->subsampling_y);
  if (xd->mb_to_right_edge < 0)
    max_blocks_wide += xd->mb_to_right_edge >> (5 + pd->subsampling_x);

  if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide)
    return;

  if (tx_size == plane_tx_size) {
    ++get_tx_counts(max_tx_size, ctx, tx_counts)[tx_size];
  } else {
    int bsl = b_width_log2_lookup[bsize];
    int i;

    assert(bsl > 0);
    --bsl;

    for (i = 0; i < 4; ++i) {
      const int offsetr = blk_row + ((i >> 1) << bsl);
      const int offsetc = blk_col + ((i & 0x01) << bsl);

      if (offsetr >= max_blocks_high || offsetc >= max_blocks_wide)
        continue;
      update_tx_counts(cm, xd, mbmi, plane_bsize,
                       tx_size - 1, offsetr, offsetc,
                       max_tx_size, ctx, tx_counts);
    }
  }
}

static INLINE void inter_block_tx_count_update(VP10_COMMON *cm,
                                               MACROBLOCKD *xd,
                                               MB_MODE_INFO *mbmi,
                                               BLOCK_SIZE plane_bsize,
                                               int ctx,
                                               struct tx_counts *tx_counts) {
  const int mi_width = num_4x4_blocks_wide_lookup[plane_bsize];
  const int mi_height = num_4x4_blocks_high_lookup[plane_bsize];
  TX_SIZE max_tx_size = max_txsize_lookup[plane_bsize];
  BLOCK_SIZE txb_size = txsize_to_bsize[max_tx_size];
  int bh = num_4x4_blocks_wide_lookup[txb_size];
  int idx, idy;

  for (idy = 0; idy < mi_height; idy += bh)
    for (idx = 0; idx < mi_width; idx += bh)
      update_tx_counts(cm, xd, mbmi, plane_bsize, max_tx_size, idy, idx,
                       max_tx_size, ctx, tx_counts);
}
#endif

Jingning Han's avatar
Jingning Han committed
232
233
234
235
#ifdef __cplusplus
}  // extern "C"
#endif

236
#endif  // VP10_COMMON_PRED_COMMON_H_