1 /* 2 * Copyright (c) 2010 The WebM project authors. All Rights Reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 #include "vp8/common/onyxc_int.h" 12 #if CONFIG_POSTPROC 13 #include "vp8/common/postproc.h" 14 #endif 15 #include "vp8/common/onyxd.h" 16 #include "onyxd_int.h" 17 #include "vpx_mem/vpx_mem.h" 18 #include "vp8/common/alloccommon.h" 19 #include "vp8/common/loopfilter.h" 20 #include "vp8/common/swapyv12buffer.h" 21 #include "vp8/common/threading.h" 22 #include "decoderthreading.h" 23 #include <stdio.h> 24 #include <assert.h> 25 26 #include "vp8/common/quant_common.h" 27 #include "vp8/common/reconintra.h" 28 #include "./vpx_dsp_rtcd.h" 29 #include "./vpx_scale_rtcd.h" 30 #include "vpx_scale/vpx_scale.h" 31 #include "vp8/common/systemdependent.h" 32 #include "vpx_ports/system_state.h" 33 #include "vpx_ports/vpx_once.h" 34 #include "vpx_ports/vpx_timer.h" 35 #include "detokenize.h" 36 #if CONFIG_ERROR_CONCEALMENT 37 #include "error_concealment.h" 38 #endif 39 #if ARCH_ARM 40 #include "vpx_ports/arm.h" 41 #endif 42 43 extern void vp8_init_loop_filter(VP8_COMMON *cm); 44 static int get_free_fb(VP8_COMMON *cm); 45 static void ref_cnt_fb(int *buf, int *idx, int new_idx); 46 47 static void initialize_dec(void) { 48 static volatile int init_done = 0; 49 50 if (!init_done) { 51 vpx_dsp_rtcd(); 52 vp8_init_intra_predictors(); 53 init_done = 1; 54 } 55 } 56 57 static void remove_decompressor(VP8D_COMP *pbi) { 58 #if CONFIG_ERROR_CONCEALMENT 59 vp8_de_alloc_overlap_lists(pbi); 60 #endif 61 vp8_remove_common(&pbi->common); 62 vpx_free(pbi); 63 } 64 65 static struct VP8D_COMP *create_decompressor(VP8D_CONFIG *oxcf) { 66 VP8D_COMP *pbi = vpx_memalign(32, sizeof(VP8D_COMP)); 67 68 if (!pbi) return NULL; 69 70 memset(pbi, 0, sizeof(VP8D_COMP)); 71 72 if (setjmp(pbi->common.error.jmp)) { 73 pbi->common.error.setjmp = 0; 74 remove_decompressor(pbi); 75 return 0; 76 } 77 78 pbi->common.error.setjmp = 1; 79 80 vp8_create_common(&pbi->common); 81 82 pbi->common.current_video_frame = 0; 83 pbi->ready_for_new_data = 1; 84 85 /* vp8cx_init_de_quantizer() is first called here. Add check in 86 * frame_init_dequantizer() to avoid 87 * unnecessary calling of vp8cx_init_de_quantizer() for every frame. 88 */ 89 vp8cx_init_de_quantizer(pbi); 90 91 vp8_loop_filter_init(&pbi->common); 92 93 pbi->common.error.setjmp = 0; 94 95 #if CONFIG_ERROR_CONCEALMENT 96 pbi->ec_enabled = oxcf->error_concealment; 97 pbi->overlaps = NULL; 98 #else 99 (void)oxcf; 100 pbi->ec_enabled = 0; 101 #endif 102 /* Error concealment is activated after a key frame has been 103 * decoded without errors when error concealment is enabled. 104 */ 105 pbi->ec_active = 0; 106 107 pbi->decoded_key_frame = 0; 108 109 /* Independent partitions is activated when a frame updates the 110 * token probability table to have equal probabilities over the 111 * PREV_COEF context. 112 */ 113 pbi->independent_partitions = 0; 114 115 vp8_setup_block_dptrs(&pbi->mb); 116 117 once(initialize_dec); 118 119 return pbi; 120 } 121 122 vpx_codec_err_t vp8dx_get_reference(VP8D_COMP *pbi, 123 enum vpx_ref_frame_type ref_frame_flag, 124 YV12_BUFFER_CONFIG *sd) { 125 VP8_COMMON *cm = &pbi->common; 126 int ref_fb_idx; 127 128 if (ref_frame_flag == VP8_LAST_FRAME) { 129 ref_fb_idx = cm->lst_fb_idx; 130 } else if (ref_frame_flag == VP8_GOLD_FRAME) { 131 ref_fb_idx = cm->gld_fb_idx; 132 } else if (ref_frame_flag == VP8_ALTR_FRAME) { 133 ref_fb_idx = cm->alt_fb_idx; 134 } else { 135 vpx_internal_error(&pbi->common.error, VPX_CODEC_ERROR, 136 "Invalid reference frame"); 137 return pbi->common.error.error_code; 138 } 139 140 if (cm->yv12_fb[ref_fb_idx].y_height != sd->y_height || 141 cm->yv12_fb[ref_fb_idx].y_width != sd->y_width || 142 cm->yv12_fb[ref_fb_idx].uv_height != sd->uv_height || 143 cm->yv12_fb[ref_fb_idx].uv_width != sd->uv_width) { 144 vpx_internal_error(&pbi->common.error, VPX_CODEC_ERROR, 145 "Incorrect buffer dimensions"); 146 } else 147 vp8_yv12_copy_frame(&cm->yv12_fb[ref_fb_idx], sd); 148 149 return pbi->common.error.error_code; 150 } 151 152 vpx_codec_err_t vp8dx_set_reference(VP8D_COMP *pbi, 153 enum vpx_ref_frame_type ref_frame_flag, 154 YV12_BUFFER_CONFIG *sd) { 155 VP8_COMMON *cm = &pbi->common; 156 int *ref_fb_ptr = NULL; 157 int free_fb; 158 159 if (ref_frame_flag == VP8_LAST_FRAME) { 160 ref_fb_ptr = &cm->lst_fb_idx; 161 } else if (ref_frame_flag == VP8_GOLD_FRAME) { 162 ref_fb_ptr = &cm->gld_fb_idx; 163 } else if (ref_frame_flag == VP8_ALTR_FRAME) { 164 ref_fb_ptr = &cm->alt_fb_idx; 165 } else { 166 vpx_internal_error(&pbi->common.error, VPX_CODEC_ERROR, 167 "Invalid reference frame"); 168 return pbi->common.error.error_code; 169 } 170 171 if (cm->yv12_fb[*ref_fb_ptr].y_height != sd->y_height || 172 cm->yv12_fb[*ref_fb_ptr].y_width != sd->y_width || 173 cm->yv12_fb[*ref_fb_ptr].uv_height != sd->uv_height || 174 cm->yv12_fb[*ref_fb_ptr].uv_width != sd->uv_width) { 175 vpx_internal_error(&pbi->common.error, VPX_CODEC_ERROR, 176 "Incorrect buffer dimensions"); 177 } else { 178 /* Find an empty frame buffer. */ 179 free_fb = get_free_fb(cm); 180 /* Decrease fb_idx_ref_cnt since it will be increased again in 181 * ref_cnt_fb() below. */ 182 cm->fb_idx_ref_cnt[free_fb]--; 183 184 /* Manage the reference counters and copy image. */ 185 ref_cnt_fb(cm->fb_idx_ref_cnt, ref_fb_ptr, free_fb); 186 vp8_yv12_copy_frame(sd, &cm->yv12_fb[*ref_fb_ptr]); 187 } 188 189 return pbi->common.error.error_code; 190 } 191 192 static int get_free_fb(VP8_COMMON *cm) { 193 int i; 194 for (i = 0; i < NUM_YV12_BUFFERS; ++i) { 195 if (cm->fb_idx_ref_cnt[i] == 0) break; 196 } 197 198 assert(i < NUM_YV12_BUFFERS); 199 cm->fb_idx_ref_cnt[i] = 1; 200 return i; 201 } 202 203 static void ref_cnt_fb(int *buf, int *idx, int new_idx) { 204 if (buf[*idx] > 0) buf[*idx]--; 205 206 *idx = new_idx; 207 208 buf[new_idx]++; 209 } 210 211 /* If any buffer copy / swapping is signalled it should be done here. */ 212 static int swap_frame_buffers(VP8_COMMON *cm) { 213 int err = 0; 214 215 /* The alternate reference frame or golden frame can be updated 216 * using the new, last, or golden/alt ref frame. If it 217 * is updated using the newly decoded frame it is a refresh. 218 * An update using the last or golden/alt ref frame is a copy. 219 */ 220 if (cm->copy_buffer_to_arf) { 221 int new_fb = 0; 222 223 if (cm->copy_buffer_to_arf == 1) { 224 new_fb = cm->lst_fb_idx; 225 } else if (cm->copy_buffer_to_arf == 2) { 226 new_fb = cm->gld_fb_idx; 227 } else { 228 err = -1; 229 } 230 231 ref_cnt_fb(cm->fb_idx_ref_cnt, &cm->alt_fb_idx, new_fb); 232 } 233 234 if (cm->copy_buffer_to_gf) { 235 int new_fb = 0; 236 237 if (cm->copy_buffer_to_gf == 1) { 238 new_fb = cm->lst_fb_idx; 239 } else if (cm->copy_buffer_to_gf == 2) { 240 new_fb = cm->alt_fb_idx; 241 } else { 242 err = -1; 243 } 244 245 ref_cnt_fb(cm->fb_idx_ref_cnt, &cm->gld_fb_idx, new_fb); 246 } 247 248 if (cm->refresh_golden_frame) { 249 ref_cnt_fb(cm->fb_idx_ref_cnt, &cm->gld_fb_idx, cm->new_fb_idx); 250 } 251 252 if (cm->refresh_alt_ref_frame) { 253 ref_cnt_fb(cm->fb_idx_ref_cnt, &cm->alt_fb_idx, cm->new_fb_idx); 254 } 255 256 if (cm->refresh_last_frame) { 257 ref_cnt_fb(cm->fb_idx_ref_cnt, &cm->lst_fb_idx, cm->new_fb_idx); 258 259 cm->frame_to_show = &cm->yv12_fb[cm->lst_fb_idx]; 260 } else { 261 cm->frame_to_show = &cm->yv12_fb[cm->new_fb_idx]; 262 } 263 264 cm->fb_idx_ref_cnt[cm->new_fb_idx]--; 265 266 return err; 267 } 268 269 static int check_fragments_for_errors(VP8D_COMP *pbi) { 270 if (!pbi->ec_active && pbi->fragments.count <= 1 && 271 pbi->fragments.sizes[0] == 0) { 272 VP8_COMMON *cm = &pbi->common; 273 274 /* If error concealment is disabled we won't signal missing frames 275 * to the decoder. 276 */ 277 if (cm->fb_idx_ref_cnt[cm->lst_fb_idx] > 1) { 278 /* The last reference shares buffer with another reference 279 * buffer. Move it to its own buffer before setting it as 280 * corrupt, otherwise we will make multiple buffers corrupt. 281 */ 282 const int prev_idx = cm->lst_fb_idx; 283 cm->fb_idx_ref_cnt[prev_idx]--; 284 cm->lst_fb_idx = get_free_fb(cm); 285 vp8_yv12_copy_frame(&cm->yv12_fb[prev_idx], &cm->yv12_fb[cm->lst_fb_idx]); 286 } 287 /* This is used to signal that we are missing frames. 288 * We do not know if the missing frame(s) was supposed to update 289 * any of the reference buffers, but we act conservative and 290 * mark only the last buffer as corrupted. 291 */ 292 cm->yv12_fb[cm->lst_fb_idx].corrupted = 1; 293 294 /* Signal that we have no frame to show. */ 295 cm->show_frame = 0; 296 297 /* Nothing more to do. */ 298 return 0; 299 } 300 301 return 1; 302 } 303 304 int vp8dx_receive_compressed_data(VP8D_COMP *pbi, size_t size, 305 const uint8_t *source, int64_t time_stamp) { 306 VP8_COMMON *cm = &pbi->common; 307 int retcode = -1; 308 (void)size; 309 (void)source; 310 311 pbi->common.error.error_code = VPX_CODEC_OK; 312 313 retcode = check_fragments_for_errors(pbi); 314 if (retcode <= 0) return retcode; 315 316 cm->new_fb_idx = get_free_fb(cm); 317 318 /* setup reference frames for vp8_decode_frame */ 319 pbi->dec_fb_ref[INTRA_FRAME] = &cm->yv12_fb[cm->new_fb_idx]; 320 pbi->dec_fb_ref[LAST_FRAME] = &cm->yv12_fb[cm->lst_fb_idx]; 321 pbi->dec_fb_ref[GOLDEN_FRAME] = &cm->yv12_fb[cm->gld_fb_idx]; 322 pbi->dec_fb_ref[ALTREF_FRAME] = &cm->yv12_fb[cm->alt_fb_idx]; 323 324 if (setjmp(pbi->common.error.jmp)) { 325 /* We do not know if the missing frame(s) was supposed to update 326 * any of the reference buffers, but we act conservative and 327 * mark only the last buffer as corrupted. 328 */ 329 cm->yv12_fb[cm->lst_fb_idx].corrupted = 1; 330 331 if (cm->fb_idx_ref_cnt[cm->new_fb_idx] > 0) { 332 cm->fb_idx_ref_cnt[cm->new_fb_idx]--; 333 } 334 goto decode_exit; 335 } 336 337 pbi->common.error.setjmp = 1; 338 339 retcode = vp8_decode_frame(pbi); 340 341 if (retcode < 0) { 342 if (cm->fb_idx_ref_cnt[cm->new_fb_idx] > 0) { 343 cm->fb_idx_ref_cnt[cm->new_fb_idx]--; 344 } 345 346 pbi->common.error.error_code = VPX_CODEC_ERROR; 347 goto decode_exit; 348 } 349 350 if (swap_frame_buffers(cm)) { 351 pbi->common.error.error_code = VPX_CODEC_ERROR; 352 goto decode_exit; 353 } 354 355 vpx_clear_system_state(); 356 357 if (cm->show_frame) { 358 cm->current_video_frame++; 359 cm->show_frame_mi = cm->mi; 360 } 361 362 #if CONFIG_ERROR_CONCEALMENT 363 /* swap the mode infos to storage for future error concealment */ 364 if (pbi->ec_enabled && pbi->common.prev_mi) { 365 MODE_INFO *tmp = pbi->common.prev_mi; 366 int row, col; 367 pbi->common.prev_mi = pbi->common.mi; 368 pbi->common.mi = tmp; 369 370 /* Propagate the segment_ids to the next frame */ 371 for (row = 0; row < pbi->common.mb_rows; ++row) { 372 for (col = 0; col < pbi->common.mb_cols; ++col) { 373 const int i = row * pbi->common.mode_info_stride + col; 374 pbi->common.mi[i].mbmi.segment_id = 375 pbi->common.prev_mi[i].mbmi.segment_id; 376 } 377 } 378 } 379 #endif 380 381 pbi->ready_for_new_data = 0; 382 pbi->last_time_stamp = time_stamp; 383 384 decode_exit: 385 pbi->common.error.setjmp = 0; 386 vpx_clear_system_state(); 387 return retcode; 388 } 389 int vp8dx_get_raw_frame(VP8D_COMP *pbi, YV12_BUFFER_CONFIG *sd, 390 int64_t *time_stamp, int64_t *time_end_stamp, 391 vp8_ppflags_t *flags) { 392 int ret = -1; 393 394 if (pbi->ready_for_new_data == 1) return ret; 395 396 /* ie no raw frame to show!!! */ 397 if (pbi->common.show_frame == 0) return ret; 398 399 pbi->ready_for_new_data = 1; 400 *time_stamp = pbi->last_time_stamp; 401 *time_end_stamp = 0; 402 403 #if CONFIG_POSTPROC 404 ret = vp8_post_proc_frame(&pbi->common, sd, flags); 405 #else 406 (void)flags; 407 408 if (pbi->common.frame_to_show) { 409 *sd = *pbi->common.frame_to_show; 410 sd->y_width = pbi->common.Width; 411 sd->y_height = pbi->common.Height; 412 sd->uv_height = pbi->common.Height / 2; 413 ret = 0; 414 } else { 415 ret = -1; 416 } 417 418 #endif /*!CONFIG_POSTPROC*/ 419 vpx_clear_system_state(); 420 return ret; 421 } 422 423 /* This function as written isn't decoder specific, but the encoder has 424 * much faster ways of computing this, so it's ok for it to live in a 425 * decode specific file. 426 */ 427 int vp8dx_references_buffer(VP8_COMMON *oci, int ref_frame) { 428 const MODE_INFO *mi = oci->mi; 429 int mb_row, mb_col; 430 431 for (mb_row = 0; mb_row < oci->mb_rows; ++mb_row) { 432 for (mb_col = 0; mb_col < oci->mb_cols; mb_col++, mi++) { 433 if (mi->mbmi.ref_frame == ref_frame) return 1; 434 } 435 mi++; 436 } 437 return 0; 438 } 439 440 int vp8_create_decoder_instances(struct frame_buffers *fb, VP8D_CONFIG *oxcf) { 441 /* decoder instance for single thread mode */ 442 fb->pbi[0] = create_decompressor(oxcf); 443 if (!fb->pbi[0]) return VPX_CODEC_ERROR; 444 445 #if CONFIG_MULTITHREAD 446 if (setjmp(fb->pbi[0]->common.error.jmp)) { 447 vp8_remove_decoder_instances(fb); 448 memset(fb->pbi, 0, sizeof(fb->pbi)); 449 vpx_clear_system_state(); 450 return VPX_CODEC_ERROR; 451 } 452 453 fb->pbi[0]->common.error.setjmp = 1; 454 fb->pbi[0]->max_threads = oxcf->max_threads; 455 vp8_decoder_create_threads(fb->pbi[0]); 456 fb->pbi[0]->common.error.setjmp = 0; 457 #endif 458 return VPX_CODEC_OK; 459 } 460 461 int vp8_remove_decoder_instances(struct frame_buffers *fb) { 462 VP8D_COMP *pbi = fb->pbi[0]; 463 464 if (!pbi) return VPX_CODEC_ERROR; 465 #if CONFIG_MULTITHREAD 466 vp8_decoder_remove_threads(pbi); 467 #endif 468 469 /* decoder instance for single thread mode */ 470 remove_decompressor(pbi); 471 return VPX_CODEC_OK; 472 } 473 474 int vp8dx_get_quantizer(const VP8D_COMP *cpi) { 475 return cpi->common.base_qindex; 476 } 477