vp9_encodeintra.c 7.59 KB
Newer Older
John Koleszar's avatar
John Koleszar committed
1
/*
2
 *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
John Koleszar's avatar
John Koleszar committed
3
 *
4
 *  Use of this source code is governed by a BSD-style license
5
6
 *  that can be found in the LICENSE file in the root of the source
 *  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.
John Koleszar's avatar
John Koleszar committed
9
10
 */

11
#include "./vpx_config.h"
12
#include "vp9_rtcd.h"
13
#include "vp9/encoder/vp9_quantize.h"
14
15
#include "vp9/common/vp9_reconintra.h"
#include "vp9/common/vp9_reconintra4x4.h"
16
#include "vp9/encoder/vp9_encodemb.h"
17
#include "vp9/common/vp9_invtrans.h"
18
#include "vp9/encoder/vp9_encodeintra.h"
John Koleszar's avatar
John Koleszar committed
19

20
int vp9_encode_intra(VP9_COMP *cpi, MACROBLOCK *x, int use_16x16_pred) {
John Koleszar's avatar
John Koleszar committed
21
22
  int i;
  int intra_pred_var = 0;
Paul Wilkins's avatar
Paul Wilkins committed
23
  MB_MODE_INFO * mbmi = &x->e_mbd.mode_info_context->mbmi;
John Koleszar's avatar
John Koleszar committed
24
  (void) cpi;
Tero Rintaluoma's avatar
Tero Rintaluoma committed
25

John Koleszar's avatar
John Koleszar committed
26
  if (use_16x16_pred) {
Paul Wilkins's avatar
Paul Wilkins committed
27
    mbmi->mode = DC_PRED;
28
#if CONFIG_COMP_INTRA_PRED
Paul Wilkins's avatar
Paul Wilkins committed
29
    mbmi->second_mode = (MB_PREDICTION_MODE)(DC_PRED - 1);
30
#endif
Paul Wilkins's avatar
Paul Wilkins committed
31
32
    mbmi->uv_mode = DC_PRED;
    mbmi->ref_frame = INTRA_FRAME;
John Koleszar's avatar
John Koleszar committed
33

34
    vp9_encode_intra16x16mby(x);
John Koleszar's avatar
John Koleszar committed
35
36
37
  } else {
    for (i = 0; i < 16; i++) {
      x->e_mbd.block[i].bmi.as_mode.first = B_DC_PRED;
38
      vp9_encode_intra4x4block(x, i);
Tero Rintaluoma's avatar
Tero Rintaluoma committed
39
    }
John Koleszar's avatar
John Koleszar committed
40
  }
Tero Rintaluoma's avatar
Tero Rintaluoma committed
41

42
  intra_pred_var = vp9_get_mb_ss(x->src_diff);
Tero Rintaluoma's avatar
Tero Rintaluoma committed
43

John Koleszar's avatar
John Koleszar committed
44
  return intra_pred_var;
Tero Rintaluoma's avatar
Tero Rintaluoma committed
45
}
46

47
void vp9_encode_intra4x4block(MACROBLOCK *x, int ib) {
John Koleszar's avatar
John Koleszar committed
48
49
  BLOCKD *b = &x->e_mbd.block[ib];
  BLOCK *be = &x->block[ib];
Deb Mukherjee's avatar
Deb Mukherjee committed
50
  TX_TYPE tx_type;
51

52
53
54
55
#if CONFIG_NEWBINTRAMODES
  b->bmi.as_mode.context = vp9_find_bpred_context(b);
#endif

56
#if CONFIG_COMP_INTRA_PRED
John Koleszar's avatar
John Koleszar committed
57
  if (b->bmi.as_mode.second == (B_PREDICTION_MODE)(B_DC_PRED - 1)) {
58
#endif
59
    vp9_intra4x4_predict(b, b->bmi.as_mode.first, b->predictor);
60
#if CONFIG_COMP_INTRA_PRED
John Koleszar's avatar
John Koleszar committed
61
  } else {
62
    vp9_comp_intra4x4_predict(b, b->bmi.as_mode.first, b->bmi.as_mode.second,
63
                              b->predictor);
John Koleszar's avatar
John Koleszar committed
64
  }
65
#endif
John Koleszar's avatar
John Koleszar committed
66

67
  vp9_subtract_b(be, b, 16);
John Koleszar's avatar
John Koleszar committed
68

69
  tx_type = get_tx_type_4x4(&x->e_mbd, b);
Deb Mukherjee's avatar
Deb Mukherjee committed
70
  if (tx_type != DCT_DCT) {
71
    vp9_fht(be->src_diff, 32, be->coeff, tx_type, 4);
72
    vp9_ht_quantize_b_4x4(be, b, tx_type);
Scott LaVarnway's avatar
Scott LaVarnway committed
73
    vp9_ihtllm(b->dqcoeff, b->diff, 32, tx_type, 4, b->eob);
74
  } else {
75
    x->vp9_short_fdct4x4(be->src_diff, be->coeff, 32);
76
    x->quantize_b_4x4(be, b) ;
77
    vp9_inverse_transform_b_4x4(&x->e_mbd, ib, 32);
78
  }
John Koleszar's avatar
John Koleszar committed
79

80
  vp9_recon_b(b->predictor, b->diff, *(b->base_dst) + b->dst, b->dst_stride);
John Koleszar's avatar
John Koleszar committed
81
82
}

