summaryrefslogtreecommitdiff
path: root/vp8/encoder/bitstream.c
diff options
context:
space:
mode:
Diffstat (limited to 'vp8/encoder/bitstream.c')
-rw-r--r--vp8/encoder/bitstream.c228
1 files changed, 142 insertions, 86 deletions
diff --git a/vp8/encoder/bitstream.c b/vp8/encoder/bitstream.c
index 748b60778..669bfad9a 100644
--- a/vp8/encoder/bitstream.c
+++ b/vp8/encoder/bitstream.c
@@ -109,7 +109,7 @@ static void update_mbintra_mode_probs(VP8_COMP *cpi)
{
VP8_COMMON *const x = & cpi->common;
- vp8_writer *const w = & cpi->bc;
+ vp8_writer *const w = cpi->bc;
{
vp8_prob Pnew [VP8_YMODES-1];
@@ -221,6 +221,11 @@ static void pack_tokens_c(vp8_writer *w, const TOKENEXTRA *p, int xcount)
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;
@@ -281,6 +286,11 @@ static void pack_tokens_c(vp8_writer *w, const TOKENEXTRA *p, int xcount)
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;
@@ -329,6 +339,12 @@ static void pack_tokens_c(vp8_writer *w, const TOKENEXTRA *p, int xcount)
if (!++count)
{
count = -8;
+
+ validate_buffer(w->buffer + w->pos,
+ 1,
+ w->buffer_end,
+ w->error);
+
w->buffer[w->pos++] = (lowvalue >> 24);
lowvalue &= 0xffffff;
}
@@ -358,20 +374,21 @@ static void write_partition_size(unsigned char *cx_data, int size)
}
-static void pack_tokens_into_partitions_c(VP8_COMP *cpi, unsigned char *cx_data, unsigned char * cx_data_end, int num_part, int *size)
+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;
unsigned int shift;
- vp8_writer *w = &cpi->bc2;
- *size = 3 * (num_part - 1);
- cpi->partition_sz[0] += *size;
- ptr = cx_data + (*size);
+ vp8_writer *w;
+ ptr = cx_data;
for (i = 0; i < num_part; i++)
{
+ w = cpi->bc + i + 1;
vp8_start_encode(w, ptr, ptr_end);
{
unsigned int split;
@@ -581,17 +598,7 @@ static void pack_tokens_into_partitions_c(VP8_COMP *cpi, unsigned char *cx_data,
}
vp8_stop_encode(w);
- *size += w->pos;
-
- /* The first partition size is set earlier */
- cpi->partition_sz[i + 1] = w->pos;
-
- if (i < (num_part - 1))
- {
- write_partition_size(cx_data, w->pos);
- cx_data += 3;
- ptr += w->pos;
- }
+ ptr += w->pos;
}
}
@@ -664,6 +671,11 @@ static void pack_mb_row_tokens_c(VP8_COMP *cpi, vp8_writer *w)
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;
@@ -724,6 +736,11 @@ static void pack_mb_row_tokens_c(VP8_COMP *cpi, vp8_writer *w)
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;
@@ -770,6 +787,12 @@ static void pack_mb_row_tokens_c(VP8_COMP *cpi, vp8_writer *w)
if (!++count)
{
count = -8;
+
+ validate_buffer(w->buffer + w->pos,
+ 1,
+ w->buffer_end,
+ w->error);
+
w->buffer[w->pos++] = (lowvalue >> 24);
lowvalue &= 0xffffff;
}
@@ -855,44 +878,46 @@ static void write_mb_features(vp8_writer *w, const MB_MODE_INFO *mi, const MACRO
}
}
}
+void vp8_convert_rfct_to_prob(VP8_COMP *const cpi)
+{
+ const int *const rfct = cpi->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 useage
+ if (!(cpi->prob_intra_coded = rf_intra * 255 / (rf_intra + rf_inter)))
+ cpi->prob_intra_coded = 1;
+
+ cpi->prob_last_coded = rf_inter ? (rfct[LAST_FRAME] * 255) / rf_inter : 128;
+ if (!cpi->prob_last_coded)
+ cpi->prob_last_coded = 1;
+
+ cpi->prob_gf_coded = (rfct[GOLDEN_FRAME] + rfct[ALTREF_FRAME])
+ ? (rfct[GOLDEN_FRAME] * 255) / (rfct[GOLDEN_FRAME] + rfct[ALTREF_FRAME]) : 128;
+
+ if (!cpi->prob_gf_coded)
+ cpi->prob_gf_coded = 1;
+
+}
static void pack_inter_mode_mvs(VP8_COMP *const cpi)
{
VP8_COMMON *const pc = & cpi->common;
- vp8_writer *const w = & cpi->bc;
+ vp8_writer *const w = cpi->bc;
const MV_CONTEXT *mvc = pc->fc.mvc;
- const int *const rfct = cpi->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];
MODE_INFO *m = pc->mi, *ms;
const int mis = pc->mode_info_stride;
int mb_row = -1;
- int prob_last_coded;
- int prob_gf_coded;
int prob_skip_false = 0;
ms = pc->mi - 1;
cpi->mb.partition_info = cpi->mb.pi;
- // Calculate the probabilities to be used to code the reference frame based on actual useage this frame
- if (!(cpi->prob_intra_coded = rf_intra * 255 / (rf_intra + rf_inter)))
- cpi->prob_intra_coded = 1;
-
- prob_last_coded = rf_inter ? (rfct[LAST_FRAME] * 255) / rf_inter : 128;
-
- if (!prob_last_coded)
- prob_last_coded = 1;
-
- prob_gf_coded = (rfct[GOLDEN_FRAME] + rfct[ALTREF_FRAME])
- ? (rfct[GOLDEN_FRAME] * 255) / (rfct[GOLDEN_FRAME] + rfct[ALTREF_FRAME]) : 128;
-
- if (!prob_gf_coded)
- prob_gf_coded = 1;
-
+ vp8_convert_rfct_to_prob(cpi);
#ifdef ENTROPY_STATS
active_section = 1;
@@ -913,8 +938,8 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi)
}
vp8_write_literal(w, cpi->prob_intra_coded, 8);
- vp8_write_literal(w, prob_last_coded, 8);
- vp8_write_literal(w, prob_gf_coded, 8);
+ vp8_write_literal(w, cpi->prob_last_coded, 8);
+ vp8_write_literal(w, cpi->prob_gf_coded, 8);
update_mbintra_mode_probs(cpi);
@@ -976,11 +1001,11 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi)
vp8_write(w, 1, cpi->prob_intra_coded);
if (rf == LAST_FRAME)
- vp8_write(w, 0, prob_last_coded);
+ vp8_write(w, 0, cpi->prob_last_coded);
else
{
- vp8_write(w, 1, prob_last_coded);
- vp8_write(w, (rf == GOLDEN_FRAME) ? 0 : 1, prob_gf_coded);
+ vp8_write(w, 1, cpi->prob_last_coded);
+ vp8_write(w, (rf == GOLDEN_FRAME) ? 0 : 1, cpi->prob_gf_coded);
}
{
@@ -1075,7 +1100,7 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi)
static void write_kfmodes(VP8_COMP *cpi)
{
- vp8_writer *const bc = & cpi->bc;
+ vp8_writer *const bc = cpi->bc;
const VP8_COMMON *const c = & cpi->common;
/* const */
MODE_INFO *m = c->mi;
@@ -1181,7 +1206,7 @@ static void sum_probs_over_prev_coef_context(
{
for (j=0; j < PREV_COEF_CONTEXTS; ++j)
{
- const int tmp = out[i];
+ const unsigned int tmp = out[i];
out[i] += probs[j][i];
/* check for wrap */
if (out[i] < tmp)
@@ -1332,6 +1357,24 @@ static int default_coef_context_savings(VP8_COMP *cpi)
return savings;
}
+void vp8_calc_ref_frame_costs(int *ref_frame_cost,
+ int prob_intra,
+ int prob_last,
+ int prob_garf
+ )
+{
+ ref_frame_cost[INTRA_FRAME] = vp8_cost_zero(prob_intra);
+ ref_frame_cost[LAST_FRAME] = vp8_cost_one(prob_intra)
+ + vp8_cost_zero(prob_last);
+ ref_frame_cost[GOLDEN_FRAME] = vp8_cost_one(prob_intra)
+ + vp8_cost_one(prob_last)
+ + vp8_cost_zero(prob_garf);
+ ref_frame_cost[ALTREF_FRAME] = vp8_cost_one(prob_intra)
+ + vp8_cost_one(prob_last)
+ + vp8_cost_one(prob_garf);
+
+}
+
int vp8_estimate_entropy_savings(VP8_COMP *cpi)
{
int savings = 0;
@@ -1339,7 +1382,7 @@ int vp8_estimate_entropy_savings(VP8_COMP *cpi)
const int *const rfct = cpi->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];
- int new_intra, new_last, gf_last, oldtotal, newtotal;
+ int new_intra, new_last, new_garf, oldtotal, newtotal;
int ref_frame_cost[MAX_REF_FRAMES];
vp8_clear_system_state(); //__asm emms;
@@ -1351,19 +1394,11 @@ int vp8_estimate_entropy_savings(VP8_COMP *cpi)
new_last = rf_inter ? (rfct[LAST_FRAME] * 255) / rf_inter : 128;
- gf_last = (rfct[GOLDEN_FRAME] + rfct[ALTREF_FRAME])
+ new_garf = (rfct[GOLDEN_FRAME] + rfct[ALTREF_FRAME])
? (rfct[GOLDEN_FRAME] * 255) / (rfct[GOLDEN_FRAME] + rfct[ALTREF_FRAME]) : 128;
- // new costs
- ref_frame_cost[INTRA_FRAME] = vp8_cost_zero(new_intra);
- ref_frame_cost[LAST_FRAME] = vp8_cost_one(new_intra)
- + vp8_cost_zero(new_last);
- ref_frame_cost[GOLDEN_FRAME] = vp8_cost_one(new_intra)
- + vp8_cost_one(new_last)
- + vp8_cost_zero(gf_last);
- ref_frame_cost[ALTREF_FRAME] = vp8_cost_one(new_intra)
- + vp8_cost_one(new_last)
- + vp8_cost_one(gf_last);
+
+ vp8_calc_ref_frame_costs(ref_frame_cost,new_intra,new_last,new_garf);
newtotal =
rfct[INTRA_FRAME] * ref_frame_cost[INTRA_FRAME] +
@@ -1373,15 +1408,8 @@ int vp8_estimate_entropy_savings(VP8_COMP *cpi)
// old costs
- ref_frame_cost[INTRA_FRAME] = vp8_cost_zero(cpi->prob_intra_coded);
- ref_frame_cost[LAST_FRAME] = vp8_cost_one(cpi->prob_intra_coded)
- + vp8_cost_zero(cpi->prob_last_coded);
- ref_frame_cost[GOLDEN_FRAME] = vp8_cost_one(cpi->prob_intra_coded)
- + vp8_cost_one(cpi->prob_last_coded)
- + vp8_cost_zero(cpi->prob_gf_coded);
- ref_frame_cost[ALTREF_FRAME] = vp8_cost_one(cpi->prob_intra_coded)
- + vp8_cost_one(cpi->prob_last_coded)
- + vp8_cost_one(cpi->prob_gf_coded);
+ vp8_calc_ref_frame_costs(ref_frame_cost,cpi->prob_intra_coded,
+ cpi->prob_last_coded,cpi->prob_gf_coded);
oldtotal =
rfct[INTRA_FRAME] * ref_frame_cost[INTRA_FRAME] +
@@ -1405,7 +1433,7 @@ int vp8_estimate_entropy_savings(VP8_COMP *cpi)
static void update_coef_probs(VP8_COMP *cpi)
{
int i = 0;
- vp8_writer *const w = & cpi->bc;
+ vp8_writer *const w = cpi->bc;
int savings = 0;
vp8_clear_system_state(); //__asm emms;
@@ -1551,7 +1579,7 @@ void vp8_pack_bitstream(VP8_COMP *cpi, unsigned char *dest, unsigned char * dest
int i, j;
VP8_HEADER oh;
VP8_COMMON *const pc = & cpi->common;
- vp8_writer *const bc = & cpi->bc;
+ vp8_writer *const bc = cpi->bc;
MACROBLOCKD *const xd = & cpi->mb.e_mbd;
int extra_bytes_packed = 0;
@@ -1566,6 +1594,8 @@ void vp8_pack_bitstream(VP8_COMP *cpi, unsigned char *dest, unsigned char * dest
mb_feature_data_bits = vp8_mb_feature_data_bits;
+ bc[0].error = &pc->error;
+
validate_buffer(cx_data, 3, cx_data_end, &cpi->common.error);
cx_data += 3;
@@ -1614,20 +1644,20 @@ void vp8_pack_bitstream(VP8_COMP *cpi, unsigned char *dest, unsigned char * dest
// Signal whether or not Segmentation is enabled
- vp8_write_bit(bc, (xd->segmentation_enabled) ? 1 : 0);
+ vp8_write_bit(bc, xd->segmentation_enabled);
// Indicate which features are enabled
if (xd->segmentation_enabled)
{
// Signal whether or not the segmentation map is being updated.
- vp8_write_bit(bc, (xd->update_mb_segmentation_map) ? 1 : 0);
- vp8_write_bit(bc, (xd->update_mb_segmentation_data) ? 1 : 0);
+ vp8_write_bit(bc, xd->update_mb_segmentation_map);
+ vp8_write_bit(bc, xd->update_mb_segmentation_data);
if (xd->update_mb_segmentation_data)
{
signed char Data;
- vp8_write_bit(bc, (xd->mb_segement_abs_delta) ? 1 : 0);
+ vp8_write_bit(bc, xd->mb_segement_abs_delta);
// For each segmentation feature (Quant and loop filter level)
for (i = 0; i < MB_LVL_MAX; i++)
@@ -1684,7 +1714,7 @@ void vp8_pack_bitstream(VP8_COMP *cpi, unsigned char *dest, unsigned char * dest
vp8_write_literal(bc, pc->sharpness_level, 3);
// Write out loop filter deltas applied at the MB level based on mode or ref frame (if they are enabled).
- vp8_write_bit(bc, (xd->mode_ref_lf_delta_enabled) ? 1 : 0);
+ vp8_write_bit(bc, xd->mode_ref_lf_delta_enabled);
if (xd->mode_ref_lf_delta_enabled)
{
@@ -1844,7 +1874,9 @@ void vp8_pack_bitstream(VP8_COMP *cpi, unsigned char *dest, unsigned char * dest
vp8_stop_encode(bc);
- oh.first_partition_length_in_bytes = cpi->bc.pos;
+ cx_data += bc->pos;
+
+ oh.first_partition_length_in_bytes = cpi->bc->pos;
/* update frame tag */
{
@@ -1858,34 +1890,58 @@ void vp8_pack_bitstream(VP8_COMP *cpi, unsigned char *dest, unsigned char * dest
dest[2] = v >> 16;
}
- *size = VP8_HEADER_SIZE + extra_bytes_packed + cpi->bc.pos;
+ *size = VP8_HEADER_SIZE + extra_bytes_packed + cpi->bc->pos;
+
cpi->partition_sz[0] = *size;
if (pc->multi_token_partition != ONE_PARTITION)
{
- int num_part;
- int asize;
- num_part = 1 << pc->multi_token_partition;
+ int num_part = 1 << pc->multi_token_partition;
+
+ /* partition size table at the end of first partition */
+ cpi->partition_sz[0] += 3 * (num_part - 1);
+ *size += 3 * (num_part - 1);
+
+ validate_buffer(cx_data, 3 * (num_part - 1), cx_data_end,
+ &pc->error);
+
+ for(i = 1; i < num_part + 1; i++)
+ {
+ cpi->bc[i].error = &pc->error;
+ }
- pack_tokens_into_partitions(cpi, cx_data + bc->pos, cx_data_end, num_part, &asize);
+ pack_tokens_into_partitions(cpi, cx_data + 3 * (num_part - 1),
+ cx_data_end, num_part);
- *size += asize;
+ for(i = 1; i < num_part; i++)
+ {
+ cpi->partition_sz[i] = cpi->bc[i].pos;
+ write_partition_size(cx_data, cpi->partition_sz[i]);
+ cx_data += 3;
+ *size += cpi->partition_sz[i]; /* add to total */
+ }
+
+ /* add last partition to total size */
+ cpi->partition_sz[i] = cpi->bc[i].pos;
+ *size += cpi->partition_sz[i];
}
else
{
- vp8_start_encode(&cpi->bc2, cx_data + bc->pos, cx_data_end);
+ bc[1].error = &pc->error;
+
+ vp8_start_encode(&cpi->bc[1], cx_data, cx_data_end);
#if CONFIG_MULTITHREAD
if (cpi->b_multi_threaded)
- pack_mb_row_tokens(cpi, &cpi->bc2);
+ pack_mb_row_tokens(cpi, &cpi->bc[1]);
else
#endif
- pack_tokens(&cpi->bc2, cpi->tok, cpi->tok_count);
+ pack_tokens(&cpi->bc[1], cpi->tok, cpi->tok_count);
- vp8_stop_encode(&cpi->bc2);
+ vp8_stop_encode(&cpi->bc[1]);
- *size += cpi->bc2.pos;
- cpi->partition_sz[1] = cpi->bc2.pos;
+ *size += cpi->bc[1].pos;
+ cpi->partition_sz[1] = cpi->bc[1].pos;
}
}