| @@ -400,6 +400,21 @@ static void mt_decode_mb_rows(VP8D_COMP *pbi, MACROBLOCKD *xd, · 399 unmodified lines |
| 400 | xd->dst.u_buffer = dst_buffer[1] + recon_uvoffset; | 400 | xd->dst.u_buffer = dst_buffer[1] + recon_uvoffset; |
| 401 | xd->dst.v_buffer = dst_buffer[2] + recon_uvoffset; | 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 | xd->pre.y_buffer = | 418 | xd->pre.y_buffer = |
| 404 | ref_buffer[xd->mode_info_context->mbmi.ref_frame][0] + recon_yoffset; | 419 | ref_buffer[xd->mode_info_context->mbmi.ref_frame][0] + recon_yoffset; |
| 405 | xd->pre.u_buffer = | 420 | xd->pre.u_buffer = |
| @@ -407,9 +422,6 @@ static void mt_decode_mb_rows(VP8D_COMP *pbi, MACROBLOCKD *xd, · 1 unmodified line |
| 407 | xd->pre.v_buffer = | 422 | xd->pre.v_buffer = |
| 408 | ref_buffer[xd->mode_info_context->mbmi.ref_frame][2] + recon_uvoffset; | 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 | mt_decode_macroblock(pbi, xd, 0); | 425 | mt_decode_macroblock(pbi, xd, 0); |
| 414 | | 426 | |
| 415 | xd->left_available = 1; | 427 | xd->left_available = 1; |
| @@ -557,8 +569,9 @@ static void mt_decode_mb_rows(VP8D_COMP *pbi, MACROBLOCKD *xd, · 141 unmodified lines |
| 557 | xd->mode_info_context += xd->mode_info_stride * pbi->decoding_thread_count; | 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 */ | 572 | /* signal end of decoding of current thread for current frame */ |
| 561 | if (last_mb_row == (pc->mb_rows - 1)) sem_post(&pbi->h_event_end_decoding); | 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 | static THREAD_FUNCTION thread_decoding_proc(void *p_data) { | 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 | } else { | 589 | } else { |
| 577 | MACROBLOCKD *xd = &mbrd->mbd; | 590 | MACROBLOCKD *xd = &mbrd->mbd; |
| 578 | xd->left_context = &mb_row_left_context; | 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 | mt_decode_mb_rows(pbi, xd, ithread + 1); | 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 | VP8_COMMON *pc = &pbi->common; | 832 | VP8_COMMON *pc = &pbi->common; |
| 814 | unsigned int i; | 833 | unsigned int i; |
| 815 | int j; | 834 | int j; |
| @@ -855,7 +874,22 @@ void vp8mt_decode_mb_rows(VP8D_COMP *pbi, MACROBLOCKD *xd) { · 39 unmodified lines |
| 855 | sem_post(&pbi->h_event_start_decoding[i]); | 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 | mt_decode_mb_rows(pbi, xd, 0); | 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 | } |