vp9_decodframe.c 37 KB
Newer Older
        cm->comp_var_ref[1] = ALTREF_FRAME;
      } else {
        cm->comp_fixed_ref = LAST_FRAME;
        cm->comp_var_ref[0] = GOLDEN_FRAME;
        cm->comp_var_ref[1] = ALTREF_FRAME;
      }
    }

    xd->allow_high_precision_mv = vp9_rb_read_bit(rb);
    cm->mcomp_filter_type = read_interp_filter_type(rb);
  }

  cm->intra_only = cm->show_frame ? 0 : vp9_rb_read_bit(rb);
  cm->frame_context_idx = vp9_rb_read_literal(rb, NUM_FRAME_CONTEXTS_LG2);
  cm->clr_type = (YUV_TYPE)vp9_rb_read_bit(rb);

  setup_loopfilter(pbi, rb);
  setup_quantization(pbi, rb);
  setup_segmentation(pbi, rb);

  setup_tile_info(cm, rb);
  return vp9_rb_read_literal(rb, 16);
}
John Koleszar's avatar
John Koleszar committed

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;
  const uint8_t *data = pbi->source;
  const uint8_t *data_end = pbi->source + pbi->source_sz;
Yaowu Xu's avatar
Yaowu Xu committed

  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;
  YV12_BUFFER_CONFIG *new_fb = &pc->yv12_fb[pc->new_fb_idx];
  data += vp9_rb_bytes_read(&rb);
  xd->corrupted = 0;
  new_fb->corrupted = 0;
  if ((!pbi->decoded_key_frame && !keyframe) ||
      pc->width == 0 || pc->height == 0) {
John Koleszar's avatar
John Koleszar committed
    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");
  xd->mode_info_context = pc->mi;
  xd->prev_mode_info_context = pc->prev_mi;
  xd->frame_type = pc->frame_type;
  xd->mode_info_stride = pc->mode_info_stride;
  if (vp9_reader_init(&header_bc, data, first_partition_size))
John Koleszar's avatar
John Koleszar committed
    vpx_internal_error(&pc->error, VPX_CODEC_MEM_ERROR,
                       "Failed to allocate bool decoder 0");
  mb_init_dequantizer(pc, &pbi->mb);  // MB level dequantizer setup
    vp9_setup_interp_filters(xd, pc->mcomp_filter_type, pc);
John Koleszar's avatar
John Koleszar committed

  pc->fc = pc->frame_contexts[pc->frame_context_idx];
John Koleszar's avatar
John Koleszar committed

  setup_txfm_mode(pc, xd->lossless, &header_bc);
  update_frame_context(&pc->fc);
Yaowu Xu's avatar
Yaowu Xu committed

  // Initialize xd pointers. Any reference should do for xd->pre, so use 0.
  setup_pre_planes(xd, &pc->yv12_fb[pc->active_ref_idx[0]], NULL,
                   0, 0, NULL, NULL);
  setup_dst_planes(xd, new_fb, 0, 0);
John Koleszar's avatar
John Koleszar committed
  // 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->mi_rows * pc->mi_cols), 1));
  vp9_setup_block_dptrs(xd, pc->subsampling_x, pc->subsampling_y);
Dmitry Kovalev's avatar
Dmitry Kovalev committed
  // clear out the coeff buffer
  for (i = 0; i < MAX_MB_PLANE; ++i)
    vp9_zero(xd->plane[i].qcoeff);
  vp9_decode_mode_mvs_init(pbi, &header_bc);
  decode_tiles(pbi, data, first_partition_size, &residual_bc);
John Koleszar's avatar
John Koleszar committed

  pc->last_width = pc->width;
  pc->last_height = pc->height;
  new_fb->corrupted = vp9_reader_has_error(&header_bc) | xd->corrupted;
John Koleszar's avatar
John Koleszar committed

  if (!pbi->decoded_key_frame) {
    if (keyframe && !new_fb->corrupted)
John Koleszar's avatar
John Koleszar committed
      pbi->decoded_key_frame = 1;
    else
      vpx_internal_error(&pc->error, VPX_CODEC_CORRUPT_FRAME,
John Koleszar's avatar
John Koleszar committed
                         "A stream must start with a complete key frame");
  }
  if (!pc->error_resilient_mode && !pc->frame_parallel_decoding_mode) {
    vp9_adapt_coef_probs(pc);
      vp9_adapt_mode_probs(pc);
      vp9_adapt_nmv_probs(pc, xd->allow_high_precision_mv);
John Koleszar's avatar
John Koleszar committed
  }
  if (pc->refresh_frame_context)
    pc->frame_contexts[pc->frame_context_idx] = pc->fc;
  *p_data_end = vp9_reader_find_end(&residual_bc);
John Koleszar's avatar
John Koleszar committed
  return 0;
John Koleszar's avatar
John Koleszar committed
}