83
void vp9_encode_intra4x4mby(MACROBLOCK *mb) {
John Koleszar's avatar
John Koleszar committed
84
  int i;
John Koleszar's avatar
John Koleszar committed
85

John Koleszar's avatar
John Koleszar committed
86
  for (i = 0; i < 16; i++)
87
    vp9_encode_intra4x4block(mb, i);
John Koleszar's avatar
John Koleszar committed
88
  return;
John Koleszar's avatar
John Koleszar committed
89
90
}

91
void vp9_encode_intra16x16mby(MACROBLOCK *x) {
92
  MACROBLOCKD *xd = &x->e_mbd;
John Koleszar's avatar
John Koleszar committed
93
  BLOCK *b = &x->block[0];
94
  TX_SIZE tx_size = xd->mode_info_context->mbmi.txfm_size;
Paul Wilkins's avatar
Paul Wilkins committed
95

96
#if CONFIG_COMP_INTRA_PRED
97
  if (xd->mode_info_context->mbmi.second_mode == (MB_PREDICTION_MODE)(DC_PRED - 1))
98
#endif
99
    vp9_build_intra_predictors_mby(xd);
100
#if CONFIG_COMP_INTRA_PRED
John Koleszar's avatar
John Koleszar committed
101
  else
102
    vp9_build_comp_intra_predictors_mby(xd);
103
#endif
John Koleszar's avatar
John Koleszar committed
104

105
  vp9_subtract_mby(x->src_diff, *(b->base_src), xd->predictor, b->src_stride);
Paul Wilkins's avatar
Paul Wilkins committed
106

107
  if (tx_size == TX_16X16) {
108
109
110
111
112
    vp9_transform_mby_16x16(x);
    vp9_quantize_mby_16x16(x);
    if (x->optimize)
      vp9_optimize_mby_16x16(x);
    vp9_inverse_transform_mby_16x16(xd);
113
  } else if (tx_size == TX_8X8) {
114
115
    vp9_transform_mby_8x8(x);
    vp9_quantize_mby_8x8(x);
116
    if (x->optimize)
117
118
      vp9_optimize_mby_8x8(x);
    vp9_inverse_transform_mby_8x8(xd);
119
  } else {
120
121
    vp9_transform_mby_4x4(x);
    vp9_quantize_mby_4x4(x);
122
    if (x->optimize)
123
124
      vp9_optimize_mby_4x4(x);
    vp9_inverse_transform_mby_4x4(xd);
John Koleszar's avatar
John Koleszar committed
125
126
  }

127
  vp9_recon_mby(xd);
John Koleszar's avatar
John Koleszar committed
128
129
}

