Newer
Older
#else
for (j = 0; j < COEF_BANDS; j++)
#endif
for (k = 0; k < PREV_COEF_CONTEXTS; k++)
{
#if CONFIG_EXPANDED_COEF_CONTEXT
if (k >= 3 && ((i == 0 && j == 1) ||
(i > 0 && j == 0)))
continue;
#endif
for (l = 0; l < ENTROPY_NODES; l++)
{
vp8_prob *const p = pc->fc.coef_probs_8x8 [i][j][k] + l;
if (vp8_read(bc, COEF_UPDATE_PROB_8X8))
{
#if CONFIG_NEWUPDATE
*p = read_prob_diff_update(bc, *p);
#else
*p = (vp8_prob)vp8_read_literal(bc, 8);
#endif
}
}
int vp8_decode_frame(VP8D_COMP *pbi)
{
vp8_reader *const bc = & pbi->bc;
VP8_COMMON *const pc = & pbi->common;
MACROBLOCKD *const xd = & pbi->mb;
const unsigned char *data = (const unsigned char *)pbi->Source;
const unsigned char *data_end = data + pbi->source_sz;
ptrdiff_t first_partition_length_in_bytes = 0;
int corrupt_tokens = 0;
/* start with no corruption of current frame */
xd->corrupted = 0;
pc->yv12_fb[pc->new_fb_idx].corrupted = 0;
vpx_internal_error(&pc->error, VPX_CODEC_CORRUPT_FRAME,
"Truncated packet");
pc->last_frame_type = pc->frame_type;
pc->frame_type = (FRAME_TYPE)(data[0] & 1);
pc->version = (data[0] >> 1) & 7;
pc->show_frame = (data[0] >> 4) & 1;
first_partition_length_in_bytes =
(data[0] | (data[1] << 8) | (data[2] << 16)) >> 5;
if ((data + first_partition_length_in_bytes > data_end
|| data + first_partition_length_in_bytes < data))
vpx_internal_error(&pc->error, VPX_CODEC_CORRUPT_FRAME,
"Truncated packet or corrupt partition 0 length");
data += 3;
if (pc->frame_type == KEY_FRAME)
const int Width = pc->Width;
const int Height = pc->Height;
/* vet via sync code */
/* When error concealment is enabled we should only check the sync
* code if we have enough bits available
*/
if (data[0] != 0x9d || data[1] != 0x01 || data[2] != 0x2a)
vpx_internal_error(&pc->error, VPX_CODEC_UNSUP_BITSTREAM,
"Invalid frame sync code");
/* If error concealment is enabled we should only parse the new size
* if we have enough data. Otherwise we will end up with the wrong
* size.
*/
pc->Width = (data[3] | (data[4] << 8)) & 0x3fff;
pc->horiz_scale = data[4] >> 6;
pc->Height = (data[5] | (data[6] << 8)) & 0x3fff;
pc->vert_scale = data[6] >> 6;
data += 7;
if (Width != pc->Width || Height != pc->Height)
{
if (pc->Width <= 0)
{
pc->Width = Width;
vpx_internal_error(&pc->error, VPX_CODEC_CORRUPT_FRAME,
"Invalid frame width");
}
if (pc->Height <= 0)
{
pc->Height = Height;
vpx_internal_error(&pc->error, VPX_CODEC_CORRUPT_FRAME,
"Invalid frame height");
}
if (vp8_alloc_frame_buffers(pc, pc->Width, pc->Height))
vpx_internal_error(&pc->error, VPX_CODEC_MEM_ERROR,
"Failed to allocate frame buffers");
}
if ((!pbi->decoded_key_frame && pc->frame_type != KEY_FRAME) ||
pc->Width == 0 || pc->Height == 0)
{
return -1;
}
init_frame(pbi);
if (vp8dx_start_decode(bc, data, data_end - data))
vpx_internal_error(&pc->error, VPX_CODEC_MEM_ERROR,
"Failed to allocate bool decoder 0");
if (pc->frame_type == KEY_FRAME) {
pc->clr_type = (YUV_TYPE)vp8_read_bit(bc);
pc->clamp_type = (CLAMP_TYPE)vp8_read_bit(bc);
}
xd->segmentation_enabled = (unsigned char)vp8_read_bit(bc);
// Read whether or not the segmentation map is being explicitly
// updated this frame.
xd->update_mb_segmentation_map = (unsigned char)vp8_read_bit(bc);
// If so what method will be used.
if ( xd->update_mb_segmentation_map )
pc->temporal_update = (unsigned char)vp8_read_bit(bc);
xd->update_mb_segmentation_data = (unsigned char)vp8_read_bit(bc);
if (xd->update_mb_segmentation_data)
{
xd->mb_segment_abs_delta = (unsigned char)vp8_read_bit(bc);
for (i = 0; i < MAX_MB_SEGMENTS; i++)
{
// For each of the segments features...
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
#if CONFIG_FEATUREUPDATES
// feature updated?
if (vp8_read_bit(bc))
{
int active=1;
if ( segfeature_active( xd, i, j ))
active=vp8_read_bit(bc);
// Is the feature enabled
if (active)
{
// Update the feature data and mask
enable_segfeature(xd, i, j);
data = (signed char)vp8_read_literal(
bc, seg_feature_data_bits(j));
// Is the segment data signed..
if ( is_segfeature_signed(j) )
{
if (vp8_read_bit(bc))
data = - data;
}
}
else
data = 0;
set_segdata(xd, i, j, data);
}
#else
data = (signed char)vp8_read_literal(
bc, seg_feature_data_bits(j));
data = 0;
set_segdata(xd, i, j, data);
}
}
}
if (xd->update_mb_segmentation_map)
{
// Which macro block level features are enabled
vpx_memset(xd->mb_segment_tree_probs, 255,
sizeof(xd->mb_segment_tree_probs));
vpx_memset(pc->segment_pred_probs, 255,
sizeof(pc->segment_pred_probs));
// Read the probs used to decode the segment id for each macro
// block.
for (i = 0; i < MB_FEATURE_TREE_PROBS; i++)
{
// If not explicitly set value is defaulted to 255 by
//memset above
xd->mb_segment_tree_probs[i] =
(vp8_prob)vp8_read_literal(bc, 8);
// If predictive coding of segment map is enabled read the
// prediction probabilities.
{
// Read the prediction probs needed to decode the segment id
// when predictive coding enabled
for (i = 0; i < PREDICTION_PROBS; i++)
{
// If not explicitly set value is defaulted to 255 by
// memset above
if (vp8_read_bit(bc))
(vp8_prob)vp8_read_literal(bc, 8);
}
}
// Read common prediction model status flag probability updates for the
// reference frame
if ( pc->frame_type == KEY_FRAME )
{
// Set the prediction probabilities to defaults
pc->ref_pred_probs[0] = 120;
pc->ref_pred_probs[1] = 80;
pc->ref_pred_probs[2] = 40;
}
else
{
for (i = 0; i < PREDICTION_PROBS; i++)
{
if ( vp8_read_bit(bc) )
pc->ref_pred_probs[i] = (vp8_prob)vp8_read_literal(bc, 8);
}
}
/* Read the loop filter level and type */
pc->txfm_mode = (TXFM_MODE) vp8_read_bit(bc);
pc->filter_type = (LOOPFILTERTYPE) vp8_read_bit(bc);
pc->filter_level = vp8_read_literal(bc, 6);
pc->sharpness_level = vp8_read_literal(bc, 3);
/* Read in loop filter deltas applied at the MB level based on mode or ref frame. */
xd->mode_ref_lf_delta_update = 0;
xd->mode_ref_lf_delta_enabled = (unsigned char)vp8_read_bit(bc);
if (xd->mode_ref_lf_delta_enabled)
{
/* Do the deltas need to be updated */
xd->mode_ref_lf_delta_update = (unsigned char)vp8_read_bit(bc);
if (xd->mode_ref_lf_delta_update)
{
for (i = 0; i < MAX_REF_LF_DELTAS; i++)
{
if (vp8_read_bit(bc))
{
xd->ref_lf_deltas[i] = (signed char)vp8_read_literal(bc, 6);
if (vp8_read_bit(bc)) /* Apply sign */
xd->ref_lf_deltas[i] = xd->ref_lf_deltas[i] * -1;
}
}
for (i = 0; i < MAX_MODE_LF_DELTAS; i++)
{
if (vp8_read_bit(bc))
{
xd->mode_lf_deltas[i] = (signed char)vp8_read_literal(bc, 6);
if (vp8_read_bit(bc)) /* Apply sign */
xd->mode_lf_deltas[i] = xd->mode_lf_deltas[i] * -1;
}
}
}
}
setup_token_decoder(pbi, data + first_partition_length_in_bytes);
Q = vp8_read_literal(bc, QINDEX_BITS); /* AC 1st order Q = default */
pc->base_qindex = Q;
q_update = 0;
pc->y1dc_delta_q = get_delta_q(bc, pc->y1dc_delta_q, &q_update);
pc->y2dc_delta_q = get_delta_q(bc, pc->y2dc_delta_q, &q_update);
pc->y2ac_delta_q = get_delta_q(bc, pc->y2ac_delta_q, &q_update);
pc->uvdc_delta_q = get_delta_q(bc, pc->uvdc_delta_q, &q_update);
pc->uvac_delta_q = get_delta_q(bc, pc->uvac_delta_q, &q_update);
if (q_update)
vp8cx_init_de_quantizer(pbi);
/* Determine if the golden frame or ARF buffer should be updated and how.
* For all non key frames the GF and ARF refresh flags and sign bias
* flags must be set explicitly.
*/
/* Should the GF or ARF be updated from the current frame */
pc->refresh_golden_frame = vp8_read_bit(bc);
pc->refresh_alt_ref_frame = vp8_read_bit(bc);
vpx_memcpy(&pc->fc, &pc->lfc_a, sizeof(pc->fc));
vpx_memcpy( pc->fc.vp8_mode_contexts,
pc->fc.mode_context_a,
sizeof(pc->fc.vp8_mode_contexts));
vpx_memcpy(&pc->fc, &pc->lfc, sizeof(pc->fc));
vpx_memcpy( pc->fc.vp8_mode_contexts,
pc->fc.mode_context,
sizeof(pc->fc.vp8_mode_contexts));
pc->copy_buffer_to_gf = 0;
if (!pc->refresh_golden_frame)
pc->copy_buffer_to_gf = vp8_read_literal(bc, 2);
pc->copy_buffer_to_arf = 0;
if (!pc->refresh_alt_ref_frame)
pc->copy_buffer_to_arf = vp8_read_literal(bc, 2);
pc->ref_frame_sign_bias[GOLDEN_FRAME] = vp8_read_bit(bc);
pc->ref_frame_sign_bias[ALTREF_FRAME] = vp8_read_bit(bc);
#if CONFIG_HIGH_PRECISION_MV
/* Is high precision mv allowed */
xd->allow_high_precision_mv = (unsigned char)vp8_read_bit(bc);
#endif
#if CONFIG_ENHANCED_INTERP
// Read the type of subpel filter to use
pc->mcomp_filter_type = vp8_read_literal(bc, 2);
/* To enable choice of different interploation filters */
if (pc->mcomp_filter_type == SIXTAP)
{
xd->subpixel_predict = SUBPIX_INVOKE(RTCD_VTABLE(subpix), sixtap4x4);
xd->subpixel_predict8x4 = SUBPIX_INVOKE(RTCD_VTABLE(subpix), sixtap8x4);
xd->subpixel_predict8x8 = SUBPIX_INVOKE(RTCD_VTABLE(subpix), sixtap8x8);
xd->subpixel_predict16x16 = SUBPIX_INVOKE(RTCD_VTABLE(subpix), sixtap16x16);
xd->subpixel_predict_avg = SUBPIX_INVOKE(RTCD_VTABLE(subpix), sixtap_avg4x4);
xd->subpixel_predict_avg8x8 = SUBPIX_INVOKE(RTCD_VTABLE(subpix), sixtap_avg8x8);
xd->subpixel_predict_avg16x16 = SUBPIX_INVOKE(RTCD_VTABLE(subpix), sixtap_avg16x16);
}
else if (pc->mcomp_filter_type == EIGHTTAP)
{
xd->subpixel_predict = SUBPIX_INVOKE(RTCD_VTABLE(subpix), eighttap4x4);
xd->subpixel_predict8x4 = SUBPIX_INVOKE(RTCD_VTABLE(subpix), eighttap8x4);
xd->subpixel_predict8x8 = SUBPIX_INVOKE(RTCD_VTABLE(subpix), eighttap8x8);
xd->subpixel_predict16x16 = SUBPIX_INVOKE(RTCD_VTABLE(subpix), eighttap16x16);
xd->subpixel_predict_avg = SUBPIX_INVOKE(RTCD_VTABLE(subpix), eighttap_avg4x4);
xd->subpixel_predict_avg8x8 = SUBPIX_INVOKE(RTCD_VTABLE(subpix), eighttap_avg8x8);
xd->subpixel_predict_avg16x16 = SUBPIX_INVOKE(RTCD_VTABLE(subpix), eighttap_avg16x16);
}
else if (pc->mcomp_filter_type == EIGHTTAP_SHARP)
{
xd->subpixel_predict = SUBPIX_INVOKE(RTCD_VTABLE(subpix), eighttap4x4_sharp);
xd->subpixel_predict8x4 = SUBPIX_INVOKE(RTCD_VTABLE(subpix), eighttap8x4_sharp);
xd->subpixel_predict8x8 = SUBPIX_INVOKE(RTCD_VTABLE(subpix), eighttap8x8_sharp);
xd->subpixel_predict16x16 = SUBPIX_INVOKE(RTCD_VTABLE(subpix), eighttap16x16_sharp);
xd->subpixel_predict_avg = SUBPIX_INVOKE(RTCD_VTABLE(subpix), eighttap_avg4x4_sharp);
xd->subpixel_predict_avg8x8 = SUBPIX_INVOKE(RTCD_VTABLE(subpix), eighttap_avg8x8_sharp);
xd->subpixel_predict_avg16x16 = SUBPIX_INVOKE(RTCD_VTABLE(subpix), eighttap_avg16x16_sharp);
}
else
{
xd->subpixel_predict = SUBPIX_INVOKE(RTCD_VTABLE(subpix), bilinear4x4);
xd->subpixel_predict8x4 = SUBPIX_INVOKE(RTCD_VTABLE(subpix), bilinear8x4);
xd->subpixel_predict8x8 = SUBPIX_INVOKE(RTCD_VTABLE(subpix), bilinear8x8);
xd->subpixel_predict16x16 = SUBPIX_INVOKE(RTCD_VTABLE(subpix), bilinear16x16);
xd->subpixel_predict_avg = SUBPIX_INVOKE(RTCD_VTABLE(subpix), bilinear_avg4x4);
xd->subpixel_predict_avg8x8 = SUBPIX_INVOKE(RTCD_VTABLE(subpix), bilinear_avg8x8);
xd->subpixel_predict_avg16x16 = SUBPIX_INVOKE(RTCD_VTABLE(subpix), bilinear_avg16x16);
}
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
}
pc->refresh_entropy_probs = vp8_read_bit(bc);
if (pc->refresh_entropy_probs == 0)
{
vpx_memcpy(&pc->lfc, &pc->fc, sizeof(pc->fc));
}
pc->refresh_last_frame = pc->frame_type == KEY_FRAME || vp8_read_bit(bc);
if (0)
{
FILE *z = fopen("decodestats.stt", "a");
fprintf(z, "%6d F:%d,G:%d,A:%d,L:%d,Q:%d\n",
pc->current_video_frame,
pc->frame_type,
pc->refresh_golden_frame,
pc->refresh_alt_ref_frame,
pc->refresh_last_frame,
pc->base_qindex);
fclose(z);
}
#if CONFIG_ADAPTIVE_ENTROPY
vp8_copy(pbi->common.fc.pre_coef_probs, pbi->common.fc.coef_probs);
vp8_copy(pbi->common.fc.pre_coef_probs_8x8, pbi->common.fc.coef_probs_8x8);
vp8_copy(pbi->common.fc.pre_ymode_prob, pbi->common.fc.ymode_prob);
vp8_copy(pbi->common.fc.pre_uv_mode_prob, pbi->common.fc.uv_mode_prob);
vp8_copy(pbi->common.fc.pre_bmode_prob, pbi->common.fc.bmode_prob);
vp8_copy(pbi->common.fc.pre_i8x8_mode_prob, pbi->common.fc.i8x8_mode_prob);
vp8_copy(pbi->common.fc.pre_sub_mv_ref_prob, pbi->common.fc.sub_mv_ref_prob);
vp8_copy(pbi->common.fc.pre_mbsplit_prob, pbi->common.fc.mbsplit_prob);
vp8_copy(pbi->common.fc.pre_mvc, pbi->common.fc.mvc);
#if CONFIG_HIGH_PRECISION_MV
vp8_copy(pbi->common.fc.pre_mvc_hp, pbi->common.fc.mvc_hp);
#endif
vp8_zero(pbi->common.fc.coef_counts);
vp8_zero(pbi->common.fc.coef_counts_8x8);
vp8_zero(pbi->common.fc.ymode_counts);
vp8_zero(pbi->common.fc.uv_mode_counts);
vp8_zero(pbi->common.fc.bmode_counts);
vp8_zero(pbi->common.fc.i8x8_mode_counts);
vp8_zero(pbi->common.fc.sub_mv_ref_counts);
vp8_zero(pbi->common.fc.mbsplit_counts);
vp8_zero(pbi->common.fc.MVcount);
#if CONFIG_HIGH_PRECISION_MV
vp8_zero(pbi->common.fc.MVcount_hp);
#endif
vp8_zero(pbi->common.fc.mv_ref_ct);
vp8_zero(pbi->common.fc.mv_ref_ct_a);
#endif /* CONFIG_ADAPTIVE_ENTROPY */
#if CONFIG_NEWUPDATE && COEFUPDATETYPE == 2
#elif CONFIG_NEWUPDATE && COEFUPDATETYPE == 3
read_coef_probs3(pbi);
#else
read_coef_probs(pbi);
#endif
vpx_memcpy(&xd->pre, &pc->yv12_fb[pc->lst_fb_idx], sizeof(YV12_BUFFER_CONFIG));
vpx_memcpy(&xd->dst, &pc->yv12_fb[pc->new_fb_idx], sizeof(YV12_BUFFER_CONFIG));
// Create the segmentation map structure and set to 0
if (!pc->last_frame_seg_map)
CHECK_MEM_ERROR(pc->last_frame_seg_map,
vpx_calloc((pc->mb_rows * pc->mb_cols), 1));
/* set up frame new frame for intra coded blocks */
vp8_setup_intra_recon(&pc->yv12_fb[pc->new_fb_idx]);
vp8_setup_block_dptrs(xd);
vp8_build_block_doffsets(xd);
vpx_memset(xd->qcoeff, 0, sizeof(xd->qcoeff));
pc->mb_no_coeff_skip = (int)vp8_read_bit(bc);
#if CONFIG_ADAPTIVE_ENTROPY == 0
if (pc->frame_type != KEY_FRAME)
{
vp8_update_mode_context(&pbi->common);
}
vpx_memset(pc->above_context, 0, sizeof(ENTROPY_CONTEXT_PLANES) * pc->mb_cols);
// Resset the macroblock mode info context to the start of the list
xd->mode_info_context = pc->mi;
/* Decode a row of superblocks */
for (mb_row = 0; mb_row < pc->mb_rows; mb_row+=2)
/* Collect information about decoder corruption. */
/* 1. Check first boolean decoder for errors. */
pc->yv12_fb[pc->new_fb_idx].corrupted = vp8dx_bool_error(bc);
/* 2. Check the macroblock information */
pc->yv12_fb[pc->new_fb_idx].corrupted |= corrupt_tokens;
if (!pbi->decoded_key_frame)
{
if (pc->frame_type == KEY_FRAME &&
!pc->yv12_fb[pc->new_fb_idx].corrupted)
pbi->decoded_key_frame = 1;
else
vpx_internal_error(&pbi->common.error, VPX_CODEC_CORRUPT_FRAME,
"A stream must start with a complete key frame");
}
/* vpx_log("Decoder: Frame Decoded, Size Roughly:%d bytes \n",bc->pos+pbi->bc2.pos); */
#if CONFIG_ADAPTIVE_ENTROPY
vp8_adapt_coef_probs(pc);
if (pc->frame_type != KEY_FRAME)
{
vp8_adapt_mode_probs(pc);
vp8_adapt_mv_probs(pc);
vp8_update_mode_context(&pbi->common);
/* If this was a kf or Gf note the Q used */
if ((pc->frame_type == KEY_FRAME) ||
pc->refresh_golden_frame || pc->refresh_alt_ref_frame)
{
if(pc->refresh_entropy_probs)
{
if(pc->refresh_alt_ref_frame)
vpx_memcpy(&pc->lfc_a, &pc->fc, sizeof(pc->fc));
else
vpx_memcpy(&pc->lfc, &pc->fc, sizeof(pc->fc));
}
#ifdef PACKET_TESTING
{
FILE *f = fopen("decompressor.VP8", "ab");
unsigned int size = pbi->bc2.pos + pbi->bc.pos + 8;
fwrite((void *) &size, 4, 1, f);
fwrite((void *) pbi->Source, size, 1, f);
fclose(f);
}
#endif
//printf("Frame %d Done\n", frame_count++);