]> granicus.if.org Git - libvpx/commitdiff
Merge "Eliminated frame_type check in get_partition_probs()"
authorScott LaVarnway <slavarnway@google.com>
Tue, 16 Jun 2015 13:40:21 +0000 (13:40 +0000)
committerGerrit Code Review <noreply-gerritcodereview@google.com>
Tue, 16 Jun 2015 13:40:23 +0000 (13:40 +0000)
1  2 
vp9/common/vp9_blockd.h
vp9/common/vp9_onyxc_int.h
vp9/decoder/vp9_decodeframe.c
vp9/encoder/vp9_bitstream.c

Simple merge
Simple merge
index d309b800f03ad20c8c780b16845e5c222b53e3f6,9e60215f61149401c5f1e0cb511c27601cf660f1..76bc23b1dc86399eb2dc8767c96547d2510d3733
@@@ -697,242 -715,200 +697,242 @@@ static void dec_build_inter_predictors_
    }
  }
  
 -static void setup_frame_size(VP9_COMMON *cm, struct vp9_read_bit_buffer *rb) {
 -  int width, height;
 -  BufferPool *const pool = cm->buffer_pool;
 -  vp9_read_frame_size(rb, &width, &height);
 -  resize_context_buffers(cm, width, height);
 -  setup_display_size(cm, rb);
 +static MB_MODE_INFO *set_offsets(VP9_COMMON *const cm, MACROBLOCKD *const xd,
 +                                 const TileInfo *const tile,
 +                                 BLOCK_SIZE bsize, int mi_row, int mi_col) {
 +  const int bw = num_8x8_blocks_wide_lookup[bsize];
 +  const int bh = num_8x8_blocks_high_lookup[bsize];
 +  const int x_mis = MIN(bw, cm->mi_cols - mi_col);
 +  const int y_mis = MIN(bh, cm->mi_rows - mi_row);
 +  const int offset = mi_row * cm->mi_stride + mi_col;
 +  int x, y;
  
 -  lock_buffer_pool(pool);
 -  if (vp9_realloc_frame_buffer(
 -          get_frame_new_buffer(cm), cm->width, cm->height,
 -          cm->subsampling_x, cm->subsampling_y,
 -#if CONFIG_VP9_HIGHBITDEPTH
 -          cm->use_highbitdepth,
 -#endif
 -          VP9_DEC_BORDER_IN_PIXELS,
 -          cm->byte_alignment,
 -          &pool->frame_bufs[cm->new_fb_idx].raw_frame_buffer, pool->get_fb_cb,
 -          pool->cb_priv)) {
 -    unlock_buffer_pool(pool);
 -    vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR,
 -                       "Failed to allocate frame buffer");
 -  }
 -  unlock_buffer_pool(pool);
 +  xd->mi = cm->mi_grid_visible + offset;
 +  xd->mi[0] = &cm->mi[offset];
 +  xd->mi[0]->mbmi.sb_type = bsize;
 +  for (y = 0; y < y_mis; ++y)
 +    for (x = !y; x < x_mis; ++x) {
 +      xd->mi[y * cm->mi_stride + x] = xd->mi[0];
 +    }
  
 -  pool->frame_bufs[cm->new_fb_idx].buf.subsampling_x = cm->subsampling_x;
 -  pool->frame_bufs[cm->new_fb_idx].buf.subsampling_y = cm->subsampling_y;
 -  pool->frame_bufs[cm->new_fb_idx].buf.bit_depth = (unsigned int)cm->bit_depth;
 -  pool->frame_bufs[cm->new_fb_idx].buf.color_space = cm->color_space;
 -}
 +  set_skip_context(xd, mi_row, mi_col);
  
 -static INLINE int valid_ref_frame_img_fmt(vpx_bit_depth_t ref_bit_depth,
 -                                          int ref_xss, int ref_yss,
 -                                          vpx_bit_depth_t this_bit_depth,
 -                                          int this_xss, int this_yss) {
 -  return ref_bit_depth == this_bit_depth && ref_xss == this_xss &&
 -         ref_yss == this_yss;
 +  // 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);
 +
 +  vp9_setup_dst_planes(xd->plane, get_frame_new_buffer(cm), mi_row, mi_col);
 +  return &xd->mi[0]->mbmi;
  }
  
 -static void setup_frame_size_with_refs(VP9_COMMON *cm,
 -                                       struct vp9_read_bit_buffer *rb) {
 -  int width, height;
 -  int found = 0, i;
 -  int has_valid_ref_frame = 0;
 -  BufferPool *const pool = cm->buffer_pool;
 -  for (i = 0; i < REFS_PER_FRAME; ++i) {
 -    if (vp9_rb_read_bit(rb)) {
 -      YV12_BUFFER_CONFIG *const buf = cm->frame_refs[i].buf;
 -      width = buf->y_crop_width;
 -      height = buf->y_crop_height;
 -      found = 1;
 -      break;
 -    }
 +static void decode_block(VP9Decoder *const pbi, MACROBLOCKD *const xd,
 +                         const TileInfo *const tile,
 +                         int mi_row, int mi_col,
 +                         vp9_reader *r, BLOCK_SIZE bsize) {
 +  VP9_COMMON *const cm = &pbi->common;
 +  const int less8x8 = bsize < BLOCK_8X8;
 +  MB_MODE_INFO *mbmi = set_offsets(cm, xd, tile, bsize, mi_row, mi_col);
 +
 +  if (bsize >= BLOCK_8X8 && (cm->subsampling_x || cm->subsampling_y)) {
 +    const BLOCK_SIZE uv_subsize =
 +        ss_size_lookup[bsize][cm->subsampling_x][cm->subsampling_y];
 +    if (uv_subsize == BLOCK_INVALID)
 +      vpx_internal_error(xd->error_info,
 +                         VPX_CODEC_CORRUPT_FRAME, "Invalid block size.");
    }
  
 -  if (!found)
 -    vp9_read_frame_size(rb, &width, &height);
 +  vp9_read_mode_info(pbi, xd, tile, mi_row, mi_col, r);
  
 -  if (width <= 0 || height <= 0)
 -    vpx_internal_error(&cm->error, VPX_CODEC_CORRUPT_FRAME,
 -                       "Invalid frame size");
 +  if (less8x8)
 +    bsize = BLOCK_8X8;
  
 -  // Check to make sure at least one of frames that this frame references
 -  // has valid dimensions.
 -  for (i = 0; i < REFS_PER_FRAME; ++i) {
 -    RefBuffer *const ref_frame = &cm->frame_refs[i];
 -    has_valid_ref_frame |= valid_ref_frame_size(ref_frame->buf->y_crop_width,
 -                                                ref_frame->buf->y_crop_height,
 -                                                width, height);
 +  if (mbmi->skip) {
 +    reset_skip_context(xd, bsize);
    }
 -  if (!has_valid_ref_frame)
 -    vpx_internal_error(&cm->error, VPX_CODEC_CORRUPT_FRAME,
 -                       "Referenced frame has invalid size");
 -  for (i = 0; i < REFS_PER_FRAME; ++i) {
 -    RefBuffer *const ref_frame = &cm->frame_refs[i];
 -    if (!valid_ref_frame_img_fmt(
 -            ref_frame->buf->bit_depth,
 -            ref_frame->buf->subsampling_x,
 -            ref_frame->buf->subsampling_y,
 -            cm->bit_depth,
 -            cm->subsampling_x,
 -            cm->subsampling_y))
 -      vpx_internal_error(&cm->error, VPX_CODEC_CORRUPT_FRAME,
 -                         "Referenced frame has incompatible color format");
 +
 +  if (!is_inter_block(mbmi)) {
 +    struct intra_args arg = {xd, r, mbmi->segment_id};
 +    vp9_foreach_transformed_block(xd, bsize,
 +                                  predict_and_reconstruct_intra_block, &arg);
 +  } else {
 +    // Prediction
 +    dec_build_inter_predictors_sb(pbi, xd, mi_row, mi_col, bsize);
 +
 +    // Reconstruction
 +    if (!mbmi->skip) {
 +      int eobtotal = 0;
 +      struct inter_args arg = {xd, r, &eobtotal, mbmi->segment_id};
 +      vp9_foreach_transformed_block(xd, bsize, reconstruct_inter_block, &arg);
 +      if (!less8x8 && eobtotal == 0)
 +        mbmi->skip = 1;  // skip loopfilter
 +    }
    }
  
 -  resize_context_buffers(cm, width, height);
 -  setup_display_size(cm, rb);
 +  xd->corrupted |= vp9_reader_has_error(r);
 +}
  
 -  lock_buffer_pool(pool);
 -  if (vp9_realloc_frame_buffer(
 -          get_frame_new_buffer(cm), cm->width, cm->height,
 -          cm->subsampling_x, cm->subsampling_y,
 -#if CONFIG_VP9_HIGHBITDEPTH
 -          cm->use_highbitdepth,
 -#endif
 -          VP9_DEC_BORDER_IN_PIXELS,
 -          cm->byte_alignment,
 -          &pool->frame_bufs[cm->new_fb_idx].raw_frame_buffer, pool->get_fb_cb,
 -          pool->cb_priv)) {
 -    unlock_buffer_pool(pool);
 -    vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR,
 -                       "Failed to allocate frame buffer");
 +static PARTITION_TYPE read_partition(VP9_COMMON *cm, MACROBLOCKD *xd,
 +                                     int hbs,
 +                                     int mi_row, int mi_col, BLOCK_SIZE bsize,
 +                                     vp9_reader *r) {
 +  const int ctx = partition_plane_context(xd, mi_row, mi_col, bsize);
-   const vp9_prob *const probs = get_partition_probs(cm, ctx);
++  const vp9_prob *const probs = get_partition_probs(xd, ctx);
 +  const int has_rows = (mi_row + hbs) < cm->mi_rows;
 +  const int has_cols = (mi_col + hbs) < cm->mi_cols;
 +  FRAME_COUNTS *counts = xd->counts;
 +  PARTITION_TYPE p;
 +
 +  if (has_rows && has_cols)
 +    p = (PARTITION_TYPE)vp9_read_tree(r, vp9_partition_tree, probs);
 +  else if (!has_rows && has_cols)
 +    p = vp9_read(r, probs[1]) ? PARTITION_SPLIT : PARTITION_HORZ;
 +  else if (has_rows && !has_cols)
 +    p = vp9_read(r, probs[2]) ? PARTITION_SPLIT : PARTITION_VERT;
 +  else
 +    p = PARTITION_SPLIT;
 +
 +  if (counts)
 +    ++counts->partition[ctx][p];
 +
 +  return p;
 +}
 +
 +static void decode_partition(VP9Decoder *const pbi, MACROBLOCKD *const xd,
 +                             const TileInfo *const tile,
 +                             int mi_row, int mi_col,
 +                             vp9_reader* r, BLOCK_SIZE bsize) {
 +  VP9_COMMON *const cm = &pbi->common;
 +  const int hbs = num_8x8_blocks_wide_lookup[bsize] / 2;
 +  PARTITION_TYPE partition;
 +  BLOCK_SIZE subsize;
 +
 +  if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols)
 +    return;
 +
 +  partition = read_partition(cm, xd, hbs, mi_row, mi_col, bsize, r);
 +  subsize = get_subsize(bsize, partition);
 +  if (bsize == BLOCK_8X8) {
 +    decode_block(pbi, xd, tile, mi_row, mi_col, r, subsize);
 +  } else {
 +    switch (partition) {
 +      case PARTITION_NONE:
 +        decode_block(pbi, xd, tile, mi_row, mi_col, r, subsize);
 +        break;
 +      case PARTITION_HORZ:
 +        decode_block(pbi, xd, tile, mi_row, mi_col, r, subsize);
 +        if (mi_row + hbs < cm->mi_rows)
 +          decode_block(pbi, xd, tile, mi_row + hbs, mi_col, r, subsize);
 +        break;
 +      case PARTITION_VERT:
 +        decode_block(pbi, xd, tile, mi_row, mi_col, r, subsize);
 +        if (mi_col + hbs < cm->mi_cols)
 +          decode_block(pbi, xd, tile, mi_row, mi_col + hbs, r, subsize);
 +        break;
 +      case PARTITION_SPLIT:
 +        decode_partition(pbi, xd, tile, mi_row, mi_col, r, subsize);
 +        decode_partition(pbi, xd, tile, mi_row, mi_col + hbs, r, subsize);
 +        decode_partition(pbi, xd, tile, mi_row + hbs, mi_col, r, subsize);
 +        decode_partition(pbi, xd, tile, mi_row + hbs, mi_col + hbs, r, subsize);
 +        break;
 +      default:
 +        assert(0 && "Invalid partition type");
 +    }
    }
 -  unlock_buffer_pool(pool);
  
 -  pool->frame_bufs[cm->new_fb_idx].buf.subsampling_x = cm->subsampling_x;
 -  pool->frame_bufs[cm->new_fb_idx].buf.subsampling_y = cm->subsampling_y;
 -  pool->frame_bufs[cm->new_fb_idx].buf.bit_depth = (unsigned int)cm->bit_depth;
 -  pool->frame_bufs[cm->new_fb_idx].buf.color_space = cm->color_space;
 +  // update partition context
 +  if (bsize >= BLOCK_8X8 &&
 +      (bsize == BLOCK_8X8 || partition != PARTITION_SPLIT))
 +    update_partition_context(xd, 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,
 +                                vpx_decrypt_cb decrypt_cb,
 +                                void *decrypt_state) {
 +  // 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, decrypt_cb, decrypt_state))
 +    vpx_internal_error(error_info, VPX_CODEC_MEM_ERROR,
 +                       "Failed to allocate bool decoder %d", 1);
  }
  
 -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++;
 +static void read_coef_probs_common(vp9_coeff_probs_model *coef_probs,
 +                                   vp9_reader *r) {
 +  int i, j, k, l, m;
  
 -  if (cm->log2_tile_cols > 6)
 -    vpx_internal_error(&cm->error, VPX_CODEC_CORRUPT_FRAME,
 -                       "Invalid number of tile columns");
 +  if (vp9_read_bit(r))
 +    for (i = 0; i < PLANE_TYPES; ++i)
 +      for (j = 0; j < REF_TYPES; ++j)
 +        for (k = 0; k < COEF_BANDS; ++k)
 +          for (l = 0; l < BAND_COEFF_CONTEXTS(k); ++l)
 +            for (m = 0; m < UNCONSTRAINED_NODES; ++m)
 +              vp9_diff_update_prob(r, &coef_probs[i][j][k][l][m]);
 +}
  
 -  // rows
 -  cm->log2_tile_rows = vp9_rb_read_bit(rb);
 -  if (cm->log2_tile_rows)
 -    cm->log2_tile_rows += vp9_rb_read_bit(rb);
 +static void read_coef_probs(FRAME_CONTEXT *fc, TX_MODE tx_mode,
 +                            vp9_reader *r) {
 +    const TX_SIZE max_tx_size = tx_mode_to_biggest_tx_size[tx_mode];
 +    TX_SIZE tx_size;
 +    for (tx_size = TX_4X4; tx_size <= max_tx_size; ++tx_size)
 +      read_coef_probs_common(fc->coef_probs[tx_size], r);
  }
  
 -typedef struct TileBuffer {
 -  const uint8_t *data;
 -  size_t size;
 -  int col;  // only used with multi-threaded decoding
 -} TileBuffer;
 +static void setup_segmentation(struct segmentation *seg,
 +                               struct vp9_read_bit_buffer *rb) {
 +  int i, j;
  
 -// Reads the next tile returning its size and adjusting '*data' accordingly
 -// based on 'is_last'.
 -static void get_tile_buffer(const uint8_t *const data_end,
 -                            int is_last,
 -                            struct vpx_internal_error_info *error_info,
 -                            const uint8_t **data,
 -                            vpx_decrypt_cb decrypt_cb, void *decrypt_state,
 -                            TileBuffer *buf) {
 -  size_t size;
 +  seg->update_map = 0;
 +  seg->update_data = 0;
  
 -  if (!is_last) {
 -    if (!read_is_valid(*data, 4, data_end))
 -      vpx_internal_error(error_info, VPX_CODEC_CORRUPT_FRAME,
 -                         "Truncated packet or corrupt tile length");
 +  seg->enabled = vp9_rb_read_bit(rb);
 +  if (!seg->enabled)
 +    return;
  
 -    if (decrypt_cb) {
 -      uint8_t be_data[4];
 -      decrypt_cb(decrypt_state, *data, be_data, 4);
 -      size = mem_get_be32(be_data);
 +  // 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 {
 -      size = mem_get_be32(*data);
 +      for (i = 0; i < PREDICTION_PROBS; i++)
 +        seg->pred_probs[i] = MAX_PROB;
      }
 -    *data += 4;
 -
 -    if (size > (size_t)(data_end - *data))
 -      vpx_internal_error(error_info, VPX_CODEC_CORRUPT_FRAME,
 -                         "Truncated packet or corrupt tile size");
 -  } else {
 -    size = data_end - *data;
    }
  
 -  buf->data = *data;
 -  buf->size = size;
 -
 -  *data += size;
 -}
 +  // Segmentation data update
 +  seg->update_data = vp9_rb_read_bit(rb);
 +  if (seg->update_data) {
 +    seg->abs_delta = vp9_rb_read_bit(rb);
  
 -static void get_tile_buffers(VP9Decoder *pbi,
 -                             const uint8_t *data, const uint8_t *data_end,
 -                             int tile_cols, int tile_rows,
 -                             TileBuffer (*tile_buffers)[1 << 6]) {
 -  int r, c;
 +    vp9_clearall_segfeatures(seg);
  
 -  for (r = 0; r < tile_rows; ++r) {
 -    for (c = 0; c < tile_cols; ++c) {
 -      const int is_last = (r == tile_rows - 1) && (c == tile_cols - 1);
 -      TileBuffer *const buf = &tile_buffers[r][c];
 -      buf->col = c;
 -      get_tile_buffer(data_end, is_last, &pbi->common.error, &data,
 -                      pbi->decrypt_cb, pbi->decrypt_state, buf);
 +    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);
 +      }
      }
    }
  }
Simple merge