2751878230e86d6e439172e1ba94a000fa742690
[libav.git] / libavcodec / error_resilience.c
1 /*
2 * Error resilience / concealment
3 *
4 * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
5 *
6 * This file is part of FFmpeg.
7 *
8 * FFmpeg is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * FFmpeg is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with FFmpeg; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
23 /**
24 * @file libavcodec/error_resilience.c
25 * Error resilience / concealment.
26 */
27
28 #include <limits.h>
29
30 #include "avcodec.h"
31 #include "dsputil.h"
32 #include "mpegvideo.h"
33 #include "h264.h"
34
35 /*
36 * H264 redefines mb_intra so it is not mistakely used (its uninitialized in h264)
37 * but error concealment must support both h264 and h263 thus we must undo this
38 */
39 #undef mb_intra
40
41 static void decode_mb(MpegEncContext *s){
42 s->dest[0] = s->current_picture.data[0] + (s->mb_y * 16* s->linesize ) + s->mb_x * 16;
43 s->dest[1] = s->current_picture.data[1] + (s->mb_y * (16>>s->chroma_y_shift) * s->uvlinesize) + s->mb_x * (16>>s->chroma_x_shift);
44 s->dest[2] = s->current_picture.data[2] + (s->mb_y * (16>>s->chroma_y_shift) * s->uvlinesize) + s->mb_x * (16>>s->chroma_x_shift);
45
46 if(s->codec_id == CODEC_ID_H264){
47 H264Context *h= (void*)s;
48 h->mb_xy= s->mb_x + s->mb_y*s->mb_stride;
49 memset(h->non_zero_count_cache, 0, sizeof(h->non_zero_count_cache));
50 fill_rectangle(&h->ref_cache[0][scan8[0]], 4, 4, 8, 0, 1);
51 fill_rectangle(h->mv_cache[0][ scan8[0] ], 4, 4, 8, pack16to32(s->mv[0][0][0],s->mv[0][0][1]), 4);
52 assert(h->list_count==1);
53 assert(!FRAME_MBAFF);
54 ff_h264_hl_decode_mb(h);
55 }else{
56 MPV_decode_mb(s, s->block);
57 }
58 }
59
60 /**
61 * @param stride the number of MVs to get to the next row
62 * @param mv_step the number of MVs per row or column in a macroblock
63 */
64 static void set_mv_strides(MpegEncContext *s, int *mv_step, int *stride){
65 if(s->codec_id == CODEC_ID_H264){
66 H264Context *h= (void*)s;
67 assert(s->quarter_sample);
68 *mv_step= 4;
69 *stride= h->b_stride;
70 }else{
71 *mv_step= 2;
72 *stride= s->b8_stride;
73 }
74 }
75
76 /**
77 * replaces the current MB with a flat dc only version.
78 */
79 static void put_dc(MpegEncContext *s, uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr, int mb_x, int mb_y)
80 {
81 int dc, dcu, dcv, y, i;
82 for(i=0; i<4; i++){
83 dc= s->dc_val[0][mb_x*2 + (i&1) + (mb_y*2 + (i>>1))*s->b8_stride];
84 if(dc<0) dc=0;
85 else if(dc>2040) dc=2040;
86 for(y=0; y<8; y++){
87 int x;
88 for(x=0; x<8; x++){
89 dest_y[x + (i&1)*8 + (y + (i>>1)*8)*s->linesize]= dc/8;
90 }
91 }
92 }
93 dcu = s->dc_val[1][mb_x + mb_y*s->mb_stride];
94 dcv = s->dc_val[2][mb_x + mb_y*s->mb_stride];
95 if (dcu<0 ) dcu=0;
96 else if(dcu>2040) dcu=2040;
97 if (dcv<0 ) dcv=0;
98 else if(dcv>2040) dcv=2040;
99 for(y=0; y<8; y++){
100 int x;
101 for(x=0; x<8; x++){
102 dest_cb[x + y*(s->uvlinesize)]= dcu/8;
103 dest_cr[x + y*(s->uvlinesize)]= dcv/8;
104 }
105 }
106 }
107
108 static void filter181(int16_t *data, int width, int height, int stride){
109 int x,y;
110
111 /* horizontal filter */
112 for(y=1; y<height-1; y++){
113 int prev_dc= data[0 + y*stride];
114
115 for(x=1; x<width-1; x++){
116 int dc;
117
118 dc= - prev_dc
119 + data[x + y*stride]*8
120 - data[x + 1 + y*stride];
121 dc= (dc*10923 + 32768)>>16;
122 prev_dc= data[x + y*stride];
123 data[x + y*stride]= dc;
124 }
125 }
126
127 /* vertical filter */
128 for(x=1; x<width-1; x++){
129 int prev_dc= data[x];
130
131 for(y=1; y<height-1; y++){
132 int dc;
133
134 dc= - prev_dc
135 + data[x + y *stride]*8
136 - data[x + (y+1)*stride];
137 dc= (dc*10923 + 32768)>>16;
138 prev_dc= data[x + y*stride];
139 data[x + y*stride]= dc;
140 }
141 }
142 }
143
144 /**
145 * guess the dc of blocks which do not have an undamaged dc
146 * @param w width in 8 pixel blocks
147 * @param h height in 8 pixel blocks
148 */
149 static void guess_dc(MpegEncContext *s, int16_t *dc, int w, int h, int stride, int is_luma){
150 int b_x, b_y;
151
152 for(b_y=0; b_y<h; b_y++){
153 for(b_x=0; b_x<w; b_x++){
154 int color[4]={1024,1024,1024,1024};
155 int distance[4]={9999,9999,9999,9999};
156 int mb_index, error, j;
157 int64_t guess, weight_sum;
158
159 mb_index= (b_x>>is_luma) + (b_y>>is_luma)*s->mb_stride;
160
161 error= s->error_status_table[mb_index];
162
163 if(IS_INTER(s->current_picture.mb_type[mb_index])) continue; //inter
164 if(!(error&DC_ERROR)) continue; //dc-ok
165
166 /* right block */
167 for(j=b_x+1; j<w; j++){
168 int mb_index_j= (j>>is_luma) + (b_y>>is_luma)*s->mb_stride;
169 int error_j= s->error_status_table[mb_index_j];
170 int intra_j= IS_INTRA(s->current_picture.mb_type[mb_index_j]);
171 if(intra_j==0 || !(error_j&DC_ERROR)){
172 color[0]= dc[j + b_y*stride];
173 distance[0]= j-b_x;
174 break;
175 }
176 }
177
178 /* left block */
179 for(j=b_x-1; j>=0; j--){
180 int mb_index_j= (j>>is_luma) + (b_y>>is_luma)*s->mb_stride;
181 int error_j= s->error_status_table[mb_index_j];
182 int intra_j= IS_INTRA(s->current_picture.mb_type[mb_index_j]);
183 if(intra_j==0 || !(error_j&DC_ERROR)){
184 color[1]= dc[j + b_y*stride];
185 distance[1]= b_x-j;
186 break;
187 }
188 }
189
190 /* bottom block */
191 for(j=b_y+1; j<h; j++){
192 int mb_index_j= (b_x>>is_luma) + (j>>is_luma)*s->mb_stride;
193 int error_j= s->error_status_table[mb_index_j];
194 int intra_j= IS_INTRA(s->current_picture.mb_type[mb_index_j]);
195 if(intra_j==0 || !(error_j&DC_ERROR)){
196 color[2]= dc[b_x + j*stride];
197 distance[2]= j-b_y;
198 break;
199 }
200 }
201
202 /* top block */
203 for(j=b_y-1; j>=0; j--){
204 int mb_index_j= (b_x>>is_luma) + (j>>is_luma)*s->mb_stride;
205 int error_j= s->error_status_table[mb_index_j];
206 int intra_j= IS_INTRA(s->current_picture.mb_type[mb_index_j]);
207 if(intra_j==0 || !(error_j&DC_ERROR)){
208 color[3]= dc[b_x + j*stride];
209 distance[3]= b_y-j;
210 break;
211 }
212 }
213
214 weight_sum=0;
215 guess=0;
216 for(j=0; j<4; j++){
217 int64_t weight= 256*256*256*16/distance[j];
218 guess+= weight*(int64_t)color[j];
219 weight_sum+= weight;
220 }
221 guess= (guess + weight_sum/2) / weight_sum;
222
223 dc[b_x + b_y*stride]= guess;
224 }
225 }
226 }
227
228 /**
229 * simple horizontal deblocking filter used for error resilience
230 * @param w width in 8 pixel blocks
231 * @param h height in 8 pixel blocks
232 */
233 static void h_block_filter(MpegEncContext *s, uint8_t *dst, int w, int h, int stride, int is_luma){
234 int b_x, b_y, mvx_stride, mvy_stride;
235 uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
236 set_mv_strides(s, &mvx_stride, &mvy_stride);
237 mvx_stride >>= is_luma;
238 mvy_stride *= mvx_stride;
239
240 for(b_y=0; b_y<h; b_y++){
241 for(b_x=0; b_x<w-1; b_x++){
242 int y;
243 int left_status = s->error_status_table[( b_x >>is_luma) + (b_y>>is_luma)*s->mb_stride];
244 int right_status= s->error_status_table[((b_x+1)>>is_luma) + (b_y>>is_luma)*s->mb_stride];
245 int left_intra= IS_INTRA(s->current_picture.mb_type [( b_x >>is_luma) + (b_y>>is_luma)*s->mb_stride]);
246 int right_intra= IS_INTRA(s->current_picture.mb_type [((b_x+1)>>is_luma) + (b_y>>is_luma)*s->mb_stride]);
247 int left_damage = left_status&(DC_ERROR|AC_ERROR|MV_ERROR);
248 int right_damage= right_status&(DC_ERROR|AC_ERROR|MV_ERROR);
249 int offset= b_x*8 + b_y*stride*8;
250 int16_t *left_mv= s->current_picture.motion_val[0][mvy_stride*b_y + mvx_stride* b_x ];
251 int16_t *right_mv= s->current_picture.motion_val[0][mvy_stride*b_y + mvx_stride*(b_x+1)];
252
253 if(!(left_damage||right_damage)) continue; // both undamaged
254
255 if( (!left_intra) && (!right_intra)
256 && FFABS(left_mv[0]-right_mv[0]) + FFABS(left_mv[1]+right_mv[1]) < 2) continue;
257
258 for(y=0; y<8; y++){
259 int a,b,c,d;
260
261 a= dst[offset + 7 + y*stride] - dst[offset + 6 + y*stride];
262 b= dst[offset + 8 + y*stride] - dst[offset + 7 + y*stride];
263 c= dst[offset + 9 + y*stride] - dst[offset + 8 + y*stride];
264
265 d= FFABS(b) - ((FFABS(a) + FFABS(c) + 1)>>1);
266 d= FFMAX(d, 0);
267 if(b<0) d= -d;
268
269 if(d==0) continue;
270
271 if(!(left_damage && right_damage))
272 d= d*16/9;
273
274 if(left_damage){
275 dst[offset + 7 + y*stride] = cm[dst[offset + 7 + y*stride] + ((d*7)>>4)];
276 dst[offset + 6 + y*stride] = cm[dst[offset + 6 + y*stride] + ((d*5)>>4)];
277 dst[offset + 5 + y*stride] = cm[dst[offset + 5 + y*stride] + ((d*3)>>4)];
278 dst[offset + 4 + y*stride] = cm[dst[offset + 4 + y*stride] + ((d*1)>>4)];
279 }
280 if(right_damage){
281 dst[offset + 8 + y*stride] = cm[dst[offset + 8 + y*stride] - ((d*7)>>4)];
282 dst[offset + 9 + y*stride] = cm[dst[offset + 9 + y*stride] - ((d*5)>>4)];
283 dst[offset + 10+ y*stride] = cm[dst[offset +10 + y*stride] - ((d*3)>>4)];
284 dst[offset + 11+ y*stride] = cm[dst[offset +11 + y*stride] - ((d*1)>>4)];
285 }
286 }
287 }
288 }
289 }
290
291 /**
292 * simple vertical deblocking filter used for error resilience
293 * @param w width in 8 pixel blocks
294 * @param h height in 8 pixel blocks
295 */
296 static void v_block_filter(MpegEncContext *s, uint8_t *dst, int w, int h, int stride, int is_luma){
297 int b_x, b_y, mvx_stride, mvy_stride;
298 uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
299 set_mv_strides(s, &mvx_stride, &mvy_stride);
300 mvx_stride >>= is_luma;
301 mvy_stride *= mvx_stride;
302
303 for(b_y=0; b_y<h-1; b_y++){
304 for(b_x=0; b_x<w; b_x++){
305 int x;
306 int top_status = s->error_status_table[(b_x>>is_luma) + ( b_y >>is_luma)*s->mb_stride];
307 int bottom_status= s->error_status_table[(b_x>>is_luma) + ((b_y+1)>>is_luma)*s->mb_stride];
308 int top_intra= IS_INTRA(s->current_picture.mb_type [(b_x>>is_luma) + ( b_y >>is_luma)*s->mb_stride]);
309 int bottom_intra= IS_INTRA(s->current_picture.mb_type [(b_x>>is_luma) + ((b_y+1)>>is_luma)*s->mb_stride]);
310 int top_damage = top_status&(DC_ERROR|AC_ERROR|MV_ERROR);
311 int bottom_damage= bottom_status&(DC_ERROR|AC_ERROR|MV_ERROR);
312 int offset= b_x*8 + b_y*stride*8;
313 int16_t *top_mv= s->current_picture.motion_val[0][mvy_stride* b_y + mvx_stride*b_x];
314 int16_t *bottom_mv= s->current_picture.motion_val[0][mvy_stride*(b_y+1) + mvx_stride*b_x];
315
316 if(!(top_damage||bottom_damage)) continue; // both undamaged
317
318 if( (!top_intra) && (!bottom_intra)
319 && FFABS(top_mv[0]-bottom_mv[0]) + FFABS(top_mv[1]+bottom_mv[1]) < 2) continue;
320
321 for(x=0; x<8; x++){
322 int a,b,c,d;
323
324 a= dst[offset + x + 7*stride] - dst[offset + x + 6*stride];
325 b= dst[offset + x + 8*stride] - dst[offset + x + 7*stride];
326 c= dst[offset + x + 9*stride] - dst[offset + x + 8*stride];
327
328 d= FFABS(b) - ((FFABS(a) + FFABS(c)+1)>>1);
329 d= FFMAX(d, 0);
330 if(b<0) d= -d;
331
332 if(d==0) continue;
333
334 if(!(top_damage && bottom_damage))
335 d= d*16/9;
336
337 if(top_damage){
338 dst[offset + x + 7*stride] = cm[dst[offset + x + 7*stride] + ((d*7)>>4)];
339 dst[offset + x + 6*stride] = cm[dst[offset + x + 6*stride] + ((d*5)>>4)];
340 dst[offset + x + 5*stride] = cm[dst[offset + x + 5*stride] + ((d*3)>>4)];
341 dst[offset + x + 4*stride] = cm[dst[offset + x + 4*stride] + ((d*1)>>4)];
342 }
343 if(bottom_damage){
344 dst[offset + x + 8*stride] = cm[dst[offset + x + 8*stride] - ((d*7)>>4)];
345 dst[offset + x + 9*stride] = cm[dst[offset + x + 9*stride] - ((d*5)>>4)];
346 dst[offset + x + 10*stride] = cm[dst[offset + x + 10*stride] - ((d*3)>>4)];
347 dst[offset + x + 11*stride] = cm[dst[offset + x + 11*stride] - ((d*1)>>4)];
348 }
349 }
350 }
351 }
352 }
353
354 static void guess_mv(MpegEncContext *s){
355 uint8_t fixed[s->mb_stride * s->mb_height];
356 #define MV_FROZEN 3
357 #define MV_CHANGED 2
358 #define MV_UNCHANGED 1
359 const int mb_stride = s->mb_stride;
360 const int mb_width = s->mb_width;
361 const int mb_height= s->mb_height;
362 int i, depth, num_avail;
363 int mb_x, mb_y, mot_step, mot_stride;
364
365 set_mv_strides(s, &mot_step, &mot_stride);
366
367 num_avail=0;
368 for(i=0; i<s->mb_num; i++){
369 const int mb_xy= s->mb_index2xy[ i ];
370 int f=0;
371 int error= s->error_status_table[mb_xy];
372
373 if(IS_INTRA(s->current_picture.mb_type[mb_xy])) f=MV_FROZEN; //intra //FIXME check
374 if(!(error&MV_ERROR)) f=MV_FROZEN; //inter with undamaged MV
375
376 fixed[mb_xy]= f;
377 if(f==MV_FROZEN)
378 num_avail++;
379 }
380
381 if((!(s->avctx->error_concealment&FF_EC_GUESS_MVS)) || num_avail <= mb_width/2){
382 for(mb_y=0; mb_y<s->mb_height; mb_y++){
383 for(mb_x=0; mb_x<s->mb_width; mb_x++){
384 const int mb_xy= mb_x + mb_y*s->mb_stride;
385
386 if(IS_INTRA(s->current_picture.mb_type[mb_xy])) continue;
387 if(!(s->error_status_table[mb_xy]&MV_ERROR)) continue;
388
389 s->mv_dir = s->last_picture.data[0] ? MV_DIR_FORWARD : MV_DIR_BACKWARD;
390 s->mb_intra=0;
391 s->mv_type = MV_TYPE_16X16;
392 s->mb_skipped=0;
393
394 s->dsp.clear_blocks(s->block[0]);
395
396 s->mb_x= mb_x;
397 s->mb_y= mb_y;
398 s->mv[0][0][0]= 0;
399 s->mv[0][0][1]= 0;
400 decode_mb(s);
401 }
402 }
403 return;
404 }
405
406 for(depth=0;; depth++){
407 int changed, pass, none_left;
408
409 none_left=1;
410 changed=1;
411 for(pass=0; (changed || pass<2) && pass<10; pass++){
412 int mb_x, mb_y;
413 int score_sum=0;
414
415 changed=0;
416 for(mb_y=0; mb_y<s->mb_height; mb_y++){
417 for(mb_x=0; mb_x<s->mb_width; mb_x++){
418 const int mb_xy= mb_x + mb_y*s->mb_stride;
419 int mv_predictor[8][2]={{0}};
420 int pred_count=0;
421 int j;
422 int best_score=256*256*256*64;
423 int best_pred=0;
424 const int mot_index= (mb_x + mb_y*mot_stride) * mot_step;
425 int prev_x= s->current_picture.motion_val[0][mot_index][0];
426 int prev_y= s->current_picture.motion_val[0][mot_index][1];
427
428 if((mb_x^mb_y^pass)&1) continue;
429
430 if(fixed[mb_xy]==MV_FROZEN) continue;
431 assert(!IS_INTRA(s->current_picture.mb_type[mb_xy]));
432 assert(s->last_picture_ptr && s->last_picture_ptr->data[0]);
433
434 j=0;
435 if(mb_x>0 && fixed[mb_xy-1 ]==MV_FROZEN) j=1;
436 if(mb_x+1<mb_width && fixed[mb_xy+1 ]==MV_FROZEN) j=1;
437 if(mb_y>0 && fixed[mb_xy-mb_stride]==MV_FROZEN) j=1;
438 if(mb_y+1<mb_height && fixed[mb_xy+mb_stride]==MV_FROZEN) j=1;
439 if(j==0) continue;
440
441 j=0;
442 if(mb_x>0 && fixed[mb_xy-1 ]==MV_CHANGED) j=1;
443 if(mb_x+1<mb_width && fixed[mb_xy+1 ]==MV_CHANGED) j=1;
444 if(mb_y>0 && fixed[mb_xy-mb_stride]==MV_CHANGED) j=1;
445 if(mb_y+1<mb_height && fixed[mb_xy+mb_stride]==MV_CHANGED) j=1;
446 if(j==0 && pass>1) continue;
447
448 none_left=0;
449
450 if(mb_x>0 && fixed[mb_xy-1]){
451 mv_predictor[pred_count][0]= s->current_picture.motion_val[0][mot_index - mot_step][0];
452 mv_predictor[pred_count][1]= s->current_picture.motion_val[0][mot_index - mot_step][1];
453 pred_count++;
454 }
455 if(mb_x+1<mb_width && fixed[mb_xy+1]){
456 mv_predictor[pred_count][0]= s->current_picture.motion_val[0][mot_index + mot_step][0];
457 mv_predictor[pred_count][1]= s->current_picture.motion_val[0][mot_index + mot_step][1];
458 pred_count++;
459 }
460 if(mb_y>0 && fixed[mb_xy-mb_stride]){
461 mv_predictor[pred_count][0]= s->current_picture.motion_val[0][mot_index - mot_stride*mot_step][0];
462 mv_predictor[pred_count][1]= s->current_picture.motion_val[0][mot_index - mot_stride*mot_step][1];
463 pred_count++;
464 }
465 if(mb_y+1<mb_height && fixed[mb_xy+mb_stride]){
466 mv_predictor[pred_count][0]= s->current_picture.motion_val[0][mot_index + mot_stride*mot_step][0];
467 mv_predictor[pred_count][1]= s->current_picture.motion_val[0][mot_index + mot_stride*mot_step][1];
468 pred_count++;
469 }
470 if(pred_count==0) continue;
471
472 if(pred_count>1){
473 int sum_x=0, sum_y=0;
474 int max_x, max_y, min_x, min_y;
475
476 for(j=0; j<pred_count; j++){
477 sum_x+= mv_predictor[j][0];
478 sum_y+= mv_predictor[j][1];
479 }
480
481 /* mean */
482 mv_predictor[pred_count][0] = sum_x/j;
483 mv_predictor[pred_count][1] = sum_y/j;
484
485 /* median */
486 if(pred_count>=3){
487 min_y= min_x= 99999;
488 max_y= max_x=-99999;
489 }else{
490 min_x=min_y=max_x=max_y=0;
491 }
492 for(j=0; j<pred_count; j++){
493 max_x= FFMAX(max_x, mv_predictor[j][0]);
494 max_y= FFMAX(max_y, mv_predictor[j][1]);
495 min_x= FFMIN(min_x, mv_predictor[j][0]);
496 min_y= FFMIN(min_y, mv_predictor[j][1]);
497 }
498 mv_predictor[pred_count+1][0] = sum_x - max_x - min_x;
499 mv_predictor[pred_count+1][1] = sum_y - max_y - min_y;
500
501 if(pred_count==4){
502 mv_predictor[pred_count+1][0] /= 2;
503 mv_predictor[pred_count+1][1] /= 2;
504 }
505 pred_count+=2;
506 }
507
508 /* zero MV */
509 pred_count++;
510
511 /* last MV */
512 mv_predictor[pred_count][0]= s->current_picture.motion_val[0][mot_index][0];
513 mv_predictor[pred_count][1]= s->current_picture.motion_val[0][mot_index][1];
514 pred_count++;
515
516 s->mv_dir = MV_DIR_FORWARD;
517 s->mb_intra=0;
518 s->mv_type = MV_TYPE_16X16;
519 s->mb_skipped=0;
520
521 s->dsp.clear_blocks(s->block[0]);
522
523 s->mb_x= mb_x;
524 s->mb_y= mb_y;
525
526 for(j=0; j<pred_count; j++){
527 int score=0;
528 uint8_t *src= s->current_picture.data[0] + mb_x*16 + mb_y*16*s->linesize;
529
530 s->current_picture.motion_val[0][mot_index][0]= s->mv[0][0][0]= mv_predictor[j][0];
531 s->current_picture.motion_val[0][mot_index][1]= s->mv[0][0][1]= mv_predictor[j][1];
532
533 decode_mb(s);
534
535 if(mb_x>0 && fixed[mb_xy-1]){
536 int k;
537 for(k=0; k<16; k++)
538 score += FFABS(src[k*s->linesize-1 ]-src[k*s->linesize ]);
539 }
540 if(mb_x+1<mb_width && fixed[mb_xy+1]){
541 int k;
542 for(k=0; k<16; k++)
543 score += FFABS(src[k*s->linesize+15]-src[k*s->linesize+16]);
544 }
545 if(mb_y>0 && fixed[mb_xy-mb_stride]){
546 int k;
547 for(k=0; k<16; k++)
548 score += FFABS(src[k-s->linesize ]-src[k ]);
549 }
550 if(mb_y+1<mb_height && fixed[mb_xy+mb_stride]){
551 int k;
552 for(k=0; k<16; k++)
553 score += FFABS(src[k+s->linesize*15]-src[k+s->linesize*16]);
554 }
555
556 if(score <= best_score){ // <= will favor the last MV
557 best_score= score;
558 best_pred= j;
559 }
560 }
561 score_sum+= best_score;
562 s->mv[0][0][0]= mv_predictor[best_pred][0];
563 s->mv[0][0][1]= mv_predictor[best_pred][1];
564
565 for(i=0; i<mot_step; i++)
566 for(j=0; j<mot_step; j++){
567 s->current_picture.motion_val[0][mot_index+i+j*mot_stride][0]= s->mv[0][0][0];
568 s->current_picture.motion_val[0][mot_index+i+j*mot_stride][1]= s->mv[0][0][1];
569 }
570
571 decode_mb(s);
572
573
574 if(s->mv[0][0][0] != prev_x || s->mv[0][0][1] != prev_y){
575 fixed[mb_xy]=MV_CHANGED;
576 changed++;
577 }else
578 fixed[mb_xy]=MV_UNCHANGED;
579 }
580 }
581
582 // printf(".%d/%d", changed, score_sum); fflush(stdout);
583 }
584
585 if(none_left)
586 return;
587
588 for(i=0; i<s->mb_num; i++){
589 int mb_xy= s->mb_index2xy[i];
590 if(fixed[mb_xy])
591 fixed[mb_xy]=MV_FROZEN;
592 }
593 // printf(":"); fflush(stdout);
594 }
595 }
596
597 static int is_intra_more_likely(MpegEncContext *s){
598 int is_intra_likely, i, j, undamaged_count, skip_amount, mb_x, mb_y;
599
600 if(!s->last_picture_ptr || !s->last_picture_ptr->data[0]) return 1; //no previous frame available -> use spatial prediction
601
602 undamaged_count=0;
603 for(i=0; i<s->mb_num; i++){
604 const int mb_xy= s->mb_index2xy[i];
605 const int error= s->error_status_table[mb_xy];
606 if(!((error&DC_ERROR) && (error&MV_ERROR)))
607 undamaged_count++;
608 }
609
610 if(undamaged_count < 5) return 0; //almost all MBs damaged -> use temporal prediction
611
612 //prevent dsp.sad() check, that requires access to the image
613 if(CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration && s->pict_type == FF_I_TYPE)
614 return 1;
615
616 skip_amount= FFMAX(undamaged_count/50, 1); //check only upto 50 MBs
617 is_intra_likely=0;
618
619 j=0;
620 for(mb_y= 0; mb_y<s->mb_height-1; mb_y++){
621 for(mb_x= 0; mb_x<s->mb_width; mb_x++){
622 int error;
623 const int mb_xy= mb_x + mb_y*s->mb_stride;
624
625 error= s->error_status_table[mb_xy];
626 if((error&DC_ERROR) && (error&MV_ERROR))
627 continue; //skip damaged
628
629 j++;
630 if((j%skip_amount) != 0) continue; //skip a few to speed things up
631
632 if(s->pict_type==FF_I_TYPE){
633 uint8_t *mb_ptr = s->current_picture.data[0] + mb_x*16 + mb_y*16*s->linesize;
634 uint8_t *last_mb_ptr= s->last_picture.data [0] + mb_x*16 + mb_y*16*s->linesize;
635
636 is_intra_likely += s->dsp.sad[0](NULL, last_mb_ptr, mb_ptr , s->linesize, 16);
637 is_intra_likely -= s->dsp.sad[0](NULL, last_mb_ptr, last_mb_ptr+s->linesize*16, s->linesize, 16);
638 }else{
639 if(IS_INTRA(s->current_picture.mb_type[mb_xy]))
640 is_intra_likely++;
641 else
642 is_intra_likely--;
643 }
644 }
645 }
646 //printf("is_intra_likely: %d type:%d\n", is_intra_likely, s->pict_type);
647 return is_intra_likely > 0;
648 }
649
650 void ff_er_frame_start(MpegEncContext *s){
651 if(!s->error_recognition) return;
652
653 memset(s->error_status_table, MV_ERROR|AC_ERROR|DC_ERROR|VP_START|AC_END|DC_END|MV_END, s->mb_stride*s->mb_height*sizeof(uint8_t));
654 s->error_count= 3*s->mb_num;
655 }
656
657 /**
658 * adds a slice.
659 * @param endx x component of the last macroblock, can be -1 for the last of the previous line
660 * @param status the status at the end (MV_END, AC_ERROR, ...), it is assumed that no earlier end or
661 * error of the same type occurred
662 */
663 void ff_er_add_slice(MpegEncContext *s, int startx, int starty, int endx, int endy, int status){
664 const int start_i= av_clip(startx + starty * s->mb_width , 0, s->mb_num-1);
665 const int end_i = av_clip(endx + endy * s->mb_width , 0, s->mb_num);
666 const int start_xy= s->mb_index2xy[start_i];
667 const int end_xy = s->mb_index2xy[end_i];
668 int mask= -1;
669
670 if(s->avctx->hwaccel)
671 return;
672
673 if(start_i > end_i || start_xy > end_xy){
674 av_log(s->avctx, AV_LOG_ERROR, "internal error, slice end before start\n");
675 return;
676 }
677
678 if(!s->error_recognition) return;
679
680 mask &= ~VP_START;
681 if(status & (AC_ERROR|AC_END)){
682 mask &= ~(AC_ERROR|AC_END);
683 s->error_count -= end_i - start_i + 1;
684 }
685 if(status & (DC_ERROR|DC_END)){
686 mask &= ~(DC_ERROR|DC_END);
687 s->error_count -= end_i - start_i + 1;
688 }
689 if(status & (MV_ERROR|MV_END)){
690 mask &= ~(MV_ERROR|MV_END);
691 s->error_count -= end_i - start_i + 1;
692 }
693
694 if(status & (AC_ERROR|DC_ERROR|MV_ERROR)) s->error_count= INT_MAX;
695
696 if(mask == ~0x7F){
697 memset(&s->error_status_table[start_xy], 0, (end_xy - start_xy) * sizeof(uint8_t));
698 }else{
699 int i;
700 for(i=start_xy; i<end_xy; i++){
701 s->error_status_table[ i ] &= mask;
702 }
703 }
704
705 if(end_i == s->mb_num)
706 s->error_count= INT_MAX;
707 else{
708 s->error_status_table[end_xy] &= mask;
709 s->error_status_table[end_xy] |= status;
710 }
711
712 s->error_status_table[start_xy] |= VP_START;
713
714 if(start_xy > 0 && s->avctx->thread_count <= 1 && s->avctx->skip_top*s->mb_width < start_i){
715 int prev_status= s->error_status_table[ s->mb_index2xy[start_i - 1] ];
716
717 prev_status &= ~ VP_START;
718 if(prev_status != (MV_END|DC_END|AC_END)) s->error_count= INT_MAX;
719 }
720 }
721
722 void ff_er_frame_end(MpegEncContext *s){
723 int i, mb_x, mb_y, error, error_type, dc_error, mv_error, ac_error;
724 int distance;
725 int threshold_part[4]= {100,100,100};
726 int threshold= 50;
727 int is_intra_likely;
728 int size = s->b8_stride * 2 * s->mb_height;
729 Picture *pic= s->current_picture_ptr;
730
731 if(!s->error_recognition || s->error_count==0 || s->avctx->lowres ||
732 s->avctx->hwaccel ||
733 s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU ||
734 s->picture_structure != PICT_FRAME || // we dont support ER of field pictures yet, though it should not crash if enabled
735 s->error_count==3*s->mb_width*(s->avctx->skip_top + s->avctx->skip_bottom)) return;
736
737 if(s->current_picture.motion_val[0] == NULL){
738 av_log(s->avctx, AV_LOG_ERROR, "Warning MVs not available\n");
739
740 for(i=0; i<2; i++){
741 pic->ref_index[i]= av_mallocz(s->mb_stride * s->mb_height * 4 * sizeof(uint8_t));
742 pic->motion_val_base[i]= av_mallocz((size+4) * 2 * sizeof(uint16_t));
743 pic->motion_val[i]= pic->motion_val_base[i]+4;
744 }
745 pic->motion_subsample_log2= 3;
746 s->current_picture= *s->current_picture_ptr;
747 }
748
749 for(i=0; i<2; i++){
750 if(pic->ref_index[i])
751 memset(pic->ref_index[i], 0, size * sizeof(uint8_t));
752 }
753
754 if(s->avctx->debug&FF_DEBUG_ER){
755 for(mb_y=0; mb_y<s->mb_height; mb_y++){
756 for(mb_x=0; mb_x<s->mb_width; mb_x++){
757 int status= s->error_status_table[mb_x + mb_y*s->mb_stride];
758
759 av_log(s->avctx, AV_LOG_DEBUG, "%2X ", status);
760 }
761 av_log(s->avctx, AV_LOG_DEBUG, "\n");
762 }
763 }
764
765 #if 1
766 /* handle overlapping slices */
767 for(error_type=1; error_type<=3; error_type++){
768 int end_ok=0;
769
770 for(i=s->mb_num-1; i>=0; i--){
771 const int mb_xy= s->mb_index2xy[i];
772 int error= s->error_status_table[mb_xy];
773
774 if(error&(1<<error_type))
775 end_ok=1;
776 if(error&(8<<error_type))
777 end_ok=1;
778
779 if(!end_ok)
780 s->error_status_table[mb_xy]|= 1<<error_type;
781
782 if(error&VP_START)
783 end_ok=0;
784 }
785 }
786 #endif
787 #if 1
788 /* handle slices with partitions of different length */
789 if(s->partitioned_frame){
790 int end_ok=0;
791
792 for(i=s->mb_num-1; i>=0; i--){
793 const int mb_xy= s->mb_index2xy[i];
794 int error= s->error_status_table[mb_xy];
795
796 if(error&AC_END)
797 end_ok=0;
798 if((error&MV_END) || (error&DC_END) || (error&AC_ERROR))
799 end_ok=1;
800
801 if(!end_ok)
802 s->error_status_table[mb_xy]|= AC_ERROR;
803
804 if(error&VP_START)
805 end_ok=0;
806 }
807 }
808 #endif
809 /* handle missing slices */
810 if(s->error_recognition>=4){
811 int end_ok=1;
812
813 for(i=s->mb_num-2; i>=s->mb_width+100; i--){ //FIXME +100 hack
814 const int mb_xy= s->mb_index2xy[i];
815 int error1= s->error_status_table[mb_xy ];
816 int error2= s->error_status_table[s->mb_index2xy[i+1]];
817
818 if(error1&VP_START)
819 end_ok=1;
820
821 if( error2==(VP_START|DC_ERROR|AC_ERROR|MV_ERROR|AC_END|DC_END|MV_END)
822 && error1!=(VP_START|DC_ERROR|AC_ERROR|MV_ERROR|AC_END|DC_END|MV_END)
823 && ((error1&AC_END) || (error1&DC_END) || (error1&MV_END))){ //end & uninit
824 end_ok=0;
825 }
826
827 if(!end_ok)
828 s->error_status_table[mb_xy]|= DC_ERROR|AC_ERROR|MV_ERROR;
829 }
830 }
831
832 #if 1
833 /* backward mark errors */
834 distance=9999999;
835 for(error_type=1; error_type<=3; error_type++){
836 for(i=s->mb_num-1; i>=0; i--){
837 const int mb_xy= s->mb_index2xy[i];
838 int error= s->error_status_table[mb_xy];
839
840 if(!s->mbskip_table[mb_xy]) //FIXME partition specific
841 distance++;
842 if(error&(1<<error_type))
843 distance= 0;
844
845 if(s->partitioned_frame){
846 if(distance < threshold_part[error_type-1])
847 s->error_status_table[mb_xy]|= 1<<error_type;
848 }else{
849 if(distance < threshold)
850 s->error_status_table[mb_xy]|= 1<<error_type;
851 }
852
853 if(error&VP_START)
854 distance= 9999999;
855 }
856 }
857 #endif
858
859 /* forward mark errors */
860 error=0;
861 for(i=0; i<s->mb_num; i++){
862 const int mb_xy= s->mb_index2xy[i];
863 int old_error= s->error_status_table[mb_xy];
864
865 if(old_error&VP_START)
866 error= old_error& (DC_ERROR|AC_ERROR|MV_ERROR);
867 else{
868 error|= old_error& (DC_ERROR|AC_ERROR|MV_ERROR);
869 s->error_status_table[mb_xy]|= error;
870 }
871 }
872 #if 1
873 /* handle not partitioned case */
874 if(!s->partitioned_frame){
875 for(i=0; i<s->mb_num; i++){
876 const int mb_xy= s->mb_index2xy[i];
877 error= s->error_status_table[mb_xy];
878 if(error&(AC_ERROR|DC_ERROR|MV_ERROR))
879 error|= AC_ERROR|DC_ERROR|MV_ERROR;
880 s->error_status_table[mb_xy]= error;
881 }
882 }
883 #endif
884
885 dc_error= ac_error= mv_error=0;
886 for(i=0; i<s->mb_num; i++){
887 const int mb_xy= s->mb_index2xy[i];
888 error= s->error_status_table[mb_xy];
889 if(error&DC_ERROR) dc_error ++;
890 if(error&AC_ERROR) ac_error ++;
891 if(error&MV_ERROR) mv_error ++;
892 }
893 av_log(s->avctx, AV_LOG_INFO, "concealing %d DC, %d AC, %d MV errors\n", dc_error, ac_error, mv_error);
894
895 is_intra_likely= is_intra_more_likely(s);
896
897 /* set unknown mb-type to most likely */
898 for(i=0; i<s->mb_num; i++){
899 const int mb_xy= s->mb_index2xy[i];
900 error= s->error_status_table[mb_xy];
901 if(!((error&DC_ERROR) && (error&MV_ERROR)))
902 continue;
903
904 if(is_intra_likely)
905 s->current_picture.mb_type[mb_xy]= MB_TYPE_INTRA4x4;
906 else
907 s->current_picture.mb_type[mb_xy]= MB_TYPE_16x16 | MB_TYPE_L0;
908 }
909
910 // change inter to intra blocks if no reference frames are available
911 if (!s->last_picture.data[0] && !s->next_picture.data[0])
912 for(i=0; i<s->mb_num; i++){
913 const int mb_xy= s->mb_index2xy[i];
914 if(!IS_INTRA(s->current_picture.mb_type[mb_xy]))
915 s->current_picture.mb_type[mb_xy]= MB_TYPE_INTRA4x4;
916 }
917
918 /* handle inter blocks with damaged AC */
919 for(mb_y=0; mb_y<s->mb_height; mb_y++){
920 for(mb_x=0; mb_x<s->mb_width; mb_x++){
921 const int mb_xy= mb_x + mb_y * s->mb_stride;
922 const int mb_type= s->current_picture.mb_type[mb_xy];
923 int dir = !s->last_picture.data[0];
924 error= s->error_status_table[mb_xy];
925
926 if(IS_INTRA(mb_type)) continue; //intra
927 if(error&MV_ERROR) continue; //inter with damaged MV
928 if(!(error&AC_ERROR)) continue; //undamaged inter
929
930 s->mv_dir = dir ? MV_DIR_BACKWARD : MV_DIR_FORWARD;
931 s->mb_intra=0;
932 s->mb_skipped=0;
933 if(IS_8X8(mb_type)){
934 int mb_index= mb_x*2 + mb_y*2*s->b8_stride;
935 int j;
936 s->mv_type = MV_TYPE_8X8;
937 for(j=0; j<4; j++){
938 s->mv[0][j][0] = s->current_picture.motion_val[dir][ mb_index + (j&1) + (j>>1)*s->b8_stride ][0];
939 s->mv[0][j][1] = s->current_picture.motion_val[dir][ mb_index + (j&1) + (j>>1)*s->b8_stride ][1];
940 }
941 }else{
942 s->mv_type = MV_TYPE_16X16;
943 s->mv[0][0][0] = s->current_picture.motion_val[dir][ mb_x*2 + mb_y*2*s->b8_stride ][0];
944 s->mv[0][0][1] = s->current_picture.motion_val[dir][ mb_x*2 + mb_y*2*s->b8_stride ][1];
945 }
946
947 s->dsp.clear_blocks(s->block[0]);
948
949 s->mb_x= mb_x;
950 s->mb_y= mb_y;
951 decode_mb(s);
952 }
953 }
954
955 /* guess MVs */
956 if(s->pict_type==FF_B_TYPE){
957 for(mb_y=0; mb_y<s->mb_height; mb_y++){
958 for(mb_x=0; mb_x<s->mb_width; mb_x++){
959 int xy= mb_x*2 + mb_y*2*s->b8_stride;
960 const int mb_xy= mb_x + mb_y * s->mb_stride;
961 const int mb_type= s->current_picture.mb_type[mb_xy];
962 error= s->error_status_table[mb_xy];
963
964 if(IS_INTRA(mb_type)) continue;
965 if(!(error&MV_ERROR)) continue; //inter with undamaged MV
966 if(!(error&AC_ERROR)) continue; //undamaged inter
967
968 s->mv_dir = MV_DIR_FORWARD|MV_DIR_BACKWARD;
969 if(!s->last_picture.data[0]) s->mv_dir &= ~MV_DIR_FORWARD;
970 if(!s->next_picture.data[0]) s->mv_dir &= ~MV_DIR_BACKWARD;
971 s->mb_intra=0;
972 s->mv_type = MV_TYPE_16X16;
973 s->mb_skipped=0;
974
975 if(s->pp_time){
976 int time_pp= s->pp_time;
977 int time_pb= s->pb_time;
978
979 s->mv[0][0][0] = s->next_picture.motion_val[0][xy][0]*time_pb/time_pp;
980 s->mv[0][0][1] = s->next_picture.motion_val[0][xy][1]*time_pb/time_pp;
981 s->mv[1][0][0] = s->next_picture.motion_val[0][xy][0]*(time_pb - time_pp)/time_pp;
982 s->mv[1][0][1] = s->next_picture.motion_val[0][xy][1]*(time_pb - time_pp)/time_pp;
983 }else{
984 s->mv[0][0][0]= 0;
985 s->mv[0][0][1]= 0;
986 s->mv[1][0][0]= 0;
987 s->mv[1][0][1]= 0;
988 }
989
990 s->dsp.clear_blocks(s->block[0]);
991 s->mb_x= mb_x;
992 s->mb_y= mb_y;
993 decode_mb(s);
994 }
995 }
996 }else
997 guess_mv(s);
998
999 /* the filters below are not XvMC compatible, skip them */
1000 if(CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration)
1001 goto ec_clean;
1002 /* fill DC for inter blocks */
1003 for(mb_y=0; mb_y<s->mb_height; mb_y++){
1004 for(mb_x=0; mb_x<s->mb_width; mb_x++){
1005 int dc, dcu, dcv, y, n;
1006 int16_t *dc_ptr;
1007 uint8_t *dest_y, *dest_cb, *dest_cr;
1008 const int mb_xy= mb_x + mb_y * s->mb_stride;
1009 const int mb_type= s->current_picture.mb_type[mb_xy];
1010
1011 error= s->error_status_table[mb_xy];
1012
1013 if(IS_INTRA(mb_type) && s->partitioned_frame) continue;
1014 // if(error&MV_ERROR) continue; //inter data damaged FIXME is this good?
1015
1016 dest_y = s->current_picture.data[0] + mb_x*16 + mb_y*16*s->linesize;
1017 dest_cb= s->current_picture.data[1] + mb_x*8 + mb_y*8 *s->uvlinesize;
1018 dest_cr= s->current_picture.data[2] + mb_x*8 + mb_y*8 *s->uvlinesize;
1019
1020 dc_ptr= &s->dc_val[0][mb_x*2 + mb_y*2*s->b8_stride];
1021 for(n=0; n<4; n++){
1022 dc=0;
1023 for(y=0; y<8; y++){
1024 int x;
1025 for(x=0; x<8; x++){
1026 dc+= dest_y[x + (n&1)*8 + (y + (n>>1)*8)*s->linesize];
1027 }
1028 }
1029 dc_ptr[(n&1) + (n>>1)*s->b8_stride]= (dc+4)>>3;
1030 }
1031
1032 dcu=dcv=0;
1033 for(y=0; y<8; y++){
1034 int x;
1035 for(x=0; x<8; x++){
1036 dcu+=dest_cb[x + y*(s->uvlinesize)];
1037 dcv+=dest_cr[x + y*(s->uvlinesize)];
1038 }
1039 }
1040 s->dc_val[1][mb_x + mb_y*s->mb_stride]= (dcu+4)>>3;
1041 s->dc_val[2][mb_x + mb_y*s->mb_stride]= (dcv+4)>>3;
1042 }
1043 }
1044 #if 1
1045 /* guess DC for damaged blocks */
1046 guess_dc(s, s->dc_val[0], s->mb_width*2, s->mb_height*2, s->b8_stride, 1);
1047 guess_dc(s, s->dc_val[1], s->mb_width , s->mb_height , s->mb_stride, 0);
1048 guess_dc(s, s->dc_val[2], s->mb_width , s->mb_height , s->mb_stride, 0);
1049 #endif
1050 /* filter luma DC */
1051 filter181(s->dc_val[0], s->mb_width*2, s->mb_height*2, s->b8_stride);
1052
1053 #if 1
1054 /* render DC only intra */
1055 for(mb_y=0; mb_y<s->mb_height; mb_y++){
1056 for(mb_x=0; mb_x<s->mb_width; mb_x++){
1057 uint8_t *dest_y, *dest_cb, *dest_cr;
1058 const int mb_xy= mb_x + mb_y * s->mb_stride;
1059 const int mb_type= s->current_picture.mb_type[mb_xy];
1060
1061 error= s->error_status_table[mb_xy];
1062
1063 if(IS_INTER(mb_type)) continue;
1064 if(!(error&AC_ERROR)) continue; //undamaged
1065
1066 dest_y = s->current_picture.data[0] + mb_x*16 + mb_y*16*s->linesize;
1067 dest_cb= s->current_picture.data[1] + mb_x*8 + mb_y*8 *s->uvlinesize;
1068 dest_cr= s->current_picture.data[2] + mb_x*8 + mb_y*8 *s->uvlinesize;
1069
1070 put_dc(s, dest_y, dest_cb, dest_cr, mb_x, mb_y);
1071 }
1072 }
1073 #endif
1074
1075 if(s->avctx->error_concealment&FF_EC_DEBLOCK){
1076 /* filter horizontal block boundaries */
1077 h_block_filter(s, s->current_picture.data[0], s->mb_width*2, s->mb_height*2, s->linesize , 1);
1078 h_block_filter(s, s->current_picture.data[1], s->mb_width , s->mb_height , s->uvlinesize, 0);
1079 h_block_filter(s, s->current_picture.data[2], s->mb_width , s->mb_height , s->uvlinesize, 0);
1080
1081 /* filter vertical block boundaries */
1082 v_block_filter(s, s->current_picture.data[0], s->mb_width*2, s->mb_height*2, s->linesize , 1);
1083 v_block_filter(s, s->current_picture.data[1], s->mb_width , s->mb_height , s->uvlinesize, 0);
1084 v_block_filter(s, s->current_picture.data[2], s->mb_width , s->mb_height , s->uvlinesize, 0);
1085 }
1086
1087 ec_clean:
1088 /* clean a few tables */
1089 for(i=0; i<s->mb_num; i++){
1090 const int mb_xy= s->mb_index2xy[i];
1091 int error= s->error_status_table[mb_xy];
1092
1093 if(s->pict_type!=FF_B_TYPE && (error&(DC_ERROR|MV_ERROR|AC_ERROR))){
1094 s->mbskip_table[mb_xy]=0;
1095 }
1096 s->mbintra_table[mb_xy]=1;
1097 }
1098 }