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.
30 #include "libavutil/internal.h"
32 #include "error_resilience.h"
33 #include "mpegutils.h"
34 #include "mpegvideo.h"
35 #include "rectangle.h"
40 * @param stride the number of MVs to get to the next row
41 * @param mv_step the number of MVs per row or column in a macroblock
43 static void set_mv_strides(ERContext
*s
, int *mv_step
, int *stride
)
45 if (s
->avctx
->codec_id
== AV_CODEC_ID_H264
) {
46 av_assert0(s
->quarter_sample
);
48 *stride
= s
->mb_width
* 4;
51 *stride
= s
->b8_stride
;
56 * Replace the current MB with a flat dc-only version.
58 static void put_dc(ERContext
*s
, uint8_t *dest_y
, uint8_t *dest_cb
,
59 uint8_t *dest_cr
, int mb_x
, int mb_y
)
61 int *linesize
= s
->cur_pic
.f
->linesize
;
62 int dc
, dcu
, dcv
, y
, i
;
63 for (i
= 0; i
< 4; i
++) {
64 dc
= s
->dc_val
[0][mb_x
* 2 + (i
& 1) + (mb_y
* 2 + (i
>> 1)) * s
->b8_stride
];
69 for (y
= 0; y
< 8; y
++) {
71 for (x
= 0; x
< 8; x
++)
72 dest_y
[x
+ (i
& 1) * 8 + (y
+ (i
>> 1) * 8) * linesize
[0]] = dc
/ 8;
75 dcu
= s
->dc_val
[1][mb_x
+ mb_y
* s
->mb_stride
];
76 dcv
= s
->dc_val
[2][mb_x
+ mb_y
* s
->mb_stride
];
85 for (y
= 0; y
< 8; y
++) {
87 for (x
= 0; x
< 8; x
++) {
88 dest_cb
[x
+ y
* linesize
[1]] = dcu
/ 8;
89 dest_cr
[x
+ y
* linesize
[2]] = dcv
/ 8;
94 static void filter181(int16_t *data
, int width
, int height
, int stride
)
98 /* horizontal filter */
99 for (y
= 1; y
< height
- 1; y
++) {
100 int prev_dc
= data
[0 + y
* stride
];
102 for (x
= 1; x
< width
- 1; x
++) {
105 data
[x
+ y
* stride
] * 8 -
106 data
[x
+ 1 + y
* stride
];
107 dc
= (dc
* 10923 + 32768) >> 16;
108 prev_dc
= data
[x
+ y
* stride
];
109 data
[x
+ y
* stride
] = dc
;
113 /* vertical filter */
114 for (x
= 1; x
< width
- 1; x
++) {
115 int prev_dc
= data
[x
];
117 for (y
= 1; y
< height
- 1; y
++) {
121 data
[x
+ y
* stride
] * 8 -
122 data
[x
+ (y
+ 1) * stride
];
123 dc
= (dc
* 10923 + 32768) >> 16;
124 prev_dc
= data
[x
+ y
* stride
];
125 data
[x
+ y
* stride
] = dc
;
131 * guess the dc of blocks which do not have an undamaged dc
132 * @param w width in 8 pixel blocks
133 * @param h height in 8 pixel blocks
135 static void guess_dc(ERContext
*s
, int16_t *dc
, int w
,
136 int h
, int stride
, int is_luma
)
139 int16_t (*col
)[4] = av_malloc_array(stride
, h
*sizeof( int16_t)*4);
140 uint32_t (*dist
)[4] = av_malloc_array(stride
, h
*sizeof(uint32_t)*4);
143 av_log(s
->avctx
, AV_LOG_ERROR
, "guess_dc() is out of memory\n");
147 for(b_y
=0; b_y
<h
; b_y
++){
150 for(b_x
=0; b_x
<w
; b_x
++){
151 int mb_index_j
= (b_x
>>is_luma
) + (b_y
>>is_luma
)*s
->mb_stride
;
152 int error_j
= s
->error_status_table
[mb_index_j
];
153 int intra_j
= IS_INTRA(s
->cur_pic
.mb_type
[mb_index_j
]);
154 if(intra_j
==0 || !(error_j
&ER_DC_ERROR
)){
155 color
= dc
[b_x
+ b_y
*stride
];
158 col
[b_x
+ b_y
*stride
][1]= color
;
159 dist
[b_x
+ b_y
*stride
][1]= distance
>= 0 ? b_x
-distance
: 9999;
163 for(b_x
=w
-1; b_x
>=0; b_x
--){
164 int mb_index_j
= (b_x
>>is_luma
) + (b_y
>>is_luma
)*s
->mb_stride
;
165 int error_j
= s
->error_status_table
[mb_index_j
];
166 int intra_j
= IS_INTRA(s
->cur_pic
.mb_type
[mb_index_j
]);
167 if(intra_j
==0 || !(error_j
&ER_DC_ERROR
)){
168 color
= dc
[b_x
+ b_y
*stride
];
171 col
[b_x
+ b_y
*stride
][0]= color
;
172 dist
[b_x
+ b_y
*stride
][0]= distance
>= 0 ? distance
-b_x
: 9999;
175 for(b_x
=0; b_x
<w
; b_x
++){
178 for(b_y
=0; b_y
<h
; b_y
++){
179 int mb_index_j
= (b_x
>>is_luma
) + (b_y
>>is_luma
)*s
->mb_stride
;
180 int error_j
= s
->error_status_table
[mb_index_j
];
181 int intra_j
= IS_INTRA(s
->cur_pic
.mb_type
[mb_index_j
]);
182 if(intra_j
==0 || !(error_j
&ER_DC_ERROR
)){
183 color
= dc
[b_x
+ b_y
*stride
];
186 col
[b_x
+ b_y
*stride
][3]= color
;
187 dist
[b_x
+ b_y
*stride
][3]= distance
>= 0 ? b_y
-distance
: 9999;
191 for(b_y
=h
-1; b_y
>=0; b_y
--){
192 int mb_index_j
= (b_x
>>is_luma
) + (b_y
>>is_luma
)*s
->mb_stride
;
193 int error_j
= s
->error_status_table
[mb_index_j
];
194 int intra_j
= IS_INTRA(s
->cur_pic
.mb_type
[mb_index_j
]);
195 if(intra_j
==0 || !(error_j
&ER_DC_ERROR
)){
196 color
= dc
[b_x
+ b_y
*stride
];
199 col
[b_x
+ b_y
*stride
][2]= color
;
200 dist
[b_x
+ b_y
*stride
][2]= distance
>= 0 ? distance
-b_y
: 9999;
204 for (b_y
= 0; b_y
< h
; b_y
++) {
205 for (b_x
= 0; b_x
< w
; b_x
++) {
206 int mb_index
, error
, j
;
207 int64_t guess
, weight_sum
;
208 mb_index
= (b_x
>> is_luma
) + (b_y
>> is_luma
) * s
->mb_stride
;
209 error
= s
->error_status_table
[mb_index
];
211 if (IS_INTER(s
->cur_pic
.mb_type
[mb_index
]))
213 if (!(error
& ER_DC_ERROR
))
218 for (j
= 0; j
< 4; j
++) {
219 int64_t weight
= 256 * 256 * 256 * 16 / FFMAX(dist
[b_x
+ b_y
*stride
][j
], 1);
220 guess
+= weight
*(int64_t)col
[b_x
+ b_y
*stride
][j
];
221 weight_sum
+= weight
;
223 guess
= (guess
+ weight_sum
/ 2) / weight_sum
;
224 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(ERContext
*s
, uint8_t *dst
, int w
,
239 int h
, int stride
, int is_luma
)
241 int b_x
, b_y
, mvx_stride
, mvy_stride
;
242 const uint8_t *cm
= ff_crop_tab
+ MAX_NEG_CROP
;
243 set_mv_strides(s
, &mvx_stride
, &mvy_stride
);
244 mvx_stride
>>= is_luma
;
245 mvy_stride
*= mvx_stride
;
247 for (b_y
= 0; b_y
< h
; b_y
++) {
248 for (b_x
= 0; b_x
< w
- 1; b_x
++) {
250 int left_status
= s
->error_status_table
[( b_x
>> is_luma
) + (b_y
>> is_luma
) * s
->mb_stride
];
251 int right_status
= s
->error_status_table
[((b_x
+ 1) >> is_luma
) + (b_y
>> is_luma
) * s
->mb_stride
];
252 int left_intra
= IS_INTRA(s
->cur_pic
.mb_type
[( b_x
>> is_luma
) + (b_y
>> is_luma
) * s
->mb_stride
]);
253 int right_intra
= IS_INTRA(s
->cur_pic
.mb_type
[((b_x
+ 1) >> is_luma
) + (b_y
>> is_luma
) * s
->mb_stride
]);
254 int left_damage
= left_status
& ER_MB_ERROR
;
255 int right_damage
= right_status
& ER_MB_ERROR
;
256 int offset
= b_x
* 8 + b_y
* stride
* 8;
257 int16_t *left_mv
= s
->cur_pic
.motion_val
[0][mvy_stride
* b_y
+ mvx_stride
* b_x
];
258 int16_t *right_mv
= s
->cur_pic
.motion_val
[0][mvy_stride
* b_y
+ mvx_stride
* (b_x
+ 1)];
259 if (!(left_damage
|| right_damage
))
260 continue; // both undamaged
261 if ((!left_intra
) && (!right_intra
) &&
262 FFABS(left_mv
[0] - right_mv
[0]) +
263 FFABS(left_mv
[1] + right_mv
[1]) < 2)
266 for (y
= 0; y
< 8; y
++) {
269 a
= dst
[offset
+ 7 + y
* stride
] - dst
[offset
+ 6 + y
* stride
];
270 b
= dst
[offset
+ 8 + y
* stride
] - dst
[offset
+ 7 + y
* stride
];
271 c
= dst
[offset
+ 9 + y
* stride
] - dst
[offset
+ 8 + y
* stride
];
273 d
= FFABS(b
) - ((FFABS(a
) + FFABS(c
) + 1) >> 1);
281 if (!(left_damage
&& right_damage
))
285 dst
[offset
+ 7 + y
* stride
] = cm
[dst
[offset
+ 7 + y
* stride
] + ((d
* 7) >> 4)];
286 dst
[offset
+ 6 + y
* stride
] = cm
[dst
[offset
+ 6 + y
* stride
] + ((d
* 5) >> 4)];
287 dst
[offset
+ 5 + y
* stride
] = cm
[dst
[offset
+ 5 + y
* stride
] + ((d
* 3) >> 4)];
288 dst
[offset
+ 4 + y
* stride
] = cm
[dst
[offset
+ 4 + y
* stride
] + ((d
* 1) >> 4)];
291 dst
[offset
+ 8 + y
* stride
] = cm
[dst
[offset
+ 8 + y
* stride
] - ((d
* 7) >> 4)];
292 dst
[offset
+ 9 + y
* stride
] = cm
[dst
[offset
+ 9 + y
* stride
] - ((d
* 5) >> 4)];
293 dst
[offset
+ 10+ y
* stride
] = cm
[dst
[offset
+ 10 + y
* stride
] - ((d
* 3) >> 4)];
294 dst
[offset
+ 11+ y
* stride
] = cm
[dst
[offset
+ 11 + y
* stride
] - ((d
* 1) >> 4)];
302 * simple vertical deblocking filter used for error resilience
303 * @param w width in 8 pixel blocks
304 * @param h height in 8 pixel blocks
306 static void v_block_filter(ERContext
*s
, uint8_t *dst
, int w
, int h
,
307 int stride
, int is_luma
)
309 int b_x
, b_y
, mvx_stride
, mvy_stride
;
310 const uint8_t *cm
= ff_crop_tab
+ MAX_NEG_CROP
;
311 set_mv_strides(s
, &mvx_stride
, &mvy_stride
);
312 mvx_stride
>>= is_luma
;
313 mvy_stride
*= mvx_stride
;
315 for (b_y
= 0; b_y
< h
- 1; b_y
++) {
316 for (b_x
= 0; b_x
< w
; b_x
++) {
318 int top_status
= s
->error_status_table
[(b_x
>> is_luma
) + (b_y
>> is_luma
) * s
->mb_stride
];
319 int bottom_status
= s
->error_status_table
[(b_x
>> is_luma
) + ((b_y
+ 1) >> is_luma
) * s
->mb_stride
];
320 int top_intra
= IS_INTRA(s
->cur_pic
.mb_type
[(b_x
>> is_luma
) + ( b_y
>> is_luma
) * s
->mb_stride
]);
321 int bottom_intra
= IS_INTRA(s
->cur_pic
.mb_type
[(b_x
>> is_luma
) + ((b_y
+ 1) >> is_luma
) * s
->mb_stride
]);
322 int top_damage
= top_status
& ER_MB_ERROR
;
323 int bottom_damage
= bottom_status
& ER_MB_ERROR
;
324 int offset
= b_x
* 8 + b_y
* stride
* 8;
326 int16_t *top_mv
= s
->cur_pic
.motion_val
[0][mvy_stride
* b_y
+ mvx_stride
* b_x
];
327 int16_t *bottom_mv
= s
->cur_pic
.motion_val
[0][mvy_stride
* (b_y
+ 1) + mvx_stride
* b_x
];
329 if (!(top_damage
|| bottom_damage
))
330 continue; // both undamaged
332 if ((!top_intra
) && (!bottom_intra
) &&
333 FFABS(top_mv
[0] - bottom_mv
[0]) +
334 FFABS(top_mv
[1] + bottom_mv
[1]) < 2)
337 for (x
= 0; x
< 8; x
++) {
340 a
= dst
[offset
+ x
+ 7 * stride
] - dst
[offset
+ x
+ 6 * stride
];
341 b
= dst
[offset
+ x
+ 8 * stride
] - dst
[offset
+ x
+ 7 * stride
];
342 c
= dst
[offset
+ x
+ 9 * stride
] - dst
[offset
+ x
+ 8 * stride
];
344 d
= FFABS(b
) - ((FFABS(a
) + FFABS(c
) + 1) >> 1);
352 if (!(top_damage
&& bottom_damage
))
356 dst
[offset
+ x
+ 7 * stride
] = cm
[dst
[offset
+ x
+ 7 * stride
] + ((d
* 7) >> 4)];
357 dst
[offset
+ x
+ 6 * stride
] = cm
[dst
[offset
+ x
+ 6 * stride
] + ((d
* 5) >> 4)];
358 dst
[offset
+ x
+ 5 * stride
] = cm
[dst
[offset
+ x
+ 5 * stride
] + ((d
* 3) >> 4)];
359 dst
[offset
+ x
+ 4 * stride
] = cm
[dst
[offset
+ x
+ 4 * stride
] + ((d
* 1) >> 4)];
362 dst
[offset
+ x
+ 8 * stride
] = cm
[dst
[offset
+ x
+ 8 * stride
] - ((d
* 7) >> 4)];
363 dst
[offset
+ x
+ 9 * stride
] = cm
[dst
[offset
+ x
+ 9 * stride
] - ((d
* 5) >> 4)];
364 dst
[offset
+ x
+ 10 * stride
] = cm
[dst
[offset
+ x
+ 10 * stride
] - ((d
* 3) >> 4)];
365 dst
[offset
+ x
+ 11 * stride
] = cm
[dst
[offset
+ x
+ 11 * stride
] - ((d
* 1) >> 4)];
372 static void guess_mv(ERContext
*s
)
374 uint8_t *fixed
= s
->er_temp_buffer
;
377 #define MV_UNCHANGED 1
378 const int mb_stride
= s
->mb_stride
;
379 const int mb_width
= s
->mb_width
;
380 const int mb_height
= s
->mb_height
;
381 int i
, depth
, num_avail
;
382 int mb_x
, mb_y
, mot_step
, mot_stride
;
384 set_mv_strides(s
, &mot_step
, &mot_stride
);
387 for (i
= 0; i
< s
->mb_num
; i
++) {
388 const int mb_xy
= s
->mb_index2xy
[i
];
390 int error
= s
->error_status_table
[mb_xy
];
392 if (IS_INTRA(s
->cur_pic
.mb_type
[mb_xy
]))
393 f
= MV_FROZEN
; // intra // FIXME check
394 if (!(error
& ER_MV_ERROR
))
395 f
= MV_FROZEN
; // inter with undamaged MV
400 else if(s
->last_pic
.f
->data
[0] && s
->last_pic
.motion_val
[0]){
401 const int mb_y
= mb_xy
/ s
->mb_stride
;
402 const int mb_x
= mb_xy
% s
->mb_stride
;
403 const int mot_index
= (mb_x
+ mb_y
*mot_stride
) * mot_step
;
404 s
->cur_pic
.motion_val
[0][mot_index
][0]= s
->last_pic
.motion_val
[0][mot_index
][0];
405 s
->cur_pic
.motion_val
[0][mot_index
][1]= s
->last_pic
.motion_val
[0][mot_index
][1];
406 s
->cur_pic
.ref_index
[0][4*mb_xy
] = s
->last_pic
.ref_index
[0][4*mb_xy
];
410 if ((!(s
->avctx
->error_concealment
&FF_EC_GUESS_MVS
)) ||
411 num_avail
<= mb_width
/ 2) {
412 for (mb_y
= 0; mb_y
< s
->mb_height
; mb_y
++) {
413 for (mb_x
= 0; mb_x
< s
->mb_width
; mb_x
++) {
414 const int mb_xy
= mb_x
+ mb_y
* s
->mb_stride
;
415 int mv_dir
= (s
->last_pic
.f
&& s
->last_pic
.f
->data
[0]) ? MV_DIR_FORWARD
: MV_DIR_BACKWARD
;
417 if (IS_INTRA(s
->cur_pic
.mb_type
[mb_xy
]))
419 if (!(s
->error_status_table
[mb_xy
] & ER_MV_ERROR
))
424 s
->decode_mb(s
->opaque
, 0, mv_dir
, MV_TYPE_16X16
, &s
->mv
,
431 for (depth
= 0; ; depth
++) {
432 int changed
, pass
, none_left
;
436 for (pass
= 0; (changed
|| pass
< 2) && pass
< 10; pass
++) {
441 for (mb_y
= 0; mb_y
< s
->mb_height
; mb_y
++) {
442 for (mb_x
= 0; mb_x
< s
->mb_width
; mb_x
++) {
443 const int mb_xy
= mb_x
+ mb_y
* s
->mb_stride
;
444 int mv_predictor
[8][2] = { { 0 } };
448 int best_score
= 256 * 256 * 256 * 64;
450 const int mot_index
= (mb_x
+ mb_y
* mot_stride
) * mot_step
;
451 int prev_x
= 0, prev_y
= 0, prev_ref
= 0;
453 if ((mb_x
^ mb_y
^ pass
) & 1)
456 if (fixed
[mb_xy
] == MV_FROZEN
)
458 av_assert1(!IS_INTRA(s
->cur_pic
.mb_type
[mb_xy
]));
459 av_assert1(s
->last_pic
.f
&& s
->last_pic
.f
->data
[0]);
462 if (mb_x
> 0 && fixed
[mb_xy
- 1] == MV_FROZEN
)
464 if (mb_x
+ 1 < mb_width
&& fixed
[mb_xy
+ 1] == MV_FROZEN
)
466 if (mb_y
> 0 && fixed
[mb_xy
- mb_stride
] == MV_FROZEN
)
468 if (mb_y
+ 1 < mb_height
&& fixed
[mb_xy
+ mb_stride
] == MV_FROZEN
)
474 if (mb_x
> 0 && fixed
[mb_xy
- 1 ] == MV_CHANGED
)
476 if (mb_x
+ 1 < mb_width
&& fixed
[mb_xy
+ 1 ] == MV_CHANGED
)
478 if (mb_y
> 0 && fixed
[mb_xy
- mb_stride
] == MV_CHANGED
)
480 if (mb_y
+ 1 < mb_height
&& fixed
[mb_xy
+ mb_stride
] == MV_CHANGED
)
482 if (j
== 0 && pass
> 1)
487 if (mb_x
> 0 && fixed
[mb_xy
- 1]) {
488 mv_predictor
[pred_count
][0] =
489 s
->cur_pic
.motion_val
[0][mot_index
- mot_step
][0];
490 mv_predictor
[pred_count
][1] =
491 s
->cur_pic
.motion_val
[0][mot_index
- mot_step
][1];
493 s
->cur_pic
.ref_index
[0][4 * (mb_xy
- 1)];
496 if (mb_x
+ 1 < mb_width
&& fixed
[mb_xy
+ 1]) {
497 mv_predictor
[pred_count
][0] =
498 s
->cur_pic
.motion_val
[0][mot_index
+ mot_step
][0];
499 mv_predictor
[pred_count
][1] =
500 s
->cur_pic
.motion_val
[0][mot_index
+ mot_step
][1];
502 s
->cur_pic
.ref_index
[0][4 * (mb_xy
+ 1)];
505 if (mb_y
> 0 && fixed
[mb_xy
- mb_stride
]) {
506 mv_predictor
[pred_count
][0] =
507 s
->cur_pic
.motion_val
[0][mot_index
- mot_stride
* mot_step
][0];
508 mv_predictor
[pred_count
][1] =
509 s
->cur_pic
.motion_val
[0][mot_index
- mot_stride
* mot_step
][1];
511 s
->cur_pic
.ref_index
[0][4 * (mb_xy
- s
->mb_stride
)];
514 if (mb_y
+ 1<mb_height
&& fixed
[mb_xy
+ mb_stride
]) {
515 mv_predictor
[pred_count
][0] =
516 s
->cur_pic
.motion_val
[0][mot_index
+ mot_stride
* mot_step
][0];
517 mv_predictor
[pred_count
][1] =
518 s
->cur_pic
.motion_val
[0][mot_index
+ mot_stride
* mot_step
][1];
520 s
->cur_pic
.ref_index
[0][4 * (mb_xy
+ s
->mb_stride
)];
526 if (pred_count
> 1) {
527 int sum_x
= 0, sum_y
= 0, sum_r
= 0;
528 int max_x
, max_y
, min_x
, min_y
, max_r
, min_r
;
530 for (j
= 0; j
< pred_count
; j
++) {
531 sum_x
+= mv_predictor
[j
][0];
532 sum_y
+= mv_predictor
[j
][1];
534 if (j
&& ref
[j
] != ref
[j
- 1])
535 goto skip_mean_and_median
;
539 mv_predictor
[pred_count
][0] = sum_x
/ j
;
540 mv_predictor
[pred_count
][1] = sum_y
/ j
;
541 ref
[pred_count
] = sum_r
/ j
;
544 if (pred_count
>= 3) {
545 min_y
= min_x
= min_r
= 99999;
546 max_y
= max_x
= max_r
= -99999;
548 min_x
= min_y
= max_x
= max_y
= min_r
= max_r
= 0;
550 for (j
= 0; j
< pred_count
; j
++) {
551 max_x
= FFMAX(max_x
, mv_predictor
[j
][0]);
552 max_y
= FFMAX(max_y
, mv_predictor
[j
][1]);
553 max_r
= FFMAX(max_r
, ref
[j
]);
554 min_x
= FFMIN(min_x
, mv_predictor
[j
][0]);
555 min_y
= FFMIN(min_y
, mv_predictor
[j
][1]);
556 min_r
= FFMIN(min_r
, ref
[j
]);
558 mv_predictor
[pred_count
+ 1][0] = sum_x
- max_x
- min_x
;
559 mv_predictor
[pred_count
+ 1][1] = sum_y
- max_y
- min_y
;
560 ref
[pred_count
+ 1] = sum_r
- max_r
- min_r
;
562 if (pred_count
== 4) {
563 mv_predictor
[pred_count
+ 1][0] /= 2;
564 mv_predictor
[pred_count
+ 1][1] /= 2;
565 ref
[pred_count
+ 1] /= 2;
570 skip_mean_and_median
:
574 if (!fixed
[mb_xy
] && 0) {
575 if (s
->avctx
->codec_id
== AV_CODEC_ID_H264
) {
578 ff_thread_await_progress(s
->last_pic
.tf
,
581 if (!s
->last_pic
.motion_val
[0] ||
582 !s
->last_pic
.ref_index
[0])
584 prev_x
= s
->last_pic
.motion_val
[0][mot_index
][0];
585 prev_y
= s
->last_pic
.motion_val
[0][mot_index
][1];
586 prev_ref
= s
->last_pic
.ref_index
[0][4 * mb_xy
];
588 prev_x
= s
->cur_pic
.motion_val
[0][mot_index
][0];
589 prev_y
= s
->cur_pic
.motion_val
[0][mot_index
][1];
590 prev_ref
= s
->cur_pic
.ref_index
[0][4 * mb_xy
];
594 mv_predictor
[pred_count
][0] = prev_x
;
595 mv_predictor
[pred_count
][1] = prev_y
;
596 ref
[pred_count
] = prev_ref
;
601 for (j
= 0; j
< pred_count
; j
++) {
602 int *linesize
= s
->cur_pic
.f
->linesize
;
604 uint8_t *src
= s
->cur_pic
.f
->data
[0] +
605 mb_x
* 16 + mb_y
* 16 * linesize
[0];
607 s
->cur_pic
.motion_val
[0][mot_index
][0] =
608 s
->mv
[0][0][0] = mv_predictor
[j
][0];
609 s
->cur_pic
.motion_val
[0][mot_index
][1] =
610 s
->mv
[0][0][1] = mv_predictor
[j
][1];
612 // predictor intra or otherwise not available
616 s
->decode_mb(s
->opaque
, ref
[j
], MV_DIR_FORWARD
,
617 MV_TYPE_16X16
, &s
->mv
, mb_x
, mb_y
, 0, 0);
619 if (mb_x
> 0 && fixed
[mb_xy
- 1]) {
621 for (k
= 0; k
< 16; k
++)
622 score
+= FFABS(src
[k
* linesize
[0] - 1] -
623 src
[k
* linesize
[0]]);
625 if (mb_x
+ 1 < mb_width
&& fixed
[mb_xy
+ 1]) {
627 for (k
= 0; k
< 16; k
++)
628 score
+= FFABS(src
[k
* linesize
[0] + 15] -
629 src
[k
* linesize
[0] + 16]);
631 if (mb_y
> 0 && fixed
[mb_xy
- mb_stride
]) {
633 for (k
= 0; k
< 16; k
++)
634 score
+= FFABS(src
[k
- linesize
[0]] - src
[k
]);
636 if (mb_y
+ 1 < mb_height
&& fixed
[mb_xy
+ mb_stride
]) {
638 for (k
= 0; k
< 16; k
++)
639 score
+= FFABS(src
[k
+ linesize
[0] * 15] -
640 src
[k
+ linesize
[0] * 16]);
643 if (score
<= best_score
) { // <= will favor the last MV
648 score_sum
+= best_score
;
649 s
->mv
[0][0][0] = mv_predictor
[best_pred
][0];
650 s
->mv
[0][0][1] = mv_predictor
[best_pred
][1];
652 for (i
= 0; i
< mot_step
; i
++)
653 for (j
= 0; j
< mot_step
; j
++) {
654 s
->cur_pic
.motion_val
[0][mot_index
+ i
+ j
* mot_stride
][0] = s
->mv
[0][0][0];
655 s
->cur_pic
.motion_val
[0][mot_index
+ i
+ j
* mot_stride
][1] = s
->mv
[0][0][1];
658 s
->decode_mb(s
->opaque
, ref
[best_pred
], MV_DIR_FORWARD
,
659 MV_TYPE_16X16
, &s
->mv
, mb_x
, mb_y
, 0, 0);
662 if (s
->mv
[0][0][0] != prev_x
|| s
->mv
[0][0][1] != prev_y
) {
663 fixed
[mb_xy
] = MV_CHANGED
;
666 fixed
[mb_xy
] = MV_UNCHANGED
;
674 for (i
= 0; i
< s
->mb_num
; i
++) {
675 int mb_xy
= s
->mb_index2xy
[i
];
677 fixed
[mb_xy
] = MV_FROZEN
;
682 static int is_intra_more_likely(ERContext
*s
)
684 int is_intra_likely
, i
, j
, undamaged_count
, skip_amount
, mb_x
, mb_y
;
686 if (!s
->last_pic
.f
|| !s
->last_pic
.f
->data
[0])
687 return 1; // no previous frame available -> use spatial prediction
689 if (s
->avctx
->error_concealment
& FF_EC_FAVOR_INTER
)
693 for (i
= 0; i
< s
->mb_num
; i
++) {
694 const int mb_xy
= s
->mb_index2xy
[i
];
695 const int error
= s
->error_status_table
[mb_xy
];
696 if (!((error
& ER_DC_ERROR
) && (error
& ER_MV_ERROR
)))
700 if (s
->avctx
->codec_id
== AV_CODEC_ID_H264
&& s
->ref_count
<= 0)
703 if (undamaged_count
< 5)
704 return 0; // almost all MBs damaged -> use temporal prediction
706 // prevent dsp.sad() check, that requires access to the image
708 s
->avctx
->hwaccel
&& s
->avctx
->hwaccel
->decode_mb
&&
709 s
->cur_pic
.f
->pict_type
== AV_PICTURE_TYPE_I
)
712 skip_amount
= FFMAX(undamaged_count
/ 50, 1); // check only up to 50 MBs
716 for (mb_y
= 0; mb_y
< s
->mb_height
- 1; mb_y
++) {
717 for (mb_x
= 0; mb_x
< s
->mb_width
; mb_x
++) {
719 const int mb_xy
= mb_x
+ mb_y
* s
->mb_stride
;
721 error
= s
->error_status_table
[mb_xy
];
722 if ((error
& ER_DC_ERROR
) && (error
& ER_MV_ERROR
))
723 continue; // skip damaged
726 // skip a few to speed things up
727 if ((j
% skip_amount
) != 0)
730 if (s
->cur_pic
.f
->pict_type
== AV_PICTURE_TYPE_I
) {
731 int *linesize
= s
->cur_pic
.f
->linesize
;
732 uint8_t *mb_ptr
= s
->cur_pic
.f
->data
[0] +
733 mb_x
* 16 + mb_y
* 16 * linesize
[0];
734 uint8_t *last_mb_ptr
= s
->last_pic
.f
->data
[0] +
735 mb_x
* 16 + mb_y
* 16 * linesize
[0];
737 if (s
->avctx
->codec_id
== AV_CODEC_ID_H264
) {
740 ff_thread_await_progress(s
->last_pic
.tf
, mb_y
, 0);
742 is_intra_likely
+= s
->mecc
->sad
[0](NULL
, last_mb_ptr
, mb_ptr
,
744 // FIXME need await_progress() here
745 is_intra_likely
-= s
->mecc
->sad
[0](NULL
, last_mb_ptr
,
746 last_mb_ptr
+ linesize
[0] * 16,
749 if (IS_INTRA(s
->cur_pic
.mb_type
[mb_xy
]))
756 // av_log(NULL, AV_LOG_ERROR, "is_intra_likely: %d type:%d\n", is_intra_likely, s->pict_type);
757 return is_intra_likely
> 0;
760 void ff_er_frame_start(ERContext
*s
)
762 if (!s
->avctx
->error_concealment
)
765 memset(s
->error_status_table
, ER_MB_ERROR
| VP_START
| ER_MB_END
,
766 s
->mb_stride
* s
->mb_height
* sizeof(uint8_t));
767 s
->error_count
= 3 * s
->mb_num
;
768 s
->error_occurred
= 0;
771 static int er_supported(ERContext
*s
)
773 if(s
->avctx
->hwaccel
&& s
->avctx
->hwaccel
->decode_slice
||
774 s
->avctx
->codec
->capabilities
&CODEC_CAP_HWACCEL_VDPAU
||
776 s
->cur_pic
.field_picture
784 * @param endx x component of the last macroblock, can be -1
785 * for the last of the previous line
786 * @param status the status at the end (ER_MV_END, ER_AC_ERROR, ...), it is
787 * assumed that no earlier end or error of the same type occurred
789 void ff_er_add_slice(ERContext
*s
, int startx
, int starty
,
790 int endx
, int endy
, int status
)
792 const int start_i
= av_clip(startx
+ starty
* s
->mb_width
, 0, s
->mb_num
- 1);
793 const int end_i
= av_clip(endx
+ endy
* s
->mb_width
, 0, s
->mb_num
);
794 const int start_xy
= s
->mb_index2xy
[start_i
];
795 const int end_xy
= s
->mb_index2xy
[end_i
];
798 if (s
->avctx
->hwaccel
&& s
->avctx
->hwaccel
->decode_slice
)
801 if (start_i
> end_i
|| start_xy
> end_xy
) {
802 av_log(s
->avctx
, AV_LOG_ERROR
,
803 "internal error, slice end before start\n");
807 if (!s
->avctx
->error_concealment
)
811 if (status
& (ER_AC_ERROR
| ER_AC_END
)) {
812 mask
&= ~(ER_AC_ERROR
| ER_AC_END
);
813 s
->error_count
-= end_i
- start_i
+ 1;
815 if (status
& (ER_DC_ERROR
| ER_DC_END
)) {
816 mask
&= ~(ER_DC_ERROR
| ER_DC_END
);
817 s
->error_count
-= end_i
- start_i
+ 1;
819 if (status
& (ER_MV_ERROR
| ER_MV_END
)) {
820 mask
&= ~(ER_MV_ERROR
| ER_MV_END
);
821 s
->error_count
-= end_i
- start_i
+ 1;
824 if (status
& ER_MB_ERROR
) {
825 s
->error_occurred
= 1;
826 s
->error_count
= INT_MAX
;
830 memset(&s
->error_status_table
[start_xy
], 0,
831 (end_xy
- start_xy
) * sizeof(uint8_t));
834 for (i
= start_xy
; i
< end_xy
; i
++)
835 s
->error_status_table
[i
] &= mask
;
838 if (end_i
== s
->mb_num
)
839 s
->error_count
= INT_MAX
;
841 s
->error_status_table
[end_xy
] &= mask
;
842 s
->error_status_table
[end_xy
] |= status
;
845 s
->error_status_table
[start_xy
] |= VP_START
;
847 if (start_xy
> 0 && !(s
->avctx
->active_thread_type
& FF_THREAD_SLICE
) &&
848 er_supported(s
) && s
->avctx
->skip_top
* s
->mb_width
< start_i
) {
849 int prev_status
= s
->error_status_table
[s
->mb_index2xy
[start_i
- 1]];
851 prev_status
&= ~ VP_START
;
852 if (prev_status
!= (ER_MV_END
| ER_DC_END
| ER_AC_END
)) {
853 s
->error_occurred
= 1;
854 s
->error_count
= INT_MAX
;
859 void ff_er_frame_end(ERContext
*s
)
861 int *linesize
= NULL
;
862 int i
, mb_x
, mb_y
, error
, error_type
, dc_error
, mv_error
, ac_error
;
864 int threshold_part
[4] = { 100, 100, 100 };
867 int size
= s
->b8_stride
* 2 * s
->mb_height
;
869 /* We do not support ER of field pictures yet,
870 * though it should not crash if enabled. */
871 if (!s
->avctx
->error_concealment
|| s
->error_count
== 0 ||
874 s
->error_count
== 3 * s
->mb_width
*
875 (s
->avctx
->skip_top
+ s
->avctx
->skip_bottom
)) {
878 linesize
= s
->cur_pic
.f
->linesize
;
879 for (mb_x
= 0; mb_x
< s
->mb_width
; mb_x
++) {
880 int status
= s
->error_status_table
[mb_x
+ (s
->mb_height
- 1) * s
->mb_stride
];
885 if ( mb_x
== s
->mb_width
886 && s
->avctx
->codec_id
== AV_CODEC_ID_MPEG2VIDEO
887 && (s
->avctx
->height
&16)
888 && s
->error_count
== 3 * s
->mb_width
* (s
->avctx
->skip_top
+ s
->avctx
->skip_bottom
+ 1)
890 av_log(s
->avctx
, AV_LOG_DEBUG
, "ignoring last missing slice\n");
895 if (s
->last_pic
.f
->width
!= s
->cur_pic
.f
->width
||
896 s
->last_pic
.f
->height
!= s
->cur_pic
.f
->height
||
897 s
->last_pic
.f
->format
!= s
->cur_pic
.f
->format
) {
898 av_log(s
->avctx
, AV_LOG_WARNING
, "Cannot use previous picture in error concealment\n");
899 memset(&s
->last_pic
, 0, sizeof(s
->last_pic
));
903 if (s
->next_pic
.f
->width
!= s
->cur_pic
.f
->width
||
904 s
->next_pic
.f
->height
!= s
->cur_pic
.f
->height
||
905 s
->next_pic
.f
->format
!= s
->cur_pic
.f
->format
) {
906 av_log(s
->avctx
, AV_LOG_WARNING
, "Cannot use next picture in error concealment\n");
907 memset(&s
->next_pic
, 0, sizeof(s
->next_pic
));
911 if (!s
->cur_pic
.motion_val
[0] || !s
->cur_pic
.ref_index
[0]) {
912 av_log(s
->avctx
, AV_LOG_ERROR
, "Warning MVs not available\n");
914 for (i
= 0; i
< 2; i
++) {
915 s
->ref_index_buf
[i
] = av_buffer_allocz(s
->mb_stride
* s
->mb_height
* 4 * sizeof(uint8_t));
916 s
->motion_val_buf
[i
] = av_buffer_allocz((size
+ 4) * 2 * sizeof(uint16_t));
917 if (!s
->ref_index_buf
[i
] || !s
->motion_val_buf
[i
])
919 s
->cur_pic
.ref_index
[i
] = s
->ref_index_buf
[i
]->data
;
920 s
->cur_pic
.motion_val
[i
] = (int16_t (*)[2])s
->motion_val_buf
[i
]->data
+ 4;
923 for (i
= 0; i
< 2; i
++) {
924 av_buffer_unref(&s
->ref_index_buf
[i
]);
925 av_buffer_unref(&s
->motion_val_buf
[i
]);
926 s
->cur_pic
.ref_index
[i
] = NULL
;
927 s
->cur_pic
.motion_val
[i
] = NULL
;
933 if (s
->avctx
->debug
& FF_DEBUG_ER
) {
934 for (mb_y
= 0; mb_y
< s
->mb_height
; mb_y
++) {
935 for (mb_x
= 0; mb_x
< s
->mb_width
; mb_x
++) {
936 int status
= s
->error_status_table
[mb_x
+ mb_y
* s
->mb_stride
];
938 av_log(s
->avctx
, AV_LOG_DEBUG
, "%2X ", status
);
940 av_log(s
->avctx
, AV_LOG_DEBUG
, "\n");
945 /* handle overlapping slices */
946 for (error_type
= 1; error_type
<= 3; error_type
++) {
949 for (i
= s
->mb_num
- 1; i
>= 0; i
--) {
950 const int mb_xy
= s
->mb_index2xy
[i
];
951 int error
= s
->error_status_table
[mb_xy
];
953 if (error
& (1 << error_type
))
955 if (error
& (8 << error_type
))
959 s
->error_status_table
[mb_xy
] |= 1 << error_type
;
961 if (error
& VP_START
)
967 /* handle slices with partitions of different length */
968 if (s
->partitioned_frame
) {
971 for (i
= s
->mb_num
- 1; i
>= 0; i
--) {
972 const int mb_xy
= s
->mb_index2xy
[i
];
973 int error
= s
->error_status_table
[mb_xy
];
975 if (error
& ER_AC_END
)
977 if ((error
& ER_MV_END
) ||
978 (error
& ER_DC_END
) ||
979 (error
& ER_AC_ERROR
))
983 s
->error_status_table
[mb_xy
]|= ER_AC_ERROR
;
985 if (error
& VP_START
)
990 /* handle missing slices */
991 if (s
->avctx
->err_recognition
& AV_EF_EXPLODE
) {
995 for (i
= s
->mb_num
- 2; i
>= s
->mb_width
+ 100; i
--) {
996 const int mb_xy
= s
->mb_index2xy
[i
];
997 int error1
= s
->error_status_table
[mb_xy
];
998 int error2
= s
->error_status_table
[s
->mb_index2xy
[i
+ 1]];
1000 if (error1
& VP_START
)
1003 if (error2
== (VP_START
| ER_MB_ERROR
| ER_MB_END
) &&
1004 error1
!= (VP_START
| ER_MB_ERROR
| ER_MB_END
) &&
1005 ((error1
& ER_AC_END
) || (error1
& ER_DC_END
) ||
1006 (error1
& ER_MV_END
))) {
1012 s
->error_status_table
[mb_xy
] |= ER_MB_ERROR
;
1017 /* backward mark errors */
1019 for (error_type
= 1; error_type
<= 3; error_type
++) {
1020 for (i
= s
->mb_num
- 1; i
>= 0; i
--) {
1021 const int mb_xy
= s
->mb_index2xy
[i
];
1022 int error
= s
->error_status_table
[mb_xy
];
1024 if (!s
->mbskip_table
[mb_xy
]) // FIXME partition specific
1026 if (error
& (1 << error_type
))
1029 if (s
->partitioned_frame
) {
1030 if (distance
< threshold_part
[error_type
- 1])
1031 s
->error_status_table
[mb_xy
] |= 1 << error_type
;
1033 if (distance
< threshold
)
1034 s
->error_status_table
[mb_xy
] |= 1 << error_type
;
1037 if (error
& VP_START
)
1043 /* forward mark errors */
1045 for (i
= 0; i
< s
->mb_num
; i
++) {
1046 const int mb_xy
= s
->mb_index2xy
[i
];
1047 int old_error
= s
->error_status_table
[mb_xy
];
1049 if (old_error
& VP_START
) {
1050 error
= old_error
& ER_MB_ERROR
;
1052 error
|= old_error
& ER_MB_ERROR
;
1053 s
->error_status_table
[mb_xy
] |= error
;
1057 /* handle not partitioned case */
1058 if (!s
->partitioned_frame
) {
1059 for (i
= 0; i
< s
->mb_num
; i
++) {
1060 const int mb_xy
= s
->mb_index2xy
[i
];
1061 int error
= s
->error_status_table
[mb_xy
];
1062 if (error
& ER_MB_ERROR
)
1063 error
|= ER_MB_ERROR
;
1064 s
->error_status_table
[mb_xy
] = error
;
1069 dc_error
= ac_error
= mv_error
= 0;
1070 for (i
= 0; i
< s
->mb_num
; i
++) {
1071 const int mb_xy
= s
->mb_index2xy
[i
];
1072 int error
= s
->error_status_table
[mb_xy
];
1073 if (error
& ER_DC_ERROR
)
1075 if (error
& ER_AC_ERROR
)
1077 if (error
& ER_MV_ERROR
)
1080 av_log(s
->avctx
, AV_LOG_INFO
, "concealing %d DC, %d AC, %d MV errors in %c frame\n",
1081 dc_error
, ac_error
, mv_error
, av_get_picture_type_char(s
->cur_pic
.f
->pict_type
));
1083 is_intra_likely
= is_intra_more_likely(s
);
1085 /* set unknown mb-type to most likely */
1086 for (i
= 0; i
< s
->mb_num
; i
++) {
1087 const int mb_xy
= s
->mb_index2xy
[i
];
1088 int error
= s
->error_status_table
[mb_xy
];
1089 if (!((error
& ER_DC_ERROR
) && (error
& ER_MV_ERROR
)))
1092 if (is_intra_likely
)
1093 s
->cur_pic
.mb_type
[mb_xy
] = MB_TYPE_INTRA4x4
;
1095 s
->cur_pic
.mb_type
[mb_xy
] = MB_TYPE_16x16
| MB_TYPE_L0
;
1098 // change inter to intra blocks if no reference frames are available
1099 if (!(s
->last_pic
.f
&& s
->last_pic
.f
->data
[0]) &&
1100 !(s
->next_pic
.f
&& s
->next_pic
.f
->data
[0]))
1101 for (i
= 0; i
< s
->mb_num
; i
++) {
1102 const int mb_xy
= s
->mb_index2xy
[i
];
1103 if (!IS_INTRA(s
->cur_pic
.mb_type
[mb_xy
]))
1104 s
->cur_pic
.mb_type
[mb_xy
] = MB_TYPE_INTRA4x4
;
1107 /* handle inter blocks with damaged AC */
1108 for (mb_y
= 0; mb_y
< s
->mb_height
; mb_y
++) {
1109 for (mb_x
= 0; mb_x
< s
->mb_width
; mb_x
++) {
1110 const int mb_xy
= mb_x
+ mb_y
* s
->mb_stride
;
1111 const int mb_type
= s
->cur_pic
.mb_type
[mb_xy
];
1112 const int dir
= !(s
->last_pic
.f
&& s
->last_pic
.f
->data
[0]);
1113 const int mv_dir
= dir
? MV_DIR_BACKWARD
: MV_DIR_FORWARD
;
1116 int error
= s
->error_status_table
[mb_xy
];
1118 if (IS_INTRA(mb_type
))
1120 if (error
& ER_MV_ERROR
)
1121 continue; // inter with damaged MV
1122 if (!(error
& ER_AC_ERROR
))
1123 continue; // undamaged inter
1125 if (IS_8X8(mb_type
)) {
1126 int mb_index
= mb_x
* 2 + mb_y
* 2 * s
->b8_stride
;
1128 mv_type
= MV_TYPE_8X8
;
1129 for (j
= 0; j
< 4; j
++) {
1130 s
->mv
[0][j
][0] = s
->cur_pic
.motion_val
[dir
][mb_index
+ (j
& 1) + (j
>> 1) * s
->b8_stride
][0];
1131 s
->mv
[0][j
][1] = s
->cur_pic
.motion_val
[dir
][mb_index
+ (j
& 1) + (j
>> 1) * s
->b8_stride
][1];
1134 mv_type
= MV_TYPE_16X16
;
1135 s
->mv
[0][0][0] = s
->cur_pic
.motion_val
[dir
][mb_x
* 2 + mb_y
* 2 * s
->b8_stride
][0];
1136 s
->mv
[0][0][1] = s
->cur_pic
.motion_val
[dir
][mb_x
* 2 + mb_y
* 2 * s
->b8_stride
][1];
1139 s
->decode_mb(s
->opaque
, 0 /* FIXME h264 partitioned slices need this set */,
1140 mv_dir
, mv_type
, &s
->mv
, mb_x
, mb_y
, 0, 0);
1145 if (s
->cur_pic
.f
->pict_type
== AV_PICTURE_TYPE_B
) {
1146 for (mb_y
= 0; mb_y
< s
->mb_height
; mb_y
++) {
1147 for (mb_x
= 0; mb_x
< s
->mb_width
; mb_x
++) {
1148 int xy
= mb_x
* 2 + mb_y
* 2 * s
->b8_stride
;
1149 const int mb_xy
= mb_x
+ mb_y
* s
->mb_stride
;
1150 const int mb_type
= s
->cur_pic
.mb_type
[mb_xy
];
1151 int mv_dir
= MV_DIR_FORWARD
| MV_DIR_BACKWARD
;
1153 int error
= s
->error_status_table
[mb_xy
];
1155 if (IS_INTRA(mb_type
))
1157 if (!(error
& ER_MV_ERROR
))
1158 continue; // inter with undamaged MV
1159 if (!(error
& ER_AC_ERROR
))
1160 continue; // undamaged inter
1162 if (!(s
->last_pic
.f
&& s
->last_pic
.f
->data
[0]))
1163 mv_dir
&= ~MV_DIR_FORWARD
;
1164 if (!(s
->next_pic
.f
&& s
->next_pic
.f
->data
[0]))
1165 mv_dir
&= ~MV_DIR_BACKWARD
;
1168 int time_pp
= s
->pp_time
;
1169 int time_pb
= s
->pb_time
;
1171 av_assert0(s
->avctx
->codec_id
!= AV_CODEC_ID_H264
);
1172 ff_thread_await_progress(s
->next_pic
.tf
, mb_y
, 0);
1174 s
->mv
[0][0][0] = s
->next_pic
.motion_val
[0][xy
][0] * time_pb
/ time_pp
;
1175 s
->mv
[0][0][1] = s
->next_pic
.motion_val
[0][xy
][1] * time_pb
/ time_pp
;
1176 s
->mv
[1][0][0] = s
->next_pic
.motion_val
[0][xy
][0] * (time_pb
- time_pp
) / time_pp
;
1177 s
->mv
[1][0][1] = s
->next_pic
.motion_val
[0][xy
][1] * (time_pb
- time_pp
) / time_pp
;
1185 s
->decode_mb(s
->opaque
, 0, mv_dir
, MV_TYPE_16X16
, &s
->mv
,
1192 /* the filters below manipulate raw image, skip them */
1193 if (CONFIG_XVMC
&& s
->avctx
->hwaccel
&& s
->avctx
->hwaccel
->decode_mb
)
1195 /* fill DC for inter blocks */
1196 for (mb_y
= 0; mb_y
< s
->mb_height
; mb_y
++) {
1197 for (mb_x
= 0; mb_x
< s
->mb_width
; mb_x
++) {
1198 int dc
, dcu
, dcv
, y
, n
;
1200 uint8_t *dest_y
, *dest_cb
, *dest_cr
;
1201 const int mb_xy
= mb_x
+ mb_y
* s
->mb_stride
;
1202 const int mb_type
= s
->cur_pic
.mb_type
[mb_xy
];
1204 // error = s->error_status_table[mb_xy];
1206 if (IS_INTRA(mb_type
) && s
->partitioned_frame
)
1208 // if (error & ER_MV_ERROR)
1209 // continue; // inter data damaged FIXME is this good?
1211 dest_y
= s
->cur_pic
.f
->data
[0] + mb_x
* 16 + mb_y
* 16 * linesize
[0];
1212 dest_cb
= s
->cur_pic
.f
->data
[1] + mb_x
* 8 + mb_y
* 8 * linesize
[1];
1213 dest_cr
= s
->cur_pic
.f
->data
[2] + mb_x
* 8 + mb_y
* 8 * linesize
[2];
1215 dc_ptr
= &s
->dc_val
[0][mb_x
* 2 + mb_y
* 2 * s
->b8_stride
];
1216 for (n
= 0; n
< 4; n
++) {
1218 for (y
= 0; y
< 8; y
++) {
1220 for (x
= 0; x
< 8; x
++)
1221 dc
+= dest_y
[x
+ (n
& 1) * 8 +
1222 (y
+ (n
>> 1) * 8) * linesize
[0]];
1224 dc_ptr
[(n
& 1) + (n
>> 1) * s
->b8_stride
] = (dc
+ 4) >> 3;
1228 for (y
= 0; y
< 8; y
++) {
1230 for (x
= 0; x
< 8; x
++) {
1231 dcu
+= dest_cb
[x
+ y
* linesize
[1]];
1232 dcv
+= dest_cr
[x
+ y
* linesize
[2]];
1235 s
->dc_val
[1][mb_x
+ mb_y
* s
->mb_stride
] = (dcu
+ 4) >> 3;
1236 s
->dc_val
[2][mb_x
+ mb_y
* s
->mb_stride
] = (dcv
+ 4) >> 3;
1240 /* guess DC for damaged blocks */
1241 guess_dc(s
, s
->dc_val
[0], s
->mb_width
*2, s
->mb_height
*2, s
->b8_stride
, 1);
1242 guess_dc(s
, s
->dc_val
[1], s
->mb_width
, s
->mb_height
, s
->mb_stride
, 0);
1243 guess_dc(s
, s
->dc_val
[2], s
->mb_width
, s
->mb_height
, s
->mb_stride
, 0);
1246 /* filter luma DC */
1247 filter181(s
->dc_val
[0], s
->mb_width
* 2, s
->mb_height
* 2, s
->b8_stride
);
1250 /* render DC only intra */
1251 for (mb_y
= 0; mb_y
< s
->mb_height
; mb_y
++) {
1252 for (mb_x
= 0; mb_x
< s
->mb_width
; mb_x
++) {
1253 uint8_t *dest_y
, *dest_cb
, *dest_cr
;
1254 const int mb_xy
= mb_x
+ mb_y
* s
->mb_stride
;
1255 const int mb_type
= s
->cur_pic
.mb_type
[mb_xy
];
1257 int error
= s
->error_status_table
[mb_xy
];
1259 if (IS_INTER(mb_type
))
1261 if (!(error
& ER_AC_ERROR
))
1262 continue; // undamaged
1264 dest_y
= s
->cur_pic
.f
->data
[0] + mb_x
* 16 + mb_y
* 16 * linesize
[0];
1265 dest_cb
= s
->cur_pic
.f
->data
[1] + mb_x
* 8 + mb_y
* 8 * linesize
[1];
1266 dest_cr
= s
->cur_pic
.f
->data
[2] + mb_x
* 8 + mb_y
* 8 * linesize
[2];
1268 put_dc(s
, dest_y
, dest_cb
, dest_cr
, mb_x
, mb_y
);
1273 if (s
->avctx
->error_concealment
& FF_EC_DEBLOCK
) {
1274 /* filter horizontal block boundaries */
1275 h_block_filter(s
, s
->cur_pic
.f
->data
[0], s
->mb_width
* 2,
1276 s
->mb_height
* 2, linesize
[0], 1);
1277 h_block_filter(s
, s
->cur_pic
.f
->data
[1], s
->mb_width
,
1278 s
->mb_height
, linesize
[1], 0);
1279 h_block_filter(s
, s
->cur_pic
.f
->data
[2], s
->mb_width
,
1280 s
->mb_height
, linesize
[2], 0);
1282 /* filter vertical block boundaries */
1283 v_block_filter(s
, s
->cur_pic
.f
->data
[0], s
->mb_width
* 2,
1284 s
->mb_height
* 2, linesize
[0], 1);
1285 v_block_filter(s
, s
->cur_pic
.f
->data
[1], s
->mb_width
,
1286 s
->mb_height
, linesize
[1], 0);
1287 v_block_filter(s
, s
->cur_pic
.f
->data
[2], s
->mb_width
,
1288 s
->mb_height
, linesize
[2], 0);
1292 /* clean a few tables */
1293 for (i
= 0; i
< s
->mb_num
; i
++) {
1294 const int mb_xy
= s
->mb_index2xy
[i
];
1295 int error
= s
->error_status_table
[mb_xy
];
1297 if (s
->cur_pic
.f
->pict_type
!= AV_PICTURE_TYPE_B
&&
1298 (error
& (ER_DC_ERROR
| ER_MV_ERROR
| ER_AC_ERROR
))) {
1299 s
->mbskip_table
[mb_xy
] = 0;
1301 s
->mbintra_table
[mb_xy
] = 1;
1304 for (i
= 0; i
< 2; i
++) {
1305 av_buffer_unref(&s
->ref_index_buf
[i
]);
1306 av_buffer_unref(&s
->motion_val_buf
[i
]);
1307 s
->cur_pic
.ref_index
[i
] = NULL
;
1308 s
->cur_pic
.motion_val
[i
] = NULL
;
1311 memset(&s
->cur_pic
, 0, sizeof(ERPicture
));
1312 memset(&s
->last_pic
, 0, sizeof(ERPicture
));
1313 memset(&s
->next_pic
, 0, sizeof(ERPicture
));