• Ronald S. Bultje's avatar
    Make RD superblock mode search size-agnostic. · b4f6098e
    Ronald S. Bultje authored
    Merge various super_block_yrd and super_block_uvrd versions into one
    common function that works for all sizes. Make transform size selection
    size-agnostic also. This fixes a slight bug in the intra UV superblock
    code where it used the wrong transform size for txsz > 8x8, and stores
    the txsz selection for superblocks properly (instead of forgetting it).
    Lastly, it removes the trellis search that was done for 16x16 intra
    predictors, since trellis is relatively expensive and should thus only
    be done after RD mode selection.
    
    Gives basically identical results on derf (+0.009%).
    
    Change-Id: If4485c6f0a0fe4038b3172f7a238477c35a6f8d3
    b4f6098e
vp9_decodframe.c 45.21 KiB
/*
 *  Copyright (c) 2010 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.
 */
#include <assert.h>
#include "./vp9_rtcd.h"
#include "vpx_mem/vpx_mem.h"
#include "vpx_scale/vpx_scale.h"
#include "vp9/common/vp9_alloccommon.h"
#include "vp9/common/vp9_common.h"
#include "vp9/common/vp9_entropy.h"
#include "vp9/common/vp9_entropymode.h"
#include "vp9/common/vp9_extend.h"
#include "vp9/common/vp9_idct.h"
#include "vp9/common/vp9_pred_common.h"
#include "vp9/common/vp9_quant_common.h"
#include "vp9/common/vp9_reconintra.h"
#include "vp9/common/vp9_reconinter.h"
#include "vp9/common/vp9_seg_common.h"
#include "vp9/common/vp9_tile_common.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_dsubexp.h"
#include "vp9/decoder/vp9_onyxd_int.h"
#include "vp9/decoder/vp9_read_bit_buffer.h"
#include "vp9/decoder/vp9_thread.h"
#include "vp9/decoder/vp9_treereader.h"
typedef struct TileWorkerData {
  VP9_COMMON *cm;
  vp9_reader bit_reader;
  DECLARE_ALIGNED(16, MACROBLOCKD, xd);
} TileWorkerData;
static int read_be32(const uint8_t *p) {
  return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
static int is_compound_prediction_allowed(const VP9_COMMON *cm) {
  int i;
  for (i = 1; i < ALLOWED_REFS_PER_FRAME; ++i)
    if  (cm->ref_frame_sign_bias[i + 1] != cm->ref_frame_sign_bias[1])
      return 1;
  return 0;
static void setup_compound_prediction(VP9_COMMON *cm) {
  if (cm->ref_frame_sign_bias[LAST_FRAME] ==
          cm->ref_frame_sign_bias[GOLDEN_FRAME]) {
    cm->comp_fixed_ref = ALTREF_FRAME;
    cm->comp_var_ref[0] = LAST_FRAME;
    cm->comp_var_ref[1] = GOLDEN_FRAME;
  } else if (cm->ref_frame_sign_bias[LAST_FRAME] ==
                 cm->ref_frame_sign_bias[ALTREF_FRAME]) {
    cm->comp_fixed_ref = GOLDEN_FRAME;
    cm->comp_var_ref[0] = LAST_FRAME;
    cm->comp_var_ref[1] = ALTREF_FRAME;
  } else {
7172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
cm->comp_fixed_ref = LAST_FRAME; cm->comp_var_ref[0] = GOLDEN_FRAME; cm->comp_var_ref[1] = ALTREF_FRAME; } } // len == 0 is not allowed static int read_is_valid(const uint8_t *start, size_t len, const uint8_t *end) { return start + len > start && start + len <= end; } static int decode_unsigned_max(struct vp9_read_bit_buffer *rb, int max) { const int data = vp9_rb_read_literal(rb, get_unsigned_bits(max)); return data > max ? max : data; } static TX_MODE read_tx_mode(vp9_reader *r) { TX_MODE tx_mode = vp9_read_literal(r, 2); if (tx_mode == ALLOW_32X32) tx_mode += vp9_read_bit(r); return tx_mode; } static void read_tx_probs(struct tx_probs *tx_probs, vp9_reader *r) { int i, j; for (i = 0; i < TX_SIZE_CONTEXTS; ++i) for (j = 0; j < TX_SIZES - 3; ++j) vp9_diff_update_prob(r, &tx_probs->p8x8[i][j]); for (i = 0; i < TX_SIZE_CONTEXTS; ++i) for (j = 0; j < TX_SIZES - 2; ++j) vp9_diff_update_prob(r, &tx_probs->p16x16[i][j]); for (i = 0; i < TX_SIZE_CONTEXTS; ++i) for (j = 0; j < TX_SIZES - 1; ++j) vp9_diff_update_prob(r, &tx_probs->p32x32[i][j]); } static void read_switchable_interp_probs(FRAME_CONTEXT *fc, vp9_reader *r) { int i, j; for (j = 0; j < SWITCHABLE_FILTERS + 1; ++j) for (i = 0; i < SWITCHABLE_FILTERS - 1; ++i) vp9_diff_update_prob(r, &fc->switchable_interp_prob[j][i]); } static void read_inter_mode_probs(FRAME_CONTEXT *fc, vp9_reader *r) { int i, j; for (i = 0; i < INTER_MODE_CONTEXTS; ++i) for (j = 0; j < INTER_MODES - 1; ++j) vp9_diff_update_prob(r, &fc->inter_mode_probs[i][j]); } static INLINE COMPPREDMODE_TYPE read_comp_pred_mode(vp9_reader *r) { COMPPREDMODE_TYPE mode = vp9_read_bit(r); if (mode) mode += vp9_read_bit(r); return mode; } static void read_comp_pred(VP9_COMMON *cm, vp9_reader *r) { int i; const int compound_allowed = is_compound_prediction_allowed(cm); cm->comp_pred_mode = compound_allowed ? read_comp_pred_mode(r) : SINGLE_PREDICTION_ONLY; if (compound_allowed) setup_compound_prediction(cm); if (cm->comp_pred_mode == HYBRID_PREDICTION)
141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
for (i = 0; i < COMP_INTER_CONTEXTS; i++) vp9_diff_update_prob(r, &cm->fc.comp_inter_prob[i]); if (cm->comp_pred_mode != COMP_PREDICTION_ONLY) for (i = 0; i < REF_CONTEXTS; i++) { vp9_diff_update_prob(r, &cm->fc.single_ref_prob[i][0]); vp9_diff_update_prob(r, &cm->fc.single_ref_prob[i][1]); } if (cm->comp_pred_mode != SINGLE_PREDICTION_ONLY) for (i = 0; i < REF_CONTEXTS; i++) vp9_diff_update_prob(r, &cm->fc.comp_ref_prob[i]); } static void update_mv(vp9_reader *r, vp9_prob *p) { if (vp9_read(r, NMV_UPDATE_PROB)) *p = (vp9_read_literal(r, 7) << 1) | 1; } static void read_mv_probs(vp9_reader *r, nmv_context *mvc, int allow_hp) { int i, j, k; for (j = 0; j < MV_JOINTS - 1; ++j) update_mv(r, &mvc->joints[j]); for (i = 0; i < 2; ++i) { nmv_component *const comp = &mvc->comps[i]; update_mv(r, &comp->sign); for (j = 0; j < MV_CLASSES - 1; ++j) update_mv(r, &comp->classes[j]); for (j = 0; j < CLASS0_SIZE - 1; ++j) update_mv(r, &comp->class0[j]); for (j = 0; j < MV_OFFSET_BITS; ++j) update_mv(r, &comp->bits[j]); } for (i = 0; i < 2; ++i) { nmv_component *const comp = &mvc->comps[i]; for (j = 0; j < CLASS0_SIZE; ++j) for (k = 0; k < 3; ++k) update_mv(r, &comp->class0_fp[j][k]); for (j = 0; j < 3; ++j) update_mv(r, &comp->fp[j]); } if (allow_hp) { for (i = 0; i < 2; ++i) { update_mv(r, &mvc->comps[i].class0_hp); update_mv(r, &mvc->comps[i].hp); } } } static void setup_plane_dequants(VP9_COMMON *cm, MACROBLOCKD *xd, int q_index) { int i; xd->plane[0].dequant = cm->y_dequant[q_index]; for (i = 1; i < MAX_MB_PLANE; i++) xd->plane[i].dequant = cm->uv_dequant[q_index]; } // Allocate storage for each tile column. // TODO(jzern): when max_threads <= 1 the same storage could be used for each // tile.
211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
static void alloc_tile_storage(VP9D_COMP *pbi, int tile_cols) { VP9_COMMON *const cm = &pbi->common; const int aligned_mi_cols = mi_cols_aligned_to_sb(cm->mi_cols); int i, tile_col; CHECK_MEM_ERROR(cm, pbi->mi_streams, vpx_realloc(pbi->mi_streams, tile_cols * sizeof(*pbi->mi_streams))); for (tile_col = 0; tile_col < tile_cols; ++tile_col) { TileInfo tile; vp9_tile_init(&tile, cm, 0, tile_col); pbi->mi_streams[tile_col] = &cm->mi[cm->mi_rows * tile.mi_col_start]; } // 2 contexts per 'mi unit', so that we have one context per 4x4 txfm // block where mi unit size is 8x8. CHECK_MEM_ERROR(cm, pbi->above_context[0], vpx_realloc(pbi->above_context[0], sizeof(*pbi->above_context[0]) * MAX_MB_PLANE * 2 * aligned_mi_cols)); for (i = 1; i < MAX_MB_PLANE; ++i) { pbi->above_context[i] = pbi->above_context[0] + i * sizeof(*pbi->above_context[0]) * 2 * aligned_mi_cols; } // This is sized based on the entire frame. Each tile operates within its // column bounds. CHECK_MEM_ERROR(cm, pbi->above_seg_context, vpx_realloc(pbi->above_seg_context, sizeof(*pbi->above_seg_context) * aligned_mi_cols)); } static void decode_block(int plane, int block, BLOCK_SIZE plane_bsize, TX_SIZE tx_size, void *arg) { MACROBLOCKD* const xd = arg; struct macroblockd_plane *const pd = &xd->plane[plane]; int16_t* const qcoeff = BLOCK_OFFSET(pd->qcoeff, block); const int stride = pd->dst.stride; const int eob = pd->eobs[block]; if (eob > 0) { TX_TYPE tx_type; const int raster_block = txfrm_block_to_raster_block(plane_bsize, tx_size, block); uint8_t* const dst = raster_block_offset_uint8(plane_bsize, raster_block, pd->dst.buf, stride); switch (tx_size) { case TX_4X4: tx_type = get_tx_type_4x4(pd->plane_type, xd, raster_block); if (tx_type == DCT_DCT) xd->itxm_add(qcoeff, dst, stride, eob); else vp9_iht4x4_add(tx_type, qcoeff, dst, stride, eob); break; case TX_8X8: tx_type = get_tx_type_8x8(pd->plane_type, xd); vp9_iht8x8_add(tx_type, qcoeff, dst, stride, eob); break; case TX_16X16: tx_type = get_tx_type_16x16(pd->plane_type, xd); vp9_iht16x16_add(tx_type, qcoeff, dst, stride, eob); break; case TX_32X32: tx_type = DCT_DCT; vp9_idct32x32_add(qcoeff, dst, stride, eob); break; default:
281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
assert(!"Invalid transform size"); } if (eob == 1) { vpx_memset(qcoeff, 0, 2 * sizeof(qcoeff[0])); } else { if (tx_type == DCT_DCT && tx_size <= TX_16X16 && eob <= 10) vpx_memset(qcoeff, 0, 4 * (4 << tx_size) * sizeof(qcoeff[0])); else vpx_memset(qcoeff, 0, (16 << (tx_size << 1)) * sizeof(qcoeff[0])); } } } static void decode_block_intra(int plane, int block, BLOCK_SIZE plane_bsize, TX_SIZE tx_size, void *arg) { MACROBLOCKD* const xd = arg; struct macroblockd_plane *const pd = &xd->plane[plane]; MODE_INFO *const mi = xd->mi_8x8[0]; const int raster_block = txfrm_block_to_raster_block(plane_bsize, tx_size, block); uint8_t* const dst = raster_block_offset_uint8(plane_bsize, raster_block, pd->dst.buf, pd->dst.stride); const MB_PREDICTION_MODE mode = (plane == 0) ? ((mi->mbmi.sb_type < BLOCK_8X8) ? mi->bmi[raster_block].as_mode : mi->mbmi.mode) : mi->mbmi.uv_mode; if (xd->mb_to_right_edge < 0 || xd->mb_to_bottom_edge < 0) extend_for_intra(xd, plane_bsize, plane, block, tx_size); vp9_predict_intra_block(xd, raster_block >> tx_size, b_width_log2(plane_bsize), tx_size, mode, dst, pd->dst.stride, dst, pd->dst.stride); if (!mi->mbmi.skip_coeff) decode_block(plane, block, plane_bsize, tx_size, arg); } static int decode_tokens(VP9_COMMON *const cm, MACROBLOCKD *const xd, BLOCK_SIZE bsize, vp9_reader *r) { MB_MODE_INFO *const mbmi = &xd->mi_8x8[0]->mbmi; if (mbmi->skip_coeff) { reset_skip_context(xd, bsize); return -1; } else { if (cm->seg.enabled) setup_plane_dequants(cm, xd, vp9_get_qindex(&cm->seg, mbmi->segment_id, cm->base_qindex)); // TODO(dkovalev) if (!vp9_reader_has_error(r)) return vp9_decode_tokens(cm, xd, &cm->seg, r, bsize); } } static void set_offsets(VP9_COMMON *const cm, MACROBLOCKD *const xd, const TileInfo *const tile, BLOCK_SIZE bsize, int mi_row, int mi_col) { const int bh = num_8x8_blocks_high_lookup[bsize]; const int bw = num_8x8_blocks_wide_lookup[bsize]; const int offset = mi_row * cm->mode_info_stride + mi_col; xd->mode_info_stride = cm->mode_info_stride; xd->mi_8x8 = cm->mi_grid_visible + offset; xd->prev_mi_8x8 = cm->prev_mi_grid_visible + offset; // we are using the mode info context stream here xd->mi_8x8[0] = xd->mi_stream;
351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420
xd->mi_8x8[0]->mbmi.sb_type = bsize; ++xd->mi_stream; // Special case: if prev_mi is NULL, the previous mode info context // cannot be used. xd->last_mi = cm->prev_mi ? xd->prev_mi_8x8[0] : NULL; set_skip_context(xd, xd->above_context, xd->left_context, mi_row, mi_col); // Distance of Mb to the various image edges. These are specified to 8th pel // as they are always compared to values that are in 1/8th pel units set_mi_row_col(xd, tile, mi_row, bh, mi_col, bw, cm->mi_rows, cm->mi_cols); setup_dst_planes(xd, get_frame_new_buffer(cm), mi_row, mi_col); } static void set_ref(VP9_COMMON *const cm, MACROBLOCKD *const xd, int idx, int mi_row, int mi_col) { MB_MODE_INFO *const mbmi = &xd->mi_8x8[0]->mbmi; const int ref = mbmi->ref_frame[idx] - LAST_FRAME; const YV12_BUFFER_CONFIG *cfg = get_frame_ref_buffer(cm, ref); const struct scale_factors_common *sfc = &cm->active_ref_scale_comm[ref]; if (!vp9_is_valid_scale(sfc)) vpx_internal_error(&cm->error, VPX_CODEC_UNSUP_BITSTREAM, "Invalid scale factors"); xd->scale_factor[idx].sfc = sfc; setup_pre_planes(xd, idx, cfg, mi_row, mi_col, &xd->scale_factor[idx]); xd->corrupted |= cfg->corrupted; } static void decode_modes_b(VP9_COMMON *const cm, MACROBLOCKD *const xd, const TileInfo *const tile, int mi_row, int mi_col, vp9_reader *r, BLOCK_SIZE bsize, int index) { const int less8x8 = bsize < BLOCK_8X8; MB_MODE_INFO *mbmi; int eobtotal; if (less8x8) if (index > 0) return; set_offsets(cm, xd, tile, bsize, mi_row, mi_col); vp9_read_mode_info(cm, xd, tile, mi_row, mi_col, r); if (less8x8) bsize = BLOCK_8X8; // Has to be called after set_offsets mbmi = &xd->mi_8x8[0]->mbmi; eobtotal = decode_tokens(cm, xd, bsize, r); if (!is_inter_block(mbmi)) { // Intra reconstruction foreach_transformed_block(xd, bsize, decode_block_intra, xd); } else { // Inter reconstruction const int decode_blocks = (eobtotal > 0); if (!less8x8) { assert(mbmi->sb_type == bsize); if (eobtotal == 0) mbmi->skip_coeff = 1; // skip loopfilter } set_ref(cm, xd, 0, mi_row, mi_col); if (has_second_ref(mbmi)) set_ref(cm, xd, 1, mi_row, mi_col);
421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490
xd->subpix.filter_x = xd->subpix.filter_y = vp9_get_filter_kernel(mbmi->interp_filter); vp9_build_inter_predictors_sb(xd, mi_row, mi_col, bsize); if (decode_blocks) foreach_transformed_block(xd, bsize, decode_block, xd); } xd->corrupted |= vp9_reader_has_error(r); } static PARTITION_TYPE read_partition(int hbs, int mi_rows, int mi_cols, int mi_row, int mi_col, vp9_prob probs[PARTITION_TYPES - 1], vp9_reader *r) { const int has_rows = (mi_row + hbs) < mi_rows; const int has_cols = (mi_col + hbs) < mi_cols; if (has_rows && has_cols) return treed_read(r, vp9_partition_tree, probs); else if (!has_rows && has_cols) return vp9_read(r, probs[1]) ? PARTITION_SPLIT : PARTITION_HORZ; else if (has_rows && !has_cols) return vp9_read(r, probs[2]) ? PARTITION_SPLIT : PARTITION_VERT; else return PARTITION_SPLIT; } static void decode_modes_sb(VP9_COMMON *const cm, MACROBLOCKD *const xd, const TileInfo *const tile, int mi_row, int mi_col, vp9_reader* r, BLOCK_SIZE bsize, int index) { const int hbs = num_8x8_blocks_wide_lookup[bsize] / 2; PARTITION_TYPE partition = PARTITION_NONE; BLOCK_SIZE subsize; if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return; if (bsize < BLOCK_8X8) { if (index > 0) return; } else { const int ctx = partition_plane_context(xd->above_seg_context, xd->left_seg_context, mi_row, mi_col, bsize); partition = read_partition(hbs, cm->mi_rows, cm->mi_cols, mi_row, mi_col, cm->fc.partition_prob[cm->frame_type][ctx], r); if (!cm->frame_parallel_decoding_mode) ++cm->counts.partition[ctx][partition]; } subsize = get_subsize(bsize, partition); switch (partition) { case PARTITION_NONE: decode_modes_b(cm, xd, tile, mi_row, mi_col, r, subsize, 0); break; case PARTITION_HORZ: decode_modes_b(cm, xd, tile, mi_row, mi_col, r, subsize, 0); if (mi_row + hbs < cm->mi_rows) decode_modes_b(cm, xd, tile, mi_row + hbs, mi_col, r, subsize, 1); break; case PARTITION_VERT: decode_modes_b(cm, xd, tile, mi_row, mi_col, r, subsize, 0); if (mi_col + hbs < cm->mi_cols) decode_modes_b(cm, xd, tile, mi_row, mi_col + hbs, r, subsize, 1); break; case PARTITION_SPLIT: { int n;
491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560
for (n = 0; n < 4; n++) { const int j = n >> 1, i = n & 1; decode_modes_sb(cm, xd, tile, mi_row + j * hbs, mi_col + i * hbs, r, subsize, n); } } break; default: assert(!"Invalid partition type"); } // update partition context if (bsize >= BLOCK_8X8 && (bsize == BLOCK_8X8 || partition != PARTITION_SPLIT)) update_partition_context(xd->above_seg_context, xd->left_seg_context, mi_row, mi_col, subsize, bsize); } static void setup_token_decoder(const uint8_t *data, const uint8_t *data_end, size_t read_size, struct vpx_internal_error_info *error_info, vp9_reader *r) { // Validate the calculated partition length. If the buffer // described by the partition can't be fully read, then restrict // it to the portion that can be (for EC mode) or throw an error. if (!read_is_valid(data, read_size, data_end)) vpx_internal_error(error_info, VPX_CODEC_CORRUPT_FRAME, "Truncated packet or corrupt tile length"); if (vp9_reader_init(r, data, read_size)) vpx_internal_error(error_info, VPX_CODEC_MEM_ERROR, "Failed to allocate bool decoder %d", 1); } static void read_coef_probs_common(vp9_coeff_probs_model *coef_probs, vp9_reader *r) { int i, j, k, l, m; if (vp9_read_bit(r)) for (i = 0; i < BLOCK_TYPES; i++) for (j = 0; j < REF_TYPES; j++) for (k = 0; k < COEF_BANDS; k++) for (l = 0; l < PREV_COEF_CONTEXTS; l++) if (k > 0 || l < 3) for (m = 0; m < UNCONSTRAINED_NODES; m++) vp9_diff_update_prob(r, &coef_probs[i][j][k][l][m]); } static void read_coef_probs(FRAME_CONTEXT *fc, TX_MODE tx_mode, vp9_reader *r) { read_coef_probs_common(fc->coef_probs[TX_4X4], r); if (tx_mode > ONLY_4X4) read_coef_probs_common(fc->coef_probs[TX_8X8], r); if (tx_mode > ALLOW_8X8) read_coef_probs_common(fc->coef_probs[TX_16X16], r); if (tx_mode > ALLOW_16X16) read_coef_probs_common(fc->coef_probs[TX_32X32], r); } static void setup_segmentation(struct segmentation *seg, struct vp9_read_bit_buffer *rb) { int i, j; seg->update_map = 0; seg->update_data = 0; seg->enabled = vp9_rb_read_bit(rb);
561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630
if (!seg->enabled) return; // Segmentation map update seg->update_map = vp9_rb_read_bit(rb); if (seg->update_map) { for (i = 0; i < SEG_TREE_PROBS; i++) seg->tree_probs[i] = vp9_rb_read_bit(rb) ? vp9_rb_read_literal(rb, 8) : MAX_PROB; seg->temporal_update = vp9_rb_read_bit(rb); if (seg->temporal_update) { for (i = 0; i < PREDICTION_PROBS; i++) seg->pred_probs[i] = vp9_rb_read_bit(rb) ? vp9_rb_read_literal(rb, 8) : MAX_PROB; } else { for (i = 0; i < PREDICTION_PROBS; i++) seg->pred_probs[i] = MAX_PROB; } } // Segmentation data update seg->update_data = vp9_rb_read_bit(rb); if (seg->update_data) { seg->abs_delta = vp9_rb_read_bit(rb); vp9_clearall_segfeatures(seg); for (i = 0; i < MAX_SEGMENTS; i++) { for (j = 0; j < SEG_LVL_MAX; j++) { int data = 0; const int feature_enabled = vp9_rb_read_bit(rb); if (feature_enabled) { vp9_enable_segfeature(seg, i, j); data = decode_unsigned_max(rb, vp9_seg_feature_data_max(j)); if (vp9_is_segfeature_signed(j)) data = vp9_rb_read_bit(rb) ? -data : data; } vp9_set_segdata(seg, i, j, data); } } } } static void setup_loopfilter(struct loopfilter *lf, struct vp9_read_bit_buffer *rb) { lf->filter_level = vp9_rb_read_literal(rb, 6); lf->sharpness_level = vp9_rb_read_literal(rb, 3); // Read in loop filter deltas applied at the MB level based on mode or ref // frame. lf->mode_ref_delta_update = 0; lf->mode_ref_delta_enabled = vp9_rb_read_bit(rb); if (lf->mode_ref_delta_enabled) { lf->mode_ref_delta_update = vp9_rb_read_bit(rb); if (lf->mode_ref_delta_update) { int i; for (i = 0; i < MAX_REF_LF_DELTAS; i++) if (vp9_rb_read_bit(rb)) lf->ref_deltas[i] = vp9_rb_read_signed_literal(rb, 6); for (i = 0; i < MAX_MODE_LF_DELTAS; i++) if (vp9_rb_read_bit(rb)) lf->mode_deltas[i] = vp9_rb_read_signed_literal(rb, 6); } } }
631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700
static int read_delta_q(struct vp9_read_bit_buffer *rb, int *delta_q) { const int old = *delta_q; *delta_q = vp9_rb_read_bit(rb) ? vp9_rb_read_signed_literal(rb, 4) : 0; return old != *delta_q; } static void setup_quantization(VP9_COMMON *const cm, MACROBLOCKD *const xd, struct vp9_read_bit_buffer *rb) { int update = 0; cm->base_qindex = vp9_rb_read_literal(rb, QINDEX_BITS); update |= read_delta_q(rb, &cm->y_dc_delta_q); update |= read_delta_q(rb, &cm->uv_dc_delta_q); update |= read_delta_q(rb, &cm->uv_ac_delta_q); if (update) vp9_init_dequantizer(cm); xd->lossless = cm->base_qindex == 0 && cm->y_dc_delta_q == 0 && cm->uv_dc_delta_q == 0 && cm->uv_ac_delta_q == 0; xd->itxm_add = xd->lossless ? vp9_iwht4x4_add : vp9_idct4x4_add; } static INTERPOLATION_TYPE read_interp_filter_type( struct vp9_read_bit_buffer *rb) { const INTERPOLATION_TYPE literal_to_type[] = { EIGHTTAP_SMOOTH, EIGHTTAP, EIGHTTAP_SHARP, BILINEAR }; return vp9_rb_read_bit(rb) ? SWITCHABLE : literal_to_type[vp9_rb_read_literal(rb, 2)]; } static void read_frame_size(struct vp9_read_bit_buffer *rb, int *width, int *height) { const int w = vp9_rb_read_literal(rb, 16) + 1; const int h = vp9_rb_read_literal(rb, 16) + 1; *width = w; *height = h; } static void setup_display_size(VP9_COMMON *cm, struct vp9_read_bit_buffer *rb) { cm->display_width = cm->width; cm->display_height = cm->height; if (vp9_rb_read_bit(rb)) read_frame_size(rb, &cm->display_width, &cm->display_height); } static void apply_frame_size(VP9D_COMP *pbi, int width, int height) { VP9_COMMON *cm = &pbi->common; if (cm->width != width || cm->height != height) { if (!pbi->initial_width || !pbi->initial_height) { if (vp9_alloc_frame_buffers(cm, width, height)) vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR, "Failed to allocate frame buffers"); pbi->initial_width = width; pbi->initial_height = height; } else { if (width > pbi->initial_width) vpx_internal_error(&cm->error, VPX_CODEC_CORRUPT_FRAME, "Frame width too large"); if (height > pbi->initial_height) vpx_internal_error(&cm->error, VPX_CODEC_CORRUPT_FRAME, "Frame height too large"); }
701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770
cm->width = width; cm->height = height; vp9_update_frame_size(cm); } vp9_realloc_frame_buffer(get_frame_new_buffer(cm), cm->width, cm->height, cm->subsampling_x, cm->subsampling_y, VP9BORDERINPIXELS); } static void setup_frame_size(VP9D_COMP *pbi, struct vp9_read_bit_buffer *rb) { int width, height; read_frame_size(rb, &width, &height); apply_frame_size(pbi, width, height); setup_display_size(&pbi->common, rb); } static void setup_frame_size_with_refs(VP9D_COMP *pbi, struct vp9_read_bit_buffer *rb) { VP9_COMMON *const cm = &pbi->common; int width, height; int found = 0, i; for (i = 0; i < ALLOWED_REFS_PER_FRAME; ++i) { if (vp9_rb_read_bit(rb)) { YV12_BUFFER_CONFIG *const cfg = get_frame_ref_buffer(cm, i); width = cfg->y_crop_width; height = cfg->y_crop_height; found = 1; break; } } if (!found) read_frame_size(rb, &width, &height); if (!width || !height) vpx_internal_error(&cm->error, VPX_CODEC_CORRUPT_FRAME, "Referenced frame with invalid size"); apply_frame_size(pbi, width, height); setup_display_size(cm, rb); } static void setup_tile_context(VP9D_COMP *const pbi, MACROBLOCKD *const xd, int tile_col) { int i; xd->mi_stream = pbi->mi_streams[tile_col]; for (i = 0; i < MAX_MB_PLANE; ++i) { xd->above_context[i] = pbi->above_context[i]; } // see note in alloc_tile_storage(). xd->above_seg_context = pbi->above_seg_context; } static void decode_tile(VP9D_COMP *pbi, const TileInfo *const tile, vp9_reader *r) { const int num_threads = pbi->oxcf.max_threads; VP9_COMMON *const cm = &pbi->common; int mi_row, mi_col; MACROBLOCKD *xd = &pbi->mb; if (pbi->do_loopfilter_inline) { LFWorkerData *const lf_data = (LFWorkerData*)pbi->lf_worker.data1; lf_data->frame_buffer = get_frame_new_buffer(cm); lf_data->cm = cm; lf_data->xd = pbi->mb;
771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840
lf_data->stop = 0; lf_data->y_only = 0; vp9_loop_filter_frame_init(cm, cm->lf.filter_level); } for (mi_row = tile->mi_row_start; mi_row < tile->mi_row_end; mi_row += MI_BLOCK_SIZE) { // For a SB there are 2 left contexts, each pertaining to a MB row within vp9_zero(xd->left_context); vp9_zero(xd->left_seg_context); for (mi_col = tile->mi_col_start; mi_col < tile->mi_col_end; mi_col += MI_BLOCK_SIZE) decode_modes_sb(cm, xd, tile, mi_row, mi_col, r, BLOCK_64X64, 0); if (pbi->do_loopfilter_inline) { const int lf_start = mi_row - MI_BLOCK_SIZE; LFWorkerData *const lf_data = (LFWorkerData*)pbi->lf_worker.data1; // delay the loopfilter by 1 macroblock row. if (lf_start < 0) continue; // decoding has completed: finish up the loop filter in this thread. if (mi_row + MI_BLOCK_SIZE >= tile->mi_row_end) continue; vp9_worker_sync(&pbi->lf_worker); lf_data->start = lf_start; lf_data->stop = mi_row; if (num_threads > 1) { vp9_worker_launch(&pbi->lf_worker); } else { vp9_worker_execute(&pbi->lf_worker); } } } if (pbi->do_loopfilter_inline) { LFWorkerData *const lf_data = (LFWorkerData*)pbi->lf_worker.data1; vp9_worker_sync(&pbi->lf_worker); lf_data->start = lf_data->stop; lf_data->stop = cm->mi_rows; vp9_worker_execute(&pbi->lf_worker); } } static void setup_tile_info(VP9_COMMON *cm, struct vp9_read_bit_buffer *rb) { int min_log2_tile_cols, max_log2_tile_cols, max_ones; vp9_get_tile_n_bits(cm->mi_cols, &min_log2_tile_cols, &max_log2_tile_cols); // columns max_ones = max_log2_tile_cols - min_log2_tile_cols; cm->log2_tile_cols = min_log2_tile_cols; while (max_ones-- && vp9_rb_read_bit(rb)) cm->log2_tile_cols++; // rows cm->log2_tile_rows = vp9_rb_read_bit(rb); if (cm->log2_tile_rows) cm->log2_tile_rows += vp9_rb_read_bit(rb); } // Reads the next tile returning its size and adjusting '*data' accordingly // based on 'is_last'. static size_t get_tile(const uint8_t *const data_end, int is_last, struct vpx_internal_error_info *error_info, const uint8_t **data) { size_t size; if (!is_last) {
841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910
if (!read_is_valid(*data, 4, data_end)) vpx_internal_error(error_info, VPX_CODEC_CORRUPT_FRAME, "Truncated packet or corrupt tile length"); size = read_be32(*data); *data += 4; } else { size = data_end - *data; } return size; } static const uint8_t *decode_tiles(VP9D_COMP *pbi, const uint8_t *data) { vp9_reader residual_bc; VP9_COMMON *const cm = &pbi->common; MACROBLOCKD *const xd = &pbi->mb; const uint8_t *const data_end = pbi->source + pbi->source_sz; const int aligned_mi_cols = mi_cols_aligned_to_sb(cm->mi_cols); const int tile_cols = 1 << cm->log2_tile_cols; const int tile_rows = 1 << cm->log2_tile_rows; int tile_row, tile_col; // Note: this memset assumes above_context[0], [1] and [2] // are allocated as part of the same buffer. vpx_memset(pbi->above_context[0], 0, sizeof(*pbi->above_context[0]) * MAX_MB_PLANE * 2 * aligned_mi_cols); vpx_memset(pbi->above_seg_context, 0, sizeof(*pbi->above_seg_context) * aligned_mi_cols); if (pbi->oxcf.inv_tile_order) { const uint8_t *data_ptr2[4][1 << 6]; vp9_reader bc_bak = {0}; // pre-initialize the offsets, we're going to decode in inverse order data_ptr2[0][0] = data; for (tile_row = 0; tile_row < tile_rows; tile_row++) { for (tile_col = 0; tile_col < tile_cols; tile_col++) { const int last_tile = tile_row == tile_rows - 1 && tile_col == tile_cols - 1; const size_t size = get_tile(data_end, last_tile, &cm->error, &data); data_ptr2[tile_row][tile_col] = data; data += size; } } for (tile_row = 0; tile_row < tile_rows; tile_row++) { for (tile_col = tile_cols - 1; tile_col >= 0; tile_col--) { TileInfo tile; vp9_tile_init(&tile, cm, tile_row, tile_col); setup_token_decoder(data_ptr2[tile_row][tile_col], data_end, data_end - data_ptr2[tile_row][tile_col], &cm->error, &residual_bc); setup_tile_context(pbi, xd, tile_col); decode_tile(pbi, &tile, &residual_bc); if (tile_row == tile_rows - 1 && tile_col == tile_cols - 1) bc_bak = residual_bc; } } residual_bc = bc_bak; } else { for (tile_row = 0; tile_row < tile_rows; tile_row++) { for (tile_col = 0; tile_col < tile_cols; tile_col++) { const int last_tile = tile_row == tile_rows - 1 && tile_col == tile_cols - 1; const size_t size = get_tile(data_end, last_tile, &cm->error, &data);
911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980
TileInfo tile; vp9_tile_init(&tile, cm, tile_row, tile_col); setup_token_decoder(data, data_end, size, &cm->error, &residual_bc); setup_tile_context(pbi, xd, tile_col); decode_tile(pbi, &tile, &residual_bc); data += size; } } } return vp9_reader_find_end(&residual_bc); } static int tile_worker_hook(void *arg1, void *arg2) { TileWorkerData *const tile_data = (TileWorkerData*)arg1; const TileInfo *const tile = (TileInfo*)arg2; int mi_row, mi_col; for (mi_row = tile->mi_row_start; mi_row < tile->mi_row_end; mi_row += MI_BLOCK_SIZE) { vp9_zero(tile_data->xd.left_context); vp9_zero(tile_data->xd.left_seg_context); for (mi_col = tile->mi_col_start; mi_col < tile->mi_col_end; mi_col += MI_BLOCK_SIZE) decode_modes_sb(tile_data->cm, &tile_data->xd, tile, mi_row, mi_col, &tile_data->bit_reader, BLOCK_64X64, 0); } return !tile_data->xd.corrupted; } static const uint8_t *decode_tiles_mt(VP9D_COMP *pbi, const uint8_t *data) { VP9_COMMON *const cm = &pbi->common; const uint8_t *const data_end = pbi->source + pbi->source_sz; const int aligned_mi_cols = mi_cols_aligned_to_sb(cm->mi_cols); const int tile_cols = 1 << cm->log2_tile_cols; const int tile_rows = 1 << cm->log2_tile_rows; const int num_workers = MIN(pbi->oxcf.max_threads & ~1, tile_cols); int tile_col = 0; assert(tile_rows == 1); (void)tile_rows; if (num_workers > pbi->num_tile_workers) { int i; CHECK_MEM_ERROR(cm, pbi->tile_workers, vpx_realloc(pbi->tile_workers, num_workers * sizeof(*pbi->tile_workers))); for (i = pbi->num_tile_workers; i < num_workers; ++i) { VP9Worker *const worker = &pbi->tile_workers[i]; ++pbi->num_tile_workers; vp9_worker_init(worker); worker->hook = (VP9WorkerHook)tile_worker_hook; CHECK_MEM_ERROR(cm, worker->data1, vpx_memalign(32, sizeof(TileWorkerData))); CHECK_MEM_ERROR(cm, worker->data2, vpx_malloc(sizeof(TileInfo))); if (i < num_workers - 1 && !vp9_worker_reset(worker)) { vpx_internal_error(&cm->error, VPX_CODEC_ERROR, "Tile decoder thread creation failed"); } } } // Note: this memset assumes above_context[0], [1] and [2] // are allocated as part of the same buffer. vpx_memset(pbi->above_context[0], 0, sizeof(*pbi->above_context[0]) * MAX_MB_PLANE * 2 * aligned_mi_cols);
981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050
vpx_memset(pbi->above_seg_context, 0, sizeof(*pbi->above_seg_context) * aligned_mi_cols); while (tile_col < tile_cols) { int i; for (i = 0; i < num_workers && tile_col < tile_cols; ++i) { VP9Worker *const worker = &pbi->tile_workers[i]; TileWorkerData *const tile_data = (TileWorkerData*)worker->data1; TileInfo *const tile = (TileInfo*)worker->data2; const size_t size = get_tile(data_end, tile_col == tile_cols - 1, &cm->error, &data); tile_data->cm = cm; tile_data->xd = pbi->mb; tile_data->xd.corrupted = 0; vp9_tile_init(tile, tile_data->cm, 0, tile_col); setup_token_decoder(data, data_end, size, &cm->error, &tile_data->bit_reader); setup_tile_context(pbi, &tile_data->xd, tile_col); worker->had_error = 0; if (i == num_workers - 1 || tile_col == tile_cols - 1) { vp9_worker_execute(worker); } else { vp9_worker_launch(worker); } data += size; ++tile_col; } for (; i > 0; --i) { VP9Worker *const worker = &pbi->tile_workers[i - 1]; pbi->mb.corrupted |= !vp9_worker_sync(worker); } } { const int final_worker = (tile_cols + num_workers - 1) % num_workers; TileWorkerData *const tile_data = (TileWorkerData*)pbi->tile_workers[final_worker].data1; return vp9_reader_find_end(&tile_data->bit_reader); } } static void check_sync_code(VP9_COMMON *cm, struct vp9_read_bit_buffer *rb) { if (vp9_rb_read_literal(rb, 8) != VP9_SYNC_CODE_0 || vp9_rb_read_literal(rb, 8) != VP9_SYNC_CODE_1 || vp9_rb_read_literal(rb, 8) != VP9_SYNC_CODE_2) { vpx_internal_error(&cm->error, VPX_CODEC_UNSUP_BITSTREAM, "Invalid frame sync code"); } } static void error_handler(void *data, size_t bit_offset) { VP9_COMMON *const cm = (VP9_COMMON *)data; vpx_internal_error(&cm->error, VPX_CODEC_CORRUPT_FRAME, "Truncated packet"); } #define RESERVED \ if (vp9_rb_read_bit(rb)) \ vpx_internal_error(&cm->error, VPX_CODEC_UNSUP_BITSTREAM, \ "Reserved bit must be unset") static size_t read_uncompressed_header(VP9D_COMP *pbi, struct vp9_read_bit_buffer *rb) { VP9_COMMON *const cm = &pbi->common; size_t sz; int i;
1051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120
cm->last_frame_type = cm->frame_type; if (vp9_rb_read_literal(rb, 2) != VP9_FRAME_MARKER) vpx_internal_error(&cm->error, VPX_CODEC_UNSUP_BITSTREAM, "Invalid frame marker"); cm->version = vp9_rb_read_bit(rb); RESERVED; if (vp9_rb_read_bit(rb)) { // show an existing frame directly int frame_to_show = cm->ref_frame_map[vp9_rb_read_literal(rb, 3)]; ref_cnt_fb(cm->fb_idx_ref_cnt, &cm->new_fb_idx, frame_to_show); pbi->refresh_frame_flags = 0; cm->lf.filter_level = 0; return 0; } cm->frame_type = (FRAME_TYPE) vp9_rb_read_bit(rb); cm->show_frame = vp9_rb_read_bit(rb); cm->error_resilient_mode = vp9_rb_read_bit(rb); if (cm->frame_type == KEY_FRAME) { check_sync_code(cm, rb); cm->color_space = vp9_rb_read_literal(rb, 3); // colorspace if (cm->color_space != SRGB) { vp9_rb_read_bit(rb); // [16,235] (including xvycc) vs [0,255] range if (cm->version == 1) { cm->subsampling_x = vp9_rb_read_bit(rb); cm->subsampling_y = vp9_rb_read_bit(rb); vp9_rb_read_bit(rb); // has extra plane } else { cm->subsampling_y = cm->subsampling_x = 1; } } else { if (cm->version == 1) { cm->subsampling_y = cm->subsampling_x = 0; vp9_rb_read_bit(rb); // has extra plane } else { vpx_internal_error(&cm->error, VPX_CODEC_UNSUP_BITSTREAM, "RGB not supported in profile 0"); } } pbi->refresh_frame_flags = (1 << NUM_REF_FRAMES) - 1; for (i = 0; i < ALLOWED_REFS_PER_FRAME; ++i) cm->active_ref_idx[i] = cm->new_fb_idx; setup_frame_size(pbi, rb); } else { cm->intra_only = cm->show_frame ? 0 : vp9_rb_read_bit(rb); cm->reset_frame_context = cm->error_resilient_mode ? 0 : vp9_rb_read_literal(rb, 2); if (cm->intra_only) { check_sync_code(cm, rb); pbi->refresh_frame_flags = vp9_rb_read_literal(rb, NUM_REF_FRAMES); setup_frame_size(pbi, rb); } else { pbi->refresh_frame_flags = vp9_rb_read_literal(rb, NUM_REF_FRAMES); for (i = 0; i < ALLOWED_REFS_PER_FRAME; ++i) { const int ref = vp9_rb_read_literal(rb, NUM_REF_FRAMES_LOG2); cm->active_ref_idx[i] = cm->ref_frame_map[ref]; cm->ref_frame_sign_bias[LAST_FRAME + i] = vp9_rb_read_bit(rb);
1121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190
} setup_frame_size_with_refs(pbi, rb); cm->allow_high_precision_mv = vp9_rb_read_bit(rb); cm->mcomp_filter_type = read_interp_filter_type(rb); for (i = 0; i < ALLOWED_REFS_PER_FRAME; ++i) vp9_setup_scale_factors(cm, i); } } 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 { cm->refresh_frame_context = 0; cm->frame_parallel_decoding_mode = 1; } // This flag will be overridden by the call to vp9_setup_past_independence // below, forcing the use of context 0 for those frame types. cm->frame_context_idx = vp9_rb_read_literal(rb, NUM_FRAME_CONTEXTS_LOG2); if (frame_is_intra_only(cm) || cm->error_resilient_mode) vp9_setup_past_independence(cm); setup_loopfilter(&cm->lf, rb); setup_quantization(cm, &pbi->mb, rb); setup_segmentation(&cm->seg, rb); setup_tile_info(cm, rb); sz = vp9_rb_read_literal(rb, 16); if (sz == 0) vpx_internal_error(&cm->error, VPX_CODEC_CORRUPT_FRAME, "Invalid header size"); return sz; } static int read_compressed_header(VP9D_COMP *pbi, const uint8_t *data, size_t partition_size) { VP9_COMMON *const cm = &pbi->common; MACROBLOCKD *const xd = &pbi->mb; FRAME_CONTEXT *const fc = &cm->fc; vp9_reader r; int k; if (vp9_reader_init(&r, data, partition_size)) vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR, "Failed to allocate bool decoder 0"); cm->tx_mode = xd->lossless ? ONLY_4X4 : read_tx_mode(&r); if (cm->tx_mode == TX_MODE_SELECT) read_tx_probs(&fc->tx_probs, &r); read_coef_probs(fc, cm->tx_mode, &r); for (k = 0; k < MBSKIP_CONTEXTS; ++k) vp9_diff_update_prob(&r, &fc->mbskip_probs[k]); if (!frame_is_intra_only(cm)) { nmv_context *const nmvc = &fc->nmvc; int i, j; read_inter_mode_probs(fc, &r); if (cm->mcomp_filter_type == SWITCHABLE) read_switchable_interp_probs(fc, &r);
1191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260
for (i = 0; i < INTRA_INTER_CONTEXTS; i++) vp9_diff_update_prob(&r, &fc->intra_inter_prob[i]); read_comp_pred(cm, &r); for (j = 0; j < BLOCK_SIZE_GROUPS; j++) for (i = 0; i < INTRA_MODES - 1; ++i) vp9_diff_update_prob(&r, &fc->y_mode_prob[j][i]); for (j = 0; j < PARTITION_CONTEXTS; ++j) for (i = 0; i < PARTITION_TYPES - 1; ++i) vp9_diff_update_prob(&r, &fc->partition_prob[INTER_FRAME][j][i]); read_mv_probs(&r, nmvc, cm->allow_high_precision_mv); } return vp9_reader_has_error(&r); } void vp9_init_dequantizer(VP9_COMMON *cm) { int q; for (q = 0; q < QINDEX_RANGE; q++) { cm->y_dequant[q][0] = vp9_dc_quant(q, cm->y_dc_delta_q); cm->y_dequant[q][1] = vp9_ac_quant(q, 0); cm->uv_dequant[q][0] = vp9_dc_quant(q, cm->uv_dc_delta_q); cm->uv_dequant[q][1] = vp9_ac_quant(q, cm->uv_ac_delta_q); } } #ifdef NDEBUG #define debug_check_frame_counts(cm) (void)0 #else // !NDEBUG // Counts should only be incremented when frame_parallel_decoding_mode and // error_resilient_mode are disabled. static void debug_check_frame_counts(const VP9_COMMON *const cm) { FRAME_COUNTS zero_counts; vp9_zero(zero_counts); assert(cm->frame_parallel_decoding_mode || cm->error_resilient_mode); assert(!memcmp(cm->counts.y_mode, zero_counts.y_mode, sizeof(cm->counts.y_mode))); assert(!memcmp(cm->counts.uv_mode, zero_counts.uv_mode, sizeof(cm->counts.uv_mode))); assert(!memcmp(cm->counts.partition, zero_counts.partition, sizeof(cm->counts.partition))); assert(!memcmp(cm->counts.coef, zero_counts.coef, sizeof(cm->counts.coef))); assert(!memcmp(cm->counts.eob_branch, zero_counts.eob_branch, sizeof(cm->counts.eob_branch))); assert(!memcmp(cm->counts.switchable_interp, zero_counts.switchable_interp, sizeof(cm->counts.switchable_interp))); assert(!memcmp(cm->counts.inter_mode, zero_counts.inter_mode, sizeof(cm->counts.inter_mode))); assert(!memcmp(cm->counts.intra_inter, zero_counts.intra_inter, sizeof(cm->counts.intra_inter))); assert(!memcmp(cm->counts.comp_inter, zero_counts.comp_inter, sizeof(cm->counts.comp_inter))); assert(!memcmp(cm->counts.single_ref, zero_counts.single_ref, sizeof(cm->counts.single_ref))); assert(!memcmp(cm->counts.comp_ref, zero_counts.comp_ref, sizeof(cm->counts.comp_ref))); assert(!memcmp(&cm->counts.tx, &zero_counts.tx, sizeof(cm->counts.tx))); assert(!memcmp(cm->counts.mbskip, zero_counts.mbskip, sizeof(cm->counts.mbskip))); assert(!memcmp(&cm->counts.mv, &zero_counts.mv, sizeof(cm->counts.mv))); } #endif // NDEBUG int vp9_decode_frame(VP9D_COMP *pbi, const uint8_t **p_data_end) {
1261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330
int i; VP9_COMMON *const cm = &pbi->common; MACROBLOCKD *const xd = &pbi->mb; const uint8_t *data = pbi->source; const uint8_t *const data_end = pbi->source + pbi->source_sz; struct vp9_read_bit_buffer rb = { data, data_end, 0, cm, error_handler }; const size_t first_partition_size = read_uncompressed_header(pbi, &rb); const int keyframe = cm->frame_type == KEY_FRAME; const int tile_rows = 1 << cm->log2_tile_rows; const int tile_cols = 1 << cm->log2_tile_cols; YV12_BUFFER_CONFIG *const new_fb = get_frame_new_buffer(cm); if (!first_partition_size) { // showing a frame directly *p_data_end = data + 1; return 0; } if (!pbi->decoded_key_frame && !keyframe) return -1; data += vp9_rb_bytes_read(&rb); if (!read_is_valid(data, first_partition_size, data_end)) vpx_internal_error(&cm->error, VPX_CODEC_CORRUPT_FRAME, "Truncated packet or corrupt header length"); pbi->do_loopfilter_inline = (cm->log2_tile_rows | cm->log2_tile_cols) == 0 && cm->lf.filter_level; if (pbi->do_loopfilter_inline && pbi->lf_worker.data1 == NULL) { CHECK_MEM_ERROR(cm, pbi->lf_worker.data1, vpx_malloc(sizeof(LFWorkerData))); pbi->lf_worker.hook = (VP9WorkerHook)vp9_loop_filter_worker; if (pbi->oxcf.max_threads > 1 && !vp9_worker_reset(&pbi->lf_worker)) { vpx_internal_error(&cm->error, VPX_CODEC_ERROR, "Loop filter thread creation failed"); } } alloc_tile_storage(pbi, tile_cols); xd->mi_8x8 = cm->mi_grid_visible; xd->mode_info_stride = cm->mode_info_stride; set_prev_mi(cm); setup_plane_dequants(cm, xd, cm->base_qindex); setup_block_dptrs(xd, cm->subsampling_x, cm->subsampling_y); cm->fc = cm->frame_contexts[cm->frame_context_idx]; vp9_zero(cm->counts); for (i = 0; i < MAX_MB_PLANE; ++i) vp9_zero(xd->plane[i].qcoeff); xd->corrupted = 0; new_fb->corrupted = read_compressed_header(pbi, data, first_partition_size); // TODO(jzern): remove frame_parallel_decoding_mode restriction for // single-frame tile decoding. if (pbi->oxcf.max_threads > 1 && tile_rows == 1 && tile_cols > 1 && cm->frame_parallel_decoding_mode) { *p_data_end = decode_tiles_mt(pbi, data + first_partition_size); } else { *p_data_end = decode_tiles(pbi, data + first_partition_size); } cm->last_width = cm->width; cm->last_height = cm->height; new_fb->corrupted |= xd->corrupted;
1331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355
if (!pbi->decoded_key_frame) { if (keyframe && !new_fb->corrupted) pbi->decoded_key_frame = 1; else vpx_internal_error(&cm->error, VPX_CODEC_CORRUPT_FRAME, "A stream must start with a complete key frame"); } if (!cm->error_resilient_mode && !cm->frame_parallel_decoding_mode) { vp9_adapt_coef_probs(cm); if (!frame_is_intra_only(cm)) { vp9_adapt_mode_probs(cm); vp9_adapt_mv_probs(cm, cm->allow_high_precision_mv); } } else { debug_check_frame_counts(cm); } if (cm->refresh_frame_context) cm->frame_contexts[cm->frame_context_idx] = cm->fc; return 0; }