static int check_fragments_for_errors(VP8D_COMP *pbi) { if (!pbi->ec_active && pbi->fragments.count <= 1 && pbi->fragments.sizes[0] == 0) { VP8_COMMON *cm = &pbi->common; /* If error concealment is disabled we won't signal missing frames * to the decoder. */ if (cm->fb_idx_ref_cnt[cm->lst_fb_idx] > 1) { /* The last reference shares buffer with another reference * buffer. Move it to its own buffer before setting it as * corrupt, otherwise we will make multiple buffers corrupt. */ const int prev_idx = cm->lst_fb_idx; cm->fb_idx_ref_cnt[prev_idx]--; cm->lst_fb_idx = get_free_fb(cm); vp8_yv12_copy_frame(&cm->yv12_fb[prev_idx], &cm->yv12_fb[cm->lst_fb_idx]); } /* 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. */ cm->yv12_fb[cm->lst_fb_idx].corrupted = 1; /* Signal that we have no frame to show. */ cm->show_frame = 0; /* Nothing more to do. */ return 0; } return 1; }
vpx_codec_err_t vp10_set_reference_dec(VP10_COMMON *cm, VP9_REFFRAME ref_frame_flag, YV12_BUFFER_CONFIG *sd) { RefBuffer *ref_buf = NULL; RefCntBuffer *const frame_bufs = cm->buffer_pool->frame_bufs; // TODO(jkoleszar): The decoder doesn't have any real knowledge of what the // encoder is using the frame buffers for. This is just a stub to keep the // vpxenc --test-decode functionality working, and will be replaced in a // later commit that adds VP9-specific controls for this functionality. if (ref_frame_flag == VP9_LAST_FLAG) { ref_buf = &cm->frame_refs[0]; } else if (ref_frame_flag == VP9_GOLD_FLAG) { ref_buf = &cm->frame_refs[1]; } else if (ref_frame_flag == VP9_ALT_FLAG) { ref_buf = &cm->frame_refs[2]; } else { vpx_internal_error(&cm->error, VPX_CODEC_ERROR, "Invalid reference frame"); return cm->error.error_code; } if (!equal_dimensions(ref_buf->buf, sd)) { vpx_internal_error(&cm->error, VPX_CODEC_ERROR, "Incorrect buffer dimensions"); } else { int *ref_fb_ptr = &ref_buf->idx; // Find an empty frame buffer. const int free_fb = get_free_fb(cm); if (cm->new_fb_idx == INVALID_IDX) return VPX_CODEC_MEM_ERROR; // Decrease ref_count since it will be increased again in // ref_cnt_fb() below. --frame_bufs[free_fb].ref_count; // Manage the reference counters and copy image. ref_cnt_fb(frame_bufs, ref_fb_ptr, free_fb); ref_buf->buf = &frame_bufs[*ref_fb_ptr].buf; vp8_yv12_copy_frame(sd, ref_buf->buf); } return cm->error.error_code; }
vpx_codec_err_t vp9_set_reference_dec(VP9D_PTR ptr, VP9_REFFRAME ref_frame_flag, YV12_BUFFER_CONFIG *sd) { VP9D_COMP *pbi = (VP9D_COMP *) ptr; VP9_COMMON *cm = &pbi->common; int *ref_fb_ptr = NULL; /* TODO(jkoleszar): The decoder doesn't have any real knowledge of what the * encoder is using the frame buffers for. This is just a stub to keep the * vpxenc --test-decode functionality working, and will be replaced in a * later commit that adds VP9-specific controls for this functionality. */ if (ref_frame_flag == VP9_LAST_FLAG) { ref_fb_ptr = &pbi->common.active_ref_idx[0]; } else if (ref_frame_flag == VP9_GOLD_FLAG) { ref_fb_ptr = &pbi->common.active_ref_idx[1]; } else if (ref_frame_flag == VP9_ALT_FLAG) { ref_fb_ptr = &pbi->common.active_ref_idx[2]; } else { vpx_internal_error(&pbi->common.error, VPX_CODEC_ERROR, "Invalid reference frame"); return pbi->common.error.error_code; } if (!equal_dimensions(&cm->yv12_fb[*ref_fb_ptr], sd)) { vpx_internal_error(&pbi->common.error, VPX_CODEC_ERROR, "Incorrect buffer dimensions"); } else { // Find an empty frame buffer. const int free_fb = get_free_fb(cm); // Decrease fb_idx_ref_cnt since it will be increased again in // ref_cnt_fb() below. cm->fb_idx_ref_cnt[free_fb]--; // Manage the reference counters and copy image. ref_cnt_fb(cm->fb_idx_ref_cnt, ref_fb_ptr, free_fb); vp8_yv12_copy_frame(sd, &cm->yv12_fb[*ref_fb_ptr]); } return pbi->common.error.error_code; }
vpx_codec_err_t vp8dx_set_reference(VP8D_COMP *pbi, enum vpx_ref_frame_type ref_frame_flag, YV12_BUFFER_CONFIG *sd) { VP8_COMMON *cm = &pbi->common; int *ref_fb_ptr = NULL; int free_fb; if (ref_frame_flag == VP8_LAST_FRAME) ref_fb_ptr = &cm->lst_fb_idx; else if (ref_frame_flag == VP8_GOLD_FRAME) ref_fb_ptr = &cm->gld_fb_idx; else if (ref_frame_flag == VP8_ALTR_FRAME) ref_fb_ptr = &cm->alt_fb_idx; else{ vpx_internal_error(&pbi->common.error, VPX_CODEC_ERROR, "Invalid reference frame"); return pbi->common.error.error_code; } if(cm->yv12_fb[*ref_fb_ptr].y_height != sd->y_height || cm->yv12_fb[*ref_fb_ptr].y_width != sd->y_width || cm->yv12_fb[*ref_fb_ptr].uv_height != sd->uv_height || cm->yv12_fb[*ref_fb_ptr].uv_width != sd->uv_width){ vpx_internal_error(&pbi->common.error, VPX_CODEC_ERROR, "Incorrect buffer dimensions"); } else{ /* Find an empty frame buffer. */ free_fb = get_free_fb(cm); /* Decrease fb_idx_ref_cnt since it will be increased again in * ref_cnt_fb() below. */ cm->fb_idx_ref_cnt[free_fb]--; /* Manage the reference counters and copy image. */ ref_cnt_fb (cm->fb_idx_ref_cnt, ref_fb_ptr, free_fb); vp8_yv12_copy_frame(sd, &cm->yv12_fb[*ref_fb_ptr]); } return pbi->common.error.error_code; }
int vp8dx_receive_compressed_data(VP8D_COMP *pbi, size_t size, const uint8_t *source, int64_t time_stamp, uint8_t dry_run) { #if HAVE_NEON int64_t dx_store_reg[8]; #endif VP8_COMMON *cm = &pbi->common; int retcode = -1; pbi->common.error.error_code = VPX_CODEC_OK; retcode = check_fragments_for_errors(pbi); if(retcode <= 0) return retcode; #if HAVE_NEON #if CONFIG_RUNTIME_CPU_DETECT if (cm->cpu_caps & HAS_NEON) #endif { vp8_push_neon(dx_store_reg); } #endif cm->new_fb_idx = get_free_fb (cm); /* setup reference frames for vp8_decode_frame */ pbi->dec_fb_ref[INTRA_FRAME] = &cm->yv12_fb[cm->new_fb_idx]; pbi->dec_fb_ref[LAST_FRAME] = &cm->yv12_fb[cm->lst_fb_idx]; pbi->dec_fb_ref[GOLDEN_FRAME] = &cm->yv12_fb[cm->gld_fb_idx]; pbi->dec_fb_ref[ALTREF_FRAME] = &cm->yv12_fb[cm->alt_fb_idx]; if (setjmp(pbi->common.error.jmp)) { /* 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. */ cm->yv12_fb[cm->lst_fb_idx].corrupted = 1; if (cm->fb_idx_ref_cnt[cm->new_fb_idx] > 0) cm->fb_idx_ref_cnt[cm->new_fb_idx]--; goto decode_exit; } pbi->common.error.setjmp = 1; retcode = vp8_decode_frame(pbi, dry_run); if (retcode < 0) { if (cm->fb_idx_ref_cnt[cm->new_fb_idx] > 0) cm->fb_idx_ref_cnt[cm->new_fb_idx]--; pbi->common.error.error_code = VPX_CODEC_ERROR; goto decode_exit; } if (swap_frame_buffers (cm)) { pbi->common.error.error_code = VPX_CODEC_ERROR; goto decode_exit; } vp8_clear_system_state(); if (cm->show_frame) { cm->current_video_frame++; cm->show_frame_mi = cm->mi; } #if CONFIG_ERROR_CONCEALMENT /* swap the mode infos to storage for future error concealment */ if (pbi->ec_enabled && pbi->common.prev_mi) { MODE_INFO* tmp = pbi->common.prev_mi; int row, col; pbi->common.prev_mi = pbi->common.mi; pbi->common.mi = tmp; /* Propagate the segment_ids to the next frame */ for (row = 0; row < pbi->common.mb_rows; ++row) { for (col = 0; col < pbi->common.mb_cols; ++col) { const int i = row*pbi->common.mode_info_stride + col; pbi->common.mi[i].mbmi.segment_id = pbi->common.prev_mi[i].mbmi.segment_id; } } } #endif pbi->ready_for_new_data = 0; pbi->last_time_stamp = time_stamp; decode_exit: #if HAVE_NEON #if CONFIG_RUNTIME_CPU_DETECT if (cm->cpu_caps & HAS_NEON) #endif { vp8_pop_neon(dx_store_reg); } #endif pbi->common.error.setjmp = 0; return retcode; }
int vp9_receive_compressed_data(VP9D_PTR ptr, size_t size, const uint8_t **psource, int64_t time_stamp) { VP9D_COMP *pbi = (VP9D_COMP *) ptr; VP9_COMMON *cm = &pbi->common; const uint8_t *source = *psource; int retcode = 0; /*if(pbi->ready_for_new_data == 0) return -1;*/ if (ptr == 0) return -1; cm->error.error_code = VPX_CODEC_OK; pbi->source = source; pbi->source_sz = size; if (pbi->source_sz == 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->active_ref_idx[0] != INT_MAX) get_frame_ref_buffer(cm, 0)->corrupted = 1; } 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->active_ref_idx[0] != INT_MAX) get_frame_ref_buffer(cm, 0)->corrupted = 1; if (cm->fb_idx_ref_cnt[cm->new_fb_idx] > 0) cm->fb_idx_ref_cnt[cm->new_fb_idx]--; return -1; } cm->error.setjmp = 1; retcode = vp9_decode_frame(pbi, psource); if (retcode < 0) { cm->error.error_code = VPX_CODEC_ERROR; cm->error.setjmp = 0; if (cm->fb_idx_ref_cnt[cm->new_fb_idx] > 0) cm->fb_idx_ref_cnt[cm->new_fb_idx]--; 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) { vp9_loop_filter_frame(cm, &pbi->mb, pbi->common.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 vp9_extend_frame_inner_borders(cm->frame_to_show, cm->subsampling_x, cm->subsampling_y); #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_show_frame = cm->show_frame; if (cm->show_frame) { // current mip will be the prev_mip for the next frame MODE_INFO *temp = cm->prev_mip; MODE_INFO **temp2 = cm->prev_mi_grid_base; cm->prev_mip = cm->mip; cm->mip = temp; cm->prev_mi_grid_base = cm->mi_grid_base; cm->mi_grid_base = temp2; // update the upper left visible macroblock ptrs cm->mi = cm->mip + cm->mode_info_stride + 1; cm->prev_mi = cm->prev_mip + cm->mode_info_stride + 1; cm->mi_grid_visible = cm->mi_grid_base + cm->mode_info_stride + 1; cm->prev_mi_grid_visible = cm->prev_mi_grid_base + cm->mode_info_stride + 1; pbi->mb.mi_8x8 = cm->mi_grid_visible; pbi->mb.mi_8x8[0] = cm->mi; cm->current_video_frame++; } pbi->ready_for_new_data = 0; pbi->last_time_stamp = time_stamp; pbi->source_sz = 0; cm->error.setjmp = 0; return retcode; }
int vp10_receive_compressed_data(VP10Decoder *pbi, size_t size, const uint8_t **psource) { VP10_COMMON *volatile const cm = &pbi->common; BufferPool *volatile const pool = cm->buffer_pool; RefCntBuffer *volatile const frame_bufs = cm->buffer_pool->frame_bufs; 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 > 0) { assert(cm->frame_refs[0].buf != NULL); cm->frame_refs[0].buf->corrupted = 1; } } pbi->ready_for_new_data = 0; // Check if the previous frame was a frame without any references to it. // Release frame buffer if not decoding in frame parallel mode. if (!pbi->frame_parallel_decode && cm->new_fb_idx >= 0 && frame_bufs[cm->new_fb_idx].ref_count == 0) pool->release_fb_cb(pool->cb_priv, &frame_bufs[cm->new_fb_idx].raw_frame_buffer); // Find a free frame buffer. Return error if can not find any. cm->new_fb_idx = get_free_fb(cm); if (cm->new_fb_idx == INVALID_IDX) return VPX_CODEC_MEM_ERROR; // Assign a MV array to the frame buffer. cm->cur_frame = &pool->frame_bufs[cm->new_fb_idx]; pbi->hold_ref_buf = 0; if (pbi->frame_parallel_decode) { VPxWorker *const worker = pbi->frame_worker_owner; vp10_frameworker_lock_stats(worker); frame_bufs[cm->new_fb_idx].frame_worker_owner = worker; // Reset decoding progress. pbi->cur_buf = &frame_bufs[cm->new_fb_idx]; pbi->cur_buf->row = -1; pbi->cur_buf->col = -1; vp10_frameworker_unlock_stats(worker); } else { pbi->cur_buf = &frame_bufs[cm->new_fb_idx]; } if (setjmp(cm->error.jmp)) { const VPxWorkerInterface *const winterface = vpx_get_worker_interface(); int i; cm->error.setjmp = 0; pbi->ready_for_new_data = 1; // Synchronize all threads immediately as a subsequent decode call may // cause a resize invalidating some allocations. winterface->sync(&pbi->lf_worker); for (i = 0; i < pbi->num_tile_workers; ++i) { winterface->sync(&pbi->tile_workers[i]); } lock_buffer_pool(pool); // Release all the reference buffers if worker thread is holding them. if (pbi->hold_ref_buf == 1) { int ref_index = 0, mask; for (mask = pbi->refresh_frame_flags; mask; mask >>= 1) { const int old_idx = cm->ref_frame_map[ref_index]; // Current thread releases the holding of reference frame. decrease_ref_count(old_idx, frame_bufs, pool); // Release the reference frame in reference map. if ((mask & 1) && old_idx >= 0) { decrease_ref_count(old_idx, frame_bufs, pool); } ++ref_index; } // Current thread releases the holding of reference frame. for (; ref_index < REF_FRAMES && !cm->show_existing_frame; ++ref_index) { const int old_idx = cm->ref_frame_map[ref_index]; decrease_ref_count(old_idx, frame_bufs, pool); } pbi->hold_ref_buf = 0; } // Release current frame. decrease_ref_count(cm->new_fb_idx, frame_bufs, pool); unlock_buffer_pool(pool); vpx_clear_system_state(); return -1; }
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; } pbi->ready_for_new_data = 0; // 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); // Assign a MV array to the frame buffer. cm->cur_frame = &cm->frame_bufs[cm->new_fb_idx]; if (setjmp(cm->error.jmp)) { pbi->need_resync = 1; 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; cm->prev_frame = cm->cur_frame; } if (cm->show_frame) cm->current_video_frame++; cm->error.setjmp = 0; return retcode; }
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 vp8dx_receive_compressed_data(VP8D_PTR ptr, unsigned long size, const unsigned char *source, INT64 time_stamp) { #if HAVE_ARMV7 INT64 dx_store_reg[8]; #endif VP8D_COMP *pbi = (VP8D_COMP *) ptr; VP8_COMMON *cm = &pbi->common; int retcode = 0; struct vpx_usec_timer timer; /*if(pbi->ready_for_new_data == 0) return -1;*/ if (ptr == 0) { return -1; } pbi->common.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. */ cm->yv12_fb[cm->lst_fb_idx].corrupted = 1; /* Signal that we have no frame to show. */ cm->show_frame = 0; /* Nothing more to do. */ return 0; } #if HAVE_ARMV7 #if CONFIG_RUNTIME_CPU_DETECT if (cm->rtcd.flags & HAS_NEON) #endif { vp8_push_neon(dx_store_reg); } #endif cm->new_fb_idx = get_free_fb (cm); if (setjmp(pbi->common.error.jmp)) { #if HAVE_ARMV7 #if CONFIG_RUNTIME_CPU_DETECT if (cm->rtcd.flags & HAS_NEON) #endif { vp8_pop_neon(dx_store_reg); } #endif pbi->common.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. */ cm->yv12_fb[cm->lst_fb_idx].corrupted = 1; if (cm->fb_idx_ref_cnt[cm->new_fb_idx] > 0) cm->fb_idx_ref_cnt[cm->new_fb_idx]--; return -1; } pbi->common.error.setjmp = 1; vpx_usec_timer_start(&timer); /*cm->current_video_frame++;*/ pbi->Source = source; pbi->source_sz = size; retcode = vp8_decode_frame(pbi); if (retcode < 0) { #if HAVE_ARMV7 #if CONFIG_RUNTIME_CPU_DETECT if (cm->rtcd.flags & HAS_NEON) #endif { vp8_pop_neon(dx_store_reg); } #endif pbi->common.error.error_code = VPX_CODEC_ERROR; pbi->common.error.setjmp = 0; if (cm->fb_idx_ref_cnt[cm->new_fb_idx] > 0) cm->fb_idx_ref_cnt[cm->new_fb_idx]--; return retcode; } #if CONFIG_MULTITHREAD if (pbi->b_multithreaded_rd && cm->multi_token_partition != ONE_PARTITION) { if (swap_frame_buffers (cm)) { #if HAVE_ARMV7 #if CONFIG_RUNTIME_CPU_DETECT if (cm->rtcd.flags & HAS_NEON) #endif { vp8_pop_neon(dx_store_reg); } #endif pbi->common.error.error_code = VPX_CODEC_ERROR; pbi->common.error.setjmp = 0; return -1; } } else #endif { if (swap_frame_buffers (cm)) { #if HAVE_ARMV7 #if CONFIG_RUNTIME_CPU_DETECT if (cm->rtcd.flags & HAS_NEON) #endif { vp8_pop_neon(dx_store_reg); } #endif pbi->common.error.error_code = VPX_CODEC_ERROR; pbi->common.error.setjmp = 0; return -1; } if(pbi->common.filter_level) { struct vpx_usec_timer lpftimer; vpx_usec_timer_start(&lpftimer); /* Apply the loop filter if appropriate. */ vp8_loop_filter_frame(cm, &pbi->mb, cm->filter_level); vpx_usec_timer_mark(&lpftimer); pbi->time_loop_filtering += vpx_usec_timer_elapsed(&lpftimer); cm->last_frame_type = cm->frame_type; cm->last_filter_type = cm->filter_type; cm->last_sharpness_level = cm->sharpness_level; } vp8_yv12_extend_frame_borders_ptr(cm->frame_to_show); } vp8_clear_system_state(); vpx_usec_timer_mark(&timer); pbi->decode_microseconds = vpx_usec_timer_elapsed(&timer); pbi->time_decoding += pbi->decode_microseconds; /*vp8_print_modes_and_motion_vectors( cm->mi, cm->mb_rows,cm->mb_cols, cm->current_video_frame);*/ if (cm->show_frame) cm->current_video_frame++; pbi->ready_for_new_data = 0; pbi->last_time_stamp = time_stamp; #if 0 { int i; INT64 earliest_time = pbi->dr[0].time_stamp; INT64 latest_time = pbi->dr[0].time_stamp; INT64 time_diff = 0; int bytes = 0; pbi->dr[pbi->common.current_video_frame&0xf].size = pbi->bc.pos + pbi->bc2.pos + 4;; pbi->dr[pbi->common.current_video_frame&0xf].time_stamp = time_stamp; for (i = 0; i < 16; i++) { bytes += pbi->dr[i].size; if (pbi->dr[i].time_stamp < earliest_time) earliest_time = pbi->dr[i].time_stamp; if (pbi->dr[i].time_stamp > latest_time) latest_time = pbi->dr[i].time_stamp; } time_diff = latest_time - earliest_time; if (time_diff > 0) { pbi->common.bitrate = 80000.00 * bytes / time_diff ; pbi->common.framerate = 160000000.00 / time_diff ; } } #endif #if HAVE_ARMV7 #if CONFIG_RUNTIME_CPU_DETECT if (cm->rtcd.flags & HAS_NEON) #endif { vp8_pop_neon(dx_store_reg); } #endif pbi->common.error.setjmp = 0; return retcode; }