diff options
Diffstat (limited to 'vp9/decoder')
-rw-r--r-- | vp9/decoder/vp9_decodframe.c | 194 | ||||
-rw-r--r-- | vp9/decoder/vp9_detokenize.c | 4 | ||||
-rw-r--r-- | vp9/decoder/vp9_read_bit_buffer.h | 50 |
3 files changed, 149 insertions, 99 deletions
diff --git a/vp9/decoder/vp9_decodframe.c b/vp9/decoder/vp9_decodframe.c index 70e0c8759..a4a8226a0 100644 --- a/vp9/decoder/vp9_decodframe.c +++ b/vp9/decoder/vp9_decodframe.c @@ -10,29 +10,30 @@ #include <assert.h> -#include "vp9/decoder/vp9_onyxd_int.h" +#include "./vp9_rtcd.h" +#include "vpx_mem/vpx_mem.h" +#include "vpx_scale/vpx_scale.h" + +#include "vp9/common/vp9_extend.h" +#include "vp9/common/vp9_modecont.h" #include "vp9/common/vp9_common.h" -#include "vp9/common/vp9_header.h" #include "vp9/common/vp9_reconintra.h" #include "vp9/common/vp9_reconinter.h" #include "vp9/common/vp9_entropy.h" -#include "vp9/decoder/vp9_decodframe.h" -#include "vp9/decoder/vp9_detokenize.h" #include "vp9/common/vp9_invtrans.h" #include "vp9/common/vp9_alloccommon.h" #include "vp9/common/vp9_entropymode.h" #include "vp9/common/vp9_quant_common.h" -#include "vpx_scale/vpx_scale.h" +#include "vp9/common/vp9_seg_common.h" +#include "vp9/common/vp9_tile_common.h" -#include "vp9/decoder/vp9_decodemv.h" -#include "vp9/common/vp9_extend.h" -#include "vp9/common/vp9_modecont.h" -#include "vpx_mem/vpx_mem.h" #include "vp9/decoder/vp9_dboolhuff.h" +#include "vp9/decoder/vp9_decodframe.h" +#include "vp9/decoder/vp9_detokenize.h" +#include "vp9/decoder/vp9_decodemv.h" +#include "vp9/decoder/vp9_onyxd_int.h" +#include "vp9/decoder/vp9_read_bit_buffer.h" -#include "vp9/common/vp9_seg_common.h" -#include "vp9/common/vp9_tile_common.h" -#include "./vp9_rtcd.h" // #define DEC_DEBUG #ifdef DEC_DEBUG @@ -743,32 +744,24 @@ static INTERPOLATIONFILTERTYPE read_mcomp_filter_type(vp9_reader *r) { : vp9_read_literal(r, 2); } -static const uint8_t *read_frame_size(VP9_COMMON *const pc, const uint8_t *data, - const uint8_t *data_end, - int *width, int *height) { - if (data + 4 < data_end) { - const int w = read_le16(data); - const int h = read_le16(data + 2); - if (w <= 0) - vpx_internal_error(&pc->error, VPX_CODEC_CORRUPT_FRAME, - "Invalid frame width"); - - if (h <= 0) - vpx_internal_error(&pc->error, VPX_CODEC_CORRUPT_FRAME, - "Invalid frame height"); - *width = w; - *height = h; - data += 4; - } else { - vpx_internal_error(&pc->error, VPX_CODEC_CORRUPT_FRAME, - "Failed to read frame size"); - } - return data; +static void read_frame_size(VP9_COMMON *cm, + struct vp9_read_bit_buffer *rb, + int *width, int *height) { + const int w = vp9_rb_read_literal(rb, 16); + const int h = vp9_rb_read_literal(rb, 16); + if (w <= 0) + vpx_internal_error(&cm->error, VPX_CODEC_CORRUPT_FRAME, + "Invalid frame width"); + + if (h <= 0) + vpx_internal_error(&cm->error, VPX_CODEC_CORRUPT_FRAME, + "Invalid frame height"); + *width = w; + *height = h; } -static const uint8_t *setup_frame_size(VP9D_COMP *pbi, int scaling_active, - const uint8_t *data, - const uint8_t *data_end) { +static void setup_frame_size(VP9D_COMP *pbi, int scaling_active, + struct vp9_read_bit_buffer *rb) { // 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. VP9_COMMON *const pc = &pbi->common; @@ -778,9 +771,9 @@ static const uint8_t *setup_frame_size(VP9D_COMP *pbi, int scaling_active, int height = pc->height; if (scaling_active) - data = read_frame_size(pc, data, data_end, &display_width, &display_height); + read_frame_size(pc, rb, &display_width, &display_height); - data = read_frame_size(pc, data, data_end, &width, &height); + read_frame_size(pc, rb, &width, &height); if (pc->width != width || pc->height != height) { if (!pbi->initial_width || !pbi->initial_height) { @@ -806,8 +799,6 @@ static const uint8_t *setup_frame_size(VP9D_COMP *pbi, int scaling_active, vp9_update_frame_size(pc); } - - return data; } static void update_frame_context(FRAME_CONTEXT *fc) { @@ -937,59 +928,78 @@ static void decode_tiles(VP9D_COMP *pbi, } } -int vp9_decode_frame(VP9D_COMP *pbi, const uint8_t **p_data_end) { - vp9_reader header_bc, residual_bc; - VP9_COMMON *const pc = &pbi->common; - MACROBLOCKD *const xd = &pbi->mb; - const uint8_t *data = pbi->source; - const uint8_t *data_end = data + pbi->source_sz; - size_t first_partition_size = 0; - YV12_BUFFER_CONFIG *new_fb = &pc->yv12_fb[pc->new_fb_idx]; - int i; - xd->corrupted = 0; // start with no corruption of current frame - new_fb->corrupted = 0; +static void error_handler(void *data, int bit_offset) { + VP9_COMMON *const cm = (VP9_COMMON *)data; + vpx_internal_error(&cm->error, VPX_CODEC_CORRUPT_FRAME, "Truncated packet"); +} + +size_t read_uncompressed_header(VP9D_COMP *pbi, + struct vp9_read_bit_buffer *rb) { + VP9_COMMON *const cm = &pbi->common; + + int scaling_active; + cm->last_frame_type = cm->frame_type; + cm->frame_type = (FRAME_TYPE) vp9_rb_read_bit(rb); + cm->version = vp9_rb_read_literal(rb, 3); + cm->show_frame = vp9_rb_read_bit(rb); + scaling_active = vp9_rb_read_bit(rb); + cm->subsampling_x = vp9_rb_read_bit(rb); + cm->subsampling_y = vp9_rb_read_bit(rb); + + if (cm->frame_type == KEY_FRAME) { + if (vp9_rb_read_literal(rb, 8) != SYNC_CODE_0 || + vp9_rb_read_literal(rb, 8) != SYNC_CODE_1 || + vp9_rb_read_literal(rb, 8) != SYNC_CODE_2) { + vpx_internal_error(&cm->error, VPX_CODEC_UNSUP_BITSTREAM, + "Invalid frame sync code"); + } + } + setup_frame_size(pbi, scaling_active, rb); - if (data_end - data < 3) { - vpx_internal_error(&pc->error, VPX_CODEC_CORRUPT_FRAME, "Truncated packet"); + cm->frame_context_idx = vp9_rb_read_literal(rb, NUM_FRAME_CONTEXTS_LG2); + cm->clr_type = (YUV_TYPE)vp9_rb_read_bit(rb); + + cm->error_resilient_mode = vp9_rb_read_bit(rb); + if (!cm->error_resilient_mode) { + cm->refresh_frame_context = vp9_rb_read_bit(rb); + cm->frame_parallel_decoding_mode = vp9_rb_read_bit(rb); } else { - int scaling_active; - 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; - scaling_active = (data[0] >> 5) & 1; - pc->subsampling_x = (data[0] >> 6) & 1; - pc->subsampling_y = (data[0] >> 7) & 1; - first_partition_size = read_le16(data + 1); - - if (!read_is_valid(data, first_partition_size, data_end)) - vpx_internal_error(&pc->error, VPX_CODEC_CORRUPT_FRAME, - "Truncated packet or corrupt partition 0 length"); + cm->refresh_frame_context = 0; + cm->frame_parallel_decoding_mode = 1; + } - data += 3; + return vp9_rb_read_literal(rb, 16); +} - vp9_setup_version(pc); +int vp9_decode_frame(VP9D_COMP *pbi, const uint8_t **p_data_end) { + int i; + vp9_reader header_bc, residual_bc; + VP9_COMMON *const pc = &pbi->common; + MACROBLOCKD *const xd = &pbi->mb; + YV12_BUFFER_CONFIG *new_fb = &pc->yv12_fb[pc->new_fb_idx]; + const uint8_t *data = pbi->source; + const uint8_t *data_end = pbi->source + pbi->source_sz; - if (pc->frame_type == KEY_FRAME) { - // When error concealment is enabled we should only check the sync - // code if we have enough bits available - if (data + 3 < data_end) { - if (data[0] != 0x49 || data[1] != 0x83 || data[2] != 0x42) - vpx_internal_error(&pc->error, VPX_CODEC_UNSUP_BITSTREAM, - "Invalid frame sync code"); - } - data += 3; - } + struct vp9_read_bit_buffer rb = { data, data_end, 0, + pc, error_handler }; + const size_t first_partition_size = read_uncompressed_header(pbi, &rb); + const int keyframe = pc->frame_type == KEY_FRAME; - data = setup_frame_size(pbi, scaling_active, data, data_end); - } + data += vp9_rb_bytes_read(&rb); + xd->corrupted = 0; + new_fb->corrupted = 0; - if ((!pbi->decoded_key_frame && pc->frame_type != KEY_FRAME) || + if ((!pbi->decoded_key_frame && !keyframe) || pc->width == 0 || pc->height == 0) { return -1; } + vp9_setup_version(pc); + if (!read_is_valid(data, first_partition_size, data_end)) + vpx_internal_error(&pc->error, VPX_CODEC_CORRUPT_FRAME, + "Truncated packet or corrupt partition 0 length"); + init_frame(pbi); // Reset the frame pointers to the current frame size @@ -1001,9 +1011,6 @@ int vp9_decode_frame(VP9D_COMP *pbi, const uint8_t **p_data_end) { vpx_internal_error(&pc->error, VPX_CODEC_MEM_ERROR, "Failed to allocate bool decoder 0"); - pc->clr_type = (YUV_TYPE)vp9_read_bit(&header_bc); - pc->error_resilient_mode = vp9_read_bit(&header_bc); - setup_loopfilter(pc, xd, &header_bc); setup_quantization(pbi, &header_bc); @@ -1025,7 +1032,7 @@ int vp9_decode_frame(VP9D_COMP *pbi, const uint8_t **p_data_end) { // 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. - if (pc->frame_type == KEY_FRAME) { + if (keyframe) { for (i = 0; i < ALLOWED_REFS_PER_FRAME; ++i) pc->active_ref_idx[i] = pc->new_fb_idx; } else { @@ -1050,15 +1057,6 @@ int vp9_decode_frame(VP9D_COMP *pbi, const uint8_t **p_data_end) { vp9_setup_interp_filters(xd, pc->mcomp_filter_type, pc); } - if (!pc->error_resilient_mode) { - pc->refresh_frame_context = vp9_read_bit(&header_bc); - pc->frame_parallel_decoding_mode = vp9_read_bit(&header_bc); - } else { - pc->refresh_frame_context = 0; - pc->frame_parallel_decoding_mode = 1; - } - - pc->frame_context_idx = vp9_read_literal(&header_bc, NUM_FRAME_CONTEXTS_LG2); pc->fc = pc->frame_contexts[pc->frame_context_idx]; setup_segmentation(pc, xd, &header_bc); @@ -1068,7 +1066,7 @@ int vp9_decode_frame(VP9D_COMP *pbi, const uint8_t **p_data_end) { setup_txfm_mode(pc, xd->lossless, &header_bc); // Read inter mode probability context updates - if (pc->frame_type != KEY_FRAME) { + if (!keyframe) { int i, j; for (i = 0; i < INTER_MODE_CONTEXTS; ++i) for (j = 0; j < 4; ++j) @@ -1076,7 +1074,7 @@ int vp9_decode_frame(VP9D_COMP *pbi, const uint8_t **p_data_end) { pc->fc.vp9_mode_contexts[i][j] = vp9_read_prob(&header_bc); } // Is this needed ? - if (pc->frame_type == KEY_FRAME) + if (keyframe) vp9_default_coef_probs(pc); update_frame_context(&pc->fc); @@ -1109,7 +1107,7 @@ int vp9_decode_frame(VP9D_COMP *pbi, const uint8_t **p_data_end) { new_fb->corrupted = vp9_reader_has_error(&header_bc) | xd->corrupted; if (!pbi->decoded_key_frame) { - if (pc->frame_type == KEY_FRAME && !new_fb->corrupted) + if (keyframe && !new_fb->corrupted) pbi->decoded_key_frame = 1; else vpx_internal_error(&pc->error, VPX_CODEC_CORRUPT_FRAME, @@ -1120,7 +1118,7 @@ int vp9_decode_frame(VP9D_COMP *pbi, const uint8_t **p_data_end) { if (!pc->error_resilient_mode && !pc->frame_parallel_decoding_mode) { vp9_adapt_coef_probs(pc); - if (pc->frame_type != KEY_FRAME) { + if (!keyframe) { vp9_adapt_mode_probs(pc); vp9_adapt_mode_context(pc); vp9_adapt_nmv_probs(pc, xd->allow_high_precision_mv); diff --git a/vp9/decoder/vp9_detokenize.c b/vp9/decoder/vp9_detokenize.c index 02900c08c..890d5d0d6 100644 --- a/vp9/decoder/vp9_detokenize.c +++ b/vp9/decoder/vp9_detokenize.c @@ -58,13 +58,15 @@ static const vp9_prob cat6_prob[15] = { 254, 254, 254, 252, 249, 243, 230, 196, 177, 153, 140, 133, 130, 129, 0 }; +DECLARE_ALIGNED(16, extern const uint8_t, + vp9_pt_energy_class[MAX_ENTROPY_TOKENS]); #define INCREMENT_COUNT(token) \ do { \ coef_counts[type][ref][band][pt] \ [token >= TWO_TOKEN ? \ (token == DCT_EOB_TOKEN ? DCT_EOB_MODEL_TOKEN : TWO_TOKEN) : \ token]++; \ - token_cache[scan[c]] = token; \ + token_cache[scan[c]] = vp9_pt_energy_class[token]; \ } while (0) #define WRITE_COEF_CONTINUE(val, token) \ diff --git a/vp9/decoder/vp9_read_bit_buffer.h b/vp9/decoder/vp9_read_bit_buffer.h new file mode 100644 index 000000000..fa2dbee8d --- /dev/null +++ b/vp9/decoder/vp9_read_bit_buffer.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2013 The WebM project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef VP9_READ_BIT_BUFFER_ +#define VP9_READ_BIT_BUFFER_ + +typedef void (*vp9_rb_error_handler)(void *data, int bit_offset); + +struct vp9_read_bit_buffer { + const uint8_t *bit_buffer; + const uint8_t *bit_buffer_end; + size_t bit_offset; + + void *error_handler_data; + vp9_rb_error_handler error_handler; +}; + +static size_t vp9_rb_bytes_read(struct vp9_read_bit_buffer *rb) { + return rb->bit_offset / CHAR_BIT + (rb->bit_offset % CHAR_BIT > 0); +} + +static int vp9_rb_read_bit(struct vp9_read_bit_buffer *rb) { + const int off = rb->bit_offset; + const int p = off / CHAR_BIT; + const int q = CHAR_BIT - 1 - off % CHAR_BIT; + if (rb->bit_buffer + p >= rb->bit_buffer_end) { + rb->error_handler(rb->error_handler_data, rb->bit_offset); + return 0; + } else { + const int bit = (rb->bit_buffer[p] & (1 << q)) >> q; + rb->bit_offset = off + 1; + return bit; + } +} + +static int vp9_rb_read_literal(struct vp9_read_bit_buffer *rb, int bits) { + int value = 0, bit; + for (bit = bits - 1; bit >= 0; bit--) + value |= vp9_rb_read_bit(rb) << bit; + return value; +} + +#endif // VP9_READ_BIT_BUFFER_ |