vp9_encodeintra.c 6.87 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
#include "vp9/common/vp9_reconintra.h"
15
#include "vp9/encoder/vp9_encodemb.h"
16
#include "vp9/common/vp9_invtrans.h"
17
#include "vp9/encoder/vp9_encodeintra.h"
John Koleszar's avatar
John Koleszar committed
18

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

John Koleszar's avatar
John Koleszar committed
23
  if (use_16x16_pred) {
Paul Wilkins's avatar
Paul Wilkins committed
24
25
26
    mbmi->mode = DC_PRED;
    mbmi->uv_mode = DC_PRED;
    mbmi->ref_frame = INTRA_FRAME;
John Koleszar's avatar
John Koleszar committed
27

28
    vp9_encode_intra16x16mby(&cpi->common, x);
John Koleszar's avatar
John Koleszar committed
29
  } else {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
30
31
    int i;

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

Dmitry Kovalev's avatar
Dmitry Kovalev committed
38
  return vp9_get_mb_ss(x->src_diff);
Tero Rintaluoma's avatar
Tero Rintaluoma committed
39
}
40

41
void vp9_encode_intra4x4block(MACROBLOCK *x, int ib) {
John Koleszar's avatar
John Koleszar committed
42
43
  BLOCKD *b = &x->e_mbd.block[ib];
  BLOCK *be = &x->block[ib];
Deb Mukherjee's avatar
Deb Mukherjee committed
44
  TX_TYPE tx_type;
45

46
47
48
49
#if CONFIG_NEWBINTRAMODES
  b->bmi.as_mode.context = vp9_find_bpred_context(b);
#endif

50
  vp9_intra4x4_predict(&x->e_mbd, b, b->bmi.as_mode.first, b->predictor);
51
  vp9_subtract_b(be, b, 16);
John Koleszar's avatar
John Koleszar committed
52

53
  tx_type = get_tx_type_4x4(&x->e_mbd, b);
Deb Mukherjee's avatar
Deb Mukherjee committed
54
  if (tx_type != DCT_DCT) {
55
    vp9_short_fht4x4(be->src_diff, be->coeff, 16, tx_type);
56
    vp9_ht_quantize_b_4x4(x, ib, tx_type);
57
    vp9_short_iht4x4(b->dqcoeff, b->diff, 16, tx_type);
58
  } else {
Yaowu Xu's avatar
Yaowu Xu committed
59
    x->fwd_txm4x4(be->src_diff, be->coeff, 32);
60
    x->quantize_b_4x4(x, ib);
61
62
    vp9_inverse_transform_b_4x4(&x->e_mbd, x->e_mbd.eobs[ib],
                                b->dqcoeff, b->diff, 32);
63
  }
John Koleszar's avatar
John Koleszar committed
64

65
  vp9_recon_b(b->predictor, b->diff, *(b->base_dst) + b->dst, b->dst_stride);
John Koleszar's avatar
John Koleszar committed
66
67
}

68
void vp9_encode_intra4x4mby(MACROBLOCK *mb) {
John Koleszar's avatar
John Koleszar committed
69
  int i;
John Koleszar's avatar
John Koleszar committed
70

John Koleszar's avatar
John Koleszar committed
71
  for (i = 0; i < 16; i++)
72
    vp9_encode_intra4x4block(mb, i);
John Koleszar's avatar
John Koleszar committed
73
74
}

75
void vp9_encode_intra16x16mby(VP9_COMMON *const cm, MACROBLOCK *x) {
76
  MACROBLOCKD *xd = &x->e_mbd;
John Koleszar's avatar
John Koleszar committed
77
  BLOCK *b = &x->block[0];
78
  TX_SIZE tx_size = xd->mode_info_context->mbmi.txfm_size;
Paul Wilkins's avatar
Paul Wilkins committed
79

80
  vp9_build_intra_predictors_mby(xd);
John Koleszar's avatar
John Koleszar committed
81

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

Dmitry Kovalev's avatar
Dmitry Kovalev committed
84
85
86
87
88
  switch (tx_size) {
    case TX_16X16:
      vp9_transform_mby_16x16(x);
      vp9_quantize_mby_16x16(x);
      if (x->optimize)
89
        vp9_optimize_mby_16x16(cm, x);
Dmitry Kovalev's avatar
Dmitry Kovalev committed
90
91
92
93
94
95
      vp9_inverse_transform_mby_16x16(xd);
      break;
    case TX_8X8:
      vp9_transform_mby_8x8(x);
      vp9_quantize_mby_8x8(x);
      if (x->optimize)
96
        vp9_optimize_mby_8x8(cm, x);
Dmitry Kovalev's avatar
Dmitry Kovalev committed
97
98
99
100
101
102
      vp9_inverse_transform_mby_8x8(xd);
      break;
    default:
      vp9_transform_mby_4x4(x);
      vp9_quantize_mby_4x4(x);
      if (x->optimize)
103
        vp9_optimize_mby_4x4(cm, x);
Dmitry Kovalev's avatar
Dmitry Kovalev committed
104
105
      vp9_inverse_transform_mby_4x4(xd);
      break;
John Koleszar's avatar
John Koleszar committed
106
107
  }

108
  vp9_recon_mby(xd);
John Koleszar's avatar
John Koleszar committed
109
110
}

