encodeintra.c 11.1 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
12
 */


#include "vpx_ports/config.h"
John Koleszar's avatar
John Koleszar committed
13
#include "vp8/common/idct.h"
John Koleszar's avatar
John Koleszar committed
14
#include "quantize.h"
John Koleszar's avatar
John Koleszar committed
15
16
#include "vp8/common/reconintra.h"
#include "vp8/common/reconintra4x4.h"
John Koleszar's avatar
John Koleszar committed
17
#include "encodemb.h"
John Koleszar's avatar
John Koleszar committed
18
19
#include "vp8/common/invtrans.h"
#include "vp8/common/recon.h"
John Koleszar's avatar
John Koleszar committed
20
#include "dct.h"
John Koleszar's avatar
John Koleszar committed
21
#include "vp8/common/g_common.h"
John Koleszar's avatar
John Koleszar committed
22
23
24
#include "encodeintra.h"


25
26
27
28
#ifdef ENC_DEBUG
extern int enc_debug;
#endif

John Koleszar's avatar
John Koleszar committed
29
30
31
32
33
#if CONFIG_RUNTIME_CPU_DETECT
#define IF_RTCD(x) (x)
#else
#define IF_RTCD(x) NULL
#endif
34

Jingning Han's avatar
Jingning Han committed
35
36
37
#if CONFIG_HYBRIDTRANSFORM
extern void vp8_ht_quantize_b(BLOCK *b, BLOCKD *d);
#endif
Tero Rintaluoma's avatar
Tero Rintaluoma committed
38

Jingning Han's avatar
Jingning Han committed
39
int vp8_encode_intra(VP8_COMP *cpi, MACROBLOCK *x, int use_16x16_pred) {
John Koleszar's avatar
John Koleszar committed
40
41
42
  int i;
  int intra_pred_var = 0;
  (void) cpi;
Tero Rintaluoma's avatar
Tero Rintaluoma committed
43

John Koleszar's avatar
John Koleszar committed
44
45
  if (use_16x16_pred) {
    x->e_mbd.mode_info_context->mbmi.mode = DC_PRED;
46
#if CONFIG_COMP_INTRA_PRED
John Koleszar's avatar
John Koleszar committed
47
    x->e_mbd.mode_info_context->mbmi.second_mode = (MB_PREDICTION_MODE)(DC_PRED - 1);
48
#endif
John Koleszar's avatar
John Koleszar committed
49
50
51
52
53
54
55
56
    x->e_mbd.mode_info_context->mbmi.uv_mode = DC_PRED;
    x->e_mbd.mode_info_context->mbmi.ref_frame = INTRA_FRAME;

    vp8_encode_intra16x16mby(IF_RTCD(&cpi->rtcd), x);
  } else {
    for (i = 0; i < 16; i++) {
      x->e_mbd.block[i].bmi.as_mode.first = B_DC_PRED;
      vp8_encode_intra4x4block(IF_RTCD(&cpi->rtcd), x, i);
Tero Rintaluoma's avatar
Tero Rintaluoma committed
57
    }
John Koleszar's avatar
John Koleszar committed
58
  }
Tero Rintaluoma's avatar
Tero Rintaluoma committed
59

John Koleszar's avatar
John Koleszar committed
60
  intra_pred_var = VARIANCE_INVOKE(&cpi->rtcd.variance, getmbss)(x->src_diff);
Tero Rintaluoma's avatar
Tero Rintaluoma committed
61

John Koleszar's avatar
John Koleszar committed
62
  return intra_pred_var;
Tero Rintaluoma's avatar
Tero Rintaluoma committed
63
}
64
65

