* Add a slice. * @param endx x component of the last macroblock, can be -1 * for the last of the previous line * @param status the status at the end (ER_MV_END, ER_AC_ERROR, ...), it is * assumed that no earlier end or error of the same type occurred */
| 838 | * assumed that no earlier end or error of the same type occurred |
| 839 | */ |
| 840 | void ff_er_add_slice(ERContext *s, int startx, int starty, |
| 841 | int endx, int endy, int status) |
| 842 | { |
| 843 | const int start_i = av_clip(startx + starty * s->mb_width, 0, s->mb_num - 1); |
| 844 | const int end_i = av_clip(endx + endy * s->mb_width, 0, s->mb_num); |
| 845 | const int start_xy = s->mb_index2xy[start_i]; |
| 846 | const int end_xy = s->mb_index2xy[end_i]; |
| 847 | int mask = -1; |
| 848 | |
| 849 | if (s->avctx->hwaccel) |
| 850 | return; |
| 851 | |
| 852 | if (start_i > end_i || start_xy > end_xy) { |
| 853 | av_log(s->avctx, AV_LOG_ERROR, |
| 854 | "internal error, slice end before start\n"); |
| 855 | return; |
| 856 | } |
| 857 | |
| 858 | if (!s->avctx->error_concealment) |
| 859 | return; |
| 860 | |
| 861 | mask &= ~VP_START; |
| 862 | if (status & (ER_AC_ERROR | ER_AC_END)) { |
| 863 | mask &= ~(ER_AC_ERROR | ER_AC_END); |
| 864 | atomic_fetch_add(&s->error_count, start_i - end_i - 1); |
| 865 | } |
| 866 | if (status & (ER_DC_ERROR | ER_DC_END)) { |
| 867 | mask &= ~(ER_DC_ERROR | ER_DC_END); |
| 868 | atomic_fetch_add(&s->error_count, start_i - end_i - 1); |
| 869 | } |
| 870 | if (status & (ER_MV_ERROR | ER_MV_END)) { |
| 871 | mask &= ~(ER_MV_ERROR | ER_MV_END); |
| 872 | atomic_fetch_add(&s->error_count, start_i - end_i - 1); |
| 873 | } |
| 874 | |
| 875 | if (status & ER_MB_ERROR) { |
| 876 | s->error_occurred = 1; |
| 877 | atomic_store(&s->error_count, INT_MAX); |
| 878 | } |
| 879 | |
| 880 | if (mask == ~0x7F) { |
| 881 | memset(&s->error_status_table[start_xy], 0, |
| 882 | (end_xy - start_xy) * sizeof(uint8_t)); |
| 883 | } else { |
| 884 | int i; |
| 885 | for (i = start_xy; i < end_xy; i++) |
| 886 | s->error_status_table[i] &= mask; |
| 887 | } |
| 888 | |
| 889 | if (end_i == s->mb_num) |
| 890 | atomic_store(&s->error_count, INT_MAX); |
| 891 | else { |
| 892 | s->error_status_table[end_xy] &= mask; |
| 893 | s->error_status_table[end_xy] |= status; |
| 894 | } |
| 895 | |
| 896 | s->error_status_table[start_xy] |= VP_START; |
| 897 |
no test coverage detected