111
void vp9_encode_intra16x16mbuv(VP9_COMMON *const cm, MACROBLOCK *x) {
112
113
114
  MACROBLOCKD *xd = &x->e_mbd;
  TX_SIZE tx_size = xd->mode_info_context->mbmi.txfm_size;

115
  vp9_build_intra_predictors_mbuv(xd);
John Koleszar's avatar
John Koleszar committed
116

117
  vp9_subtract_mbuv(x->src_diff, x->src.u_buffer, x->src.v_buffer,
Jim Bankoski's avatar
Jim Bankoski committed
118
119
                    xd->predictor, x->src.uv_stride);

Dmitry Kovalev's avatar
Dmitry Kovalev committed
120
121
122
123
124
  switch (tx_size) {
    case TX_4X4:
      vp9_transform_mbuv_4x4(x);
      vp9_quantize_mbuv_4x4(x);
      if (x->optimize)
125
        vp9_optimize_mbuv_4x4(cm, x);
Dmitry Kovalev's avatar
Dmitry Kovalev committed
126
127
128
129
130
131
      vp9_inverse_transform_mbuv_4x4(xd);
      break;
    default:  // 16x16 or 8x8
      vp9_transform_mbuv_8x8(x);
      vp9_quantize_mbuv_8x8(x);
      if (x->optimize)
132
        vp9_optimize_mbuv_8x8(cm, x);
Dmitry Kovalev's avatar
Dmitry Kovalev committed
133
134
135
      vp9_inverse_transform_mbuv_8x8(xd);
      break;
    }
John Koleszar's avatar
John Koleszar committed
136

137
  vp9_recon_intra_mbuv(xd);
John Koleszar's avatar
John Koleszar committed
138
}
Yaowu Xu's avatar
Yaowu Xu committed
139

140
void vp9_encode_intra8x8(MACROBLOCK *x, int ib) {
141
142
  MACROBLOCKD *xd = &x->e_mbd;
  BLOCKD *b = &xd->block[ib];
John Koleszar's avatar
John Koleszar committed
143
144
145
  BLOCK *be = &x->block[ib];
  const int iblock[4] = {0, 1, 4, 5};
  int i;
Deb Mukherjee's avatar
Deb Mukherjee committed
146
  TX_TYPE tx_type;
Yaowu Xu's avatar
Yaowu Xu committed
147

148
  vp9_intra8x8_predict(xd, b, b->bmi.as_mode.first, b->predictor);
149
150
  // generate residual blocks
  vp9_subtract_4b_c(be, b, 16);
Yaowu Xu's avatar
Yaowu Xu committed
151

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

155
    tx_type = get_tx_type_8x8(xd, &xd->block[ib]);
Deb Mukherjee's avatar
Deb Mukherjee committed
156
    if (tx_type != DCT_DCT) {
157
      vp9_short_fht8x8(be->src_diff, (x->block + idx)->coeff, 16, tx_type);
158
      x->quantize_b_8x8(x, idx);
159
      vp9_short_iht8x8(xd->block[idx].dqcoeff, xd->block[ib].diff,
160
                            16, tx_type);
Deb Mukherjee's avatar
Deb Mukherjee committed
161
    } else {
Yaowu Xu's avatar
Yaowu Xu committed
162
      x->fwd_txm8x8(be->src_diff, (x->block + idx)->coeff, 32);
163
      x->quantize_b_8x8(x, idx);
164
      vp9_short_idct8x8(xd->block[idx].dqcoeff, xd->block[ib].diff, 32);
Deb Mukherjee's avatar
Deb Mukherjee committed
165
    }
166
  } else {
167
168
    for (i = 0; i < 4; i++) {
      b = &xd->block[ib + iblock[i]];
169
      be = &x->block[ib + iblock[i]];
170
171
      tx_type = get_tx_type_4x4(xd, b);
      if (tx_type != DCT_DCT) {
172
        vp9_short_fht4x4(be->src_diff, be->coeff, 16, tx_type);
173
        vp9_ht_quantize_b_4x4(x, ib + iblock[i], tx_type);
174
        vp9_short_iht4x4(b->dqcoeff, b->diff, 16, tx_type);
175
      } else if (!(i & 1) && get_tx_type_4x4(xd, b + 1) == DCT_DCT) {
Yaowu Xu's avatar
Yaowu Xu committed
176
        x->fwd_txm8x4(be->src_diff, be->coeff, 32);
177
        x->quantize_b_4x4_pair(x, ib + iblock[i], ib + iblock[i] + 1);
178
179
180
181
        vp9_inverse_transform_b_4x4(xd, xd->eobs[ib + iblock[i]],
                                    b->dqcoeff, b->diff, 32);
        vp9_inverse_transform_b_4x4(xd, xd->eobs[ib + iblock[i] + 1],
                                    (b + 1)->dqcoeff, (b + 1)->diff, 32);
182
        i++;
183
      } else {
Yaowu Xu's avatar
Yaowu Xu committed
184
        x->fwd_txm4x4(be->src_diff, be->coeff, 32);
185
        x->quantize_b_4x4(x, ib + iblock[i]);
186
187
        vp9_inverse_transform_b_4x4(xd, xd->eobs[ib + iblock[i]],
                                    b->dqcoeff, b->diff, 32);
188
      }
189
190
    }
  }