void vp8_encode_intra4x4block(const VP8_ENCODER_RTCD *rtcd,
John Koleszar's avatar
John Koleszar committed
66
67
68
                              MACROBLOCK *x, int ib) {
  BLOCKD *b = &x->e_mbd.block[ib];
  BLOCK *be = &x->block[ib];
69

Jingning Han's avatar
Jingning Han committed
70
71
72
73
74
75
#if CONFIG_HYBRIDTRANSFORM
    int QIndex = x->q_index;
    int active_ht = (QIndex < ACTIVE_HT);
#endif


76
#if CONFIG_COMP_INTRA_PRED
John Koleszar's avatar
John Koleszar committed
77
  if (b->bmi.as_mode.second == (B_PREDICTION_MODE)(B_DC_PRED - 1)) {
78
#endif
79
    RECON_INVOKE(&rtcd->common->recon, intra4x4_predict)
John Koleszar's avatar
John Koleszar committed
80
    (b, b->bmi.as_mode.first, b->predictor);
81
#if CONFIG_COMP_INTRA_PRED
John Koleszar's avatar
John Koleszar committed
82
83
84
85
  } else {
    RECON_INVOKE(&rtcd->common->recon, comp_intra4x4_predict)
    (b, b->bmi.as_mode.first, b->bmi.as_mode.second, b->predictor);
  }
86
#endif
John Koleszar's avatar
John Koleszar committed
87

John Koleszar's avatar
John Koleszar committed
88
  ENCODEMB_INVOKE(&rtcd->encodemb, subb)(be, b, 16);
John Koleszar's avatar
John Koleszar committed
89

Jingning Han's avatar
Jingning Han committed
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#if CONFIG_HYBRIDTRANSFORM
    if(active_ht) {
      b->bmi.as_mode.test = b->bmi.as_mode.first;
      switch(b->bmi.as_mode.first) {
        // case B_DC_PRED :
        case B_TM_PRED :
        case B_RD_PRED :
          b->bmi.as_mode.tx_type = ADST_ADST;
          break;

        case B_VE_PRED :
        case B_VR_PRED :
          b->bmi.as_mode.tx_type = ADST_DCT;
          break;

        case B_HE_PRED :
        case B_HD_PRED :
        case B_HU_PRED :
          b->bmi.as_mode.tx_type = DCT_ADST;
          break;

        default :
          b->bmi.as_mode.tx_type = DCT_DCT;
          break;
      }

      vp8_fht4x4_c(be->src_diff, be->coeff, 32, b->bmi.as_mode.tx_type);
      vp8_ht_quantize_b(be, b);
      vp8_inverse_htransform_b(IF_RTCD(&rtcd->common->idct), b, 32) ;
    } else {
      x->vp8_short_fdct4x4(be->src_diff, be->coeff, 32) ;
      x->quantize_b(be, b) ;
      vp8_inverse_transform_b(IF_RTCD(&rtcd->common->idct), b, 32) ;
    }
#else
    x->vp8_short_fdct4x4(be->src_diff, be->coeff, 32);
    x->quantize_b(be, b);
    vp8_inverse_transform_b(IF_RTCD(&rtcd->common->idct), b, 32);
#endif
John Koleszar's avatar
John Koleszar committed
129

John Koleszar's avatar
John Koleszar committed
130
  RECON_INVOKE(&rtcd->common->recon, recon)(b->predictor, b->diff, *(b->base_dst) + b->dst, b->dst_stride);
John Koleszar's avatar
John Koleszar committed
131
132
}

John Koleszar's avatar
John Koleszar committed
133
134
void vp8_encode_intra4x4mby(const VP8_ENCODER_RTCD *rtcd, MACROBLOCK *mb) {
  int i;
John Koleszar's avatar
John Koleszar committed
135

Adrian Grange's avatar
Adrian Grange committed
136
#if 0
John Koleszar's avatar
John Koleszar committed
137
138
139
  MACROBLOCKD *x = &mb->e_mbd;
  // Intra modes requiring top-right MB reconstructed data have been disabled
  vp8_intra_prediction_down_copy(x);
Adrian Grange's avatar
Adrian Grange committed
140
#endif
John Koleszar's avatar
John Koleszar committed
141

John Koleszar's avatar
John Koleszar committed
142
143
144
  for (i = 0; i < 16; i++)
    vp8_encode_intra4x4block(rtcd, mb, i);
  return;
John Koleszar's avatar
John Koleszar committed
145
146
}

