annotate error_resilience.c @ 905:2b93dc762f9a libavcodec

fixing illegal 3. esc bug (the mpeg4 std only requires encoders to use unescaped symbols but not esc1 or esc2 if they are shorter than esc3, andjust beause its logical to use the shortest possible vlc doesnt mean encoders do that)
author michaelni
date Wed, 04 Dec 2002 11:47:24 +0000
parents 06776293eabb
children b32afefe7d33
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
745
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
1 /*
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
2 * Error resilience / concealment
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
3 *
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
4 * Copyright (c) 2002 Michael Niedermayer <michaelni@gmx.at>
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
5 *
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
6 * This library is free software; you can redistribute it and/or
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
7 * modify it under the terms of the GNU Lesser General Public
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
8 * License as published by the Free Software Foundation; either
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
9 * version 2 of the License, or (at your option) any later version.
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
10 *
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
11 * This library is distributed in the hope that it will be useful,
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
14 * Lesser General Public License for more details.
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
15 *
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
16 * You should have received a copy of the GNU Lesser General Public
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
17 * License along with this library; if not, write to the Free Software
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
19 */
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
20
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
21 #include "avcodec.h"
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
22 #include "dsputil.h"
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
23 #include "mpegvideo.h"
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
24
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
25 /**
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
26 * replaces the current MB with a flat dc only version.
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
27 */
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
28 static void put_dc(MpegEncContext *s, uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr, int mb_x, int mb_y)
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
29 {
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
30 int dc, dcu, dcv, y, i;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
31 for(i=0; i<4; i++){
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
32 dc= s->dc_val[0][mb_x*2+1 + (i&1) + (mb_y*2+1 + (i>>1))*(s->mb_width*2+2)];
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
33 if(dc<0) dc=0;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
34 else if(dc>2040) dc=2040;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
35 for(y=0; y<8; y++){
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
36 int x;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
37 for(x=0; x<8; x++){
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
38 dest_y[x + (i&1)*8 + (y + (i>>1)*8)*s->linesize]= dc/8;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
39 }
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
40 }
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
41 }
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
42 dcu = s->dc_val[1][mb_x+1 + (mb_y+1)*(s->mb_width+2)];
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
43 dcv = s->dc_val[2][mb_x+1 + (mb_y+1)*(s->mb_width+2)];
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
44 if (dcu<0 ) dcu=0;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
45 else if(dcu>2040) dcu=2040;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
46 if (dcv<0 ) dcv=0;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
47 else if(dcv>2040) dcv=2040;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
48 for(y=0; y<8; y++){
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
49 int x;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
50 for(x=0; x<8; x++){
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
51 dest_cb[x + y*(s->uvlinesize)]= dcu/8;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
52 dest_cr[x + y*(s->uvlinesize)]= dcv/8;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
53 }
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
54 }
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
55 }
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
56
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
57 static void filter181(INT16 *data, int width, int height, int stride){
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
58 int x,y;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
59
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
60 /* horizontal filter */
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
61 for(y=1; y<height-1; y++){
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
62 int prev_dc= data[0 + y*stride];
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
63
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
64 for(x=1; x<width-1; x++){
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
65 int dc;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
66
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
67 dc= - prev_dc
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
68 + data[x + y*stride]*8
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
69 - data[x + 1 + y*stride];
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
70 dc= (dc*10923 + 32768)>>16;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
71 prev_dc= data[x + y*stride];
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
72 data[x + y*stride]= dc;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
73 }
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
74 }
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
75
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
76 /* vertical filter */
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
77 for(x=1; x<width-1; x++){
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
78 int prev_dc= data[x];
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
79
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
80 for(y=1; y<height-1; y++){
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
81 int dc;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
82
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
83 dc= - prev_dc
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
84 + data[x + y *stride]*8
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
85 - data[x + (y+1)*stride];
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
86 dc= (dc*10923 + 32768)>>16;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
87 prev_dc= data[x + y*stride];
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
88 data[x + y*stride]= dc;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
89 }
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
90 }
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
91 }
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
92
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
93 /**
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
94 * guess the dc of blocks which dont have a undamaged dc
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
95 * @param w width in 8 pixel blocks
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
96 * @param h height in 8 pixel blocks
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
97 */
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
98 static void guess_dc(MpegEncContext *s, INT16 *dc, int w, int h, int stride, int is_luma){
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
99 int b_x, b_y;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
100
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
101 for(b_y=0; b_y<h; b_y++){
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
102 for(b_x=0; b_x<w; b_x++){
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
103 int color[4]={1024,1024,1024,1024};
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
104 int distance[4]={9999,9999,9999,9999};
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
105 int mb_index, error, j;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
106 INT64 guess, weight_sum;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
107
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
108 mb_index= (b_x>>is_luma) + (b_y>>is_luma)*s->mb_width;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
109
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
110 error= s->error_status_table[mb_index];
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
111
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
112 if(!(s->mb_type[mb_index]&MB_TYPE_INTRA)) continue; //inter
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
113 if(!(error&DC_ERROR)) continue; //dc-ok
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
114
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
115 /* right block */
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
116 for(j=b_x+1; j<w; j++){
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
117 int mb_index_j= (j>>is_luma) + (b_y>>is_luma)*s->mb_width;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
118 int error_j= s->error_status_table[mb_index_j];
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
119 int intra_j= s->mb_type[mb_index_j]&MB_TYPE_INTRA;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
120 if(intra_j==0 || !(error_j&DC_ERROR)){
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
121 color[0]= dc[j + b_y*stride];
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
122 distance[0]= j-b_x;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
123 break;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
124 }
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
125 }
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
126
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
127 /* left block */
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
128 for(j=b_x-1; j>=0; j--){
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
129 int mb_index_j= (j>>is_luma) + (b_y>>is_luma)*s->mb_width;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
130 int error_j= s->error_status_table[mb_index_j];
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
131 int intra_j= s->mb_type[mb_index_j]&MB_TYPE_INTRA;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
132 if(intra_j==0 || !(error_j&DC_ERROR)){
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
133 color[1]= dc[j + b_y*stride];
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
134 distance[1]= b_x-j;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
135 break;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
136 }
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
137 }
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
138
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
139 /* bottom block */
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
140 for(j=b_y+1; j<h; j++){
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
141 int mb_index_j= (b_x>>is_luma) + (j>>is_luma)*s->mb_width;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
142 int error_j= s->error_status_table[mb_index_j];
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
143 int intra_j= s->mb_type[mb_index_j]&MB_TYPE_INTRA;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
144 if(intra_j==0 || !(error_j&DC_ERROR)){
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
145 color[2]= dc[b_x + j*stride];
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
146 distance[2]= j-b_y;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
147 break;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
148 }
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
149 }
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
150
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
151 /* top block */
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
152 for(j=b_y-1; j>=0; j--){
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
153 int mb_index_j= (b_x>>is_luma) + (j>>is_luma)*s->mb_width;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
154 int error_j= s->error_status_table[mb_index_j];
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
155 int intra_j= s->mb_type[mb_index_j]&MB_TYPE_INTRA;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
156 if(intra_j==0 || !(error_j&DC_ERROR)){
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
157 color[3]= dc[b_x + j*stride];
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
158 distance[3]= b_y-j;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
159 break;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
160 }
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
161 }
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
162
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
163 weight_sum=0;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
164 guess=0;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
165 for(j=0; j<4; j++){
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
166 INT64 weight= 256*256*256*16/distance[j];
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
167 guess+= weight*(INT64)color[j];
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
168 weight_sum+= weight;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
169 }
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
170 guess= (guess + weight_sum/2) / weight_sum;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
171
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
172 dc[b_x + b_y*stride]= guess;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
173 }
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
174 }
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
175 }
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
176
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
177 /**
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
178 * simple horizontal deblocking filter used for error resilience
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
179 * @param w width in 8 pixel blocks
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
180 * @param h height in 8 pixel blocks
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
181 */
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
182 static void h_block_filter(MpegEncContext *s, UINT8 *dst, int w, int h, int stride, int is_luma){
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
183 int b_x, b_y;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
184 UINT8 *cm = cropTbl + MAX_NEG_CROP;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
185
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
186 for(b_y=0; b_y<h; b_y++){
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
187 for(b_x=0; b_x<w-1; b_x++){
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
188 int y;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
189 int left_status = s->error_status_table[( b_x >>is_luma) + (b_y>>is_luma)*s->mb_width];
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
190 int right_status= s->error_status_table[((b_x+1)>>is_luma) + (b_y>>is_luma)*s->mb_width];
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
191 int left_intra= s->mb_type [( b_x >>is_luma) + (b_y>>is_luma)*s->mb_width]&MB_TYPE_INTRA;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
192 int right_intra= s->mb_type [((b_x+1)>>is_luma) + (b_y>>is_luma)*s->mb_width]&MB_TYPE_INTRA;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
193 int left_damage = left_status&(DC_ERROR|AC_ERROR|MV_ERROR);
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
194 int right_damage= right_status&(DC_ERROR|AC_ERROR|MV_ERROR);
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
195 int offset= b_x*8 + b_y*stride*8;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
196 INT16 *left_mv= s->motion_val[s->block_wrap[0]*((b_y<<(1-is_luma)) + 1) + ( b_x <<(1-is_luma))];
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
197 INT16 *right_mv= s->motion_val[s->block_wrap[0]*((b_y<<(1-is_luma)) + 1) + ((b_x+1)<<(1-is_luma))];
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
198
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
199 if(!(left_damage||right_damage)) continue; // both undamaged
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
200
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
201 if( (!left_intra) && (!right_intra)
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
202 && ABS(left_mv[0]-right_mv[0]) + ABS(left_mv[1]+right_mv[1]) < 2) continue;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
203
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
204 for(y=0; y<8; y++){
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
205 int a,b,c,d;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
206
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
207 a= dst[offset + 7 + y*stride] - dst[offset + 6 + y*stride];
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
208 b= dst[offset + 8 + y*stride] - dst[offset + 7 + y*stride];
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
209 c= dst[offset + 9 + y*stride] - dst[offset + 8 + y*stride];
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
210
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
211 d= ABS(b) - ((ABS(a) + ABS(c) + 1)>>1);
847
f3c369b8ddca reversing header game
michaelni
parents: 745
diff changeset
212 d= FFMAX(d, 0);
745
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
213 if(b<0) d= -d;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
214
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
215 if(d==0) continue;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
216
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
217 if(!(left_damage && right_damage))
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
218 d= d*16/9;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
219
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
220 if(left_damage){
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
221 dst[offset + 7 + y*stride] = cm[dst[offset + 7 + y*stride] + ((d*7)>>4)];
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
222 dst[offset + 6 + y*stride] = cm[dst[offset + 6 + y*stride] + ((d*5)>>4)];
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
223 dst[offset + 5 + y*stride] = cm[dst[offset + 5 + y*stride] + ((d*3)>>4)];
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
224 dst[offset + 4 + y*stride] = cm[dst[offset + 4 + y*stride] + ((d*1)>>4)];
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
225 }
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
226 if(right_damage){
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
227 dst[offset + 8 + y*stride] = cm[dst[offset + 8 + y*stride] - ((d*7)>>4)];
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
228 dst[offset + 9 + y*stride] = cm[dst[offset + 9 + y*stride] - ((d*5)>>4)];
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
229 dst[offset + 10+ y*stride] = cm[dst[offset +10 + y*stride] - ((d*3)>>4)];
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
230 dst[offset + 11+ y*stride] = cm[dst[offset +11 + y*stride] - ((d*1)>>4)];
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
231 }
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
232 }
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
233 }
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
234 }
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
235 }
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
236
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
237 /**
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
238 * simple vertical deblocking filter used for error resilience
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
239 * @param w width in 8 pixel blocks
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
240 * @param h height in 8 pixel blocks
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
241 */
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
242 static void v_block_filter(MpegEncContext *s, UINT8 *dst, int w, int h, int stride, int is_luma){
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
243 int b_x, b_y;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
244 UINT8 *cm = cropTbl + MAX_NEG_CROP;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
245
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
246 for(b_y=0; b_y<h-1; b_y++){
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
247 for(b_x=0; b_x<w; b_x++){
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
248 int x;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
249 int top_status = s->error_status_table[(b_x>>is_luma) + ( b_y >>is_luma)*s->mb_width];
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
250 int bottom_status= s->error_status_table[(b_x>>is_luma) + ((b_y+1)>>is_luma)*s->mb_width];
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
251 int top_intra= s->mb_type [(b_x>>is_luma) + ( b_y >>is_luma)*s->mb_width]&MB_TYPE_INTRA;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
252 int bottom_intra= s->mb_type [(b_x>>is_luma) + ((b_y+1)>>is_luma)*s->mb_width]&MB_TYPE_INTRA;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
253 int top_damage = top_status&(DC_ERROR|AC_ERROR|MV_ERROR);
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
254 int bottom_damage= bottom_status&(DC_ERROR|AC_ERROR|MV_ERROR);
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
255 int offset= b_x*8 + b_y*stride*8;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
256 INT16 *top_mv= s->motion_val[s->block_wrap[0]*(( b_y <<(1-is_luma)) + 1) + (b_x<<(1-is_luma))];
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
257 INT16 *bottom_mv= s->motion_val[s->block_wrap[0]*(((b_y+1)<<(1-is_luma)) + 1) + (b_x<<(1-is_luma))];
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
258
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
259 if(!(top_damage||bottom_damage)) continue; // both undamaged
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
260
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
261 if( (!top_intra) && (!bottom_intra)
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
262 && ABS(top_mv[0]-bottom_mv[0]) + ABS(top_mv[1]+bottom_mv[1]) < 2) continue;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
263
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
264 for(x=0; x<8; x++){
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
265 int a,b,c,d;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
266
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
267 a= dst[offset + x + 7*stride] - dst[offset + x + 6*stride];
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
268 b= dst[offset + x + 8*stride] - dst[offset + x + 7*stride];
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
269 c= dst[offset + x + 9*stride] - dst[offset + x + 8*stride];
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
270
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
271 d= ABS(b) - ((ABS(a) + ABS(c)+1)>>1);
847
f3c369b8ddca reversing header game
michaelni
parents: 745
diff changeset
272 d= FFMAX(d, 0);
745
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
273 if(b<0) d= -d;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
274
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
275 if(d==0) continue;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
276
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
277 if(!(top_damage && bottom_damage))
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
278 d= d*16/9;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
279
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
280 if(top_damage){
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
281 dst[offset + x + 7*stride] = cm[dst[offset + x + 7*stride] + ((d*7)>>4)];
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
282 dst[offset + x + 6*stride] = cm[dst[offset + x + 6*stride] + ((d*5)>>4)];
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
283 dst[offset + x + 5*stride] = cm[dst[offset + x + 5*stride] + ((d*3)>>4)];
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
284 dst[offset + x + 4*stride] = cm[dst[offset + x + 4*stride] + ((d*1)>>4)];
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
285 }
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
286 if(bottom_damage){
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
287 dst[offset + x + 8*stride] = cm[dst[offset + x + 8*stride] - ((d*7)>>4)];
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
288 dst[offset + x + 9*stride] = cm[dst[offset + x + 9*stride] - ((d*5)>>4)];
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
289 dst[offset + x + 10*stride] = cm[dst[offset + x + 10*stride] - ((d*3)>>4)];
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
290 dst[offset + x + 11*stride] = cm[dst[offset + x + 11*stride] - ((d*1)>>4)];
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
291 }
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
292 }
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
293 }
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
294 }
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
295 }
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
296
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
297 static void guess_mv(MpegEncContext *s){
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
298 UINT8 fixed[s->mb_num];
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
299 #define MV_FROZEN 3
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
300 #define MV_CHANGED 2
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
301 #define MV_UNCHANGED 1
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
302 const int mb_width = s->mb_width;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
303 const int mb_height= s->mb_height;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
304 int i, depth, num_avail;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
305
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
306 num_avail=0;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
307 for(i=0; i<s->mb_num; i++){
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
308 int f=0;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
309 int error= s->error_status_table[i];
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
310
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
311 if(s->mb_type[i]&MB_TYPE_INTRA) f=MV_FROZEN; //intra //FIXME check
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
312 if(!(error&MV_ERROR)) f=MV_FROZEN; //inter with undamaged MV
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
313
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
314 fixed[i]= f;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
315 if(f==MV_FROZEN)
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
316 num_avail++;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
317 }
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
318
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
319 if((!(s->avctx->error_concealment&FF_EC_GUESS_MVS)) || num_avail <= mb_width/2){
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
320 int mb_x, mb_y;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
321 i= -1;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
322 for(mb_y=0; mb_y<s->mb_height; mb_y++){
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
323 for(mb_x=0; mb_x<s->mb_width; mb_x++){
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
324 i++;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
325
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
326 if(s->mb_type[i]&MB_TYPE_INTRA) continue;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
327 if(!(s->error_status_table[i]&MV_ERROR)) continue;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
328
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
329 s->mv_dir = MV_DIR_FORWARD;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
330 s->mb_intra=0;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
331 s->mv_type = MV_TYPE_16X16;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
332 s->mb_skiped=0;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
333
853
eacc2dd8fd9d * using DSPContext - so each codec could use its local (sub)set of CPU extension
kabi
parents: 847
diff changeset
334 s->dsp.clear_blocks(s->block[0]);
745
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
335
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
336 s->mb_x= mb_x;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
337 s->mb_y= mb_y;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
338 s->mv[0][0][0]= 0;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
339 s->mv[0][0][1]= 0;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
340 MPV_decode_mb(s, s->block);
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
341 }
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
342 }
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
343 return;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
344 }
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
345
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
346 for(depth=0;; depth++){
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
347 int changed, pass, none_left;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
348
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
349 none_left=1;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
350 changed=1;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
351 for(pass=0; (changed || pass<2) && pass<10; pass++){
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
352 int i,mb_x, mb_y;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
353 int score_sum=0;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
354
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
355 changed=0;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
356 i= -1;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
357 for(mb_y=0; mb_y<s->mb_height; mb_y++){
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
358 for(mb_x=0; mb_x<s->mb_width; mb_x++){
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
359 int mv_predictor[8][2]={{0}};
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
360 int pred_count=0;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
361 int j;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
362 int best_score=256*256*256*64;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
363 int best_pred=0;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
364 const int mot_stride= mb_width*2+2;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
365 const int mot_index= mb_x*2 + 1 + (mb_y*2+1)*mot_stride;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
366 int prev_x= s->motion_val[mot_index][0];
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
367 int prev_y= s->motion_val[mot_index][1];
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
368
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
369 i++;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
370 if((mb_x^mb_y^pass)&1) continue;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
371
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
372 if(fixed[i]==MV_FROZEN) continue;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
373
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
374 j=0;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
375 if(mb_x>0 && fixed[i-1 ]==MV_FROZEN) j=1;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
376 if(mb_x+1<mb_width && fixed[i+1 ]==MV_FROZEN) j=1;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
377 if(mb_y>0 && fixed[i-mb_width]==MV_FROZEN) j=1;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
378 if(mb_y+1<mb_height && fixed[i+mb_width]==MV_FROZEN) j=1;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
379 if(j==0) continue;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
380
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
381 j=0;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
382 if(mb_x>0 && fixed[i-1 ]==MV_CHANGED) j=1;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
383 if(mb_x+1<mb_width && fixed[i+1 ]==MV_CHANGED) j=1;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
384 if(mb_y>0 && fixed[i-mb_width]==MV_CHANGED) j=1;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
385 if(mb_y+1<mb_height && fixed[i+mb_width]==MV_CHANGED) j=1;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
386 if(j==0 && pass>1) continue;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
387
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
388 none_left=0;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
389
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
390 if(mb_x>0 && fixed[i-1]){
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
391 mv_predictor[pred_count][0]= s->motion_val[mot_index - 2][0];
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
392 mv_predictor[pred_count][1]= s->motion_val[mot_index - 2][1];
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
393 pred_count++;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
394 }
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
395 if(mb_x+1<mb_width && fixed[i+1]){
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
396 mv_predictor[pred_count][0]= s->motion_val[mot_index + 2][0];
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
397 mv_predictor[pred_count][1]= s->motion_val[mot_index + 2][1];
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
398 pred_count++;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
399 }
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
400 if(mb_y>0 && fixed[i-mb_width]){
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
401 mv_predictor[pred_count][0]= s->motion_val[mot_index - mot_stride*2][0];
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
402 mv_predictor[pred_count][1]= s->motion_val[mot_index - mot_stride*2][1];
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
403 pred_count++;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
404 }
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
405 if(mb_y+1<mb_height && fixed[i+mb_width]){
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
406 mv_predictor[pred_count][0]= s->motion_val[mot_index + mot_stride*2][0];
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
407 mv_predictor[pred_count][1]= s->motion_val[mot_index + mot_stride*2][1];
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
408 pred_count++;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
409 }
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
410 if(pred_count==0) continue;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
411
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
412 if(pred_count>1){
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
413 int sum_x=0, sum_y=0;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
414 int max_x, max_y, min_x, min_y;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
415
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
416 for(j=0; j<pred_count; j++){
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
417 sum_x+= mv_predictor[j][0];
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
418 sum_y+= mv_predictor[j][1];
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
419 }
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
420
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
421 /* mean */
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
422 mv_predictor[pred_count][0] = sum_x/j;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
423 mv_predictor[pred_count][1] = sum_y/j;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
424
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
425 /* median */
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
426 if(pred_count>=3){
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
427 min_y= min_x= 99999;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
428 max_y= max_x=-99999;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
429 }else{
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
430 min_x=min_y=max_x=max_y=0;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
431 }
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
432 for(j=0; j<pred_count; j++){
847
f3c369b8ddca reversing header game
michaelni
parents: 745
diff changeset
433 max_x= FFMAX(max_x, mv_predictor[j][0]);
f3c369b8ddca reversing header game
michaelni
parents: 745
diff changeset
434 max_y= FFMAX(max_y, mv_predictor[j][1]);
f3c369b8ddca reversing header game
michaelni
parents: 745
diff changeset
435 min_x= FFMIN(min_x, mv_predictor[j][0]);
f3c369b8ddca reversing header game
michaelni
parents: 745
diff changeset
436 min_y= FFMIN(min_y, mv_predictor[j][1]);
745
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
437 }
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
438 mv_predictor[pred_count+1][0] = sum_x - max_x - min_x;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
439 mv_predictor[pred_count+1][1] = sum_y - max_y - min_y;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
440
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
441 if(pred_count==4){
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
442 mv_predictor[pred_count+1][0] /= 2;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
443 mv_predictor[pred_count+1][1] /= 2;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
444 }
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
445 pred_count+=2;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
446 }
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
447
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
448 /* zero MV */
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
449 pred_count++;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
450
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
451 /* last MV */
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
452 mv_predictor[pred_count][0]= s->motion_val[mot_index][0];
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
453 mv_predictor[pred_count][1]= s->motion_val[mot_index][1];
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
454 pred_count++;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
455
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
456 s->mv_dir = MV_DIR_FORWARD;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
457 s->mb_intra=0;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
458 s->mv_type = MV_TYPE_16X16;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
459 s->mb_skiped=0;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
460
853
eacc2dd8fd9d * using DSPContext - so each codec could use its local (sub)set of CPU extension
kabi
parents: 847
diff changeset
461 s->dsp.clear_blocks(s->block[0]);
745
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
462
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
463 s->mb_x= mb_x;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
464 s->mb_y= mb_y;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
465 for(j=0; j<pred_count; j++){
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
466 int score=0;
903
22ee74da2cd3 cleanup
michaelni
parents: 853
diff changeset
467 UINT8 *src= s->current_picture.data[0] + mb_x*16 + mb_y*16*s->linesize;
745
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
468
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
469 s->motion_val[mot_index][0]= s->mv[0][0][0]= mv_predictor[j][0];
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
470 s->motion_val[mot_index][1]= s->mv[0][0][1]= mv_predictor[j][1];
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
471 MPV_decode_mb(s, s->block);
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
472
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
473 if(mb_x>0 && fixed[i-1]){
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
474 int k;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
475 for(k=0; k<16; k++)
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
476 score += ABS(src[k*s->linesize-1 ]-src[k*s->linesize ]);
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
477 }
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
478 if(mb_x+1<mb_width && fixed[i+1]){
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
479 int k;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
480 for(k=0; k<16; k++)
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
481 score += ABS(src[k*s->linesize+15]-src[k*s->linesize+16]);
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
482 }
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
483 if(mb_y>0 && fixed[i-mb_width]){
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
484 int k;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
485 for(k=0; k<16; k++)
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
486 score += ABS(src[k-s->linesize ]-src[k ]);
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
487 }
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
488 if(mb_y+1<mb_height && fixed[i+mb_width]){
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
489 int k;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
490 for(k=0; k<16; k++)
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
491 score += ABS(src[k+s->linesize*15]-src[k+s->linesize*16]);
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
492 }
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
493
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
494 if(score <= best_score){ // <= will favor the last MV
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
495 best_score= score;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
496 best_pred= j;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
497 }
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
498 }
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
499 score_sum+= best_score;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
500 //FIXME no need to set s->motion_val[mot_index][0] explicit
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
501 s->motion_val[mot_index][0]= s->mv[0][0][0]= mv_predictor[best_pred][0];
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
502 s->motion_val[mot_index][1]= s->mv[0][0][1]= mv_predictor[best_pred][1];
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
503
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
504 MPV_decode_mb(s, s->block);
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
505
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
506
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
507 if(s->mv[0][0][0] != prev_x || s->mv[0][0][1] != prev_y){
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
508 fixed[i]=MV_CHANGED;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
509 changed++;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
510 }else
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
511 fixed[i]=MV_UNCHANGED;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
512 }
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
513 }
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
514
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
515 // printf(".%d/%d", changed, score_sum); fflush(stdout);
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
516 }
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
517
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
518 if(none_left)
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
519 return;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
520
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
521 for(i=0; i<s->mb_num; i++){
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
522 if(fixed[i])
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
523 fixed[i]=MV_FROZEN;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
524 }
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
525 // printf(":"); fflush(stdout);
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
526 }
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
527 }
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
528
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
529 static int is_intra_more_likely(MpegEncContext *s){
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
530 int is_intra_likely, i, j, undamaged_count, skip_amount, mb_x, mb_y;
904
06776293eabb use spatial error concealment if we dont have a previous frame
michaelni
parents: 903
diff changeset
531
06776293eabb use spatial error concealment if we dont have a previous frame
michaelni
parents: 903
diff changeset
532 if(s->last_picture.data[0]==NULL) return 1; //no previous frame available -> use spatial prediction
745
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
533
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
534 undamaged_count=0;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
535 for(i=0; i<s->mb_num; i++){
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
536 int error= s->error_status_table[i];
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
537 if(!((error&DC_ERROR) && (error&MV_ERROR)))
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
538 undamaged_count++;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
539 }
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
540
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
541 if(undamaged_count < 5) return 0; //allmost all MBs damaged -> use temporal prediction
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
542
847
f3c369b8ddca reversing header game
michaelni
parents: 745
diff changeset
543 skip_amount= FFMAX(undamaged_count/50, 1); //check only upto 50 MBs
745
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
544 is_intra_likely=0;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
545
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
546 j=0;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
547 i=-1;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
548 for(mb_y= 0; mb_y<s->mb_height-1; mb_y++){
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
549 for(mb_x= 0; mb_x<s->mb_width; mb_x++){
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
550 int error;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
551
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
552 i++;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
553 error= s->error_status_table[i];
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
554 if((error&DC_ERROR) && (error&MV_ERROR))
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
555 continue; //skip damaged
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
556
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
557 j++;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
558 if((j%skip_amount) != 0) continue; //skip a few to speed things up
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
559
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
560 if(s->pict_type==I_TYPE){
903
22ee74da2cd3 cleanup
michaelni
parents: 853
diff changeset
561 UINT8 *mb_ptr = s->current_picture.data[0] + mb_x*16 + mb_y*16*s->linesize;
22ee74da2cd3 cleanup
michaelni
parents: 853
diff changeset
562 UINT8 *last_mb_ptr= s->last_picture.data [0] + mb_x*16 + mb_y*16*s->linesize;
745
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
563
853
eacc2dd8fd9d * using DSPContext - so each codec could use its local (sub)set of CPU extension
kabi
parents: 847
diff changeset
564 is_intra_likely += s->dsp.pix_abs16x16(last_mb_ptr, mb_ptr , s->linesize);
eacc2dd8fd9d * using DSPContext - so each codec could use its local (sub)set of CPU extension
kabi
parents: 847
diff changeset
565 is_intra_likely -= s->dsp.pix_abs16x16(last_mb_ptr, last_mb_ptr+s->linesize*16, s->linesize);
745
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
566 }else{
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
567 if(s->mbintra_table[i]) //HACK (this is allways inited but we should use mb_type[])
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
568 is_intra_likely++;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
569 else
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
570 is_intra_likely--;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
571 }
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
572 }
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
573 }
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
574 //printf("is_intra_likely: %d type:%d\n", is_intra_likely, s->pict_type);
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
575 return is_intra_likely > 0;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
576 }
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
577
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
578 void ff_error_resilience(MpegEncContext *s){
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
579 int i, mb_x, mb_y, error, error_type;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
580 int distance;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
581 int threshold_part[4]= {100,100,100};
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
582 int threshold= 50;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
583 int is_intra_likely;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
584
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
585 #if 1
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
586 /* handle overlapping slices */
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
587 for(error_type=1; error_type<=3; error_type++){
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
588 int end_ok=0;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
589
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
590 for(i=s->mb_num-1; i>=0; i--){
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
591 int error= s->error_status_table[i];
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
592
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
593 if(error&(1<<error_type))
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
594 end_ok=1;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
595 if(error&(8<<error_type))
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
596 end_ok=1;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
597
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
598 if(!end_ok)
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
599 s->error_status_table[i]|= 1<<error_type;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
600
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
601 if(error&VP_START)
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
602 end_ok=0;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
603 }
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
604 }
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
605 #endif
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
606 #if 1
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
607 /* handle slices with partitions of different length */
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
608 if(s->partitioned_frame){
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
609 int end_ok=0;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
610
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
611 for(i=s->mb_num-1; i>=0; i--){
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
612 int error= s->error_status_table[i];
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
613
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
614 if(error&AC_END)
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
615 end_ok=0;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
616 if((error&MV_END) || (error&DC_END) || (error&AC_ERROR))
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
617 end_ok=1;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
618
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
619 if(!end_ok)
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
620 s->error_status_table[i]|= AC_ERROR;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
621
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
622 if(error&VP_START)
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
623 end_ok=0;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
624 }
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
625 }
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
626 #endif
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
627 /* handle missing slices */
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
628 if(s->error_resilience>=4){
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
629 int end_ok=1;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
630
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
631 for(i=s->mb_num-2; i>=s->mb_width+100; i--){ //FIXME +100 hack
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
632 int error1= s->error_status_table[i ];
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
633 int error2= s->error_status_table[i+1];
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
634
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
635 if(error1&VP_START)
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
636 end_ok=1;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
637
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
638 if( error2==(VP_START|DC_ERROR|AC_ERROR|MV_ERROR|AC_END|DC_END|MV_END)
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
639 && error1!=(VP_START|DC_ERROR|AC_ERROR|MV_ERROR|AC_END|DC_END|MV_END)
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
640 && ((error1&AC_END) || (error1&DC_END) || (error1&MV_END))){ //end & uninited
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
641 end_ok=0;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
642 }
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
643
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
644 if(!end_ok)
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
645 s->error_status_table[i]|= DC_ERROR|AC_ERROR|MV_ERROR;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
646 }
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
647 }
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
648
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
649 #if 1
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
650 /* backward mark errors */
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
651 distance=9999999;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
652 for(error_type=1; error_type<=3; error_type++){
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
653 for(i=s->mb_num-1; i>=0; i--){
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
654 int error= s->error_status_table[i];
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
655
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
656 if(!s->mbskip_table[i]) //FIXME partition specific
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
657 distance++;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
658 if(error&(1<<error_type))
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
659 distance= 0;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
660
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
661 if(s->partitioned_frame){
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
662 if(distance < threshold_part[error_type-1])
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
663 s->error_status_table[i]|= 1<<error_type;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
664 }else{
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
665 if(distance < threshold)
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
666 s->error_status_table[i]|= 1<<error_type;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
667 }
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
668
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
669 if(error&VP_START)
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
670 distance= 9999999;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
671 }
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
672 }
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
673 #endif
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
674
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
675 /* forward mark errors */
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
676 error=0;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
677 for(i=0; i<s->mb_num; i++){
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
678 int old_error= s->error_status_table[i];
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
679
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
680 if(old_error&VP_START)
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
681 error= old_error& (DC_ERROR|AC_ERROR|MV_ERROR);
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
682 else{
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
683 error|= old_error& (DC_ERROR|AC_ERROR|MV_ERROR);
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
684 s->error_status_table[i]|= error;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
685 }
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
686 }
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
687 #if 1
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
688 /* handle not partitioned case */
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
689 if(!s->partitioned_frame){
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
690 for(i=0; i<s->mb_num; i++){
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
691 error= s->error_status_table[i];
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
692 if(error&(AC_ERROR|DC_ERROR|MV_ERROR))
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
693 error|= AC_ERROR|DC_ERROR|MV_ERROR;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
694 s->error_status_table[i]= error;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
695 }
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
696 }
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
697 #endif
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
698 is_intra_likely= is_intra_more_likely(s);
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
699
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
700 /* set unknown mb-type to most likely */
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
701 for(i=0; i<s->mb_num; i++){
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
702 int intra;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
703 error= s->error_status_table[i];
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
704 if((error&DC_ERROR) && (error&MV_ERROR))
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
705 intra= is_intra_likely;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
706 else
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
707 intra= s->mbintra_table[i];
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
708
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
709 if(intra)
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
710 s->mb_type[i]|= MB_TYPE_INTRA;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
711 else
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
712 s->mb_type[i]&= ~MB_TYPE_INTRA;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
713 }
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
714
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
715 /* handle inter blocks with damaged AC */
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
716 i= -1;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
717 for(mb_y=0; mb_y<s->mb_height; mb_y++){
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
718 for(mb_x=0; mb_x<s->mb_width; mb_x++){
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
719 i++;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
720 error= s->error_status_table[i];
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
721
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
722 if(s->mb_type[i]&MB_TYPE_INTRA) continue; //intra
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
723 if(error&MV_ERROR) continue; //inter with damaged MV
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
724 if(!(error&AC_ERROR)) continue; //undamaged inter
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
725
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
726 s->mv_dir = MV_DIR_FORWARD;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
727 s->mb_intra=0;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
728 s->mb_skiped=0;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
729 if(s->mb_type[i]&MB_TYPE_INTER4V){
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
730 int mb_index= mb_x*2+1 + (mb_y*2+1)*s->block_wrap[0];
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
731 int j;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
732 s->mv_type = MV_TYPE_8X8;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
733 for(j=0; j<4; j++){
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
734 s->mv[0][j][0] = s->motion_val[ mb_index + (j&1) + (j>>1)*s->block_wrap[0] ][0];
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
735 s->mv[0][j][1] = s->motion_val[ mb_index + (j&1) + (j>>1)*s->block_wrap[0] ][1];
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
736 }
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
737 }else{
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
738 s->mv_type = MV_TYPE_16X16;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
739 s->mv[0][0][0] = s->motion_val[ mb_x*2+1 + (mb_y*2+1)*s->block_wrap[0] ][0];
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
740 s->mv[0][0][1] = s->motion_val[ mb_x*2+1 + (mb_y*2+1)*s->block_wrap[0] ][1];
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
741 }
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
742
853
eacc2dd8fd9d * using DSPContext - so each codec could use its local (sub)set of CPU extension
kabi
parents: 847
diff changeset
743 s->dsp.clear_blocks(s->block[0]);
745
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
744
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
745 s->mb_x= mb_x;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
746 s->mb_y= mb_y;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
747 MPV_decode_mb(s, s->block);
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
748 }
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
749 }
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
750
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
751 /* guess MVs */
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
752 if(s->pict_type==B_TYPE){
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
753 i= -1;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
754 for(mb_y=0; mb_y<s->mb_height; mb_y++){
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
755 for(mb_x=0; mb_x<s->mb_width; mb_x++){
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
756 int xy= mb_x*2+1 + (mb_y*2+1)*s->block_wrap[0];
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
757 i++;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
758 error= s->error_status_table[i];
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
759
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
760 if(s->mb_type[i]&MB_TYPE_INTRA) continue; //intra
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
761 if(!(error&MV_ERROR)) continue; //inter with undamaged MV
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
762 if(!(error&AC_ERROR)) continue; //undamaged inter
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
763
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
764 s->mv_dir = MV_DIR_FORWARD|MV_DIR_BACKWARD;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
765 s->mb_intra=0;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
766 s->mv_type = MV_TYPE_16X16;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
767 s->mb_skiped=0;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
768
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
769 if(s->pp_time){
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
770 int time_pp= s->pp_time;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
771 int time_pb= s->pb_time;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
772
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
773 s->mv[0][0][0] = s->motion_val[xy][0]*time_pb/time_pp;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
774 s->mv[0][0][1] = s->motion_val[xy][1]*time_pb/time_pp;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
775 s->mv[1][0][0] = s->motion_val[xy][0]*(time_pb - time_pp)/time_pp;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
776 s->mv[1][0][1] = s->motion_val[xy][1]*(time_pb - time_pp)/time_pp;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
777 }else{
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
778 s->mv[0][0][0]= 0;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
779 s->mv[0][0][1]= 0;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
780 s->mv[1][0][0]= 0;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
781 s->mv[1][0][1]= 0;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
782 }
853
eacc2dd8fd9d * using DSPContext - so each codec could use its local (sub)set of CPU extension
kabi
parents: 847
diff changeset
783
eacc2dd8fd9d * using DSPContext - so each codec could use its local (sub)set of CPU extension
kabi
parents: 847
diff changeset
784 s->dsp.clear_blocks(s->block[0]);
745
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
785 s->mb_x= mb_x;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
786 s->mb_y= mb_y;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
787 MPV_decode_mb(s, s->block);
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
788 }
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
789 }
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
790 }else
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
791 guess_mv(s);
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
792
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
793 /* fill DC for inter blocks */
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
794 i= -1;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
795 for(mb_y=0; mb_y<s->mb_height; mb_y++){
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
796 for(mb_x=0; mb_x<s->mb_width; mb_x++){
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
797 int dc, dcu, dcv, y, n;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
798 INT16 *dc_ptr;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
799 UINT8 *dest_y, *dest_cb, *dest_cr;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
800
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
801 i++;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
802 error= s->error_status_table[i];
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
803
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
804 if(s->mb_type[i]&MB_TYPE_INTRA) continue; //intra
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
805 // if(error&MV_ERROR) continue; //inter data damaged FIXME is this good?
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
806
903
22ee74da2cd3 cleanup
michaelni
parents: 853
diff changeset
807 dest_y = s->current_picture.data[0] + mb_x*16 + mb_y*16*s->linesize;
22ee74da2cd3 cleanup
michaelni
parents: 853
diff changeset
808 dest_cb= s->current_picture.data[1] + mb_x*8 + mb_y*8 *s->uvlinesize;
22ee74da2cd3 cleanup
michaelni
parents: 853
diff changeset
809 dest_cr= s->current_picture.data[2] + mb_x*8 + mb_y*8 *s->uvlinesize;
745
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
810
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
811 dc_ptr= &s->dc_val[0][mb_x*2+1 + (mb_y*2+1)*(s->mb_width*2+2)];
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
812 for(n=0; n<4; n++){
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
813 dc=0;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
814 for(y=0; y<8; y++){
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
815 int x;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
816 for(x=0; x<8; x++){
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
817 dc+= dest_y[x + (n&1)*8 + (y + (n>>1)*8)*s->linesize];
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
818 }
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
819 }
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
820 dc_ptr[(n&1) + (n>>1)*(s->mb_width*2+2)]= (dc+4)>>3;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
821 }
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
822
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
823 dcu=dcv=0;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
824 for(y=0; y<8; y++){
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
825 int x;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
826 for(x=0; x<8; x++){
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
827 dcu+=dest_cb[x + y*(s->uvlinesize)];
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
828 dcv+=dest_cr[x + y*(s->uvlinesize)];
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
829 }
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
830 }
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
831 s->dc_val[1][mb_x+1 + (mb_y+1)*(s->mb_width+2)]= (dcu+4)>>3;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
832 s->dc_val[2][mb_x+1 + (mb_y+1)*(s->mb_width+2)]= (dcv+4)>>3;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
833 }
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
834 }
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
835 #if 1
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
836 /* guess DC for damaged blocks */
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
837 guess_dc(s, s->dc_val[0] + s->mb_width*2+3, s->mb_width*2, s->mb_height*2, s->mb_width*2+2, 1);
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
838 guess_dc(s, s->dc_val[1] + s->mb_width +3, s->mb_width , s->mb_height , s->mb_width +2, 0);
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
839 guess_dc(s, s->dc_val[2] + s->mb_width +3, s->mb_width , s->mb_height , s->mb_width +2, 0);
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
840 #endif
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
841 /* filter luma DC */
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
842 filter181(s->dc_val[0] + s->mb_width*2+3, s->mb_width*2, s->mb_height*2, s->mb_width*2+2);
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
843
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
844 #if 1
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
845 /* render DC only intra */
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
846 i= -1;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
847 for(mb_y=0; mb_y<s->mb_height; mb_y++){
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
848 for(mb_x=0; mb_x<s->mb_width; mb_x++){
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
849 UINT8 *dest_y, *dest_cb, *dest_cr;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
850
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
851 i++;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
852 error= s->error_status_table[i];
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
853
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
854 if(!(s->mb_type[i]&MB_TYPE_INTRA)) continue; //inter
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
855 if(!(error&AC_ERROR)) continue; //undamaged
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
856
903
22ee74da2cd3 cleanup
michaelni
parents: 853
diff changeset
857 dest_y = s->current_picture.data[0] + mb_x*16 + mb_y*16*s->linesize;
22ee74da2cd3 cleanup
michaelni
parents: 853
diff changeset
858 dest_cb= s->current_picture.data[1] + mb_x*8 + mb_y*8 *s->uvlinesize;
22ee74da2cd3 cleanup
michaelni
parents: 853
diff changeset
859 dest_cr= s->current_picture.data[2] + mb_x*8 + mb_y*8 *s->uvlinesize;
745
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
860
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
861 put_dc(s, dest_y, dest_cb, dest_cr, mb_x, mb_y);
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
862 }
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
863 }
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
864 #endif
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
865
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
866 if(s->avctx->error_concealment&FF_EC_DEBLOCK){
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
867 /* filter horizontal block boundaries */
903
22ee74da2cd3 cleanup
michaelni
parents: 853
diff changeset
868 h_block_filter(s, s->current_picture.data[0], s->mb_width*2, s->mb_height*2, s->linesize , 1);
22ee74da2cd3 cleanup
michaelni
parents: 853
diff changeset
869 h_block_filter(s, s->current_picture.data[1], s->mb_width , s->mb_height , s->uvlinesize, 0);
22ee74da2cd3 cleanup
michaelni
parents: 853
diff changeset
870 h_block_filter(s, s->current_picture.data[2], s->mb_width , s->mb_height , s->uvlinesize, 0);
745
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
871
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
872 /* filter vertical block boundaries */
903
22ee74da2cd3 cleanup
michaelni
parents: 853
diff changeset
873 v_block_filter(s, s->current_picture.data[0], s->mb_width*2, s->mb_height*2, s->linesize , 1);
22ee74da2cd3 cleanup
michaelni
parents: 853
diff changeset
874 v_block_filter(s, s->current_picture.data[1], s->mb_width , s->mb_height , s->uvlinesize, 0);
22ee74da2cd3 cleanup
michaelni
parents: 853
diff changeset
875 v_block_filter(s, s->current_picture.data[2], s->mb_width , s->mb_height , s->uvlinesize, 0);
745
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
876 }
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
877
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
878 /* clean a few tables */
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
879 for(i=0; i<s->mb_num; i++){
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
880 int error= s->error_status_table[i];
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
881
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
882 if(s->pict_type!=B_TYPE && (error&(DC_ERROR|MV_ERROR|AC_ERROR))){
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
883 s->mbskip_table[i]=0;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
884 }
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
885 s->mbintra_table[i]=1;
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
886 }
25d7fb7c89be better/cleaner error resilience (done in a 2nd pass after decoding)
michaelni
parents:
diff changeset
887 }