int vp8_decode_frame(VP8D_COMP *pbi) { vp8_reader *const bc = &pbi->mbc[8]; VP8_COMMON *const pc = &pbi->common; MACROBLOCKD *const xd = &pbi->mb; const unsigned char *data = pbi->fragments.ptrs[0]; const unsigned char *data_end = data + pbi->fragments.sizes[0]; ptrdiff_t first_partition_length_in_bytes; int i, j, k, l; const int *const mb_feature_data_bits = vp8_mb_feature_data_bits; int corrupt_tokens = 0; int prev_independent_partitions = pbi->independent_partitions; YV12_BUFFER_CONFIG *yv12_fb_new = pbi->dec_fb_ref[INTRA_FRAME]; /* start with no corruption of current frame */ xd->corrupted = 0; yv12_fb_new->corrupted = 0; if (data_end - data < 3) { if (!pbi->ec_active) { vpx_internal_error(&pc->error, VPX_CODEC_CORRUPT_FRAME, "Truncated packet"); } /* Declare the missing frame as an inter frame since it will be handled as an inter frame when we have estimated its motion vectors. */ pc->frame_type = INTER_FRAME; pc->version = 0; pc->show_frame = 1; first_partition_length_in_bytes = 0; } else { unsigned char clear_buffer[10]; const unsigned char *clear = data; if (pbi->decrypt_cb) { int n = (int)MIN(sizeof(clear_buffer), data_end - data); pbi->decrypt_cb(pbi->decrypt_state, data, clear_buffer, n); clear = clear_buffer; } pc->frame_type = (FRAME_TYPE)(clear[0] & 1); pc->version = (clear[0] >> 1) & 7; pc->show_frame = (clear[0] >> 4) & 1; first_partition_length_in_bytes = (clear[0] | (clear[1] << 8) | (clear[2] << 16)) >> 5; if (!pbi->ec_active && (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; clear += 3; vp8_setup_version(pc); if (pc->frame_type == KEY_FRAME) { /* vet via sync code */ /* When error concealment is enabled we should only check the sync * code if we have enough bits available */ if (!pbi->ec_active || data + 3 < data_end) { if (clear[0] != 0x9d || clear[1] != 0x01 || clear[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. */ if (!pbi->ec_active || data + 6 < data_end) { pc->Width = (clear[3] | (clear[4] << 8)) & 0x3fff; pc->horiz_scale = clear[4] >> 6; pc->Height = (clear[5] | (clear[6] << 8)) & 0x3fff; pc->vert_scale = clear[6] >> 6; } data += 7; clear += 7; } else {
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 = pbi->fragments[0]; const unsigned char *data_end = data + pbi->fragment_sizes[0]; ptrdiff_t first_partition_length_in_bytes; int mb_row; int i, j, k, l; const int *const mb_feature_data_bits = vp8_mb_feature_data_bits; int corrupt_tokens = 0; int prev_independent_partitions = pbi->independent_partitions; /* start with no corruption of current frame */ xd->corrupted = 0; pc->yv12_fb[pc->new_fb_idx].corrupted = 0; if (data_end - data < 3) { if (!pbi->ec_active) { vpx_internal_error(&pc->error, VPX_CODEC_CORRUPT_FRAME, "Truncated packet"); } /* Declare the missing frame as an inter frame since it will be handled as an inter frame when we have estimated its motion vectors. */ pc->frame_type = INTER_FRAME; pc->version = 0; pc->show_frame = 1; first_partition_length_in_bytes = 0; } else { 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 (!pbi->ec_active && (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; vp8_setup_version(pc); 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 (!pbi->ec_active || data + 3 < data_end) { 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. */ if (!pbi->ec_active || data + 6 < data_end) { 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) { int prev_mb_rows = pc->mb_rows; 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 CONFIG_ERROR_CONCEALMENT pbi->overlaps = NULL; if (pbi->ec_enabled) { if (vp8_alloc_overlap_lists(pbi)) vpx_internal_error(&pc->error, VPX_CODEC_MEM_ERROR, "Failed to allocate overlap lists " "for error concealment"); } #endif #if CONFIG_MULTITHREAD if (pbi->b_multithreaded_rd) vp8mt_alloc_temp_buffers(pbi, pc->Width, prev_mb_rows); #endif } } }