130
void vp9_encode_intra16x16mbuv(MACROBLOCK *x) {
131
132
133
  MACROBLOCKD *xd = &x->e_mbd;
  TX_SIZE tx_size = xd->mode_info_context->mbmi.txfm_size;

134
#if CONFIG_COMP_INTRA_PRED
135
  if (xd->mode_info_context->mbmi.second_uv_mode == (MB_PREDICTION_MODE)(DC_PRED - 1)) {
Paul Wilkins's avatar
Paul Wilkins committed
136
#endif
137
    vp9_build_intra_predictors_mbuv(xd);
138
#if CONFIG_COMP_INTRA_PRED
John Koleszar's avatar
John Koleszar committed
139
  } else {
140
    vp9_build_comp_intra_predictors_mbuv(xd);
John Koleszar's avatar
John Koleszar committed
141
  }
142
#endif
John Koleszar's avatar
John Koleszar committed
143

144
  vp9_subtract_mbuv(x->src_diff, x->src.u_buffer, x->src.v_buffer,
Jim Bankoski's avatar
Jim Bankoski committed
145
146
                    xd->predictor, x->src.uv_stride);

147
  if (tx_size == TX_4X4) {
148
149
    vp9_transform_mbuv_4x4(x);
    vp9_quantize_mbuv_4x4(x);
150
    if (x->optimize)
151
152
      vp9_optimize_mbuv_4x4(x);
    vp9_inverse_transform_mbuv_4x4(xd);
153
  } else /* 16x16 or 8x8 */ {
154
155
    vp9_transform_mbuv_8x8(x);
    vp9_quantize_mbuv_8x8(x);
156
    if (x->optimize)
157
158
      vp9_optimize_mbuv_8x8(x);
    vp9_inverse_transform_mbuv_8x8(xd);
John Koleszar's avatar
John Koleszar committed
159
160
  }

161
  vp9_recon_intra_mbuv(xd);
John Koleszar's avatar
John Koleszar committed
162
}
Yaowu Xu's avatar
Yaowu Xu committed
163

164
void vp9_encode_intra8x8(MACROBLOCK *x, int ib) {
165
166
  MACROBLOCKD *xd = &x->e_mbd;
  BLOCKD *b = &xd->block[ib];
John Koleszar's avatar
John Koleszar committed
167
168
169
  BLOCK *be = &x->block[ib];
  const int iblock[4] = {0, 1, 4, 5};
  int i;
Deb Mukherjee's avatar
Deb Mukherjee committed
170
  TX_TYPE tx_type;
Yaowu Xu's avatar
Yaowu Xu committed
171

172
#if CONFIG_COMP_INTRA_PRED
John Koleszar's avatar
John Koleszar committed
173
  if (b->bmi.as_mode.second == (MB_PREDICTION_MODE)(DC_PRED - 1)) {
174
#endif
175
    vp9_intra8x8_predict(b, b->bmi.as_mode.first, b->predictor);
176
#if CONFIG_COMP_INTRA_PRED
John Koleszar's avatar
John Koleszar committed
177
  } else {
178
    vp9_comp_intra8x8_predict(b, b->bmi.as_mode.first, b->bmi.as_mode.second,
179
                              b->predictor);
John Koleszar's avatar
John Koleszar committed
180
  }
181
#endif
182
183
  // generate residual blocks
  vp9_subtract_4b_c(be, b, 16);
Yaowu Xu's avatar
Yaowu Xu committed
184

185
  if (xd->mode_info_context->mbmi.txfm_size == TX_8X8) {
186
187
    int idx = (ib & 0x02) ? (ib + 2) : ib;

188
    tx_type = get_tx_type_8x8(xd, &xd->block[ib]);
Deb Mukherjee's avatar
Deb Mukherjee committed
189
    if (tx_type != DCT_DCT) {
190
      vp9_fht(be->src_diff, 32, (x->block + idx)->coeff,
Deb Mukherjee's avatar
Deb Mukherjee committed
191
192
                tx_type, 8);
      x->quantize_b_8x8(x->block + idx, xd->block + idx);
Jim Bankoski's avatar
Jim Bankoski committed
193
      vp9_ihtllm(xd->block[idx].dqcoeff, xd->block[ib].diff, 32,
Scott LaVarnway's avatar
Scott LaVarnway committed
194
                   tx_type, 8, xd->block[idx].eob);
Deb Mukherjee's avatar
Deb Mukherjee committed
195
    } else {
196
      x->vp9_short_fdct8x8(be->src_diff, (x->block + idx)->coeff, 32);
Deb Mukherjee's avatar
Deb Mukherjee committed
197
      x->quantize_b_8x8(x->block + idx, xd->block + idx);
198
      vp9_short_idct8x8(xd->block[idx].dqcoeff, xd->block[ib].diff, 32);
Deb Mukherjee's avatar
Deb Mukherjee committed
199
    }
200
  } else {
201
202
    for (i = 0; i < 4; i++) {
      b = &xd->block[ib + iblock[i]];
203
      be = &x->block[ib + iblock[i]];
204
205
206
207
      tx_type = get_tx_type_4x4(xd, b);
      if (tx_type != DCT_DCT) {
        vp9_fht_c(be->src_diff, 32, be->coeff, tx_type, 4);
        vp9_ht_quantize_b_4x4(be, b, tx_type);
Scott LaVarnway's avatar
Scott LaVarnway committed
208
        vp9_ihtllm(b->dqcoeff, b->diff, 32, tx_type, 4, b->eob);
209
210
211
212
213
      } else {
        x->vp9_short_fdct4x4(be->src_diff, be->coeff, 32);
        x->quantize_b_4x4(be, b);
        vp9_inverse_transform_b_4x4(xd, ib + iblock[i], 32);
      }
214
215
    }
  }
216
217
218
219

  // reconstruct submacroblock
  for (i = 0; i < 4; i++) {
    b = &xd->block[ib + iblock[i]];
220
    vp9_recon_b_c(b->predictor, b->diff, *(b->base_dst) + b->dst,
221
222
                  b->dst_stride);
  }
Yaowu Xu's avatar
Yaowu Xu committed
223
224
}

