1732 lines · 48.3 KB · C
RawDownload
/* *  Copyright (c) 2010 The WebM project authors. All Rights Reserved. * *  Use of this source code is governed by a BSD-style license *  that can be found in the LICENSE file in the root of the source *  tree. An additional intellectual property rights grant can be found *  in the file PATENTS.  All contributing project authors may *  be found in the AUTHORS file in the root of the source tree. */  #include "vp8/common/header.h"#include "encodemv.h"#include "vp8/common/entropymode.h"#include "vp8/common/findnearmv.h"#include "mcomp.h"#include "vp8/common/systemdependent.h"#include <assert.h>#include <stdio.h>#include <limits.h>#include "vp8/common/pragmas.h"#include "vpx/vpx_encoder.h"#include "vpx_mem/vpx_mem.h"#include "bitstream.h" #include "defaultcoefcounts.h"#include "vp8/common/common.h" const int vp8cx_base_skip_false_prob[128] ={    255, 255, 255, 255, 255, 255, 255, 255,    255, 255, 255, 255, 255, 255, 255, 255,    255, 255, 255, 255, 255, 255, 255, 255,    255, 255, 255, 255, 255, 255, 255, 255,    255, 255, 255, 255, 255, 255, 255, 255,    255, 255, 255, 255, 255, 255, 255, 255,    255, 255, 255, 255, 255, 255, 255, 255,    251, 248, 244, 240, 236, 232, 229, 225,    221, 217, 213, 208, 204, 199, 194, 190,    187, 183, 179, 175, 172, 168, 164, 160,    157, 153, 149, 145, 142, 138, 134, 130,    127, 124, 120, 117, 114, 110, 107, 104,    101, 98,  95,  92,  89,  86,  83, 80,    77,  74,  71,  68,  65,  62,  59, 56,    53,  50,  47,  44,  41,  38,  35, 32,    30,  28,  26,  24,  22,  20,  18, 16,}; #if defined(SECTIONBITS_OUTPUT)unsigned __int64 Sectionbits[500];#endif #ifdef ENTROPY_STATSint intra_mode_stats[10][10][10];static unsigned int tree_update_hist [BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [ENTROPY_NODES] [2];extern unsigned int active_section;#endif #ifdef MODE_STATSint count_mb_seg[4] = { 0, 0, 0, 0 };#endif  static void update_mode(    vp8_writer *const w,    int n,    vp8_token tok               [/* n */],    vp8_tree tree,    vp8_prob Pnew               [/* n-1 */],    vp8_prob Pcur               [/* n-1 */],    unsigned int bct            [/* n-1 */] [2],    const unsigned int num_events[/* n */]){    unsigned int new_b = 0, old_b = 0;    int i = 0;     vp8_tree_probs_from_distribution(        n--, tok, tree,        Pnew, bct, num_events,        256, 1    );     do    {        new_b += vp8_cost_branch(bct[i], Pnew[i]);        old_b += vp8_cost_branch(bct[i], Pcur[i]);    }    while (++i < n);     if (new_b + (n << 8) < old_b)    {        int i = 0;         vp8_write_bit(w, 1);         do        {            const vp8_prob p = Pnew[i];             vp8_write_literal(w, Pcur[i] = p ? p : 1, 8);        }        while (++i < n);    }    else        vp8_write_bit(w, 0);} static void update_mbintra_mode_probs(VP8_COMP *cpi){    VP8_COMMON *const x = & cpi->common;     vp8_writer *const w = cpi->bc;     {        vp8_prob Pnew   [VP8_YMODES-1];        unsigned int bct [VP8_YMODES-1] [2];         update_mode(            w, VP8_YMODES, vp8_ymode_encodings, vp8_ymode_tree,            Pnew, x->fc.ymode_prob, bct, (unsigned int *)cpi->mb.ymode_count        );    }    {        vp8_prob Pnew   [VP8_UV_MODES-1];        unsigned int bct [VP8_UV_MODES-1] [2];         update_mode(            w, VP8_UV_MODES, vp8_uv_mode_encodings, vp8_uv_mode_tree,            Pnew, x->fc.uv_mode_prob, bct, (unsigned int *)cpi->mb.uv_mode_count        );    }} static void write_ymode(vp8_writer *bc, int m, const vp8_prob *p){    vp8_write_token(bc, vp8_ymode_tree, p, vp8_ymode_encodings + m);} static void kfwrite_ymode(vp8_writer *bc, int m, const vp8_prob *p){    vp8_write_token(bc, vp8_kf_ymode_tree, p, vp8_kf_ymode_encodings + m);} static void write_uv_mode(vp8_writer *bc, int m, const vp8_prob *p){    vp8_write_token(bc, vp8_uv_mode_tree, p, vp8_uv_mode_encodings + m);}  static void write_bmode(vp8_writer *bc, int m, const vp8_prob *p){    vp8_write_token(bc, vp8_bmode_tree, p, vp8_bmode_encodings + m);} static void write_split(vp8_writer *bc, int x){    vp8_write_token(        bc, vp8_mbsplit_tree, vp8_mbsplit_probs, vp8_mbsplit_encodings + x    );} void vp8_pack_tokens_c(vp8_writer *w, const TOKENEXTRA *p, int xcount){    const TOKENEXTRA *stop = p + xcount;    unsigned int split;    unsigned int shift;    int count = w->count;    unsigned int range = w->range;    unsigned int lowvalue = w->lowvalue;     while (p < stop)    {        const int t = p->Token;        vp8_token *a = vp8_coef_encodings + t;        const vp8_extra_bit_struct *b = vp8_extra_bits + t;        int i = 0;        const unsigned char *pp = p->context_tree;        int v = a->value;        int n = a->Len;         if (p->skip_eob_node)        {            n--;            i = 2;        }         do        {            const int bb = (v >> --n) & 1;            split = 1 + (((range - 1) * pp[i>>1]) >> 8);            i = vp8_coef_tree[i+bb];             if (bb)            {                lowvalue += split;                range = range - split;            }            else            {                range = split;            }             shift = vp8_norm[range];            range <<= shift;            count += shift;             if (count >= 0)            {                int offset = shift - count;                 if ((lowvalue << (offset - 1)) & 0x80000000)                {                    int x = w->pos - 1;                     while (x >= 0 && w->buffer[x] == 0xff)                    {                        w->buffer[x] = (unsigned char)0;                        x--;                    }                     w->buffer[x] += 1;                }                 validate_buffer(w->buffer + w->pos,                                1,                                w->buffer_end,                                w->error);                 w->buffer[w->pos++] = (lowvalue >> (24 - offset));                lowvalue <<= offset;                shift = count;                lowvalue &= 0xffffff;                count -= 8 ;            }             lowvalue <<= shift;        }        while (n);          if (b->base_val)        {            const int e = p->Extra, L = b->Len;             if (L)            {                const unsigned char *pp = b->prob;                int v = e >> 1;                int n = L;              /* number of bits in v, assumed nonzero */                int i = 0;                 do                {                    const int bb = (v >> --n) & 1;                    split = 1 + (((range - 1) * pp[i>>1]) >> 8);                    i = b->tree[i+bb];                     if (bb)                    {                        lowvalue += split;                        range = range - split;                    }                    else                    {                        range = split;                    }                     shift = vp8_norm[range];                    range <<= shift;                    count += shift;                     if (count >= 0)                    {                        int offset = shift - count;                         if ((lowvalue << (offset - 1)) & 0x80000000)                        {                            int x = w->pos - 1;                             while (x >= 0 && w->buffer[x] == 0xff)                            {                                w->buffer[x] = (unsigned char)0;                                x--;                            }                             w->buffer[x] += 1;                        }                         validate_buffer(w->buffer + w->pos,                                        1,                                        w->buffer_end,                                        w->error);                         w->buffer[w->pos++] = (lowvalue >> (24 - offset));                        lowvalue <<= offset;                        shift = count;                        lowvalue &= 0xffffff;                        count -= 8 ;                    }                     lowvalue <<= shift;                }                while (n);            }              {                 split = (range + 1) >> 1;                 if (e & 1)                {                    lowvalue += split;                    range = range - split;                }                else                {                    range = split;                }                 range <<= 1;                 if ((lowvalue & 0x80000000))                {                    int x = w->pos - 1;                     while (x >= 0 && w->buffer[x] == 0xff)                    {                        w->buffer[x] = (unsigned char)0;                        x--;                    }                     w->buffer[x] += 1;                 }                 lowvalue  <<= 1;                 if (!++count)                {                    count = -8;                     validate_buffer(w->buffer + w->pos,                                    1,                                    w->buffer_end,                                    w->error);                     w->buffer[w->pos++] = (lowvalue >> 24);                    lowvalue &= 0xffffff;                }            }         }         ++p;    }     w->count = count;    w->lowvalue = lowvalue;    w->range = range; } static void write_partition_size(unsigned char *cx_data, int size){    signed char csize;     csize = size & 0xff;    *cx_data = csize;    csize = (size >> 8) & 0xff;    *(cx_data + 1) = csize;    csize = (size >> 16) & 0xff;    *(cx_data + 2) = csize; } static void pack_tokens_into_partitions_c(VP8_COMP *cpi, unsigned char *cx_data,                                          unsigned char * cx_data_end,                                          int num_part){     int i;    unsigned char *ptr = cx_data;    unsigned char *ptr_end = cx_data_end;    vp8_writer * w;     for (i = 0; i < num_part; i++)    {        int mb_row;         w = cpi->bc + i + 1;         vp8_start_encode(w, ptr, ptr_end);         for (mb_row = i; mb_row < cpi->common.mb_rows; mb_row += num_part)        {            const TOKENEXTRA *p    = cpi->tplist[mb_row].start;            const TOKENEXTRA *stop = cpi->tplist[mb_row].stop;            int tokens = (int)(stop - p);             vp8_pack_tokens_c(w, p, tokens);        }         vp8_stop_encode(w);        ptr += w->pos;    }}  static void pack_mb_row_tokens_c(VP8_COMP *cpi, vp8_writer *w){    int mb_row;     for (mb_row = 0; mb_row < cpi->common.mb_rows; mb_row++)    {        const TOKENEXTRA *p    = cpi->tplist[mb_row].start;        const TOKENEXTRA *stop = cpi->tplist[mb_row].stop;        int tokens = (int)(stop - p);         vp8_pack_tokens_c(w, p, tokens);    } } static void write_mv_ref(    vp8_writer *w, MB_PREDICTION_MODE m, const vp8_prob *p){#if CONFIG_DEBUG    assert(NEARESTMV <= m  &&  m <= SPLITMV);#endif    vp8_write_token(w, vp8_mv_ref_tree, p,                    vp8_mv_ref_encoding_array - NEARESTMV + m);} static void write_sub_mv_ref(    vp8_writer *w, B_PREDICTION_MODE m, const vp8_prob *p){#if CONFIG_DEBUG    assert(LEFT4X4 <= m  &&  m <= NEW4X4);#endif    vp8_write_token(w, vp8_sub_mv_ref_tree, p,                    vp8_sub_mv_ref_encoding_array - LEFT4X4 + m);} static void write_mv(    vp8_writer *w, const MV *mv, const int_mv *ref, const MV_CONTEXT *mvc){    MV e;    e.row = mv->row - ref->as_mv.row;    e.col = mv->col - ref->as_mv.col;     vp8_encode_motion_vector(w, &e, mvc);} static void write_mb_features(vp8_writer *w, const MB_MODE_INFO *mi, const MACROBLOCKD *x){    /* Encode the MB segment id. */    if (x->segmentation_enabled && x->update_mb_segmentation_map)    {        switch (mi->segment_id)        {        case 0:            vp8_write(w, 0, x->mb_segment_tree_probs[0]);            vp8_write(w, 0, x->mb_segment_tree_probs[1]);            break;        case 1:            vp8_write(w, 0, x->mb_segment_tree_probs[0]);            vp8_write(w, 1, x->mb_segment_tree_probs[1]);            break;        case 2:            vp8_write(w, 1, x->mb_segment_tree_probs[0]);            vp8_write(w, 0, x->mb_segment_tree_probs[2]);            break;        case 3:            vp8_write(w, 1, x->mb_segment_tree_probs[0]);            vp8_write(w, 1, x->mb_segment_tree_probs[2]);            break;             /* TRAP.. This should not happen */        default:            vp8_write(w, 0, x->mb_segment_tree_probs[0]);            vp8_write(w, 0, x->mb_segment_tree_probs[1]);            break;        }    }}void vp8_convert_rfct_to_prob(VP8_COMP *const cpi){    const int *const rfct = cpi->mb.count_mb_ref_frame_usage;    const int rf_intra = rfct[INTRA_FRAME];    const int rf_inter = rfct[LAST_FRAME] + rfct[GOLDEN_FRAME] + rfct[ALTREF_FRAME];     /* Calculate the probabilities used to code the ref frame based on usage */

Lines 1–500 of 1732.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t