John Koleszar's avatar
John Koleszar committed
147
148
void vp8_encode_intra16x16mby(const VP8_ENCODER_RTCD *rtcd, MACROBLOCK *x) {
  BLOCK *b = &x->block[0];
John Koleszar's avatar
John Koleszar committed
149

John Koleszar's avatar
John Koleszar committed
150
  int tx_type = x->e_mbd.mode_info_context->mbmi.txfm_size;
Paul Wilkins's avatar
Paul Wilkins committed
151

152
#if CONFIG_COMP_INTRA_PRED
John Koleszar's avatar
John Koleszar committed
153
  if (x->e_mbd.mode_info_context->mbmi.second_mode == (MB_PREDICTION_MODE)(DC_PRED - 1))
154
#endif
155
    RECON_INVOKE(&rtcd->common->recon, build_intra_predictors_mby)(&x->e_mbd);
156
#if CONFIG_COMP_INTRA_PRED
John Koleszar's avatar
John Koleszar committed
157
158
  else
    RECON_INVOKE(&rtcd->common->recon, build_comp_intra_predictors_mby)(&x->e_mbd);
159
#endif
John Koleszar's avatar
John Koleszar committed
160

John Koleszar's avatar
John Koleszar committed
161
  ENCODEMB_INVOKE(&rtcd->encodemb, submby)(x->src_diff, *(b->base_src), x->e_mbd.predictor, b->src_stride);
Paul Wilkins's avatar
Paul Wilkins committed
162

John Koleszar's avatar
John Koleszar committed
163
164
165
166
  if (tx_type == TX_8X8)
    vp8_transform_intra_mby_8x8(x);
  else
    vp8_transform_intra_mby(x);
John Koleszar's avatar
John Koleszar committed
167

John Koleszar's avatar
John Koleszar committed
168
169
170
171
  if (tx_type == TX_8X8)
    vp8_quantize_mby_8x8(x);
  else
    vp8_quantize_mby(x);
John Koleszar's avatar
John Koleszar committed
172

John Koleszar's avatar
John Koleszar committed
173
174
175
  if (x->optimize) {
    if (tx_type == TX_8X8)
      vp8_optimize_mby_8x8(x, rtcd);
176
    else
John Koleszar's avatar
John Koleszar committed
177
178
179
180
181
182
183
      vp8_optimize_mby(x, rtcd);
  }

  if (tx_type == TX_8X8)
    vp8_inverse_transform_mby_8x8(IF_RTCD(&rtcd->common->idct), &x->e_mbd);
  else
    vp8_inverse_transform_mby(IF_RTCD(&rtcd->common->idct), &x->e_mbd);
184
185

#ifdef ENC_DEBUG
John Koleszar's avatar
John Koleszar committed
186
187
188
189
190
191
192
193
194
195
196
197
  if (enc_debug) {
    int i;
    printf("Intra qcoeff:\n");
    printf("%d %d:\n", x->e_mbd.mb_to_left_edge, x->e_mbd.mb_to_top_edge);
    for (i = 0; i < 400; i++) {
      printf("%3d ", x->e_mbd.qcoeff[i]);
      if (i % 16 == 15) printf("\n");
    }
    printf("Intra dqcoeff:\n");
    for (i = 0; i < 400; i++) {
      printf("%3d ", x->e_mbd.dqcoeff[i]);
      if (i % 16 == 15) printf("\n");
198
    }
John Koleszar's avatar
John Koleszar committed
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
    printf("Intra diff:\n");
    for (i = 0; i < 400; i++) {
      printf("%3d ", x->e_mbd.diff[i]);
      if (i % 16 == 15) printf("\n");
    }
    printf("Intra predictor:\n");
    for (i = 0; i < 400; i++) {
      printf("%3d ", x->e_mbd.predictor[i]);
      if (i % 16 == 15) printf("\n");
    }
    printf("eobs:\n");
    for (i = 0; i < 25; i++)
      printf("%d ", x->e_mbd.block[i].eob);
    printf("\n");
  }
214
#endif
John Koleszar's avatar
John Koleszar committed
215

John Koleszar's avatar
John Koleszar committed
216
217
  RECON_INVOKE(&rtcd->common->recon, recon_mby)
  (IF_RTCD(&rtcd->common->recon), &x->e_mbd);
John Koleszar's avatar
John Koleszar committed
218
219
220

}

