vp9_encodeintra.c 6.49 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) {
John Koleszar's avatar
John Koleszar committed
20
21
  int i;
  int intra_pred_var = 0;
Paul Wilkins's avatar
Paul Wilkins committed
22
  MB_MODE_INFO * mbmi = &x->e_mbd.mode_info_context->mbmi;
John Koleszar's avatar
John Koleszar committed
23
  (void) cpi;
Tero Rintaluoma's avatar
Tero Rintaluoma committed
24

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

30
    vp9_encode_intra16x16mby(x);
John Koleszar's avatar
John Koleszar committed
31
32
33
  } else {
    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

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

John Koleszar's avatar
John Koleszar committed
40
  return intra_pred_var;
Tero Rintaluoma's avatar
Tero Rintaluoma committed
41
}
42

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

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

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

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

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

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

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

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

82
  vp9_build_intra_predictors_mby(xd);
John Koleszar's avatar
John Koleszar committed
83

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

86
  if (tx_size == TX_16X16) {
87
88
89
90
91
    vp9_transform_mby_16x16(x);
    vp9_quantize_mby_16x16(x);
    if (x->optimize)
      vp9_optimize_mby_16x16(x);
    vp9_inverse_transform_mby_16x16(xd);
92
  } else if (tx_size == TX_8X8) {
93
94
    vp9_transform_mby_8x8(x);
    vp9_quantize_mby_8x8(x);
95
    if (x->optimize)
96
97
      vp9_optimize_mby_8x8(x);
    vp9_inverse_transform_mby_8x8(xd);
98
  } else {
99
100
    vp9_transform_mby_4x4(x);
    vp9_quantize_mby_4x4(x);
101
    if (x->optimize)
102
103
      vp9_optimize_mby_4x4(x);
    vp9_inverse_transform_mby_4x4(xd);
John Koleszar's avatar
John Koleszar committed
104
105
  }

106
  vp9_recon_mby(xd);
John Koleszar's avatar
John Koleszar committed
107
108
}

109
void vp9_encode_intra16x16mbuv(MACROBLOCK *x) {
110
111
112
  MACROBLOCKD *xd = &x->e_mbd;
  TX_SIZE tx_size = xd->mode_info_context->mbmi.txfm_size;

113
  vp9_build_intra_predictors_mbuv(xd);
John Koleszar's avatar
John Koleszar committed
114

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

118
  if (tx_size == TX_4X4) {
119
120
    vp9_transform_mbuv_4x4(x);
    vp9_quantize_mbuv_4x4(x);
121
    if (x->optimize)
122
123
      vp9_optimize_mbuv_4x4(x);
    vp9_inverse_transform_mbuv_4x4(xd);
124
  } else /* 16x16 or 8x8 */ {
125
126
    vp9_transform_mbuv_8x8(x);
    vp9_quantize_mbuv_8x8(x);
127
    if (x->optimize)
128
129
      vp9_optimize_mbuv_8x8(x);
    vp9_inverse_transform_mbuv_8x8(xd);
John Koleszar's avatar
John Koleszar committed
130
131
  }

132
  vp9_recon_intra_mbuv(xd);
John Koleszar's avatar
John Koleszar committed
133
}
Yaowu Xu's avatar
Yaowu Xu committed
134

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

143
  vp9_intra8x8_predict(xd, b, b->bmi.as_mode.first, b->predictor);
144
145
  // generate residual blocks
  vp9_subtract_4b_c(be, b, 16);
Yaowu Xu's avatar
Yaowu Xu committed
146

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

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

  // reconstruct submacroblock
  for (i = 0; i < 4; i++) {
    b = &xd->block[ib + iblock[i]];
187
    vp9_recon_b_c(b->predictor, b->diff, *(b->base_dst) + b->dst,
188
189
                  b->dst_stride);
  }
Yaowu Xu's avatar
Yaowu Xu committed
190
191
}

192
void vp9_encode_intra8x8mby(MACROBLOCK *x) {
John Koleszar's avatar
John Koleszar committed
193
194
195
  int i, ib;

  for (i = 0; i < 4; i++) {
196
    ib = vp9_i8x8_block[i];
197
    vp9_encode_intra8x8(x, ib);
John Koleszar's avatar
John Koleszar committed
198
  }
Yaowu Xu's avatar
Yaowu Xu committed
199
200
}

201
202
static void encode_intra_uv4x4(MACROBLOCK *x, int ib,
                               int mode) {
John Koleszar's avatar
John Koleszar committed
203
204
  BLOCKD *b = &x->e_mbd.block[ib];
  BLOCK *be = &x->block[ib];
Yaowu Xu's avatar
Yaowu Xu committed
205

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

208
  vp9_subtract_b(be, b, 8);
Yaowu Xu's avatar
Yaowu Xu committed
209

Yaowu Xu's avatar
Yaowu Xu committed
210
  x->fwd_txm4x4(be->src_diff, be->coeff, 16);
211
  x->quantize_b_4x4(x, ib);
212
  vp9_inverse_transform_b_4x4(&x->e_mbd, ib, 16);
Yaowu Xu's avatar
Yaowu Xu committed
213

214
215
  vp9_recon_uv_b_c(b->predictor, b->diff, *(b->base_dst) + b->dst,
                   b->dst_stride);
Yaowu Xu's avatar
Yaowu Xu committed
216
217
}

218
void vp9_encode_intra8x8mbuv(MACROBLOCK *x) {
219
  int i, ib, mode;
John Koleszar's avatar
John Koleszar committed
220
  BLOCKD *b;
221

John Koleszar's avatar
John Koleszar committed
222
  for (i = 0; i < 4; i++) {
223
    ib = vp9_i8x8_block[i];
John Koleszar's avatar
John Koleszar committed
224
225
    b = &x->e_mbd.block[ib];
    mode = b->bmi.as_mode.first;
226

John Koleszar's avatar
John Koleszar committed
227
    /*u */
228
    encode_intra_uv4x4(x, i + 16, mode);
John Koleszar's avatar
John Koleszar committed
229
    /*v */
230
    encode_intra_uv4x4(x, i + 20, mode);
John Koleszar's avatar
John Koleszar committed
231
  }
Yaowu Xu's avatar
Yaowu Xu committed
232
}