media/libvpx/vp8/encoder/tokenize.c

Thu, 15 Jan 2015 15:59:08 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 15 Jan 2015 15:59:08 +0100
branch
TOR_BUG_9701
changeset 10
ac0c01689b40
permissions
-rw-r--r--

Implement a real Private Browsing Mode condition by changing the API/ABI;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

     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  */
    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"
    20 /* Global event counters used for accumulating statistics across several
    21    compressions, then generating context.c = initial stats. */
    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);
    29 #include "dct_value_tokens.h"
    30 #include "dct_value_cost.h"
    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;
    36 #if 0
    37 int skip_true_count = 0;
    38 int skip_false_count = 0;
    39 #endif
    41 /* function used to generate dct_value_tokens and dct_value_cost tables */
    42 /*
    43 static void fill_value_tokens()
    44 {
    46     TOKENVALUE *t = dct_value_tokens + DCT_MAX_VALUE;
    47     const vp8_extra_bit_struct *e = vp8_extra_bits;
    49     int i = -DCT_MAX_VALUE;
    50     int sign = 1;
    52     do
    53     {
    54         if (!i)
    55             sign = 0;
    57         {
    58             const int a = sign ? -i : i;
    59             int eb = sign;
    61             if (a > 4)
    62             {
    63                 int j = 4;
    65                 while (++j < 11  &&  e[j].base_val <= a) {}
    67                 t[i].Token = --j;
    68                 eb |= (a - e[j].base_val) << 1;
    69             }
    70             else
    71                 t[i].Token = a;
    73             t[i].Extra = eb;
    74         }
    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;
    81             if (p->base_val)
    82             {
    83                 const int extra = t[i].Extra;
    84                 const int Length = p->Len;
    86                 if (Length)
    87                     cost += vp8_treed_cost(p->tree, p->prob, extra >> 1, Length);
    89                 cost += vp8_cost_bit(vp8_prob_half, extra & 1); // sign
    90                 dct_value_cost[i + DCT_MAX_VALUE] = cost;
    91             }
    93         }
    95     }
    96     while (++i < DCT_MAX_VALUE);
    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 */
   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;
   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);
   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;
   135         ++x->coef_counts       [1] [0] [pt] [DCT_EOB_TOKEN];
   136         t++;
   137         *tp = t;
   138         *a = *l = 0;
   139         return;
   140     }
   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;
   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;
   154     for (; c < eob; c++)
   155     {
   156         rc = vp8_default_zig_zag1d[c];
   157         band = vp8_coef_bands[c];
   158         v = qcoeff_ptr[rc];
   160         t->Extra = vp8_dct_value_tokens_ptr[v].Extra;
   161         token    = vp8_dct_value_tokens_ptr[v].Token;
   163         t->Token = token;
   164         t->context_tree = cpi->common.fc.coef_probs [1] [band] [pt];
   166         t->skip_eob_node = ((pt == 0));
   168         ++x->coef_counts       [1] [band] [pt] [token];
   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];
   179         t->skip_eob_node = 0;
   181         ++x->coef_counts       [1] [band] [pt] [DCT_EOB_TOKEN];
   183         t++;
   184     }
   186     *tp = t;
   187     *a = *l = 1;
   189 }
   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;
   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;
   222         VP8_COMBINEENTROPYCONTEXTS(pt, *a, *l);
   224         c = type ? 0 : 1;
   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;
   233             ++x->coef_counts       [type] [c] [pt] [DCT_EOB_TOKEN];
   234             t++;
   235             *tp = t;
   236             *a = *l = 0;
   237             continue;
   238         }
   240         v = qcoeff_ptr[c];
   242         t->Extra = vp8_dct_value_tokens_ptr[v].Extra;
   243         token    = vp8_dct_value_tokens_ptr[v].Token;
   244         t->Token = token;
   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++;
   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];
   259             t->Extra = vp8_dct_value_tokens_ptr[v].Extra;
   260             token    = vp8_dct_value_tokens_ptr[v].Token;
   262             t->Token = token;
   263             t->context_tree = cpi->common.fc.coef_probs [type] [band] [pt];
   265             t->skip_eob_node = (pt == 0);
   266             ++x->coef_counts       [type] [band] [pt] [token];
   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];
   277             t->skip_eob_node = 0;
   278             ++x->coef_counts       [type] [band] [pt] [DCT_EOB_TOKEN];
   280             t++;
   281         }
   282         *tp = t;
   283         *a = *l = 1;
   284     }
   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;
   295         VP8_COMBINEENTROPYCONTEXTS(pt, *a, *l);
   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;
   304             ++x->coef_counts       [2] [0] [pt] [DCT_EOB_TOKEN];
   305             t++;
   306             *tp = t;
   307             *a = *l = 0;
   308             continue;
   309         }
   311         v = qcoeff_ptr[0];
   313         t->Extra = vp8_dct_value_tokens_ptr[v].Extra;
   314         token    = vp8_dct_value_tokens_ptr[v].Token;
   315         t->Token = token;
   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;
   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];
   330             t->Extra = vp8_dct_value_tokens_ptr[v].Extra;
   331             token    = vp8_dct_value_tokens_ptr[v].Token;
   333             t->Token = token;
   334             t->context_tree = cpi->common.fc.coef_probs [2] [band] [pt];
   336             t->skip_eob_node = (pt == 0);
   338             ++x->coef_counts       [2] [band] [pt] [token];
   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];
   349             t->skip_eob_node = 0;
   351             ++x->coef_counts       [2] [band] [pt] [DCT_EOB_TOKEN];
   353             t++;
   354         }
   355         *tp = t;
   356         *a = *l = 1;
   357     }
   358 }
   361 static int mb_is_skippable(MACROBLOCKD *x, int has_y2_block)
   362 {
   363     int skip = 1;
   364     int i = 0;
   366     if (has_y2_block)
   367     {
   368         for (i = 0; i < 16; i++)
   369             skip &= (x->eobs[i] < 2);
   370     }
   372     for (; i < 24 + has_y2_block; i++)
   373         skip &= (!x->eobs[i]);
   375     return skip;
   376 }
   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;
   385     has_y2_block = (xd->mode_info_context->mbmi.mode != B_PRED
   386                     && xd->mode_info_context->mbmi.mode != SPLITMV);
   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         }
   402         return;
   403     }
   405     plane_type = 3;
   406     if(has_y2_block)
   407     {
   408         tokenize2nd_order_b(x, t, cpi);
   409         plane_type = 0;
   410     }
   412     tokenize1st_order_b(x, t, plane_type, cpi);
   413 }
   416 #ifdef VP8_ENTROPY_STATS
   418 void init_context_counters(void)
   419 {
   420     vpx_memset(context_counters, 0, sizeof(context_counters));
   421 }
   423 void print_context_counters()
   424 {
   426     int type, band, pt, t;
   428     FILE *const f = fopen("context.c", "w");
   430     fprintf(f, "#include \"entropy.h\"\n");
   432     fprintf(f, "\n/* *** GENERATED FILE: DO NOT EDIT *** */\n\n");
   434     fprintf(f, "int Contexts[BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [MAX_ENTROPY_TOKENS];\n\n");
   436     fprintf(f, "const int default_contexts[BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [MAX_ENTROPY_TOKENS] = {");
   438 # define Comma( X) (X? ",":"")
   440     type = 0;
   442     do
   443     {
   444         fprintf(f, "%s\n  { /* block Type %d */", Comma(type), type);
   446         band = 0;
   448         do
   449         {
   450             fprintf(f, "%s\n    { /* Coeff Band %d */", Comma(band), band);
   452             pt = 0;
   454             do
   455             {
   456                 fprintf(f, "%s\n      {", Comma(pt));
   458                 t = 0;
   460                 do
   461                 {
   462                     const _int64 x = context_counters [type] [band] [pt] [t];
   463                     const int y = (int) x;
   465                     assert(x == (_int64) y);  /* no overflow handling yet */
   466                     fprintf(f, "%s %d", Comma(t), y);
   468                 }
   469                 while (++t < MAX_ENTROPY_TOKENS);
   471                 fprintf(f, "}");
   472             }
   473             while (++pt < PREV_COEF_CONTEXTS);
   475             fprintf(f, "\n    }");
   477         }
   478         while (++band < COEF_BANDS);
   480         fprintf(f, "\n  }");
   481     }
   482     while (++type < BLOCK_TYPES);
   484     fprintf(f, "\n};\n");
   485     fclose(f);
   486 }
   487 #endif
   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);
   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;
   509     *tp = t;
   510     pt = 0;
   511     *a = *l = pt;
   512 }
   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 }
   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);
   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 }
   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     }
   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);
   584     for (b = 16; b < 24; b++)
   585         stuff1st_order_buv(t,
   586                            A + vp8_block2above[b],
   587                            L + vp8_block2left[b], cpi, x);
   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     }
   604 }

mercurial