2
* Error resilience / concealment
4
* Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
6
* This file is part of FFmpeg.
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.
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.
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
25
* Error resilience / concealment.
32
#include "mpegvideo.h"
34
#include "rectangle.h"
37
* H264 redefines mb_intra so it is not mistakely used (its uninitialized in h264)
38
* but error concealment must support both h264 and h263 thus we must undo this
42
static void decode_mb(MpegEncContext *s, int ref){
43
s->dest[0] = s->current_picture.data[0] + (s->mb_y * 16* s->linesize ) + s->mb_x * 16;
44
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);
45
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);
47
if(CONFIG_H264_DECODER && s->codec_id == CODEC_ID_H264){
48
H264Context *h= (void*)s;
49
h->mb_xy= s->mb_x + s->mb_y*s->mb_stride;
50
memset(h->non_zero_count_cache, 0, sizeof(h->non_zero_count_cache));
52
if(ref >= h->ref_count[0]) //FIXME it is posible albeit uncommon that slice references differ between slices, we take the easy approuch and ignore it for now. If this turns out to have any relevance in practice then correct remapping should be added
54
fill_rectangle(&s->current_picture.ref_index[0][4*h->mb_xy], 2, 2, 2, ref, 1);
55
fill_rectangle(&h->ref_cache[0][scan8[0]], 4, 4, 8, ref, 1);
56
fill_rectangle(h->mv_cache[0][ scan8[0] ], 4, 4, 8, pack16to32(s->mv[0][0][0],s->mv[0][0][1]), 4);
58
ff_h264_hl_decode_mb(h);
61
MPV_decode_mb(s, s->block);
66
* @param stride the number of MVs to get to the next row
67
* @param mv_step the number of MVs per row or column in a macroblock
69
static void set_mv_strides(MpegEncContext *s, int *mv_step, int *stride){
70
if(s->codec_id == CODEC_ID_H264){
71
H264Context *h= (void*)s;
72
assert(s->quarter_sample);
77
*stride= s->b8_stride;
82
* replaces the current MB with a flat dc only version.
84
static void put_dc(MpegEncContext *s, uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr, int mb_x, int mb_y)
86
int dc, dcu, dcv, y, i;
88
dc= s->dc_val[0][mb_x*2 + (i&1) + (mb_y*2 + (i>>1))*s->b8_stride];
90
else if(dc>2040) dc=2040;
94
dest_y[x + (i&1)*8 + (y + (i>>1)*8)*s->linesize]= dc/8;
98
dcu = s->dc_val[1][mb_x + mb_y*s->mb_stride];
99
dcv = s->dc_val[2][mb_x + mb_y*s->mb_stride];
101
else if(dcu>2040) dcu=2040;
103
else if(dcv>2040) dcv=2040;
107
dest_cb[x + y*(s->uvlinesize)]= dcu/8;
108
dest_cr[x + y*(s->uvlinesize)]= dcv/8;
113
static void filter181(int16_t *data, int width, int height, int stride){
116
/* horizontal filter */
117
for(y=1; y<height-1; y++){
118
int prev_dc= data[0 + y*stride];
120
for(x=1; x<width-1; x++){
124
+ data[x + y*stride]*8
125
- data[x + 1 + y*stride];
126
dc= (dc*10923 + 32768)>>16;
127
prev_dc= data[x + y*stride];
128
data[x + y*stride]= dc;
132
/* vertical filter */
133
for(x=1; x<width-1; x++){
134
int prev_dc= data[x];
136
for(y=1; y<height-1; y++){
140
+ data[x + y *stride]*8
141
- data[x + (y+1)*stride];
142
dc= (dc*10923 + 32768)>>16;
143
prev_dc= data[x + y*stride];
144
data[x + y*stride]= dc;
150
* guess the dc of blocks which do not have an undamaged dc
151
* @param w width in 8 pixel blocks
152
* @param h height in 8 pixel blocks
154
static void guess_dc(MpegEncContext *s, int16_t *dc, int w, int h, int stride, int is_luma){
157
for(b_y=0; b_y<h; b_y++){
158
for(b_x=0; b_x<w; b_x++){
159
int color[4]={1024,1024,1024,1024};
160
int distance[4]={9999,9999,9999,9999};
161
int mb_index, error, j;
162
int64_t guess, weight_sum;
164
mb_index= (b_x>>is_luma) + (b_y>>is_luma)*s->mb_stride;
166
error= s->error_status_table[mb_index];
168
if(IS_INTER(s->current_picture.mb_type[mb_index])) continue; //inter
169
if(!(error&DC_ERROR)) continue; //dc-ok
172
for(j=b_x+1; j<w; j++){
173
int mb_index_j= (j>>is_luma) + (b_y>>is_luma)*s->mb_stride;
174
int error_j= s->error_status_table[mb_index_j];
175
int intra_j= IS_INTRA(s->current_picture.mb_type[mb_index_j]);
176
if(intra_j==0 || !(error_j&DC_ERROR)){
177
color[0]= dc[j + b_y*stride];
184
for(j=b_x-1; j>=0; j--){
185
int mb_index_j= (j>>is_luma) + (b_y>>is_luma)*s->mb_stride;
186
int error_j= s->error_status_table[mb_index_j];
187
int intra_j= IS_INTRA(s->current_picture.mb_type[mb_index_j]);
188
if(intra_j==0 || !(error_j&DC_ERROR)){
189
color[1]= dc[j + b_y*stride];
196
for(j=b_y+1; j<h; j++){
197
int mb_index_j= (b_x>>is_luma) + (j>>is_luma)*s->mb_stride;
198
int error_j= s->error_status_table[mb_index_j];
199
int intra_j= IS_INTRA(s->current_picture.mb_type[mb_index_j]);
200
if(intra_j==0 || !(error_j&DC_ERROR)){
201
color[2]= dc[b_x + j*stride];
208
for(j=b_y-1; j>=0; j--){
209
int mb_index_j= (b_x>>is_luma) + (j>>is_luma)*s->mb_stride;
210
int error_j= s->error_status_table[mb_index_j];
211
int intra_j= IS_INTRA(s->current_picture.mb_type[mb_index_j]);
212
if(intra_j==0 || !(error_j&DC_ERROR)){
213
color[3]= dc[b_x + j*stride];
222
int64_t weight= 256*256*256*16/distance[j];
223
guess+= weight*(int64_t)color[j];
226
guess= (guess + weight_sum/2) / weight_sum;
228
dc[b_x + b_y*stride]= guess;
234
* simple horizontal deblocking filter used for error resilience
235
* @param w width in 8 pixel blocks
236
* @param h height in 8 pixel blocks
238
static void h_block_filter(MpegEncContext *s, uint8_t *dst, int w, int h, int stride, int is_luma){
239
int b_x, b_y, mvx_stride, mvy_stride;
240
uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
241
set_mv_strides(s, &mvx_stride, &mvy_stride);
242
mvx_stride >>= is_luma;
243
mvy_stride *= mvx_stride;
245
for(b_y=0; b_y<h; b_y++){
246
for(b_x=0; b_x<w-1; b_x++){
248
int left_status = s->error_status_table[( b_x >>is_luma) + (b_y>>is_luma)*s->mb_stride];
249
int right_status= s->error_status_table[((b_x+1)>>is_luma) + (b_y>>is_luma)*s->mb_stride];
250
int left_intra= IS_INTRA(s->current_picture.mb_type [( b_x >>is_luma) + (b_y>>is_luma)*s->mb_stride]);
251
int right_intra= IS_INTRA(s->current_picture.mb_type [((b_x+1)>>is_luma) + (b_y>>is_luma)*s->mb_stride]);
252
int left_damage = left_status&(DC_ERROR|AC_ERROR|MV_ERROR);
253
int right_damage= right_status&(DC_ERROR|AC_ERROR|MV_ERROR);
254
int offset= b_x*8 + b_y*stride*8;
255
int16_t *left_mv= s->current_picture.motion_val[0][mvy_stride*b_y + mvx_stride* b_x ];
256
int16_t *right_mv= s->current_picture.motion_val[0][mvy_stride*b_y + mvx_stride*(b_x+1)];
258
if(!(left_damage||right_damage)) continue; // both undamaged
260
if( (!left_intra) && (!right_intra)
261
&& FFABS(left_mv[0]-right_mv[0]) + FFABS(left_mv[1]+right_mv[1]) < 2) continue;
266
a= dst[offset + 7 + y*stride] - dst[offset + 6 + y*stride];
267
b= dst[offset + 8 + y*stride] - dst[offset + 7 + y*stride];
268
c= dst[offset + 9 + y*stride] - dst[offset + 8 + y*stride];
270
d= FFABS(b) - ((FFABS(a) + FFABS(c) + 1)>>1);
276
if(!(left_damage && right_damage))
280
dst[offset + 7 + y*stride] = cm[dst[offset + 7 + y*stride] + ((d*7)>>4)];
281
dst[offset + 6 + y*stride] = cm[dst[offset + 6 + y*stride] + ((d*5)>>4)];
282
dst[offset + 5 + y*stride] = cm[dst[offset + 5 + y*stride] + ((d*3)>>4)];
283
dst[offset + 4 + y*stride] = cm[dst[offset + 4 + y*stride] + ((d*1)>>4)];
286
dst[offset + 8 + y*stride] = cm[dst[offset + 8 + y*stride] - ((d*7)>>4)];
287
dst[offset + 9 + y*stride] = cm[dst[offset + 9 + y*stride] - ((d*5)>>4)];
288
dst[offset + 10+ y*stride] = cm[dst[offset +10 + y*stride] - ((d*3)>>4)];
289
dst[offset + 11+ y*stride] = cm[dst[offset +11 + y*stride] - ((d*1)>>4)];
297
* simple vertical deblocking filter used for error resilience
298
* @param w width in 8 pixel blocks
299
* @param h height in 8 pixel blocks
301
static void v_block_filter(MpegEncContext *s, uint8_t *dst, int w, int h, int stride, int is_luma){
302
int b_x, b_y, mvx_stride, mvy_stride;
303
uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
304
set_mv_strides(s, &mvx_stride, &mvy_stride);
305
mvx_stride >>= is_luma;
306
mvy_stride *= mvx_stride;
308
for(b_y=0; b_y<h-1; b_y++){
309
for(b_x=0; b_x<w; b_x++){
311
int top_status = s->error_status_table[(b_x>>is_luma) + ( b_y >>is_luma)*s->mb_stride];
312
int bottom_status= s->error_status_table[(b_x>>is_luma) + ((b_y+1)>>is_luma)*s->mb_stride];
313
int top_intra= IS_INTRA(s->current_picture.mb_type [(b_x>>is_luma) + ( b_y >>is_luma)*s->mb_stride]);
314
int bottom_intra= IS_INTRA(s->current_picture.mb_type [(b_x>>is_luma) + ((b_y+1)>>is_luma)*s->mb_stride]);
315
int top_damage = top_status&(DC_ERROR|AC_ERROR|MV_ERROR);
316
int bottom_damage= bottom_status&(DC_ERROR|AC_ERROR|MV_ERROR);
317
int offset= b_x*8 + b_y*stride*8;
318
int16_t *top_mv= s->current_picture.motion_val[0][mvy_stride* b_y + mvx_stride*b_x];
319
int16_t *bottom_mv= s->current_picture.motion_val[0][mvy_stride*(b_y+1) + mvx_stride*b_x];
321
if(!(top_damage||bottom_damage)) continue; // both undamaged
323
if( (!top_intra) && (!bottom_intra)
324
&& FFABS(top_mv[0]-bottom_mv[0]) + FFABS(top_mv[1]+bottom_mv[1]) < 2) continue;
329
a= dst[offset + x + 7*stride] - dst[offset + x + 6*stride];
330
b= dst[offset + x + 8*stride] - dst[offset + x + 7*stride];
331
c= dst[offset + x + 9*stride] - dst[offset + x + 8*stride];
333
d= FFABS(b) - ((FFABS(a) + FFABS(c)+1)>>1);
339
if(!(top_damage && bottom_damage))
343
dst[offset + x + 7*stride] = cm[dst[offset + x + 7*stride] + ((d*7)>>4)];
344
dst[offset + x + 6*stride] = cm[dst[offset + x + 6*stride] + ((d*5)>>4)];
345
dst[offset + x + 5*stride] = cm[dst[offset + x + 5*stride] + ((d*3)>>4)];
346
dst[offset + x + 4*stride] = cm[dst[offset + x + 4*stride] + ((d*1)>>4)];
349
dst[offset + x + 8*stride] = cm[dst[offset + x + 8*stride] - ((d*7)>>4)];
350
dst[offset + x + 9*stride] = cm[dst[offset + x + 9*stride] - ((d*5)>>4)];
351
dst[offset + x + 10*stride] = cm[dst[offset + x + 10*stride] - ((d*3)>>4)];
352
dst[offset + x + 11*stride] = cm[dst[offset + x + 11*stride] - ((d*1)>>4)];
359
static void guess_mv(MpegEncContext *s){
360
uint8_t fixed[s->mb_stride * s->mb_height];
363
#define MV_UNCHANGED 1
364
const int mb_stride = s->mb_stride;
365
const int mb_width = s->mb_width;
366
const int mb_height= s->mb_height;
367
int i, depth, num_avail;
368
int mb_x, mb_y, mot_step, mot_stride;
370
set_mv_strides(s, &mot_step, &mot_stride);
373
for(i=0; i<s->mb_num; i++){
374
const int mb_xy= s->mb_index2xy[ i ];
376
int error= s->error_status_table[mb_xy];
378
if(IS_INTRA(s->current_picture.mb_type[mb_xy])) f=MV_FROZEN; //intra //FIXME check
379
if(!(error&MV_ERROR)) f=MV_FROZEN; //inter with undamaged MV
386
if((!(s->avctx->error_concealment&FF_EC_GUESS_MVS)) || num_avail <= mb_width/2){
387
for(mb_y=0; mb_y<s->mb_height; mb_y++){
388
for(mb_x=0; mb_x<s->mb_width; mb_x++){
389
const int mb_xy= mb_x + mb_y*s->mb_stride;
391
if(IS_INTRA(s->current_picture.mb_type[mb_xy])) continue;
392
if(!(s->error_status_table[mb_xy]&MV_ERROR)) continue;
394
s->mv_dir = s->last_picture.data[0] ? MV_DIR_FORWARD : MV_DIR_BACKWARD;
396
s->mv_type = MV_TYPE_16X16;
399
s->dsp.clear_blocks(s->block[0]);
411
for(depth=0;; depth++){
412
int changed, pass, none_left;
416
for(pass=0; (changed || pass<2) && pass<10; pass++){
421
for(mb_y=0; mb_y<s->mb_height; mb_y++){
422
for(mb_x=0; mb_x<s->mb_width; mb_x++){
423
const int mb_xy= mb_x + mb_y*s->mb_stride;
424
int mv_predictor[8][2]={{0}};
428
int best_score=256*256*256*64;
430
const int mot_index= (mb_x + mb_y*mot_stride) * mot_step;
431
int prev_x= s->current_picture.motion_val[0][mot_index][0];
432
int prev_y= s->current_picture.motion_val[0][mot_index][1];
434
if((mb_x^mb_y^pass)&1) continue;
436
if(fixed[mb_xy]==MV_FROZEN) continue;
437
assert(!IS_INTRA(s->current_picture.mb_type[mb_xy]));
438
assert(s->last_picture_ptr && s->last_picture_ptr->data[0]);
441
if(mb_x>0 && fixed[mb_xy-1 ]==MV_FROZEN) j=1;
442
if(mb_x+1<mb_width && fixed[mb_xy+1 ]==MV_FROZEN) j=1;
443
if(mb_y>0 && fixed[mb_xy-mb_stride]==MV_FROZEN) j=1;
444
if(mb_y+1<mb_height && fixed[mb_xy+mb_stride]==MV_FROZEN) j=1;
448
if(mb_x>0 && fixed[mb_xy-1 ]==MV_CHANGED) j=1;
449
if(mb_x+1<mb_width && fixed[mb_xy+1 ]==MV_CHANGED) j=1;
450
if(mb_y>0 && fixed[mb_xy-mb_stride]==MV_CHANGED) j=1;
451
if(mb_y+1<mb_height && fixed[mb_xy+mb_stride]==MV_CHANGED) j=1;
452
if(j==0 && pass>1) continue;
456
if(mb_x>0 && fixed[mb_xy-1]){
457
mv_predictor[pred_count][0]= s->current_picture.motion_val[0][mot_index - mot_step][0];
458
mv_predictor[pred_count][1]= s->current_picture.motion_val[0][mot_index - mot_step][1];
459
ref [pred_count] = s->current_picture.ref_index[0][4*(mb_xy-1)];
462
if(mb_x+1<mb_width && fixed[mb_xy+1]){
463
mv_predictor[pred_count][0]= s->current_picture.motion_val[0][mot_index + mot_step][0];
464
mv_predictor[pred_count][1]= s->current_picture.motion_val[0][mot_index + mot_step][1];
465
ref [pred_count] = s->current_picture.ref_index[0][4*(mb_xy+1)];
468
if(mb_y>0 && fixed[mb_xy-mb_stride]){
469
mv_predictor[pred_count][0]= s->current_picture.motion_val[0][mot_index - mot_stride*mot_step][0];
470
mv_predictor[pred_count][1]= s->current_picture.motion_val[0][mot_index - mot_stride*mot_step][1];
471
ref [pred_count] = s->current_picture.ref_index[0][4*(mb_xy-s->mb_stride)];
474
if(mb_y+1<mb_height && fixed[mb_xy+mb_stride]){
475
mv_predictor[pred_count][0]= s->current_picture.motion_val[0][mot_index + mot_stride*mot_step][0];
476
mv_predictor[pred_count][1]= s->current_picture.motion_val[0][mot_index + mot_stride*mot_step][1];
477
ref [pred_count] = s->current_picture.ref_index[0][4*(mb_xy+s->mb_stride)];
480
if(pred_count==0) continue;
483
int sum_x=0, sum_y=0, sum_r=0;
484
int max_x, max_y, min_x, min_y, max_r, min_r;
486
for(j=0; j<pred_count; j++){
487
sum_x+= mv_predictor[j][0];
488
sum_y+= mv_predictor[j][1];
490
if(j && ref[j] != ref[j-1])
491
goto skip_mean_and_median;
495
mv_predictor[pred_count][0] = sum_x/j;
496
mv_predictor[pred_count][1] = sum_y/j;
497
ref [pred_count] = sum_r/j;
501
min_y= min_x= min_r= 99999;
502
max_y= max_x= max_r=-99999;
504
min_x=min_y=max_x=max_y=min_r=max_r=0;
506
for(j=0; j<pred_count; j++){
507
max_x= FFMAX(max_x, mv_predictor[j][0]);
508
max_y= FFMAX(max_y, mv_predictor[j][1]);
509
max_r= FFMAX(max_r, ref[j]);
510
min_x= FFMIN(min_x, mv_predictor[j][0]);
511
min_y= FFMIN(min_y, mv_predictor[j][1]);
512
min_r= FFMIN(min_r, ref[j]);
514
mv_predictor[pred_count+1][0] = sum_x - max_x - min_x;
515
mv_predictor[pred_count+1][1] = sum_y - max_y - min_y;
516
ref [pred_count+1] = sum_r - max_r - min_r;
519
mv_predictor[pred_count+1][0] /= 2;
520
mv_predictor[pred_count+1][1] /= 2;
521
ref [pred_count+1] /= 2;
525
skip_mean_and_median:
531
mv_predictor[pred_count][0]= s->current_picture.motion_val[0][mot_index][0];
532
mv_predictor[pred_count][1]= s->current_picture.motion_val[0][mot_index][1];
533
ref [pred_count] = s->current_picture.ref_index[0][4*mb_xy];
536
s->mv_dir = MV_DIR_FORWARD;
538
s->mv_type = MV_TYPE_16X16;
541
s->dsp.clear_blocks(s->block[0]);
546
for(j=0; j<pred_count; j++){
548
uint8_t *src= s->current_picture.data[0] + mb_x*16 + mb_y*16*s->linesize;
550
s->current_picture.motion_val[0][mot_index][0]= s->mv[0][0][0]= mv_predictor[j][0];
551
s->current_picture.motion_val[0][mot_index][1]= s->mv[0][0][1]= mv_predictor[j][1];
553
if(ref[j]<0) //predictor intra or otherwise not available
556
decode_mb(s, ref[j]);
558
if(mb_x>0 && fixed[mb_xy-1]){
561
score += FFABS(src[k*s->linesize-1 ]-src[k*s->linesize ]);
563
if(mb_x+1<mb_width && fixed[mb_xy+1]){
566
score += FFABS(src[k*s->linesize+15]-src[k*s->linesize+16]);
568
if(mb_y>0 && fixed[mb_xy-mb_stride]){
571
score += FFABS(src[k-s->linesize ]-src[k ]);
573
if(mb_y+1<mb_height && fixed[mb_xy+mb_stride]){
576
score += FFABS(src[k+s->linesize*15]-src[k+s->linesize*16]);
579
if(score <= best_score){ // <= will favor the last MV
584
score_sum+= best_score;
585
s->mv[0][0][0]= mv_predictor[best_pred][0];
586
s->mv[0][0][1]= mv_predictor[best_pred][1];
588
for(i=0; i<mot_step; i++)
589
for(j=0; j<mot_step; j++){
590
s->current_picture.motion_val[0][mot_index+i+j*mot_stride][0]= s->mv[0][0][0];
591
s->current_picture.motion_val[0][mot_index+i+j*mot_stride][1]= s->mv[0][0][1];
594
decode_mb(s, ref[best_pred]);
597
if(s->mv[0][0][0] != prev_x || s->mv[0][0][1] != prev_y){
598
fixed[mb_xy]=MV_CHANGED;
601
fixed[mb_xy]=MV_UNCHANGED;
605
// printf(".%d/%d", changed, score_sum); fflush(stdout);
611
for(i=0; i<s->mb_num; i++){
612
int mb_xy= s->mb_index2xy[i];
614
fixed[mb_xy]=MV_FROZEN;
616
// printf(":"); fflush(stdout);
620
static int is_intra_more_likely(MpegEncContext *s){
621
int is_intra_likely, i, j, undamaged_count, skip_amount, mb_x, mb_y;
623
if(!s->last_picture_ptr || !s->last_picture_ptr->data[0]) return 1; //no previous frame available -> use spatial prediction
626
for(i=0; i<s->mb_num; i++){
627
const int mb_xy= s->mb_index2xy[i];
628
const int error= s->error_status_table[mb_xy];
629
if(!((error&DC_ERROR) && (error&MV_ERROR)))
633
if(s->codec_id == CODEC_ID_H264){
634
H264Context *h= (void*)s;
635
if(h->ref_count[0] <= 0 || !h->ref_list[0][0].data[0])
639
if(undamaged_count < 5) return 0; //almost all MBs damaged -> use temporal prediction
641
//prevent dsp.sad() check, that requires access to the image
642
if(CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration && s->pict_type == FF_I_TYPE)
645
skip_amount= FFMAX(undamaged_count/50, 1); //check only upto 50 MBs
649
for(mb_y= 0; mb_y<s->mb_height-1; mb_y++){
650
for(mb_x= 0; mb_x<s->mb_width; mb_x++){
652
const int mb_xy= mb_x + mb_y*s->mb_stride;
654
error= s->error_status_table[mb_xy];
655
if((error&DC_ERROR) && (error&MV_ERROR))
656
continue; //skip damaged
659
if((j%skip_amount) != 0) continue; //skip a few to speed things up
661
if(s->pict_type==FF_I_TYPE){
662
uint8_t *mb_ptr = s->current_picture.data[0] + mb_x*16 + mb_y*16*s->linesize;
663
uint8_t *last_mb_ptr= s->last_picture.data [0] + mb_x*16 + mb_y*16*s->linesize;
665
is_intra_likely += s->dsp.sad[0](NULL, last_mb_ptr, mb_ptr , s->linesize, 16);
666
is_intra_likely -= s->dsp.sad[0](NULL, last_mb_ptr, last_mb_ptr+s->linesize*16, s->linesize, 16);
668
if(IS_INTRA(s->current_picture.mb_type[mb_xy]))
675
//printf("is_intra_likely: %d type:%d\n", is_intra_likely, s->pict_type);
676
return is_intra_likely > 0;
679
void ff_er_frame_start(MpegEncContext *s){
680
if(!s->error_recognition) return;
682
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));
683
s->error_count= 3*s->mb_num;
688
* @param endx x component of the last macroblock, can be -1 for the last of the previous line
689
* @param status the status at the end (MV_END, AC_ERROR, ...), it is assumed that no earlier end or
690
* error of the same type occurred
692
void ff_er_add_slice(MpegEncContext *s, int startx, int starty, int endx, int endy, int status){
693
const int start_i= av_clip(startx + starty * s->mb_width , 0, s->mb_num-1);
694
const int end_i = av_clip(endx + endy * s->mb_width , 0, s->mb_num);
695
const int start_xy= s->mb_index2xy[start_i];
696
const int end_xy = s->mb_index2xy[end_i];
699
if(s->avctx->hwaccel)
702
if(start_i > end_i || start_xy > end_xy){
703
av_log(s->avctx, AV_LOG_ERROR, "internal error, slice end before start\n");
707
if(!s->error_recognition) return;
710
if(status & (AC_ERROR|AC_END)){
711
mask &= ~(AC_ERROR|AC_END);
712
s->error_count -= end_i - start_i + 1;
714
if(status & (DC_ERROR|DC_END)){
715
mask &= ~(DC_ERROR|DC_END);
716
s->error_count -= end_i - start_i + 1;
718
if(status & (MV_ERROR|MV_END)){
719
mask &= ~(MV_ERROR|MV_END);
720
s->error_count -= end_i - start_i + 1;
723
if(status & (AC_ERROR|DC_ERROR|MV_ERROR)) s->error_count= INT_MAX;
726
memset(&s->error_status_table[start_xy], 0, (end_xy - start_xy) * sizeof(uint8_t));
729
for(i=start_xy; i<end_xy; i++){
730
s->error_status_table[ i ] &= mask;
734
if(end_i == s->mb_num)
735
s->error_count= INT_MAX;
737
s->error_status_table[end_xy] &= mask;
738
s->error_status_table[end_xy] |= status;
741
s->error_status_table[start_xy] |= VP_START;
743
if(start_xy > 0 && s->avctx->thread_count <= 1 && s->avctx->skip_top*s->mb_width < start_i){
744
int prev_status= s->error_status_table[ s->mb_index2xy[start_i - 1] ];
746
prev_status &= ~ VP_START;
747
if(prev_status != (MV_END|DC_END|AC_END)) s->error_count= INT_MAX;
751
void ff_er_frame_end(MpegEncContext *s){
752
int i, mb_x, mb_y, error, error_type, dc_error, mv_error, ac_error;
754
int threshold_part[4]= {100,100,100};
757
int size = s->b8_stride * 2 * s->mb_height;
758
Picture *pic= s->current_picture_ptr;
760
if(!s->error_recognition || s->error_count==0 || s->avctx->lowres ||
762
s->picture_structure != PICT_FRAME || // we dont support ER of field pictures yet, though it should not crash if enabled
763
s->error_count==3*s->mb_width*(s->avctx->skip_top + s->avctx->skip_bottom)) return;
765
if(s->current_picture.motion_val[0] == NULL){
766
av_log(s->avctx, AV_LOG_ERROR, "Warning MVs not available\n");
769
pic->ref_index[i]= av_mallocz(s->mb_stride * s->mb_height * 4 * sizeof(uint8_t));
770
pic->motion_val_base[i]= av_mallocz((size+4) * 2 * sizeof(uint16_t));
771
pic->motion_val[i]= pic->motion_val_base[i]+4;
773
pic->motion_subsample_log2= 3;
774
s->current_picture= *s->current_picture_ptr;
777
if(s->avctx->debug&FF_DEBUG_ER){
778
for(mb_y=0; mb_y<s->mb_height; mb_y++){
779
for(mb_x=0; mb_x<s->mb_width; mb_x++){
780
int status= s->error_status_table[mb_x + mb_y*s->mb_stride];
782
av_log(s->avctx, AV_LOG_DEBUG, "%2X ", status);
784
av_log(s->avctx, AV_LOG_DEBUG, "\n");
789
/* handle overlapping slices */
790
for(error_type=1; error_type<=3; error_type++){
793
for(i=s->mb_num-1; i>=0; i--){
794
const int mb_xy= s->mb_index2xy[i];
795
int error= s->error_status_table[mb_xy];
797
if(error&(1<<error_type))
799
if(error&(8<<error_type))
803
s->error_status_table[mb_xy]|= 1<<error_type;
811
/* handle slices with partitions of different length */
812
if(s->partitioned_frame){
815
for(i=s->mb_num-1; i>=0; i--){
816
const int mb_xy= s->mb_index2xy[i];
817
int error= s->error_status_table[mb_xy];
821
if((error&MV_END) || (error&DC_END) || (error&AC_ERROR))
825
s->error_status_table[mb_xy]|= AC_ERROR;
832
/* handle missing slices */
833
if(s->error_recognition>=4){
836
for(i=s->mb_num-2; i>=s->mb_width+100; i--){ //FIXME +100 hack
837
const int mb_xy= s->mb_index2xy[i];
838
int error1= s->error_status_table[mb_xy ];
839
int error2= s->error_status_table[s->mb_index2xy[i+1]];
844
if( error2==(VP_START|DC_ERROR|AC_ERROR|MV_ERROR|AC_END|DC_END|MV_END)
845
&& error1!=(VP_START|DC_ERROR|AC_ERROR|MV_ERROR|AC_END|DC_END|MV_END)
846
&& ((error1&AC_END) || (error1&DC_END) || (error1&MV_END))){ //end & uninit
851
s->error_status_table[mb_xy]|= DC_ERROR|AC_ERROR|MV_ERROR;
856
/* backward mark errors */
858
for(error_type=1; error_type<=3; error_type++){
859
for(i=s->mb_num-1; i>=0; i--){
860
const int mb_xy= s->mb_index2xy[i];
861
int error= s->error_status_table[mb_xy];
863
if(!s->mbskip_table[mb_xy]) //FIXME partition specific
865
if(error&(1<<error_type))
868
if(s->partitioned_frame){
869
if(distance < threshold_part[error_type-1])
870
s->error_status_table[mb_xy]|= 1<<error_type;
872
if(distance < threshold)
873
s->error_status_table[mb_xy]|= 1<<error_type;
882
/* forward mark errors */
884
for(i=0; i<s->mb_num; i++){
885
const int mb_xy= s->mb_index2xy[i];
886
int old_error= s->error_status_table[mb_xy];
888
if(old_error&VP_START)
889
error= old_error& (DC_ERROR|AC_ERROR|MV_ERROR);
891
error|= old_error& (DC_ERROR|AC_ERROR|MV_ERROR);
892
s->error_status_table[mb_xy]|= error;
896
/* handle not partitioned case */
897
if(!s->partitioned_frame){
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&(AC_ERROR|DC_ERROR|MV_ERROR))
902
error|= AC_ERROR|DC_ERROR|MV_ERROR;
903
s->error_status_table[mb_xy]= error;
908
dc_error= ac_error= mv_error=0;
909
for(i=0; i<s->mb_num; i++){
910
const int mb_xy= s->mb_index2xy[i];
911
error= s->error_status_table[mb_xy];
912
if(error&DC_ERROR) dc_error ++;
913
if(error&AC_ERROR) ac_error ++;
914
if(error&MV_ERROR) mv_error ++;
916
av_log(s->avctx, AV_LOG_INFO, "concealing %d DC, %d AC, %d MV errors\n", dc_error, ac_error, mv_error);
918
is_intra_likely= is_intra_more_likely(s);
920
/* set unknown mb-type to most likely */
921
for(i=0; i<s->mb_num; i++){
922
const int mb_xy= s->mb_index2xy[i];
923
error= s->error_status_table[mb_xy];
924
if(!((error&DC_ERROR) && (error&MV_ERROR)))
928
s->current_picture.mb_type[mb_xy]= MB_TYPE_INTRA4x4;
930
s->current_picture.mb_type[mb_xy]= MB_TYPE_16x16 | MB_TYPE_L0;
933
// change inter to intra blocks if no reference frames are available
934
if (!s->last_picture.data[0] && !s->next_picture.data[0])
935
for(i=0; i<s->mb_num; i++){
936
const int mb_xy= s->mb_index2xy[i];
937
if(!IS_INTRA(s->current_picture.mb_type[mb_xy]))
938
s->current_picture.mb_type[mb_xy]= MB_TYPE_INTRA4x4;
941
/* handle inter blocks with damaged AC */
942
for(mb_y=0; mb_y<s->mb_height; mb_y++){
943
for(mb_x=0; mb_x<s->mb_width; mb_x++){
944
const int mb_xy= mb_x + mb_y * s->mb_stride;
945
const int mb_type= s->current_picture.mb_type[mb_xy];
946
int dir = !s->last_picture.data[0];
947
error= s->error_status_table[mb_xy];
949
if(IS_INTRA(mb_type)) continue; //intra
950
if(error&MV_ERROR) continue; //inter with damaged MV
951
if(!(error&AC_ERROR)) continue; //undamaged inter
953
s->mv_dir = dir ? MV_DIR_BACKWARD : MV_DIR_FORWARD;
957
int mb_index= mb_x*2 + mb_y*2*s->b8_stride;
959
s->mv_type = MV_TYPE_8X8;
961
s->mv[0][j][0] = s->current_picture.motion_val[dir][ mb_index + (j&1) + (j>>1)*s->b8_stride ][0];
962
s->mv[0][j][1] = s->current_picture.motion_val[dir][ mb_index + (j&1) + (j>>1)*s->b8_stride ][1];
965
s->mv_type = MV_TYPE_16X16;
966
s->mv[0][0][0] = s->current_picture.motion_val[dir][ mb_x*2 + mb_y*2*s->b8_stride ][0];
967
s->mv[0][0][1] = s->current_picture.motion_val[dir][ mb_x*2 + mb_y*2*s->b8_stride ][1];
970
s->dsp.clear_blocks(s->block[0]);
974
decode_mb(s, 0/*FIXME h264 partitioned slices need this set*/);
979
if(s->pict_type==FF_B_TYPE){
980
for(mb_y=0; mb_y<s->mb_height; mb_y++){
981
for(mb_x=0; mb_x<s->mb_width; mb_x++){
982
int xy= mb_x*2 + mb_y*2*s->b8_stride;
983
const int mb_xy= mb_x + mb_y * s->mb_stride;
984
const int mb_type= s->current_picture.mb_type[mb_xy];
985
error= s->error_status_table[mb_xy];
987
if(IS_INTRA(mb_type)) continue;
988
if(!(error&MV_ERROR)) continue; //inter with undamaged MV
989
if(!(error&AC_ERROR)) continue; //undamaged inter
991
s->mv_dir = MV_DIR_FORWARD|MV_DIR_BACKWARD;
992
if(!s->last_picture.data[0]) s->mv_dir &= ~MV_DIR_FORWARD;
993
if(!s->next_picture.data[0]) s->mv_dir &= ~MV_DIR_BACKWARD;
995
s->mv_type = MV_TYPE_16X16;
999
int time_pp= s->pp_time;
1000
int time_pb= s->pb_time;
1002
s->mv[0][0][0] = s->next_picture.motion_val[0][xy][0]*time_pb/time_pp;
1003
s->mv[0][0][1] = s->next_picture.motion_val[0][xy][1]*time_pb/time_pp;
1004
s->mv[1][0][0] = s->next_picture.motion_val[0][xy][0]*(time_pb - time_pp)/time_pp;
1005
s->mv[1][0][1] = s->next_picture.motion_val[0][xy][1]*(time_pb - time_pp)/time_pp;
1013
s->dsp.clear_blocks(s->block[0]);
1022
/* the filters below are not XvMC compatible, skip them */
1023
if(CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration)
1025
/* fill DC for inter blocks */
1026
for(mb_y=0; mb_y<s->mb_height; mb_y++){
1027
for(mb_x=0; mb_x<s->mb_width; mb_x++){
1028
int dc, dcu, dcv, y, n;
1030
uint8_t *dest_y, *dest_cb, *dest_cr;
1031
const int mb_xy= mb_x + mb_y * s->mb_stride;
1032
const int mb_type= s->current_picture.mb_type[mb_xy];
1034
error= s->error_status_table[mb_xy];
1036
if(IS_INTRA(mb_type) && s->partitioned_frame) continue;
1037
// if(error&MV_ERROR) continue; //inter data damaged FIXME is this good?
1039
dest_y = s->current_picture.data[0] + mb_x*16 + mb_y*16*s->linesize;
1040
dest_cb= s->current_picture.data[1] + mb_x*8 + mb_y*8 *s->uvlinesize;
1041
dest_cr= s->current_picture.data[2] + mb_x*8 + mb_y*8 *s->uvlinesize;
1043
dc_ptr= &s->dc_val[0][mb_x*2 + mb_y*2*s->b8_stride];
1049
dc+= dest_y[x + (n&1)*8 + (y + (n>>1)*8)*s->linesize];
1052
dc_ptr[(n&1) + (n>>1)*s->b8_stride]= (dc+4)>>3;
1059
dcu+=dest_cb[x + y*(s->uvlinesize)];
1060
dcv+=dest_cr[x + y*(s->uvlinesize)];
1063
s->dc_val[1][mb_x + mb_y*s->mb_stride]= (dcu+4)>>3;
1064
s->dc_val[2][mb_x + mb_y*s->mb_stride]= (dcv+4)>>3;
1068
/* guess DC for damaged blocks */
1069
guess_dc(s, s->dc_val[0], s->mb_width*2, s->mb_height*2, s->b8_stride, 1);
1070
guess_dc(s, s->dc_val[1], s->mb_width , s->mb_height , s->mb_stride, 0);
1071
guess_dc(s, s->dc_val[2], s->mb_width , s->mb_height , s->mb_stride, 0);
1073
/* filter luma DC */
1074
filter181(s->dc_val[0], s->mb_width*2, s->mb_height*2, s->b8_stride);
1077
/* render DC only intra */
1078
for(mb_y=0; mb_y<s->mb_height; mb_y++){
1079
for(mb_x=0; mb_x<s->mb_width; mb_x++){
1080
uint8_t *dest_y, *dest_cb, *dest_cr;
1081
const int mb_xy= mb_x + mb_y * s->mb_stride;
1082
const int mb_type= s->current_picture.mb_type[mb_xy];
1084
error= s->error_status_table[mb_xy];
1086
if(IS_INTER(mb_type)) continue;
1087
if(!(error&AC_ERROR)) continue; //undamaged
1089
dest_y = s->current_picture.data[0] + mb_x*16 + mb_y*16*s->linesize;
1090
dest_cb= s->current_picture.data[1] + mb_x*8 + mb_y*8 *s->uvlinesize;
1091
dest_cr= s->current_picture.data[2] + mb_x*8 + mb_y*8 *s->uvlinesize;
1093
put_dc(s, dest_y, dest_cb, dest_cr, mb_x, mb_y);
1098
if(s->avctx->error_concealment&FF_EC_DEBLOCK){
1099
/* filter horizontal block boundaries */
1100
h_block_filter(s, s->current_picture.data[0], s->mb_width*2, s->mb_height*2, s->linesize , 1);
1101
h_block_filter(s, s->current_picture.data[1], s->mb_width , s->mb_height , s->uvlinesize, 0);
1102
h_block_filter(s, s->current_picture.data[2], s->mb_width , s->mb_height , s->uvlinesize, 0);
1104
/* filter vertical block boundaries */
1105
v_block_filter(s, s->current_picture.data[0], s->mb_width*2, s->mb_height*2, s->linesize , 1);
1106
v_block_filter(s, s->current_picture.data[1], s->mb_width , s->mb_height , s->uvlinesize, 0);
1107
v_block_filter(s, s->current_picture.data[2], s->mb_width , s->mb_height , s->uvlinesize, 0);
1111
/* clean a few tables */
1112
for(i=0; i<s->mb_num; i++){
1113
const int mb_xy= s->mb_index2xy[i];
1114
int error= s->error_status_table[mb_xy];
1116
if(s->pict_type!=FF_B_TYPE && (error&(DC_ERROR|MV_ERROR|AC_ERROR))){
1117
s->mbskip_table[mb_xy]=0;
1119
s->mbintra_table[mb_xy]=1;