| @@ -400,6 +400,21 @@ static void mt_decode_mb_rows(VP8D_COMP *pbi, MACROBLOCKD *xd, · 399 unmodified lines |
| 400 | 400 | xd->dst.u_buffer = dst_buffer[1] + recon_uvoffset; |
| 401 | 401 | xd->dst.v_buffer = dst_buffer[2] + recon_uvoffset; |
| 402 | 402 | |
| 403 | + /* propagate errors from reference frames */ |
| 404 | + xd->corrupted |= ref_fb_corrupted[xd->mode_info_context->mbmi.ref_frame]; |
| 405 | + |
| 406 | + if (xd->corrupted) { |
| 407 | + // Move current decoding marcoblock to the end of row for all rows |
| 408 | + // assigned to this thread, such that other threads won't be waiting. |
| 409 | + for (; mb_row < pc->mb_rows; |
| 410 | + mb_row += (pbi->decoding_thread_count + 1)) { |
| 411 | + current_mb_col = &pbi->mt_current_mb_col[mb_row]; |
| 412 | + vpx_atomic_store_release(current_mb_col, pc->mb_cols + nsync); |
| 413 | + } |
| 414 | + vpx_internal_error(&xd->error_info, VPX_CODEC_CORRUPT_FRAME, |
| 415 | + "Corrupted reference frame"); |
| 416 | + } |
| 417 | + |
| 403 | 418 | xd->pre.y_buffer = |
| 404 | 419 | ref_buffer[xd->mode_info_context->mbmi.ref_frame][0] + recon_yoffset; |
| 405 | 420 | xd->pre.u_buffer = |
| @@ -407,9 +422,6 @@ static void mt_decode_mb_rows(VP8D_COMP *pbi, MACROBLOCKD *xd, · 1 unmodified line |
| 407 | 422 | xd->pre.v_buffer = |
| 408 | 423 | ref_buffer[xd->mode_info_context->mbmi.ref_frame][2] + recon_uvoffset; |
| 409 | 424 | |
| 410 | | − /* propagate errors from reference frames */ |
| 411 | | − xd->corrupted |= ref_fb_corrupted[xd->mode_info_context->mbmi.ref_frame]; |
| 412 | | − |
| 413 | 425 | mt_decode_macroblock(pbi, xd, 0); |
| 414 | 426 | |
| 415 | 427 | xd->left_available = 1; |
| @@ -557,8 +569,9 @@ static void mt_decode_mb_rows(VP8D_COMP *pbi, MACROBLOCKD *xd, · 141 unmodified lines |
| 557 | 569 | xd->mode_info_context += xd->mode_info_stride * pbi->decoding_thread_count; |
| 558 | 570 | } |
| 559 | 571 | |
| 560 | | − /* signal end of frame decoding if this thread processed the last mb_row */ |
| 561 | | − if (last_mb_row == (pc->mb_rows - 1)) sem_post(&pbi->h_event_end_decoding); |
| 572 | + /* signal end of decoding of current thread for current frame */ |
| 573 | + if (last_mb_row + (int)pbi->decoding_thread_count + 1 >= pc->mb_rows) |
| 574 | + sem_post(&pbi->h_event_end_decoding); |
| 562 | 575 | } |
| 563 | 576 | |
| 564 | 577 | static THREAD_FUNCTION thread_decoding_proc(void *p_data) { |
| @@ -576,7 +589,13 @@ static THREAD_FUNCTION thread_decoding_proc(void *p_data) { · 11 unmodified lines |
| 576 | 589 | } else { |
| 577 | 590 | MACROBLOCKD *xd = &mbrd->mbd; |
| 578 | 591 | xd->left_context = &mb_row_left_context; |
| 579 | | − |
| 592 | + if (setjmp(xd->error_info.jmp)) { |
| 593 | + xd->error_info.setjmp = 0; |
| 594 | + // Signal the end of decoding for current thread. |
| 595 | + sem_post(&pbi->h_event_end_decoding); |
| 596 | + continue; |
| 597 | + } |
| 598 | + xd->error_info.setjmp = 1; |
| 580 | 599 | mt_decode_mb_rows(pbi, xd, ithread + 1); |
| 581 | 600 | } |
| 582 | 601 | } |
| @@ -809,7 +828,7 @@ void vp8_decoder_remove_threads(VP8D_COMP *pbi) { · 226 unmodified lines |
| 809 | 828 | } |
| 810 | 829 | } |
| 811 | 830 | |
| 812 | | −void vp8mt_decode_mb_rows(VP8D_COMP *pbi, MACROBLOCKD *xd) { |
| 831 | +int vp8mt_decode_mb_rows(VP8D_COMP *pbi, MACROBLOCKD *xd) { |
| 813 | 832 | VP8_COMMON *pc = &pbi->common; |
| 814 | 833 | unsigned int i; |
| 815 | 834 | int j; |
| @@ -855,7 +874,22 @@ void vp8mt_decode_mb_rows(VP8D_COMP *pbi, MACROBLOCKD *xd) { · 39 unmodified lines |
| 855 | 874 | sem_post(&pbi->h_event_start_decoding[i]); |
| 856 | 875 | } |
| 857 | 876 | |
| 877 | + if (setjmp(xd->error_info.jmp)) { |
| 878 | + xd->error_info.setjmp = 0; |
| 879 | + xd->corrupted = 1; |
| 880 | + // Wait for other threads to finish. This prevents other threads decoding |
| 881 | + // the current frame while the main thread starts decoding the next frame, |
| 882 | + // which causes a data race. |
| 883 | + for (i = 0; i < pbi->decoding_thread_count; ++i) |
| 884 | + sem_wait(&pbi->h_event_end_decoding); |
| 885 | + return -1; |
| 886 | + } |
| 887 | + |
| 888 | + xd->error_info.setjmp = 1; |
| 858 | 889 | mt_decode_mb_rows(pbi, xd, 0); |
| 859 | 890 | |
| 860 | | − sem_wait(&pbi->h_event_end_decoding); /* add back for each frame */ |
| 891 | + for (i = 0; i < pbi->decoding_thread_count + 1; ++i) |
| 892 | + sem_wait(&pbi->h_event_end_decoding); /* add back for each frame */ |
| 893 | + |
| 894 | + return 0; |
| 861 | 895 | } |