vp9_encodeintra.c 6.79 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(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(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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
  switch (tx_size) {
    case TX_16X16:
      vp9_transform_mby_16x16(x);
      vp9_quantize_mby_16x16(x);
      if (x->optimize)
        vp9_optimize_mby_16x16(x);
      vp9_inverse_transform_mby_16x16(xd);
      break;
    case TX_8X8:
      vp9_transform_mby_8x8(x);
      vp9_quantize_mby_8x8(x);
      if (x->optimize)
        vp9_optimize_mby_8x8(x);
      vp9_inverse_transform_mby_8x8(xd);
      break;
    default:
      vp9_transform_mby_4x4(x);
      vp9_quantize_mby_4x4(x);
      if (x->optimize)
        vp9_optimize_mby_4x4(x);
      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(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
125
126
127
128
129
130
131
132
133
134
135
  switch (tx_size) {
    case TX_4X4:
      vp9_transform_mbuv_4x4(x);
      vp9_quantize_mbuv_4x4(x);
      if (x->optimize)
        vp9_optimize_mbuv_4x4(x);
      vp9_inverse_transform_mbuv_4x4(xd);
      break;
    default:  // 16x16 or 8x8
      vp9_transform_mbuv_8x8(x);
      vp9_quantize_mbuv_8x8(x);
      if (x->optimize)
        vp9_optimize_mbuv_8x8(x);
      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
}