John Koleszar's avatar
John Koleszar committed
221
222
void vp8_encode_intra16x16mbuv(const VP8_ENCODER_RTCD *rtcd, MACROBLOCK *x) {
  int tx_type = x->e_mbd.mode_info_context->mbmi.txfm_size;
223
#if CONFIG_COMP_INTRA_PRED
John Koleszar's avatar
John Koleszar committed
224
  if (x->e_mbd.mode_info_context->mbmi.second_uv_mode == (MB_PREDICTION_MODE)(DC_PRED - 1)) {
Paul Wilkins's avatar
Paul Wilkins committed
225
#endif
226
    RECON_INVOKE(&rtcd->common->recon, build_intra_predictors_mbuv)(&x->e_mbd);
227
#if CONFIG_COMP_INTRA_PRED
John Koleszar's avatar
John Koleszar committed
228
229
230
  } else {
    RECON_INVOKE(&rtcd->common->recon, build_comp_intra_predictors_mbuv)(&x->e_mbd);
  }
231
#endif
John Koleszar's avatar
John Koleszar committed
232

John Koleszar's avatar
John Koleszar committed
233
234
235
236
237
  ENCODEMB_INVOKE(&rtcd->encodemb, submbuv)(x->src_diff, x->src.u_buffer, x->src.v_buffer, x->e_mbd.predictor, x->src.uv_stride);
  if (tx_type == TX_8X8)
    vp8_transform_mbuv_8x8(x);
  else
    vp8_transform_mbuv(x);
John Koleszar's avatar
John Koleszar committed
238

John Koleszar's avatar
John Koleszar committed
239
240
241
242
  if (tx_type == TX_8X8)
    vp8_quantize_mbuv_8x8(x);
  else
    vp8_quantize_mbuv(x);
243
244

#ifdef ENC_DEBUG
John Koleszar's avatar
John Koleszar committed
245
246
247
248
249
250
251
252
  if (enc_debug) {
    int i;
    printf("vp8_encode_intra16x16mbuv\n");
    printf("%d %d:\n", x->e_mbd.mb_to_left_edge, x->e_mbd.mb_to_top_edge);
    printf("qcoeff:\n");
    for (i = 0; i < 400; i++) {
      printf("%3d ", x->e_mbd.qcoeff[i]);
      if (i % 16 == 15) printf("\n");
253
    }
John Koleszar's avatar
John Koleszar committed
254
255
256
257
    printf("dqcoeff:\n");
    for (i = 0; i < 400; i++) {
      printf("%3d ", x->e_mbd.dqcoeff[i]);
      if (i % 16 == 15) printf("\n");
258
    }
John Koleszar's avatar
John Koleszar committed
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
    printf("diff:\n");
    for (i = 0; i < 400; i++) {
      printf("%3d ", x->e_mbd.diff[i]);
      if (i % 16 == 15) printf("\n");
    }
    printf("predictor:\n");
    for (i = 0; i < 400; i++) {
      printf("%3d ", x->e_mbd.predictor[i]);
      if (i % 16 == 15) printf("\n");
    }
    printf("eobs:\n");
    for (i = 0; i < 25; i++)
      printf("%d ", x->e_mbd.block[i].eob);
    printf("\n");
  }
#endif
  if (x->optimize) {
    if (tx_type == TX_8X8)
      vp8_optimize_mbuv_8x8(x, rtcd);
278
    else
John Koleszar's avatar
John Koleszar committed
279
280
281
282
283
284
285
      vp8_optimize_mbuv(x, rtcd);
  }

  if (tx_type == TX_8X8)
    vp8_inverse_transform_mbuv_8x8(IF_RTCD(&rtcd->common->idct), &x->e_mbd);
  else
    vp8_inverse_transform_mbuv(IF_RTCD(&rtcd->common->idct), &x->e_mbd);
John Koleszar's avatar
John Koleszar committed
286

John Koleszar's avatar
John Koleszar committed
287
  vp8_recon_intra_mbuv(IF_RTCD(&rtcd->common->recon), &x->e_mbd);
John Koleszar's avatar
John Koleszar committed
288
}
Yaowu Xu's avatar
Yaowu Xu committed
289
290

