Esempio n. 1
0
int vp9_receive_compressed_data(VP9Decoder *pbi,
                                size_t size, const uint8_t **psource,
                                int64_t time_stamp) {
  VP9_COMMON *const cm = &pbi->common;
  const uint8_t *source = *psource;
  int retcode = 0;

  cm->error.error_code = VPX_CODEC_OK;

  if (size == 0) {
    // This is used to signal that we are missing frames.
    // We do not know if the missing frame(s) was supposed to update
    // any of the reference buffers, but we act conservative and
    // mark only the last buffer as corrupted.
    //
    // TODO(jkoleszar): Error concealment is undefined and non-normative
    // at this point, but if it becomes so, [0] may not always be the correct
    // thing to do here.
    if (cm->frame_refs[0].idx != INT_MAX)
      cm->frame_refs[0].buf->corrupted = 1;
  }

  // Check if the previous frame was a frame without any references to it.
  if (cm->new_fb_idx >= 0 && cm->frame_bufs[cm->new_fb_idx].ref_count == 0)
    cm->release_fb_cb(cm->cb_priv,
                      &cm->frame_bufs[cm->new_fb_idx].raw_frame_buffer);
  cm->new_fb_idx = get_free_fb(cm);

  if (setjmp(cm->error.jmp)) {
    cm->error.setjmp = 0;

    // We do not know if the missing frame(s) was supposed to update
    // any of the reference buffers, but we act conservative and
    // mark only the last buffer as corrupted.
    //
    // TODO(jkoleszar): Error concealment is undefined and non-normative
    // at this point, but if it becomes so, [0] may not always be the correct
    // thing to do here.
    if (cm->frame_refs[0].idx != INT_MAX)
      cm->frame_refs[0].buf->corrupted = 1;

    if (cm->frame_bufs[cm->new_fb_idx].ref_count > 0)
      cm->frame_bufs[cm->new_fb_idx].ref_count--;

    return -1;
  }

  cm->error.setjmp = 1;

  retcode = vp9_decode_frame(pbi, source, source + size, psource);

  if (retcode < 0) {
    cm->error.error_code = VPX_CODEC_ERROR;
    cm->error.setjmp = 0;
    if (cm->frame_bufs[cm->new_fb_idx].ref_count > 0)
      cm->frame_bufs[cm->new_fb_idx].ref_count--;
    return retcode;
  }

  swap_frame_buffers(pbi);

#if WRITE_RECON_BUFFER == 2
  if (cm->show_frame)
    write_dx_frame_to_file(cm->frame_to_show,
                           cm->current_video_frame);
  else
    write_dx_frame_to_file(cm->frame_to_show,
                           cm->current_video_frame + 1000);
#endif

  if (!pbi->do_loopfilter_inline) {
    // If multiple threads are used to decode tiles, then we use those threads
    // to do parallel loopfiltering.
    if (pbi->num_tile_workers) {
      vp9_loop_filter_frame_mt(pbi, cm, cm->lf.filter_level, 0, 0);
    } else {
      vp9_loop_filter_frame(cm, &pbi->mb, cm->lf.filter_level, 0, 0);
    }
  }

#if WRITE_RECON_BUFFER == 2
  if (cm->show_frame)
    write_dx_frame_to_file(cm->frame_to_show,
                           cm->current_video_frame + 2000);
  else
    write_dx_frame_to_file(cm->frame_to_show,
                           cm->current_video_frame + 3000);
#endif

#if WRITE_RECON_BUFFER == 1
  if (cm->show_frame)
    recon_write_yuv_frame("recon.yuv", cm->frame_to_show,
                          cm->width, cm->height);
#endif

  vp9_clear_system_state();

  cm->last_width = cm->width;
  cm->last_height = cm->height;

  if (!cm->show_existing_frame)
    cm->last_show_frame = cm->show_frame;
  if (cm->show_frame) {
    if (!cm->show_existing_frame)
      vp9_swap_mi_and_prev_mi(cm);

    cm->current_video_frame++;
  }

  pbi->ready_for_new_data = 0;
  pbi->last_time_stamp = time_stamp;

  cm->error.setjmp = 0;
  return retcode;
}
int vp9_receive_compressed_data(VP9Decoder *pbi,
                                size_t size, const uint8_t **psource) {
  VP9_COMMON *const cm = &pbi->common;
  const uint8_t *source = *psource;
  int retcode = 0;

  cm->error.error_code = VPX_CODEC_OK;

  if (size == 0) {
    // This is used to signal that we are missing frames.
    // We do not know if the missing frame(s) was supposed to update
    // any of the reference buffers, but we act conservative and
    // mark only the last buffer as corrupted.
    //
    // TODO(jkoleszar): Error concealment is undefined and non-normative
    // at this point, but if it becomes so, [0] may not always be the correct
    // thing to do here.
    if (cm->frame_refs[0].idx != INT_MAX)
      cm->frame_refs[0].buf->corrupted = 1;
  }

  // Check if the previous frame was a frame without any references to it.
  if (cm->new_fb_idx >= 0 && cm->frame_bufs[cm->new_fb_idx].ref_count == 0)
    cm->release_fb_cb(cm->cb_priv,
                      &cm->frame_bufs[cm->new_fb_idx].raw_frame_buffer);
  cm->new_fb_idx = get_free_fb(cm);

  if (setjmp(cm->error.jmp)) {
    cm->error.setjmp = 0;
    vp9_clear_system_state();

    // We do not know if the missing frame(s) was supposed to update
    // any of the reference buffers, but we act conservative and
    // mark only the last buffer as corrupted.
    //
    // TODO(jkoleszar): Error concealment is undefined and non-normative
    // at this point, but if it becomes so, [0] may not always be the correct
    // thing to do here.
    if (cm->frame_refs[0].idx != INT_MAX && cm->frame_refs[0].buf != NULL)
      cm->frame_refs[0].buf->corrupted = 1;

    if (cm->new_fb_idx > 0 && cm->frame_bufs[cm->new_fb_idx].ref_count > 0)
      cm->frame_bufs[cm->new_fb_idx].ref_count--;

    return -1;
  }

  cm->error.setjmp = 1;

  vp9_decode_frame(pbi, source, source + size, psource);

  swap_frame_buffers(pbi);

  vp9_clear_system_state();

  cm->last_width = cm->width;
  cm->last_height = cm->height;

  if (!cm->show_existing_frame)
    cm->last_show_frame = cm->show_frame;
  if (cm->show_frame) {
    if (!cm->show_existing_frame)
      vp9_swap_mi_and_prev_mi(cm);

    cm->current_video_frame++;
  }

  pbi->ready_for_new_data = 0;

  cm->error.setjmp = 0;
  return retcode;
}