225
void vp9_encode_intra8x8mby(MACROBLOCK *x) {
John Koleszar's avatar
John Koleszar committed
226
227
228
  int i, ib;

  for (i = 0; i < 4; i++) {
229
    ib = vp9_i8x8_block[i];
230
    vp9_encode_intra8x8(x, ib);
John Koleszar's avatar
John Koleszar committed
231
  }
Yaowu Xu's avatar
Yaowu Xu committed
232
233
}

234
void vp9_encode_intra_uv4x4(MACROBLOCK *x, int ib,
John Koleszar's avatar
John Koleszar committed
235
236
237
                            int mode, int second) {
  BLOCKD *b = &x->e_mbd.block[ib];
  BLOCK *be = &x->block[ib];
Yaowu Xu's avatar
Yaowu Xu committed
238

239
#if CONFIG_COMP_INTRA_PRED
John Koleszar's avatar
John Koleszar committed
240
  if (second == -1) {
241
#endif
242
    vp9_intra_uv4x4_predict(b, mode, b->predictor);
243
#if CONFIG_COMP_INTRA_PRED
John Koleszar's avatar
John Koleszar committed
244
  } else {
245
    vp9_comp_intra_uv4x4_predict(b, mode, second, b->predictor);
John Koleszar's avatar
John Koleszar committed
246
  }
247
#endif
Yaowu Xu's avatar
Yaowu Xu committed
248

249
  vp9_subtract_b(be, b, 8);
Yaowu Xu's avatar
Yaowu Xu committed
250

251
  x->vp9_short_fdct4x4(be->src_diff, be->coeff, 16);
252
  x->quantize_b_4x4(be, b);
253
  vp9_inverse_transform_b_4x4(&x->e_mbd, ib, 16);
Yaowu Xu's avatar
Yaowu Xu committed
254

255
256
  vp9_recon_uv_b_c(b->predictor, b->diff, *(b->base_dst) + b->dst,
                   b->dst_stride);
Yaowu Xu's avatar
Yaowu Xu committed
257
258
}

259
void vp9_encode_intra8x8mbuv(MACROBLOCK *x) {
John Koleszar's avatar
John Koleszar committed
260
261
  int i, ib, mode, second;
  BLOCKD *b;
262

John Koleszar's avatar
John Koleszar committed
263
  for (i = 0; i < 4; i++) {
264
    ib = vp9_i8x8_block[i];
John Koleszar's avatar
John Koleszar committed
265
266
    b = &x->e_mbd.block[ib];
    mode = b->bmi.as_mode.first;
267
#if CONFIG_COMP_INTRA_PRED
John Koleszar's avatar
John Koleszar committed
268
    second = b->bmi.as_mode.second;
269
#else
John Koleszar's avatar
John Koleszar committed
270
    second = -1;
271
#endif
John Koleszar's avatar
John Koleszar committed
272
    /*u */
273
    vp9_encode_intra_uv4x4(x, i + 16, mode, second);
John Koleszar's avatar
John Koleszar committed
274
    /*v */
275
    vp9_encode_intra_uv4x4(x, i + 20, mode, second);
John Koleszar's avatar
John Koleszar committed
276
  }
Yaowu Xu's avatar
Yaowu Xu committed
277
}