diff options
Diffstat (limited to 'vp8/encoder/bitstream.c')
-rw-r--r-- | vp8/encoder/bitstream.c | 553 |
1 files changed, 145 insertions, 408 deletions
diff --git a/vp8/encoder/bitstream.c b/vp8/encoder/bitstream.c index 0bb51730e..af00f7c8c 100644 --- a/vp8/encoder/bitstream.c +++ b/vp8/encoder/bitstream.c @@ -24,6 +24,7 @@ #include "bitstream.h" #include "defaultcoefcounts.h" +#include "vp8/common/common.h" const int vp8cx_base_skip_false_prob[128] = { @@ -159,7 +160,7 @@ static void write_split(vp8_writer *bc, int x) ); } -static void pack_tokens_c(vp8_writer *w, const TOKENEXTRA *p, int xcount) +void vp8_pack_tokens_c(vp8_writer *w, const TOKENEXTRA *p, int xcount) { const TOKENEXTRA *const stop = p + xcount; unsigned int split; @@ -382,219 +383,23 @@ static void pack_tokens_into_partitions_c(VP8_COMP *cpi, unsigned char *cx_data, int i; unsigned char *ptr = cx_data; unsigned char *ptr_end = cx_data_end; - unsigned int shift; - vp8_writer *w; - ptr = cx_data; + vp8_writer * w; for (i = 0; i < num_part; i++) { - w = cpi->bc + i + 1; - vp8_start_encode(w, ptr, ptr_end); - { - unsigned int split; - int count = w->count; - unsigned int range = w->range; - unsigned int lowvalue = w->lowvalue; - int mb_row; - - for (mb_row = i; mb_row < cpi->common.mb_rows; mb_row += num_part) - { - TOKENEXTRA *p = cpi->tplist[mb_row].start; - TOKENEXTRA *stop = cpi->tplist[mb_row].stop; - - while (p < stop) - { - const int t = p->Token; - vp8_token *const a = vp8_coef_encodings + t; - const vp8_extra_bit_struct *const 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, - cx_data_end, - &cpi->common.error); - - w->buffer[w->pos++] = (lowvalue >> (24 - offset)); - - lowvalue <<= offset; - shift = count; - lowvalue &= 0xffffff; - count -= 8 ; - } - - lowvalue <<= shift; - } - while (n); + int mb_row; + w = cpi->bc + i + 1; - 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, - cx_data_end, - &cpi->common.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, - cx_data_end, - &cpi->common.error); - - w->buffer[w->pos++] = (lowvalue >> 24); - - lowvalue &= 0xffffff; - } - } - - } - - ++p; - } - } + vp8_start_encode(w, ptr, ptr_end); - w->count = count; - w->lowvalue = lowvalue; - w->range = range; + 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 = stop - p; + vp8_pack_tokens_c(w, p, tokens); } vp8_stop_encode(w); @@ -605,209 +410,17 @@ static void pack_tokens_into_partitions_c(VP8_COMP *cpi, unsigned char *cx_data, static void pack_mb_row_tokens_c(VP8_COMP *cpi, vp8_writer *w) { - - unsigned int split; - int count = w->count; - unsigned int range = w->range; - unsigned int lowvalue = w->lowvalue; - unsigned int shift; int mb_row; for (mb_row = 0; mb_row < cpi->common.mb_rows; mb_row++) { - TOKENEXTRA *p = cpi->tplist[mb_row].start; - TOKENEXTRA *stop = cpi->tplist[mb_row].stop; - - while (p < stop) - { - const int t = p->Token; - vp8_token *const a = vp8_coef_encodings + t; - const vp8_extra_bit_struct *const 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); + const TOKENEXTRA *p = cpi->tplist[mb_row].start; + const TOKENEXTRA *stop = cpi->tplist[mb_row].stop; + int tokens = stop - p; - w->buffer[w->pos++] = (lowvalue >> 24); - lowvalue &= 0xffffff; - } - } - - } - - ++p; - } + vp8_pack_tokens_c(w, p, tokens); } - w->count = count; - w->lowvalue = lowvalue; - w->range = range; - } static void write_mv_ref @@ -925,7 +538,9 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi) if (pc->mb_no_coeff_skip) { - prob_skip_false = cpi->skip_false_count * 256 / (cpi->skip_false_count + cpi->skip_true_count); + int total_mbs = pc->mb_rows * pc->mb_cols; + + prob_skip_false = (total_mbs - cpi->skip_true_count ) * 256 / total_mbs; if (prob_skip_false <= 1) prob_skip_false = 1; @@ -1112,7 +727,9 @@ static void write_kfmodes(VP8_COMP *cpi) if (c->mb_no_coeff_skip) { - prob_skip_false = cpi->skip_false_count * 256 / (cpi->skip_false_count + cpi->skip_true_count); + int total_mbs = c->mb_rows * c->mb_cols; + + prob_skip_false = (total_mbs - cpi->skip_true_count ) * 256 / total_mbs; if (prob_skip_false <= 1) prob_skip_false = 1; @@ -1167,6 +784,7 @@ static void write_kfmodes(VP8_COMP *cpi) } } +#if 0 /* This function is used for debugging probability trees. */ static void print_prob_tree(vp8_prob coef_probs[BLOCK_TYPES][COEF_BANDS][PREV_COEF_CONTEXTS][ENTROPY_NODES]) @@ -1198,6 +816,7 @@ static void print_prob_tree(vp8_prob fprintf(f, "}\n"); fclose(f); } +#endif static void sum_probs_over_prev_coef_context( const unsigned int probs[PREV_COEF_CONTEXTS][MAX_ENTROPY_TOKENS], @@ -1327,7 +946,6 @@ static int default_coef_context_savings(VP8_COMP *cpi) int t = 0; /* token/prob index */ - vp8_tree_probs_from_distribution( MAX_ENTROPY_TOKENS, vp8_coef_encodings, vp8_coef_tree, cpi->frame_coef_probs [i][j][k], @@ -1432,10 +1050,33 @@ int vp8_estimate_entropy_savings(VP8_COMP *cpi) return savings; } -static void update_coef_probs(VP8_COMP *cpi) +#if CONFIG_REALTIME_ONLY & CONFIG_ONTHEFLY_BITPACKING +int vp8_update_coef_context(VP8_COMP *cpi) +{ + int savings = 0; + + + if (cpi->common.frame_type == KEY_FRAME) + { + /* Reset to default counts/probabilities at key frames */ + vp8_copy(cpi->coef_counts, default_coef_counts); + } + + if (cpi->oxcf.error_resilient_mode & VPX_ERROR_RESILIENT_PARTITIONS) + savings += independent_coef_context_savings(cpi); + else + savings += default_coef_context_savings(cpi); + + return savings; +} +#endif + +void vp8_update_coef_probs(VP8_COMP *cpi) { int i = 0; +#if !(CONFIG_REALTIME_ONLY & CONFIG_ONTHEFLY_BITPACKING) vp8_writer *const w = cpi->bc; +#endif int savings = 0; vp8_clear_system_state(); //__asm emms; @@ -1515,7 +1156,11 @@ static void update_coef_probs(VP8_COMP *cpi) cpi->common.frame_type == KEY_FRAME && newp != *Pold) u = 1; +#if CONFIG_REALTIME_ONLY & CONFIG_ONTHEFLY_BITPACKING + cpi->update_probs[i][j][k][t] = u; +#else vp8_write(w, u, upd); +#endif #ifdef ENTROPY_STATS @@ -1527,7 +1172,9 @@ static void update_coef_probs(VP8_COMP *cpi) /* send/use new probability */ *Pold = newp; +#if !(CONFIG_REALTIME_ONLY & CONFIG_ONTHEFLY_BITPACKING) vp8_write_literal(w, newp, 8); +#endif savings += s; @@ -1556,6 +1203,50 @@ static void update_coef_probs(VP8_COMP *cpi) while (++i < BLOCK_TYPES); } + +#if CONFIG_REALTIME_ONLY & CONFIG_ONTHEFLY_BITPACKING +static void pack_coef_probs(VP8_COMP *cpi) +{ + int i = 0; + vp8_writer *const w = cpi->bc; + + do + { + int j = 0; + + do + { + int k = 0; + + do + { + int t = 0; /* token/prob index */ + + do + { + const vp8_prob newp = cpi->common.fc.coef_probs [i][j][k][t]; + const vp8_prob upd = vp8_coef_update_probs [i][j][k][t]; + + const char u = cpi->update_probs[i][j][k][t] ; + + vp8_write(w, u, upd); + + if (u) + { + /* send/use new probability */ + vp8_write_literal(w, newp, 8); + } + } + while (++t < ENTROPY_NODES); + } + while (++k < PREV_COEF_CONTEXTS); + } + while (++j < COEF_BANDS); + } + while (++i < BLOCK_TYPES); +} +#endif + #ifdef PACKET_TESTING FILE *vpxlogc = 0; #endif @@ -1818,6 +1509,7 @@ void vp8_pack_bitstream(VP8_COMP *cpi, unsigned char *dest, unsigned char * dest vp8_write_bit(bc, pc->ref_frame_sign_bias[ALTREF_FRAME]); } +#if !(CONFIG_REALTIME_ONLY & CONFIG_ONTHEFLY_BITPACKING) if (cpi->oxcf.error_resilient_mode & VPX_ERROR_RESILIENT_PARTITIONS) { if (pc->frame_type == KEY_FRAME) @@ -1825,6 +1517,7 @@ void vp8_pack_bitstream(VP8_COMP *cpi, unsigned char *dest, unsigned char * dest else pc->refresh_entropy_probs = 0; } +#endif vp8_write_bit(bc, pc->refresh_entropy_probs); @@ -1842,13 +1535,17 @@ void vp8_pack_bitstream(VP8_COMP *cpi, unsigned char *dest, unsigned char * dest vp8_clear_system_state(); //__asm emms; +#if CONFIG_REALTIME_ONLY & CONFIG_ONTHEFLY_BITPACKING + pack_coef_probs(cpi); +#else if (pc->refresh_entropy_probs == 0) { // save a copy for later refresh vpx_memcpy(&cpi->common.lfc, &cpi->common.fc, sizeof(cpi->common.fc)); } - update_coef_probs(cpi); + vp8_update_coef_probs(cpi); +#endif #ifdef ENTROPY_STATS active_section = 2; @@ -1896,6 +1593,45 @@ void vp8_pack_bitstream(VP8_COMP *cpi, unsigned char *dest, unsigned char * dest cpi->partition_sz[0] = *size; +#if CONFIG_REALTIME_ONLY & CONFIG_ONTHEFLY_BITPACKING + { + const int num_part = (1 << pc->multi_token_partition); + unsigned char * dp = cpi->partition_d[0] + cpi->partition_sz[0]; + + if (num_part > 1) + { + /* write token part sizes (all but last) if more than 1 */ + validate_buffer(dp, 3 * (num_part - 1), cpi->partition_d_end[0], + &pc->error); + + cpi->partition_sz[0] += 3*(num_part-1); + + for(i = 1; i < num_part; i++) + { + write_partition_size(dp, cpi->partition_sz[i]); + dp += 3; + } + } + + if (!cpi->output_partition) + { + /* concatenate partition buffers */ + for(i = 0; i < num_part; i++) + { + vpx_memmove(dp, cpi->partition_d[i+1], cpi->partition_sz[i+1]); + cpi->partition_d[i+1] = dp; + dp += cpi->partition_sz[i+1]; + } + } + + /* update total size */ + *size = 0; + for(i = 0; i < num_part+1; i++) + { + *size += cpi->partition_sz[i]; + } + } +#else if (pc->multi_token_partition != ONE_PARTITION) { int num_part = 1 << pc->multi_token_partition; @@ -1945,6 +1681,7 @@ void vp8_pack_bitstream(VP8_COMP *cpi, unsigned char *dest, unsigned char * dest *size += cpi->bc[1].pos; cpi->partition_sz[1] = cpi->bc[1].pos; } +#endif } #ifdef ENTROPY_STATS |