vpx_codec_err_t vp8dx_get_reference(VP8D_COMP *pbi, enum vpx_ref_frame_type ref_frame_flag, YV12_BUFFER_CONFIG *sd) { VP8_COMMON *cm = &pbi->common; int ref_fb_idx; if (ref_frame_flag == VP8_LAST_FRAME) ref_fb_idx = cm->lst_fb_idx; else if (ref_frame_flag == VP8_GOLD_FRAME) ref_fb_idx = cm->gld_fb_idx; else if (ref_frame_flag == VP8_ALTR_FRAME) ref_fb_idx = 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_idx].y_height != sd->y_height || cm->yv12_fb[ref_fb_idx].y_width != sd->y_width || cm->yv12_fb[ref_fb_idx].uv_height != sd->uv_height || cm->yv12_fb[ref_fb_idx].uv_width != sd->uv_width){ vpx_internal_error(&pbi->common.error, VPX_CODEC_ERROR, "Incorrect buffer dimensions"); } else vp8_yv12_copy_frame(&cm->yv12_fb[ref_fb_idx], sd); return pbi->common.error.error_code; }
vpx_codec_err_t vp9_copy_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; /* 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) { YV12_BUFFER_CONFIG *cfg = &cm->yv12_fb[cm->ref_frame_map[0]]; if (!equal_dimensions(cfg, sd)) vpx_internal_error(&cm->error, VPX_CODEC_ERROR, "Incorrect buffer dimensions"); else vp8_yv12_copy_frame(cfg, sd); } else { vpx_internal_error(&cm->error, VPX_CODEC_ERROR, "Invalid reference frame"); } return cm->error.error_code; }
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 onyx_blit ( XIMAGE_HANDLE src, VSCREEN_HANDLE v_screen, DXV_YUV_BUFFER_CONFIG *frame_buffer, int x, int y ) { VP8_XIMAGE_HANDLE tab = (VP8_XIMAGE_HANDLE)vpxdxv_get_algorithm_base_ptr(src); VP8D_COMP *pbi; VP8_COMMON *common = tab->common; pbi = tab->my_pbi; if (v_screen) /* if there is a v_screen, blit to it */ { unsigned char *ptr_scrn; int this_pitch, vs_height, vs_width; unsigned int start_tick, stop_tick; vpxdxv_get_vscreen_attributes(v_screen, (void **)&ptr_scrn, &vs_width, &vs_height, &this_pitch); if (ptr_scrn) { int w, h; int p_size; int view_x, view_y, view_w; int hs, hr, vs, vr; int neww, newh; int cw, ch; int microseconds_available = (int)(1000000 / 30); microseconds_available = microseconds_available * tab->cpu_free / 100; if (pbi) { microseconds_available -= pbi->decode_microseconds; if (tab->cpu_free == 0) microseconds_available = INT_MAX; if (tab->post_proc2time == 0) tab->post_proc2time = pbi->decode_microseconds * 1 / 2; if (tab->post_proc4time == 0) tab->post_proc4time = pbi->decode_microseconds; } if (tab->ppcount == 0) { tab->post_proc2time = 0; tab->post_proc4time = 0; tab->ppcount = 64; } else { tab->ppcount --; } vpxdxv_get_vscreen_view(v_screen, &view_x, &view_y, &view_w, NULL); Scale2Ratio(common->horiz_scale, &hr, &hs); Scale2Ratio(common->vert_scale, &vr, &vs); if (tab->postproc && tab->passed_in_buffer == 0) { int show_text = 0; unsigned char message[512]; int pp = tab->postproc; int q = (tab->avgq + 4) / 8; int noise = 0; vp8_clear_system_state(); if (pp >= 1000) { pp -= 1000; noise = pp / 100; pp = pp - noise * 100; } if (pp >= 300) { pp -= 300; show_text = 3; } else if (pp >= 200) { pp -= 200; show_text = 2; } else if (pp >= 100) { pp -= 100; show_text = 1; } if (pbi && (pbi->mb.segmentation_enabled & SEGMENT_PF) && tab->deinterlace) { de_interlace(common->frame_to_show->y_buffer, common->post_proc_buffer.y_buffer, common->post_proc_buffer.y_width, common->post_proc_buffer.y_height, common->post_proc_buffer.y_stride); de_interlace(common->frame_to_show->u_buffer, common->post_proc_buffer.u_buffer, common->post_proc_buffer.uv_width, common->post_proc_buffer.uv_height, common->post_proc_buffer.uv_stride); de_interlace(common->frame_to_show->v_buffer, common->post_proc_buffer.v_buffer, common->post_proc_buffer.uv_width, common->post_proc_buffer.uv_height, common->post_proc_buffer.uv_stride); } else { if (pp >= 10 && pp <= 20) { q = q + (pp - 15) * 10; if (q < 0) q = 0; } start_tick = vp8_get_high_res_timer_tick(); if (pp > 3 && tab->post_proc4time < microseconds_available) { vp8_deblock_and_de_macro_block(common->frame_to_show, &common->post_proc_buffer, q, 1, 0); stop_tick = vp8_get_high_res_timer_tick(); if (pbi) tab->post_proc4time = vp8_get_time_in_micro_sec(start_tick, stop_tick); } else if (pp > 0 && tab->post_proc2time < microseconds_available) { vp8_deblock(common->frame_to_show, &common->post_proc_buffer, q , 1, 0); stop_tick = vp8_get_high_res_timer_tick(); if (pbi) tab->post_proc2time = vp8_get_time_in_micro_sec(start_tick, stop_tick); } else { vp8_yv12_copy_frame(common->frame_to_show, &common->post_proc_buffer); } } vp8_clear_system_state(); if (tab->add_noise == 1) { vp8_plane_add_noise(common->post_proc_buffer.y_buffer, common->post_proc_buffer.y_width, common->post_proc_buffer.y_height, common->post_proc_buffer.y_stride, 63 - q, noise); } if (show_text == 1) { #ifdef PACKET_TESTING { VP8_HEADER *oh2 = (VP8_HEADER *) pbi->Source; sprintf(message, "%8d %d%d%d%d%d size:%d\n", oh2->frame_number , oh2->update_gold , oh2->update_last , oh2->uses_gold , oh2->uses_last , oh2->type, vpxdxv_get_ximage_csize(src)); } #else sprintf(message, "F:%1ldG:%1ldQ:%3ldF:%3ld,%3ldP:%d_s:%6ld,N:%d,", (common->frame_type == KEY_FRAME), common->refresh_golden_frame, common->base_qindex, common->filter_level, q, tab->postproc, vpxdxv_get_ximage_csize(src), noise); #endif vp8_blit_text(message, common->post_proc_buffer.y_buffer, common->post_proc_buffer.y_stride); } else if (show_text == 2) { int i, j; unsigned char *y_ptr; YV12_BUFFER_CONFIG *post = &common->post_proc_buffer; int mb_rows = post->y_height >> 4; int mb_cols = post->y_width >> 4; int mb_index = 0; MODE_INFO *mi = common->mi; y_ptr = post->y_buffer + 4 * post->y_stride + 4; // vp8_filter each macro block for (i = 0; i < mb_rows; i++) { for (j = 0; j < mb_cols; j++) { char zz[4]; if (pp == 4) sprintf(zz, "%c", mi[mb_index].mbmi.mode + 'a'); else sprintf(zz, "%c", mi[mb_index].mbmi.ref_frame + 'a'); vp8_blit_text(zz, y_ptr, post->y_stride); mb_index ++; y_ptr += 16; } mb_index ++; //border y_ptr += post->y_stride * 16 - post->y_width; } } else if (show_text == 3) { int i, j; unsigned char *y_ptr; YV12_BUFFER_CONFIG *post = &common->post_proc_buffer; int mb_rows = post->y_height >> 4; int mb_cols = post->y_width >> 4; int mb_index = 0; MODE_INFO *mi = common->mi; y_ptr = post->y_buffer + 4 * post->y_stride + 4; // vp8_filter each macro block for (i = 0; i < mb_rows; i++) { for (j = 0; j < mb_cols; j++) { char zz[4]; if (j == 0) sprintf(zz, "%c", '0' + i % 10); else sprintf(zz, "%c", '0' + j % 10); vp8_blit_text(zz, y_ptr, post->y_stride); mb_index ++; y_ptr += 16; } y_ptr += post->y_stride * 16 - post->y_width; } }