191
192
193
194

  // reconstruct submacroblock
  for (i = 0; i < 4; i++) {
    b = &xd->block[ib + iblock[i]];
195
    vp9_recon_b_c(b->predictor, b->diff, *(b->base_dst) + b->dst,
196
197
                  b->dst_stride);
  }
Yaowu Xu's avatar
Yaowu Xu committed
198
199
}

200
void vp9_encode_intra8x8mby(MACROBLOCK *x) {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
201
  int i;
John Koleszar's avatar
John Koleszar committed
202

Dmitry Kovalev's avatar
Dmitry Kovalev committed
203
204
  for (i = 0; i < 4; i++)
    vp9_encode_intra8x8(x, vp9_i8x8_block[i]);
Yaowu Xu's avatar
Yaowu Xu committed
205
206
}

Dmitry Kovalev's avatar
Dmitry Kovalev committed
207
static void encode_intra_uv4x4(MACROBLOCK *x, int ib, int mode) {
John Koleszar's avatar
John Koleszar committed
208
209
  BLOCKD *b = &x->e_mbd.block[ib];
  BLOCK *be = &x->block[ib];
Yaowu Xu's avatar
Yaowu Xu committed
210

211
  vp9_intra_uv4x4_predict(&x->e_mbd, b, mode, b->predictor);
Yaowu Xu's avatar
Yaowu Xu committed
212

213
  vp9_subtract_b(be, b, 8);
Yaowu Xu's avatar
Yaowu Xu committed
214

Yaowu Xu's avatar
Yaowu Xu committed
215
  x->fwd_txm4x4(be->src_diff, be->coeff, 16);
216
  x->quantize_b_4x4(x, ib);
217
218
  vp9_inverse_transform_b_4x4(&x->e_mbd, x->e_mbd.eobs[ib],
                              b->dqcoeff, b->diff, 16);
Yaowu Xu's avatar
Yaowu Xu committed
219

220
221
  vp9_recon_uv_b_c(b->predictor, b->diff, *(b->base_dst) + b->dst,
                   b->dst_stride);
Yaowu Xu's avatar
Yaowu Xu committed
222
223
}

224
void vp9_encode_intra8x8mbuv(MACROBLOCK *x) {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
225
  int i;
226

John Koleszar's avatar
John Koleszar committed
227
  for (i = 0; i < 4; i++) {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
228
229
230
231
232
    BLOCKD *b = &x->e_mbd.block[vp9_i8x8_block[i]];
    int mode = b->bmi.as_mode.first;

    encode_intra_uv4x4(x, i + 16, mode);  // u
    encode_intra_uv4x4(x, i + 20, mode);  // v
John Koleszar's avatar
John Koleszar committed
233
  }
Yaowu Xu's avatar
Yaowu Xu committed
234
}