void VPX_NO_UNSIGNED_SHIFT_CHECK vp8_pack_tokens(vp8_writer *w, const TOKENEXTRA *p, int xcount) { const TOKENEXTRA *stop = p + xcount; unsignedint split; int shift; int count = w->count; unsignedint range = w->range; unsignedint lowvalue = w->lowvalue;
while (p < stop) { constint t = p->Token;
vp8_token *a = vp8_coef_encodings + t; const vp8_extra_bit_struct *b = vp8_extra_bits + t; int i = 0; constunsignedchar *pp = p->context_tree; int v = a->value; int n = a->Len;
if (p->skip_eob_node) {
n--;
i = 2;
}
do { constint 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;
/* Calculate the probabilities used to code the ref frame based on usage */ if (!(cpi->prob_intra_coded = rf_intra * 255 / (rf_intra + rf_inter))) {
cpi->prob_intra_coded = 1;
}
do {
B_PREDICTION_MODE blockmode;
int_mv blockmv; constint *const L = vp8_mbsplits[mi->partitioning]; int k = -1; /* first block in subset j */ int mv_contz;
int_mv leftmv, abovemv;
staticint independent_coef_context_savings(VP8_COMP *cpi) {
MACROBLOCK *const x = &cpi->mb; int savings = 0; int i = 0; do { int j = 0; do { int k = 0; unsignedint prev_coef_count_sum[MAX_ENTROPY_TOKENS] = { 0 }; int prev_coef_savings[MAX_ENTROPY_TOKENS] = { 0 }; constunsignedint(*probs)[MAX_ENTROPY_TOKENS]; /* Calculate new probabilities given the constraint that *theymustbeequalovertheprevcoefcontexts
*/
if (cpi->common.frame_type != KEY_FRAME ||
(cpi->common.frame_type == KEY_FRAME && newp != oldp)) {
prev_coef_savings[t] += s;
}
} while (++t < ENTROPY_NODES);
} while (++k < PREV_COEF_CONTEXTS);
k = 0; do { /* We only update probabilities if we can save bits, except *forkeyframeswherewehavetoupdateallprobabilities *togettheequalprobabilitiesacrosstheprevcoef *contexts.
*/ if (prev_coef_savings[k] > 0 || cpi->common.frame_type == KEY_FRAME) {
savings += prev_coef_savings[k];
}
} while (++k < ENTROPY_NODES);
} while (++j < COEF_BANDS);
} while (++i < BLOCK_TYPES); return savings;
}
staticint default_coef_context_savings(VP8_COMP *cpi) {
MACROBLOCK *const x = &cpi->mb; int savings = 0; int i = 0; do { int j = 0; do { int k = 0; do { /* at every context */
/* calc probs and branch cts for this frame only */ int t = 0; /* token/prob index */
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
vpx_clear_system_state();
do { int j = 0;
do { int k = 0; int prev_coef_savings[ENTROPY_NODES] = { 0 }; if (cpi->oxcf.error_resilient_mode & VPX_ERROR_RESILIENT_PARTITIONS) { for (k = 0; k < PREV_COEF_CONTEXTS; ++k) { int t; /* token/prob index */ for (t = 0; t < ENTROPY_NODES; ++t) { constunsignedint *ct = cpi->frame_branch_ct[i][j][k][t]; const vp8_prob newp = cpi->frame_coef_probs[i][j][k][t]; const vp8_prob oldp = cpi->common.fc.coef_probs[i][j][k][t]; const vp8_prob upd = vp8_coef_update_probs[i][j][k][t];
prev_coef_savings[t] += prob_update_savings(ct, oldp, newp, upd);
}
}
k = 0;
} do { /* note: use result from vp8_estimate_entropy_savings, so no *needtocallvp8_tree_probs_from_distributionhere.
*/
/* at every context */
/* calc probs and branch cts for this frame only */ int t = 0; /* token/prob index */
do { const vp8_prob newp = cpi->frame_coef_probs[i][j][k][t];
if (!(cpi->oxcf.error_resilient_mode &
VPX_ERROR_RESILIENT_PARTITIONS)) {
s = prob_update_savings(cpi->frame_branch_ct[i][j][k][t], *Pold,
newp, upd);
}
if (s > 0) u = 1;
/* Force updates on key frames if the new is different, *sothatwecanbesureweendupwithequalprobabilities *overtheprevcoefcontexts.
*/ if ((cpi->oxcf.error_resilient_mode &
VPX_ERROR_RESILIENT_PARTITIONS) &&
cpi->common.frame_type == KEY_FRAME && newp != *Pold) {
u = 1;
}
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
staticvoid put_delta_q(vp8_writer *bc, int delta_q) { if (delta_q != 0) {
vp8_write_bit(bc, 1);
vp8_write_literal(bc, abs(delta_q), 4);
/* Pack scale and frame size into 16 bits. Store it 8 bits at a time. *https://tools.ietf.org/html/rfc6386 *9.1.UncompressedDataChunk *16bits:(2bitsHorizontalScale<<14)|Width(14bits) *16bits:(2bitsVerticalScale<<14)|Height(14bits)
*/
v = (pc->horiz_scale << 14) | pc->Width;
cx_data[3] = v & 0xff;
cx_data[4] = v >> 8;
v = (pc->vert_scale << 14) | pc->Height;
cx_data[5] = v & 0xff;
cx_data[6] = v >> 8;
/* Signal whether or not Segmentation is enabled */
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);
vp8_write_bit(bc, xd->update_mb_segmentation_data);
if (xd->update_mb_segmentation_data) { signedchar Data;
vp8_write_bit(bc, xd->mb_segment_abs_delta);
/* For each segmentation feature (Quant and loop filter level) */ for (i = 0; i < MB_LVL_MAX; ++i) { /* For each of the segments */ for (j = 0; j < MAX_MB_SEGMENTS; ++j) {
Data = xd->segment_feature_data[i][j];
/* Frame level data */ if (Data) {
vp8_write_bit(bc, 1);
if (xd->update_mb_segmentation_map) { /* Write the probs used to decode the segment id for each mb */ for (i = 0; i < MB_FEATURE_TREE_PROBS; ++i) { int Data = xd->mb_segment_tree_probs[i];
/* Write out loop filter deltas applied at the MB level based on mode *orrefframe(iftheyareenabled).
*/
vp8_write_bit(bc, xd->mode_ref_lf_delta_enabled);
if (xd->mode_ref_lf_delta_enabled) { /* Do the deltas need to be updated */ int send_update =
xd->mode_ref_lf_delta_update || cpi->oxcf.error_resilient_mode;
vp8_write_bit(bc, send_update); if (send_update) { int Data;
/* Send update */ for (i = 0; i < MAX_REF_LF_DELTAS; ++i) {
Data = xd->ref_lf_deltas[i];
/* Frame level data */ if (xd->ref_lf_deltas[i] != xd->last_ref_lf_deltas[i] ||
cpi->oxcf.error_resilient_mode) {
xd->last_ref_lf_deltas[i] = xd->ref_lf_deltas[i];
vp8_write_bit(bc, 1);
/* signal here is multi token partition is enabled */
vp8_write_literal(bc, pc->multi_token_partition, 2);
/* Frame Qbaseline quantizer index */
vp8_write_literal(bc, pc->base_qindex, 7);
/* Transmit Dc, Second order and Uv quantizer delta information */
put_delta_q(bc, pc->y1dc_delta_q);
put_delta_q(bc, pc->y2dc_delta_q);
put_delta_q(bc, pc->y2ac_delta_q);
put_delta_q(bc, pc->uvdc_delta_q);
put_delta_q(bc, pc->uvac_delta_q);
/* When there is a key frame all reference buffers are updated using *thenewkeyframe
*/ if (pc->frame_type != KEY_FRAME) { /* Should the GF or ARF be updated using the transmitted frame *orbuffer
*/
vp8_write_bit(bc, pc->refresh_golden_frame);
vp8_write_bit(bc, pc->refresh_alt_ref_frame);
/* If not being updated from current frame should either GF or ARF *beupdatedfromanotherbuffer
*/ if (!pc->refresh_golden_frame)
vp8_write_literal(bc, pc->copy_buffer_to_gf, 2);
if (!pc->refresh_alt_ref_frame)
vp8_write_literal(bc, pc->copy_buffer_to_arf, 2);
/* Indicate reference frame sign bias for Golden and ARF frames *(always0forlastframebuffer)
*/
vp8_write_bit(bc, pc->ref_frame_sign_bias[GOLDEN_FRAME]);
vp8_write_bit(bc, pc->ref_frame_sign_bias[ALTREF_FRAME]);
}
if (pc->frame_type != KEY_FRAME) vp8_write_bit(bc, pc->refresh_last_frame);
vpx_clear_system_state();
#if CONFIG_REALTIME_ONLY & CONFIG_ONTHEFLY_BITPACKING
pack_coef_probs(cpi); #else if (pc->refresh_entropy_probs == 0) { /* save a copy for later refresh */
pc->lfc = pc->fc;
}
vp8_update_coef_probs(cpi); #endif
/* Write out the mb_no_coeff_skip flag */
vp8_write_bit(bc, pc->mb_no_coeff_skip);
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) {
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;
/* partition size table at the end of first partition */
cpi->partition_sz[0] += 3 * (num_part - 1);
*size += 3 * (num_part - 1);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.