encodeintra.c 8.53 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

35
int vp8_encode_intra(VP8_COMP *cpi, MACROBLOCK *x, int use_16x16_pred)
Tero Rintaluoma's avatar
Tero Rintaluoma committed
36 37 38 39 40 41
{

    int i;
    int intra_pred_var = 0;
    (void) cpi;

42
    if (use_16x16_pred)
Tero Rintaluoma's avatar
Tero Rintaluoma committed
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
    {
        x->e_mbd.mode_info_context->mbmi.mode = DC_PRED;
        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 = B_DC_PRED;
            vp8_encode_intra4x4block(IF_RTCD(&cpi->rtcd), x, i);
        }
    }

    intra_pred_var = VARIANCE_INVOKE(&cpi->rtcd.variance, getmbss)(x->src_diff);

    return intra_pred_var;
}
63 64 65

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

70
    RECON_INVOKE(&rtcd->common->recon, intra4x4_predict)
Scott LaVarnway's avatar
Scott LaVarnway committed
71
                (b, b->bmi.as_mode, b->predictor);
John Koleszar's avatar
John Koleszar committed
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91

    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, b->diff, *(b->base_dst) + b->dst, b->dst_stride);
}

void vp8_encode_intra4x4mby(const VP8_ENCODER_RTCD *rtcd, MACROBLOCK *mb)
{
    int i;

    MACROBLOCKD *x = &mb->e_mbd;
    vp8_intra_prediction_down_copy(x);

    for (i = 0; i < 16; i++)
92
        vp8_encode_intra4x4block(rtcd, mb, i);
John Koleszar's avatar
John Koleszar committed
93 94 95 96 97
    return;
}

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

Paul Wilkins's avatar
Paul Wilkins committed
100 101 102
#if CONFIG_T8X8
    int tx_type = get_seg_tx_type(&x->e_mbd,
                                  x->e_mbd.mode_info_context->mbmi.segment_id);
103
    x->e_mbd.mode_info_context->mbmi.txfm_size = tx_type;
Paul Wilkins's avatar
Paul Wilkins committed
104 105
#endif

106
    RECON_INVOKE(&rtcd->common->recon, build_intra_predictors_mby)(&x->e_mbd);
John Koleszar's avatar
John Koleszar committed
107

108
    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
109

110
#if CONFIG_T8X8
Paul Wilkins's avatar
Paul Wilkins committed
111
    if( tx_type == TX_8X8 )
112 113 114
        vp8_transform_intra_mby_8x8(x);
    else
#endif
John Koleszar's avatar
John Koleszar committed
115 116
    vp8_transform_intra_mby(x);

117
#if  CONFIG_T8X8
Paul Wilkins's avatar
Paul Wilkins committed
118
    if(tx_type == TX_8X8)
119 120 121 122
      vp8_quantize_mby_8x8(x);
    else
#endif
      vp8_quantize_mby(x);
John Koleszar's avatar
John Koleszar committed
123

124
    if (x->optimize)
125 126
    {
#if CONFIG_T8X8
Paul Wilkins's avatar
Paul Wilkins committed
127
      if( tx_type == TX_8X8 )
128 129 130
        vp8_optimize_mby_8x8(x, rtcd);
      else
#endif
John Koleszar's avatar
John Koleszar committed
131
        vp8_optimize_mby(x, rtcd);
132
    }
John Koleszar's avatar
John Koleszar committed
133

134
#if CONFIG_T8X8
Paul Wilkins's avatar
Paul Wilkins committed
135
    if(tx_type == TX_8X8)
136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170
      vp8_inverse_transform_mby_8x8(IF_RTCD(&rtcd->common->idct), &x->e_mbd);
    else
#endif
      vp8_inverse_transform_mby(IF_RTCD(&rtcd->common->idct), &x->e_mbd);

#ifdef ENC_DEBUG
    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");
      }
      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");
    }
#endif
John Koleszar's avatar
John Koleszar committed
171

172 173
    RECON_INVOKE(&rtcd->common->recon, recon_mby)
        (IF_RTCD(&rtcd->common->recon), &x->e_mbd);
John Koleszar's avatar
John Koleszar committed
174 175 176 177 178

}