void vp8_encode_intra8x8(const VP8_ENCODER_RTCD *rtcd,
John Koleszar's avatar
John Koleszar committed
291
292
293
294
295
                         MACROBLOCK *x, int ib) {
  BLOCKD *b = &x->e_mbd.block[ib];
  BLOCK *be = &x->block[ib];
  const int iblock[4] = {0, 1, 4, 5};
  int i;
Yaowu Xu's avatar
Yaowu Xu committed
296

297
#if CONFIG_COMP_INTRA_PRED
John Koleszar's avatar
John Koleszar committed
298
  if (b->bmi.as_mode.second == (MB_PREDICTION_MODE)(DC_PRED - 1)) {
299
#endif
Yaowu Xu's avatar
Yaowu Xu committed
300
    RECON_INVOKE(&rtcd->common->recon, intra8x8_predict)
John Koleszar's avatar
John Koleszar committed
301
    (b, b->bmi.as_mode.first, b->predictor);
302
#if CONFIG_COMP_INTRA_PRED
John Koleszar's avatar
John Koleszar committed
303
304
305
306
  } else {
    RECON_INVOKE(&rtcd->common->recon, comp_intra8x8_predict)
    (b, b->bmi.as_mode.first, b->bmi.as_mode.second, b->predictor);
  }
307
#endif
Yaowu Xu's avatar
Yaowu Xu committed
308

309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
#if CONFIG_HTRANS8X8
  {
    MACROBLOCKD *xd = &x->e_mbd;
    int idx = (ib & 0x02) ? (ib + 2) : ib;

    // generate residual blocks
    vp8_subtract_4b_c(be, b, 16);
    x->vp8_short_fdct8x8(be->src_diff, (x->block + idx)->coeff, 32);
    x->quantize_b_8x8(x->block + idx, xd->block + idx);
    vp8_short_idct8x8_c(xd->block[idx].dqcoeff, xd->block[ib].diff, 32);

    // reconstruct submacroblock
    for (i = 0; i < 4; i++) {
      b = &xd->block[ib + iblock[i]];
      vp8_recon_b_c(b->predictor, b->diff, *(b->base_dst) + b->dst,
                    b->dst_stride);
    }
  }
#else
John Koleszar's avatar
John Koleszar committed
328
329
330
331
332
333
334
335
  for (i = 0; i < 4; i++) {
    b = &x->e_mbd.block[ib + iblock[i]];
    be = &x->block[ib + iblock[i]];
    ENCODEMB_INVOKE(&rtcd->encodemb, subb)(be, b, 16);
    x->vp8_short_fdct4x4(be->src_diff, be->coeff, 32);
    x->quantize_b(be, b);
    vp8_inverse_transform_b(IF_RTCD(&rtcd->common->idct), b, 32);
    RECON_INVOKE(&rtcd->common->recon, recon)(b->predictor,
336
337
                                              b->diff, *(b->base_dst) + b->dst,
                                              b->dst_stride);
John Koleszar's avatar
John Koleszar committed
338
  }
339
#endif
Yaowu Xu's avatar
Yaowu Xu committed
340
341
342
}

