Home | History | Annotate | Download | only in encoder
      1 /*
      2  *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
      3  *
      4  *  Use of this source code is governed by a BSD-style license
      5  *  that can be found in the LICENSE file in the root of the source
      6  *  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.
      9  */
     10 
     11 
     12 #include <math.h>
     13 #include <stdio.h>
     14 #include <string.h>
     15 #include <assert.h>
     16 #include "onyx_int.h"
     17 #include "tokenize.h"
     18 #include "vpx_mem/vpx_mem.h"
     19 
     20 /* Global event counters used for accumulating statistics across several
     21    compressions, then generating context.c = initial stats. */
     22 
     23 #ifdef VP8_ENTROPY_STATS
     24 _int64 context_counters[BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [MAX_ENTROPY_TOKENS];
     25 #endif
     26 void vp8_stuff_mb(VP8_COMP *cpi, MACROBLOCK *x, TOKENEXTRA **t) ;
     27 void vp8_fix_contexts(MACROBLOCKD *x);
     28 
     29 #include "dct_value_tokens.h"
     30 #include "dct_value_cost.h"
     31 
     32 const TOKENVALUE *const vp8_dct_value_tokens_ptr = dct_value_tokens +
     33         DCT_MAX_VALUE;
     34 const short *const vp8_dct_value_cost_ptr = dct_value_cost + DCT_MAX_VALUE;
     35 
     36 #if 0
     37 int skip_true_count = 0;
     38 int skip_false_count = 0;
     39 #endif
     40 
     41 /* function used to generate dct_value_tokens and dct_value_cost tables */
     42 /*
     43 static void fill_value_tokens()
     44 {
     45 
     46     TOKENVALUE *t = dct_value_tokens + DCT_MAX_VALUE;
     47     const vp8_extra_bit_struct *e = vp8_extra_bits;
     48 
     49     int i = -DCT_MAX_VALUE;
     50     int sign = 1;
     51 
     52     do
     53     {
     54         if (!i)
     55             sign = 0;
     56 
     57         {
     58             const int a = sign ? -i : i;
     59             int eb = sign;
     60 
     61             if (a > 4)
     62             {
     63                 int j = 4;
     64 
     65                 while (++j < 11  &&  e[j].base_val <= a) {}
     66 
     67                 t[i].Token = --j;
     68                 eb |= (a - e[j].base_val) << 1;
     69             }
     70             else
     71                 t[i].Token = a;
     72 
     73             t[i].Extra = eb;
     74         }
     75 
     76         // initialize the cost for extra bits for all possible coefficient value.
     77         {
     78             int cost = 0;
     79             const vp8_extra_bit_struct *p = vp8_extra_bits + t[i].Token;
     80 
     81             if (p->base_val)
     82             {
     83                 const int extra = t[i].Extra;
     84                 const int Length = p->Len;
     85 
     86                 if (Length)
     87                     cost += vp8_treed_cost(p->tree, p->prob, extra >> 1, Length);
     88 
     89                 cost += vp8_cost_bit(vp8_prob_half, extra & 1); // sign
     90                 dct_value_cost[i + DCT_MAX_VALUE] = cost;
     91             }
     92 
     93         }
     94 
     95     }
     96     while (++i < DCT_MAX_VALUE);
     97 
     98     vp8_dct_value_tokens_ptr = dct_value_tokens + DCT_MAX_VALUE;
     99     vp8_dct_value_cost_ptr   = dct_value_cost + DCT_MAX_VALUE;
    100 }
    101 */
    102 
    103 static void tokenize2nd_order_b
    104 (
    105     MACROBLOCK *x,
    106     TOKENEXTRA **tp,
    107     VP8_COMP *cpi
    108 )
    109 {
    110     MACROBLOCKD *xd = &x->e_mbd;
    111     int pt;             /* near block/prev token context index */
    112     int c;              /* start at DC */
    113     TOKENEXTRA *t = *tp;/* store tokens starting here */
    114     const BLOCKD *b;
    115     const short *qcoeff_ptr;
    116     ENTROPY_CONTEXT * a;
    117     ENTROPY_CONTEXT * l;
    118     int band, rc, v, token;
    119     int eob;
    120 
    121     b = xd->block + 24;
    122     qcoeff_ptr = b->qcoeff;
    123     a = (ENTROPY_CONTEXT *)xd->above_context + 8;
    124     l = (ENTROPY_CONTEXT *)xd->left_context + 8;
    125     eob = xd->eobs[24];
    126     VP8_COMBINEENTROPYCONTEXTS(pt, *a, *l);
    127 
    128     if(!eob)
    129     {
    130         /* c = band for this case */
    131         t->Token = DCT_EOB_TOKEN;
    132         t->context_tree = cpi->common.fc.coef_probs [1] [0] [pt];
    133         t->skip_eob_node = 0;
    134 
    135         ++x->coef_counts       [1] [0] [pt] [DCT_EOB_TOKEN];
    136         t++;
    137         *tp = t;
    138         *a = *l = 0;
    139         return;
    140     }
    141 
    142     v = qcoeff_ptr[0];
    143     t->Extra = vp8_dct_value_tokens_ptr[v].Extra;
    144     token    = vp8_dct_value_tokens_ptr[v].Token;
    145     t->Token = token;
    146 
    147     t->context_tree = cpi->common.fc.coef_probs [1] [0] [pt];
    148     t->skip_eob_node = 0;
    149     ++x->coef_counts       [1] [0] [pt] [token];
    150     pt = vp8_prev_token_class[token];
    151     t++;
    152     c = 1;
    153 
    154     for (; c < eob; c++)
    155     {
    156         rc = vp8_default_zig_zag1d[c];
    157         band = vp8_coef_bands[c];
    158         v = qcoeff_ptr[rc];
    159 
    160         t->Extra = vp8_dct_value_tokens_ptr[v].Extra;
    161         token    = vp8_dct_value_tokens_ptr[v].Token;
    162 
    163         t->Token = token;
    164         t->context_tree = cpi->common.fc.coef_probs [1] [band] [pt];
    165 
    166         t->skip_eob_node = ((pt == 0));
    167 
    168         ++x->coef_counts       [1] [band] [pt] [token];
    169 
    170         pt = vp8_prev_token_class[token];
    171         t++;
    172     }
    173     if (c < 16)
    174     {
    175         band = vp8_coef_bands[c];
    176         t->Token = DCT_EOB_TOKEN;
    177         t->context_tree = cpi->common.fc.coef_probs [1] [band] [pt];
    178 
    179         t->skip_eob_node = 0;
    180 
    181         ++x->coef_counts       [1] [band] [pt] [DCT_EOB_TOKEN];
    182 
    183         t++;
    184     }
    185 
    186     *tp = t;
    187     *a = *l = 1;
    188 
    189 }
    190 
    191 static void tokenize1st_order_b
    192 (
    193     MACROBLOCK *x,
    194     TOKENEXTRA **tp,
    195     int type,           /* which plane: 0=Y no DC, 1=Y2, 2=UV, 3=Y with DC */
    196     VP8_COMP *cpi
    197 )
    198 {
    199     MACROBLOCKD *xd = &x->e_mbd;
    200     unsigned int block;
    201     const BLOCKD *b;
    202     int pt;             /* near block/prev token context index */
    203     int c;
    204     int token;
    205     TOKENEXTRA *t = *tp;/* store tokens starting here */
    206     const short *qcoeff_ptr;
    207     ENTROPY_CONTEXT * a;
    208     ENTROPY_CONTEXT * l;
    209     int band, rc, v;
    210     int tmp1, tmp2;
    211 
    212     b = xd->block;
    213     /* Luma */
    214     for (block = 0; block < 16; block++, b++)
    215     {
    216         tmp1 = vp8_block2above[block];
    217         tmp2 = vp8_block2left[block];
    218         qcoeff_ptr = b->qcoeff;
    219         a = (ENTROPY_CONTEXT *)xd->above_context + tmp1;
    220         l = (ENTROPY_CONTEXT *)xd->left_context + tmp2;
    221 
    222         VP8_COMBINEENTROPYCONTEXTS(pt, *a, *l);
    223 
    224         c = type ? 0 : 1;
    225 
    226         if(c >= *b->eob)
    227         {
    228             /* c = band for this case */
    229             t->Token = DCT_EOB_TOKEN;
    230             t->context_tree = cpi->common.fc.coef_probs [type] [c] [pt];
    231             t->skip_eob_node = 0;
    232 
    233             ++x->coef_counts       [type] [c] [pt] [DCT_EOB_TOKEN];
    234             t++;
    235             *tp = t;
    236             *a = *l = 0;
    237             continue;
    238         }
    239 
    240         v = qcoeff_ptr[c];
    241 
    242         t->Extra = vp8_dct_value_tokens_ptr[v].Extra;
    243         token    = vp8_dct_value_tokens_ptr[v].Token;
    244         t->Token = token;
    245 
    246         t->context_tree = cpi->common.fc.coef_probs [type] [c] [pt];
    247         t->skip_eob_node = 0;
    248         ++x->coef_counts       [type] [c] [pt] [token];
    249         pt = vp8_prev_token_class[token];
    250         t++;
    251         c++;
    252 
    253         for (; c < *b->eob; c++)
    254         {
    255             rc = vp8_default_zig_zag1d[c];
    256             band = vp8_coef_bands[c];
    257             v = qcoeff_ptr[rc];
    258 
    259             t->Extra = vp8_dct_value_tokens_ptr[v].Extra;
    260             token    = vp8_dct_value_tokens_ptr[v].Token;
    261 
    262             t->Token = token;
    263             t->context_tree = cpi->common.fc.coef_probs [type] [band] [pt];
    264 
    265             t->skip_eob_node = (pt == 0);
    266             ++x->coef_counts       [type] [band] [pt] [token];
    267 
    268             pt = vp8_prev_token_class[token];
    269             t++;
    270         }
    271         if (c < 16)
    272         {
    273             band = vp8_coef_bands[c];
    274             t->Token = DCT_EOB_TOKEN;
    275             t->context_tree = cpi->common.fc.coef_probs [type] [band] [pt];
    276 
    277             t->skip_eob_node = 0;
    278             ++x->coef_counts       [type] [band] [pt] [DCT_EOB_TOKEN];
    279 
    280             t++;
    281         }
    282         *tp = t;
    283         *a = *l = 1;
    284     }
    285 
    286     /* Chroma */
    287     for (block = 16; block < 24; block++, b++)
    288     {
    289         tmp1 = vp8_block2above[block];
    290         tmp2 = vp8_block2left[block];
    291         qcoeff_ptr = b->qcoeff;
    292         a = (ENTROPY_CONTEXT *)xd->above_context + tmp1;
    293         l = (ENTROPY_CONTEXT *)xd->left_context + tmp2;
    294 
    295         VP8_COMBINEENTROPYCONTEXTS(pt, *a, *l);
    296 
    297         if(!(*b->eob))
    298         {
    299             /* c = band for this case */
    300             t->Token = DCT_EOB_TOKEN;
    301             t->context_tree = cpi->common.fc.coef_probs [2] [0] [pt];
    302             t->skip_eob_node = 0;
    303 
    304             ++x->coef_counts       [2] [0] [pt] [DCT_EOB_TOKEN];
    305             t++;
    306             *tp = t;
    307             *a = *l = 0;
    308             continue;
    309         }
    310 
    311         v = qcoeff_ptr[0];
    312 
    313         t->Extra = vp8_dct_value_tokens_ptr[v].Extra;
    314         token    = vp8_dct_value_tokens_ptr[v].Token;
    315         t->Token = token;
    316 
    317         t->context_tree = cpi->common.fc.coef_probs [2] [0] [pt];
    318         t->skip_eob_node = 0;
    319         ++x->coef_counts       [2] [0] [pt] [token];
    320         pt = vp8_prev_token_class[token];
    321         t++;
    322         c = 1;
    323 
    324         for (; c < *b->eob; c++)
    325         {
    326             rc = vp8_default_zig_zag1d[c];
    327             band = vp8_coef_bands[c];
    328             v = qcoeff_ptr[rc];
    329 
    330             t->Extra = vp8_dct_value_tokens_ptr[v].Extra;
    331             token    = vp8_dct_value_tokens_ptr[v].Token;
    332 
    333             t->Token = token;
    334             t->context_tree = cpi->common.fc.coef_probs [2] [band] [pt];
    335 
    336             t->skip_eob_node = (pt == 0);
    337 
    338             ++x->coef_counts       [2] [band] [pt] [token];
    339 
    340             pt = vp8_prev_token_class[token];
    341             t++;
    342         }
    343         if (c < 16)
    344         {
    345             band = vp8_coef_bands[c];
    346             t->Token = DCT_EOB_TOKEN;
    347             t->context_tree = cpi->common.fc.coef_probs [2] [band] [pt];
    348 
    349             t->skip_eob_node = 0;
    350 
    351             ++x->coef_counts       [2] [band] [pt] [DCT_EOB_TOKEN];
    352 
    353             t++;
    354         }
    355         *tp = t;
    356         *a = *l = 1;
    357     }
    358 }
    359 
    360 
    361 static int mb_is_skippable(MACROBLOCKD *x, int has_y2_block)
    362 {
    363     int skip = 1;
    364     int i = 0;
    365 
    366     if (has_y2_block)
    367     {
    368         for (i = 0; i < 16; i++)
    369             skip &= (x->eobs[i] < 2);
    370     }
    371 
    372     for (; i < 24 + has_y2_block; i++)
    373         skip &= (!x->eobs[i]);
    374 
    375     return skip;
    376 }
    377 
    378 
    379 void vp8_tokenize_mb(VP8_COMP *cpi, MACROBLOCK *x, TOKENEXTRA **t)
    380 {
    381     MACROBLOCKD *xd = &x->e_mbd;
    382     int plane_type;
    383     int has_y2_block;
    384 
    385     has_y2_block = (xd->mode_info_context->mbmi.mode != B_PRED
    386                     && xd->mode_info_context->mbmi.mode != SPLITMV);
    387 
    388     xd->mode_info_context->mbmi.mb_skip_coeff =
    389         mb_is_skippable(xd, has_y2_block);
    390     if (xd->mode_info_context->mbmi.mb_skip_coeff)
    391     {
    392         if (!cpi->common.mb_no_coeff_skip)
    393         {
    394             vp8_stuff_mb(cpi, x, t);
    395         }
    396         else
    397         {
    398             vp8_fix_contexts(xd);
    399             x->skip_true_count++;
    400         }
    401 
    402         return;
    403     }
    404 
    405     plane_type = 3;
    406     if(has_y2_block)
    407     {
    408         tokenize2nd_order_b(x, t, cpi);
    409         plane_type = 0;
    410     }
    411 
    412     tokenize1st_order_b(x, t, plane_type, cpi);
    413 }
    414 
    415 
    416 #ifdef VP8_ENTROPY_STATS
    417 
    418 void init_context_counters(void)
    419 {
    420     vpx_memset(context_counters, 0, sizeof(context_counters));
    421 }
    422 
    423 void print_context_counters()
    424 {
    425 
    426     int type, band, pt, t;
    427 
    428     FILE *const f = fopen("context.c", "w");
    429 
    430     fprintf(f, "#include \"entropy.h\"\n");
    431 
    432     fprintf(f, "\n/* *** GENERATED FILE: DO NOT EDIT *** */\n\n");
    433 
    434     fprintf(f, "int Contexts[BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [MAX_ENTROPY_TOKENS];\n\n");
    435 
    436     fprintf(f, "const int default_contexts[BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [MAX_ENTROPY_TOKENS] = {");
    437 
    438 # define Comma( X) (X? ",":"")
    439 
    440     type = 0;
    441 
    442     do
    443     {
    444         fprintf(f, "%s\n  { /* block Type %d */", Comma(type), type);
    445 
    446         band = 0;
    447 
    448         do
    449         {
    450             fprintf(f, "%s\n    { /* Coeff Band %d */", Comma(band), band);
    451 
    452             pt = 0;
    453 
    454             do
    455             {
    456                 fprintf(f, "%s\n      {", Comma(pt));
    457 
    458                 t = 0;
    459 
    460                 do
    461                 {
    462                     const _int64 x = context_counters [type] [band] [pt] [t];
    463                     const int y = (int) x;
    464 
    465                     assert(x == (_int64) y);  /* no overflow handling yet */
    466                     fprintf(f, "%s %d", Comma(t), y);
    467 
    468                 }
    469                 while (++t < MAX_ENTROPY_TOKENS);
    470 
    471                 fprintf(f, "}");
    472             }
    473             while (++pt < PREV_COEF_CONTEXTS);
    474 
    475             fprintf(f, "\n    }");
    476 
    477         }
    478         while (++band < COEF_BANDS);
    479 
    480         fprintf(f, "\n  }");
    481     }
    482     while (++type < BLOCK_TYPES);
    483 
    484     fprintf(f, "\n};\n");
    485     fclose(f);
    486 }
    487 #endif
    488 
    489 
    490 static void stuff2nd_order_b
    491 (
    492     TOKENEXTRA **tp,
    493     ENTROPY_CONTEXT *a,
    494     ENTROPY_CONTEXT *l,
    495     VP8_COMP *cpi,
    496     MACROBLOCK *x
    497 )
    498 {
    499     int pt; /* near block/prev token context index */
    500     TOKENEXTRA *t = *tp;        /* store tokens starting here */
    501     VP8_COMBINEENTROPYCONTEXTS(pt, *a, *l);
    502 
    503     t->Token = DCT_EOB_TOKEN;
    504     t->context_tree = cpi->common.fc.coef_probs [1] [0] [pt];
    505     t->skip_eob_node = 0;
    506     ++x->coef_counts       [1] [0] [pt] [DCT_EOB_TOKEN];
    507     ++t;
    508 
    509     *tp = t;
    510     pt = 0;
    511     *a = *l = pt;
    512 }
    513 
    514 static void stuff1st_order_b
    515 (
    516     TOKENEXTRA **tp,
    517     ENTROPY_CONTEXT *a,
    518     ENTROPY_CONTEXT *l,
    519     int type,
    520     VP8_COMP *cpi,
    521     MACROBLOCK *x
    522 )
    523 {
    524     int pt; /* near block/prev token context index */
    525     int band;
    526     TOKENEXTRA *t = *tp;        /* store tokens starting here */
    527     VP8_COMBINEENTROPYCONTEXTS(pt, *a, *l);
    528     band = type ? 0 : 1;
    529     t->Token = DCT_EOB_TOKEN;
    530     t->context_tree = cpi->common.fc.coef_probs [type] [band] [pt];
    531     t->skip_eob_node = 0;
    532     ++x->coef_counts       [type] [band] [pt] [DCT_EOB_TOKEN];
    533     ++t;
    534     *tp = t;
    535     pt = 0; /* 0 <-> all coeff data is zero */
    536     *a = *l = pt;
    537 }
    538 
    539 static
    540 void stuff1st_order_buv
    541 (
    542     TOKENEXTRA **tp,
    543     ENTROPY_CONTEXT *a,
    544     ENTROPY_CONTEXT *l,
    545     VP8_COMP *cpi,
    546     MACROBLOCK *x
    547 )
    548 {
    549     int pt; /* near block/prev token context index */
    550     TOKENEXTRA *t = *tp;        /* store tokens starting here */
    551     VP8_COMBINEENTROPYCONTEXTS(pt, *a, *l);
    552 
    553     t->Token = DCT_EOB_TOKEN;
    554     t->context_tree = cpi->common.fc.coef_probs [2] [0] [pt];
    555     t->skip_eob_node = 0;
    556     ++x->coef_counts[2] [0] [pt] [DCT_EOB_TOKEN];
    557     ++t;
    558     *tp = t;
    559     pt = 0; /* 0 <-> all coeff data is zero */
    560     *a = *l = pt;
    561 }
    562 
    563 void vp8_stuff_mb(VP8_COMP *cpi, MACROBLOCK *x, TOKENEXTRA **t)
    564 {
    565     MACROBLOCKD *xd = &x->e_mbd;
    566     ENTROPY_CONTEXT * A = (ENTROPY_CONTEXT *)xd->above_context;
    567     ENTROPY_CONTEXT * L = (ENTROPY_CONTEXT *)xd->left_context;
    568     int plane_type;
    569     int b;
    570     plane_type = 3;
    571     if((xd->mode_info_context->mbmi.mode != B_PRED
    572                         && xd->mode_info_context->mbmi.mode != SPLITMV))
    573     {
    574         stuff2nd_order_b(t,
    575                      A + vp8_block2above[24], L + vp8_block2left[24], cpi, x);
    576         plane_type = 0;
    577     }
    578 
    579     for (b = 0; b < 16; b++)
    580         stuff1st_order_b(t,
    581                          A + vp8_block2above[b],
    582                          L + vp8_block2left[b], plane_type, cpi, x);
    583 
    584     for (b = 16; b < 24; b++)
    585         stuff1st_order_buv(t,
    586                            A + vp8_block2above[b],
    587                            L + vp8_block2left[b], cpi, x);
    588 
    589 }
    590 void vp8_fix_contexts(MACROBLOCKD *x)
    591 {
    592     /* Clear entropy contexts for Y2 blocks */
    593     if (x->mode_info_context->mbmi.mode != B_PRED && x->mode_info_context->mbmi.mode != SPLITMV)
    594     {
    595         vpx_memset(x->above_context, 0, sizeof(ENTROPY_CONTEXT_PLANES));
    596         vpx_memset(x->left_context, 0, sizeof(ENTROPY_CONTEXT_PLANES));
    597     }
    598     else
    599     {
    600         vpx_memset(x->above_context, 0, sizeof(ENTROPY_CONTEXT_PLANES)-1);
    601         vpx_memset(x->left_context, 0, sizeof(ENTROPY_CONTEXT_PLANES)-1);
    602     }
    603 
    604 }
    605