void vp8_encode_intra16x16mbuv(const VP8_ENCODER_RTCD *rtcd, MACROBLOCK *x)
{
Paul Wilkins's avatar
Paul Wilkins committed
179 180 181
#if CONFIG_T8X8
    int tx_type = get_seg_tx_type(&x->e_mbd,
                                  x->e_mbd.mode_info_context->mbmi.segment_id);
182
    x->e_mbd.mode_info_context->mbmi.txfm_size = tx_type;
Paul Wilkins's avatar
Paul Wilkins committed
183 184
#endif

185
    RECON_INVOKE(&rtcd->common->recon, build_intra_predictors_mbuv)(&x->e_mbd);
John Koleszar's avatar
John Koleszar committed
186 187

    ENCODEMB_INVOKE(&rtcd->encodemb, submbuv)(x->src_diff, x->src.u_buffer, x->src.v_buffer, x->e_mbd.predictor, x->src.uv_stride);
188
#if CONFIG_T8X8
Paul Wilkins's avatar
Paul Wilkins committed
189
    if(tx_type == TX_8X8)
190 191 192 193
        vp8_transform_mbuv_8x8(x);
    else
#endif
        vp8_transform_mbuv(x);
John Koleszar's avatar
John Koleszar committed
194

195
#if CONFIG_T8X8
Paul Wilkins's avatar
Paul Wilkins committed
196
    if(tx_type == TX_8X8)
197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232
        vp8_quantize_mbuv_8x8(x);
    else
#endif
        vp8_quantize_mbuv(x);

#ifdef ENC_DEBUG
    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");
      }
      printf("dqcoeff:\n");
      for (i =0; i<400; i++) {
        printf("%3d ", x->e_mbd.dqcoeff[i]);
        if (i%16 == 15) printf("\n");
      }
      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
Yaowu Xu's avatar
Yaowu Xu committed
233
    if (x->optimize)
234 235
    {
#if CONFIG_T8X8
Paul Wilkins's avatar
Paul Wilkins committed
236
      if(tx_type == TX_8X8)
237 238 239
        vp8_optimize_mbuv_8x8(x, rtcd);
      else
#endif
John Koleszar's avatar
John Koleszar committed
240
        vp8_optimize_mbuv(x, rtcd);
241
    }
John Koleszar's avatar
John Koleszar committed
242

243
#if CONFIG_T8X8
Paul Wilkins's avatar
Paul Wilkins committed
244
    if(tx_type == TX_8X8)
245 246 247
      vp8_inverse_transform_mbuv_8x8(IF_RTCD(&rtcd->common->idct), &x->e_mbd);
    else
#endif
John Koleszar's avatar
John Koleszar committed
248 249 250 251
    vp8_inverse_transform_mbuv(IF_RTCD(&rtcd->common->idct), &x->e_mbd);

    vp8_recon_intra_mbuv(IF_RTCD(&rtcd->common->recon), &x->e_mbd);
}
Yaowu Xu's avatar
Yaowu Xu committed
252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329

void vp8_encode_intra8x8(const VP8_ENCODER_RTCD *rtcd,
                              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;

    RECON_INVOKE(&rtcd->common->recon, intra8x8_predict)
                (b, b->bmi.as_mode, b->predictor);

    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,
            b->diff, *(b->base_dst) + b->dst, b->dst_stride);
    }

}

extern const int vp8_i8x8_block[4];
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);
    }

}

void vp8_encode_intra_uv4x4(const VP8_ENCODER_RTCD *rtcd,
                              MACROBLOCK *x, int ib,
                              int mode)
{
    BLOCKD *b = &x->e_mbd.block[ib];
    BLOCK *be = &x->block[ib];

    RECON_INVOKE(&rtcd->common->recon, intra_uv4x4_predict)
                (b, mode, b->predictor);

    ENCODEMB_INVOKE(&rtcd->encodemb, subb)(be, b, 8);

    x->vp8_short_fdct4x4(be->src_diff, be->coeff, 16);

    x->quantize_b(be, b);

    vp8_inverse_transform_b(IF_RTCD(&rtcd->common->idct), b, 16);

    RECON_INVOKE(&rtcd->common->recon, recon_uv)(b->predictor,
        b->diff, *(b->base_dst) + b->dst, b->dst_stride);
}



void vp8_encode_intra8x8mbuv(const VP8_ENCODER_RTCD *rtcd, MACROBLOCK *x)
{
    int i, ib, mode;
    BLOCKD *b;
    for(i=0;i<4;i++)
    {
        ib = vp8_i8x8_block[i];
        b = &x->e_mbd.block[ib];
        mode = b->bmi.as_mode;
        /*u */
        vp8_encode_intra_uv4x4(rtcd, x, i+16, mode);
        /*v */
        vp8_encode_intra_uv4x4(rtcd, x, i+20, mode);
    }
}