extern const int vp8_i8x8_block[4];
John Koleszar's avatar
John Koleszar committed
343
344
345
346
347
348
349
void vp8_encode_intra8x8mby(const VP8_ENCODER_RTCD *rtcd, MACROBLOCK *x) {
  int i, ib;

  for (i = 0; i < 4; i++) {
    ib = vp8_i8x8_block[i];
    vp8_encode_intra8x8(rtcd, x, ib);
  }
Yaowu Xu's avatar
Yaowu Xu committed
350
351
352
353

}

void vp8_encode_intra_uv4x4(const VP8_ENCODER_RTCD *rtcd,
John Koleszar's avatar
John Koleszar committed
354
355
356
357
                            MACROBLOCK *x, int ib,
                            int mode, int second) {
  BLOCKD *b = &x->e_mbd.block[ib];
  BLOCK *be = &x->block[ib];
Yaowu Xu's avatar
Yaowu Xu committed
358

359
#if CONFIG_COMP_INTRA_PRED
John Koleszar's avatar
John Koleszar committed
360
  if (second == -1) {
361
#endif
Yaowu Xu's avatar
Yaowu Xu committed
362
    RECON_INVOKE(&rtcd->common->recon, intra_uv4x4_predict)
John Koleszar's avatar
John Koleszar committed
363
    (b, mode, b->predictor);
364
#if CONFIG_COMP_INTRA_PRED
John Koleszar's avatar
John Koleszar committed
365
366
367
368
  } else {
    RECON_INVOKE(&rtcd->common->recon, comp_intra_uv4x4_predict)
    (b, mode, second, b->predictor);
  }
369
#endif
Yaowu Xu's avatar
Yaowu Xu committed
370

John Koleszar's avatar
John Koleszar committed
371
  ENCODEMB_INVOKE(&rtcd->encodemb, subb)(be, b, 8);
Yaowu Xu's avatar
Yaowu Xu committed
372

John Koleszar's avatar
John Koleszar committed
373
  x->vp8_short_fdct4x4(be->src_diff, be->coeff, 16);
Yaowu Xu's avatar
Yaowu Xu committed
374

John Koleszar's avatar
John Koleszar committed
375
  x->quantize_b(be, b);
Yaowu Xu's avatar
Yaowu Xu committed
376

John Koleszar's avatar
John Koleszar committed
377
  vp8_inverse_transform_b(IF_RTCD(&rtcd->common->idct), b, 16);
Yaowu Xu's avatar
Yaowu Xu committed
378

John Koleszar's avatar
John Koleszar committed
379
380
  RECON_INVOKE(&rtcd->common->recon, recon_uv)(b->predictor,
                                               b->diff, *(b->base_dst) + b->dst, b->dst_stride);
Yaowu Xu's avatar
Yaowu Xu committed
381
382
383
384
}



John Koleszar's avatar
John Koleszar committed
385
386
387
388
389
390
391
void vp8_encode_intra8x8mbuv(const VP8_ENCODER_RTCD *rtcd, MACROBLOCK *x) {
  int i, ib, mode, second;
  BLOCKD *b;
  for (i = 0; i < 4; i++) {
    ib = vp8_i8x8_block[i];
    b = &x->e_mbd.block[ib];
    mode = b->bmi.as_mode.first;
392
#if CONFIG_COMP_INTRA_PRED
John Koleszar's avatar
John Koleszar committed
393
    second = b->bmi.as_mode.second;
394
#else
John Koleszar's avatar
John Koleszar committed
395
    second = -1;
396
#endif
John Koleszar's avatar
John Koleszar committed
397
398
399
400
401
    /*u */
    vp8_encode_intra_uv4x4(rtcd, x, i + 16, mode, second);
    /*v */
    vp8_encode_intra_uv4x4(rtcd, x, i + 20, mode, second);
  }
Yaowu Xu's avatar
Yaowu Xu committed
402
}