Coverage Report

Created: 2026-07-25 07:52

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ffmpeg/libavcodec/error_resilience.c
Line
Count
Source
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
25
 * Error resilience / concealment.
26
 */
27
28
#include <limits.h>
29
30
#include "libavutil/avassert.h"
31
#include "libavutil/attributes.h"
32
#include "libavutil/mem.h"
33
#include "avcodec.h"
34
#include "error_resilience.h"
35
#include "mathops.h"
36
#include "me_cmp.h"
37
#include "mpegutils.h"
38
#include "mpegvideo.h"
39
#include "threadframe.h"
40
#include "threadprogress.h"
41
42
av_cold int ff_er_init(ERContext *const s)
43
906k
{
44
906k
    MECmpContext mecc;
45
906k
    unsigned mb_array_size = s->mb_height * s->mb_stride;
46
47
906k
    s->error_status_table = av_mallocz(mb_array_size);
48
906k
    if (!s->error_status_table)
49
0
        return AVERROR(ENOMEM);
50
906k
    s->er_temp_buffer = av_malloc_array(mb_array_size, 4*sizeof(int) + 1);
51
906k
    if (!s->er_temp_buffer)
52
0
        return AVERROR(ENOMEM);
53
54
906k
    ff_me_cmp_init(&mecc, s->avctx);
55
906k
    s->sad = mecc.sad[0];
56
57
906k
    return 0;
58
906k
}
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(ERContext *s, ptrdiff_t *mv_step, ptrdiff_t *stride)
65
3.08M
{
66
3.08M
    if (s->avctx->codec_id == AV_CODEC_ID_H264) {
67
1.41M
        av_assert0(s->quarter_sample);
68
1.41M
        *mv_step = 4;
69
1.41M
        *stride  = s->mb_width * 4;
70
1.67M
    } else {
71
1.67M
        *mv_step = 2;
72
1.67M
        *stride  = s->b8_stride;
73
1.67M
    }
74
3.08M
}
75
76
/**
77
 * Replace the current MB with a flat dc-only version.
78
 */
79
static void put_dc(ERContext *s, uint8_t *dest_y, uint8_t *dest_cb,
80
                   uint8_t *dest_cr, int mb_x, int mb_y)
81
135M
{
82
135M
    int *linesize = s->cur_pic.f->linesize;
83
135M
    int dc, dcu, dcv, y, i;
84
678M
    for (i = 0; i < 4; i++) {
85
543M
        dc = s->dc_val[0][mb_x * 2 + (i &  1) + (mb_y * 2 + (i >> 1)) * s->b8_stride];
86
543M
        if (dc < 0)
87
3.40M
            dc = 0;
88
539M
        else if (dc > 2040)
89
1.66M
            dc = 2040;
90
4.88G
        for (y = 0; y < 8; y++) {
91
4.34G
            int x;
92
39.1G
            for (x = 0; x < 8; x++)
93
34.7G
                dest_y[x + (i &  1) * 8 + (y + (i >> 1) * 8) * linesize[0]] = dc / 8;
94
4.34G
        }
95
543M
    }
96
135M
    dcu = s->dc_val[1][mb_x + mb_y * s->mb_stride];
97
135M
    dcv = s->dc_val[2][mb_x + mb_y * s->mb_stride];
98
135M
    if (dcu < 0)
99
0
        dcu = 0;
100
135M
    else if (dcu > 2040)
101
4.18k
        dcu = 2040;
102
135M
    if (dcv < 0)
103
0
        dcv = 0;
104
135M
    else if (dcv > 2040)
105
3.79k
        dcv = 2040;
106
107
135M
    if (dest_cr)
108
1.22G
    for (y = 0; y < 8; y++) {
109
1.08G
        int x;
110
9.77G
        for (x = 0; x < 8; x++) {
111
8.69G
            dest_cb[x + y * linesize[1]] = dcu / 8;
112
8.69G
            dest_cr[x + y * linesize[2]] = dcv / 8;
113
8.69G
        }
114
1.08G
    }
115
135M
}
116
117
static void filter181(int16_t *data, int width, int height, ptrdiff_t stride)
118
450k
{
119
450k
    int x, y;
120
121
    /* horizontal filter */
122
75.4M
    for (y = 1; y < height - 1; y++) {
123
74.9M
        int prev_dc = data[0 + y * stride];
124
125
1.67G
        for (x = 1; x < width - 1; x++) {
126
1.60G
            int dc;
127
1.60G
            dc = -prev_dc +
128
1.60G
                 data[x     + y * stride] * 8 -
129
1.60G
                 data[x + 1 + y * stride];
130
1.60G
            dc = (av_clip(dc, INT_MIN/10923, INT_MAX/10923 - 32768) * 10923 + 32768) >> 16;
131
1.60G
            prev_dc = data[x + y * stride];
132
1.60G
            data[x + y * stride] = dc;
133
1.60G
        }
134
74.9M
    }
135
136
    /* vertical filter */
137
55.8M
    for (x = 1; x < width - 1; x++) {
138
55.4M
        int prev_dc = data[x];
139
140
1.65G
        for (y = 1; y < height - 1; y++) {
141
1.60G
            int dc;
142
143
1.60G
            dc = -prev_dc +
144
1.60G
                 data[x +  y      * stride] * 8 -
145
1.60G
                 data[x + (y + 1) * stride];
146
1.60G
            dc = (av_clip(dc, INT_MIN/10923, INT_MAX/10923 - 32768) * 10923 + 32768) >> 16;
147
1.60G
            prev_dc = data[x + y * stride];
148
1.60G
            data[x + y * stride] = dc;
149
1.60G
        }
150
55.4M
    }
151
450k
}
152
153
/**
154
 * guess the dc of blocks which do not have an undamaged dc
155
 * @param w     width in 8 pixel blocks
156
 * @param h     height in 8 pixel blocks
157
 */
158
static void guess_dc(ERContext *s, int16_t *dc, int w,
159
                     int h, ptrdiff_t stride, int is_luma)
160
1.35M
{
161
1.35M
    int b_x, b_y;
162
1.35M
    int16_t  (*col )[4] = av_malloc_array(stride, h*sizeof( int16_t)*4);
163
1.35M
    uint32_t (*dist)[4] = av_malloc_array(stride, h*sizeof(uint32_t)*4);
164
165
1.35M
    if(!col || !dist) {
166
0
        av_log(s->avctx, AV_LOG_ERROR, "guess_dc() is out of memory\n");
167
0
        goto fail;
168
0
    }
169
170
153M
    for(b_y=0; b_y<h; b_y++){
171
151M
        int color= 1024;
172
151M
        int distance= -1;
173
2.94G
        for(b_x=0; b_x<w; b_x++){
174
2.79G
            int mb_index_j= (b_x>>is_luma) + (b_y>>is_luma)*s->mb_stride;
175
2.79G
            int error_j= s->error_status_table[mb_index_j];
176
2.79G
            int intra_j = IS_INTRA(s->cur_pic.mb_type[mb_index_j]);
177
2.79G
            if(intra_j==0 || !(error_j&ER_DC_ERROR)){
178
1.98G
                color= dc[b_x + b_y*stride];
179
1.98G
                distance= b_x;
180
1.98G
            }
181
2.79G
            col [b_x + b_y*stride][1]= color;
182
2.79G
            dist[b_x + b_y*stride][1]= distance >= 0 ? b_x-distance : 9999;
183
2.79G
        }
184
151M
        color= 1024;
185
151M
        distance= -1;
186
2.94G
        for(b_x=w-1; b_x>=0; b_x--){
187
2.79G
            int mb_index_j= (b_x>>is_luma) + (b_y>>is_luma)*s->mb_stride;
188
2.79G
            int error_j= s->error_status_table[mb_index_j];
189
2.79G
            int intra_j = IS_INTRA(s->cur_pic.mb_type[mb_index_j]);
190
2.79G
            if(intra_j==0 || !(error_j&ER_DC_ERROR)){
191
1.98G
                color= dc[b_x + b_y*stride];
192
1.98G
                distance= b_x;
193
1.98G
            }
194
2.79G
            col [b_x + b_y*stride][0]= color;
195
2.79G
            dist[b_x + b_y*stride][0]= distance >= 0 ? distance-b_x : 9999;
196
2.79G
        }
197
151M
    }
198
113M
    for(b_x=0; b_x<w; b_x++){
199
112M
        int color= 1024;
200
112M
        int distance= -1;
201
2.90G
        for(b_y=0; b_y<h; b_y++){
202
2.79G
            int mb_index_j= (b_x>>is_luma) + (b_y>>is_luma)*s->mb_stride;
203
2.79G
            int error_j= s->error_status_table[mb_index_j];
204
2.79G
            int intra_j = IS_INTRA(s->cur_pic.mb_type[mb_index_j]);
205
2.79G
            if(intra_j==0 || !(error_j&ER_DC_ERROR)){
206
1.98G
                color= dc[b_x + b_y*stride];
207
1.98G
                distance= b_y;
208
1.98G
            }
209
2.79G
            col [b_x + b_y*stride][3]= color;
210
2.79G
            dist[b_x + b_y*stride][3]= distance >= 0 ? b_y-distance : 9999;
211
2.79G
        }
212
112M
        color= 1024;
213
112M
        distance= -1;
214
2.90G
        for(b_y=h-1; b_y>=0; b_y--){
215
2.79G
            int mb_index_j= (b_x>>is_luma) + (b_y>>is_luma)*s->mb_stride;
216
2.79G
            int error_j= s->error_status_table[mb_index_j];
217
2.79G
            int intra_j = IS_INTRA(s->cur_pic.mb_type[mb_index_j]);
218
2.79G
            if(intra_j==0 || !(error_j&ER_DC_ERROR)){
219
1.98G
                color= dc[b_x + b_y*stride];
220
1.98G
                distance= b_y;
221
1.98G
            }
222
2.79G
            col [b_x + b_y*stride][2]= color;
223
2.79G
            dist[b_x + b_y*stride][2]= distance >= 0 ? distance-b_y : 9999;
224
2.79G
        }
225
112M
    }
226
227
153M
    for (b_y = 0; b_y < h; b_y++) {
228
2.94G
        for (b_x = 0; b_x < w; b_x++) {
229
2.79G
            int mb_index, error, j;
230
2.79G
            int64_t guess, weight_sum;
231
2.79G
            mb_index = (b_x >> is_luma) + (b_y >> is_luma) * s->mb_stride;
232
2.79G
            error    = s->error_status_table[mb_index];
233
234
2.79G
            if (IS_INTER(s->cur_pic.mb_type[mb_index]))
235
1.86G
                continue; // inter
236
927M
            if (!(error & ER_DC_ERROR))
237
113M
                continue; // dc-ok
238
239
814M
            weight_sum = 0;
240
814M
            guess      = 0;
241
4.07G
            for (j = 0; j < 4; j++) {
242
3.25G
                int64_t weight  = 256 * 256 * 256 * 16 / FFMAX(dist[b_x + b_y*stride][j], 1);
243
3.25G
                guess          += weight*(int64_t)col[b_x + b_y*stride][j];
244
3.25G
                weight_sum     += weight;
245
3.25G
            }
246
814M
            guess = (guess + weight_sum / 2) / weight_sum;
247
814M
            dc[b_x + b_y * stride] = guess;
248
814M
        }
249
151M
    }
250
251
1.35M
fail:
252
1.35M
    av_freep(&col);
253
1.35M
    av_freep(&dist);
254
1.35M
}
255
256
/**
257
 * simple horizontal deblocking filter used for error resilience
258
 * @param w     width in 8 pixel blocks
259
 * @param h     height in 8 pixel blocks
260
 */
261
static void h_block_filter(ERContext *s, uint8_t *dst, int w,
262
                           int h, ptrdiff_t stride, int is_luma)
263
1.35M
{
264
1.35M
    int b_x, b_y;
265
1.35M
    ptrdiff_t mvx_stride, mvy_stride;
266
1.35M
    const uint8_t *cm = ff_crop_tab + MAX_NEG_CROP;
267
1.35M
    set_mv_strides(s, &mvx_stride, &mvy_stride);
268
1.35M
    mvx_stride >>= is_luma;
269
1.35M
    mvy_stride *= mvx_stride;
270
271
153M
    for (b_y = 0; b_y < h; b_y++) {
272
2.79G
        for (b_x = 0; b_x < w - 1; b_x++) {
273
2.64G
            int y;
274
2.64G
            int left_status  = s->error_status_table[( b_x      >> is_luma) + (b_y >> is_luma) * s->mb_stride];
275
2.64G
            int right_status = s->error_status_table[((b_x + 1) >> is_luma) + (b_y >> is_luma) * s->mb_stride];
276
2.64G
            int left_intra   = IS_INTRA(s->cur_pic.mb_type[( b_x      >> is_luma) + (b_y >> is_luma) * s->mb_stride]);
277
2.64G
            int right_intra  = IS_INTRA(s->cur_pic.mb_type[((b_x + 1) >> is_luma) + (b_y >> is_luma) * s->mb_stride]);
278
2.64G
            int left_damage  = left_status & ER_MB_ERROR;
279
2.64G
            int right_damage = right_status & ER_MB_ERROR;
280
2.64G
            int offset       = b_x * 8 + b_y * stride * 8;
281
2.64G
            int16_t *left_mv  = s->cur_pic.motion_val[0][mvy_stride * b_y + mvx_stride *  b_x];
282
2.64G
            int16_t *right_mv = s->cur_pic.motion_val[0][mvy_stride * b_y + mvx_stride * (b_x + 1)];
283
2.64G
            if (!(left_damage || right_damage))
284
200M
                continue; // both undamaged
285
2.44G
            if ((!left_intra) && (!right_intra) &&
286
1.66G
                FFABS(left_mv[0] - right_mv[0]) +
287
1.66G
                FFABS(left_mv[1] + right_mv[1]) < 2)
288
1.62G
                continue;
289
290
7.34G
            for (y = 0; y < 8; y++) {
291
6.52G
                int a, b, c, d;
292
293
6.52G
                a = dst[offset + 7 + y * stride] - dst[offset + 6 + y * stride];
294
6.52G
                b = dst[offset + 8 + y * stride] - dst[offset + 7 + y * stride];
295
6.52G
                c = dst[offset + 9 + y * stride] - dst[offset + 8 + y * stride];
296
297
6.52G
                d = FFABS(b) - ((FFABS(a) + FFABS(c) + 1) >> 1);
298
6.52G
                d = FFMAX(d, 0);
299
6.52G
                if (b < 0)
300
414M
                    d = -d;
301
302
6.52G
                if (d == 0)
303
5.70G
                    continue;
304
305
827M
                if (!(left_damage && right_damage))
306
743k
                    d = d * 16 / 9;
307
308
827M
                if (left_damage) {
309
826M
                    dst[offset + 7 + y * stride] = cm[dst[offset + 7 + y * stride] + ((d * 7) >> 4)];
310
826M
                    dst[offset + 6 + y * stride] = cm[dst[offset + 6 + y * stride] + ((d * 5) >> 4)];
311
826M
                    dst[offset + 5 + y * stride] = cm[dst[offset + 5 + y * stride] + ((d * 3) >> 4)];
312
826M
                    dst[offset + 4 + y * stride] = cm[dst[offset + 4 + y * stride] + ((d * 1) >> 4)];
313
826M
                }
314
827M
                if (right_damage) {
315
826M
                    dst[offset + 8 + y * stride] = cm[dst[offset +  8 + y * stride] - ((d * 7) >> 4)];
316
826M
                    dst[offset + 9 + y * stride] = cm[dst[offset +  9 + y * stride] - ((d * 5) >> 4)];
317
826M
                    dst[offset + 10+ y * stride] = cm[dst[offset + 10 + y * stride] - ((d * 3) >> 4)];
318
826M
                    dst[offset + 11+ y * stride] = cm[dst[offset + 11 + y * stride] - ((d * 1) >> 4)];
319
826M
                }
320
827M
            }
321
815M
        }
322
151M
    }
323
1.35M
}
324
325
/**
326
 * simple vertical deblocking filter used for error resilience
327
 * @param w     width in 8 pixel blocks
328
 * @param h     height in 8 pixel blocks
329
 */
330
static void v_block_filter(ERContext *s, uint8_t *dst, int w, int h,
331
                           ptrdiff_t stride, int is_luma)
332
1.35M
{
333
1.35M
    int b_x, b_y;
334
1.35M
    ptrdiff_t mvx_stride, mvy_stride;
335
1.35M
    const uint8_t *cm = ff_crop_tab + MAX_NEG_CROP;
336
1.35M
    set_mv_strides(s, &mvx_stride, &mvy_stride);
337
1.35M
    mvx_stride >>= is_luma;
338
1.35M
    mvy_stride *= mvx_stride;
339
340
151M
    for (b_y = 0; b_y < h - 1; b_y++) {
341
2.83G
        for (b_x = 0; b_x < w; b_x++) {
342
2.68G
            int x;
343
2.68G
            int top_status    = s->error_status_table[(b_x >> is_luma) +  (b_y      >> is_luma) * s->mb_stride];
344
2.68G
            int bottom_status = s->error_status_table[(b_x >> is_luma) + ((b_y + 1) >> is_luma) * s->mb_stride];
345
2.68G
            int top_intra     = IS_INTRA(s->cur_pic.mb_type[(b_x >> is_luma) + ( b_y      >> is_luma) * s->mb_stride]);
346
2.68G
            int bottom_intra  = IS_INTRA(s->cur_pic.mb_type[(b_x >> is_luma) + ((b_y + 1) >> is_luma) * s->mb_stride]);
347
2.68G
            int top_damage    = top_status & ER_MB_ERROR;
348
2.68G
            int bottom_damage = bottom_status & ER_MB_ERROR;
349
2.68G
            int offset        = b_x * 8 + b_y * stride * 8;
350
351
2.68G
            int16_t *top_mv    = s->cur_pic.motion_val[0][mvy_stride *  b_y      + mvx_stride * b_x];
352
2.68G
            int16_t *bottom_mv = s->cur_pic.motion_val[0][mvy_stride * (b_y + 1) + mvx_stride * b_x];
353
354
2.68G
            if (!(top_damage || bottom_damage))
355
194M
                continue; // both undamaged
356
357
2.48G
            if ((!top_intra) && (!bottom_intra) &&
358
1.70G
                FFABS(top_mv[0] - bottom_mv[0]) +
359
1.70G
                FFABS(top_mv[1] + bottom_mv[1]) < 2)
360
1.66G
                continue;
361
362
7.43G
            for (x = 0; x < 8; x++) {
363
6.61G
                int a, b, c, d;
364
365
6.61G
                a = dst[offset + x + 7 * stride] - dst[offset + x + 6 * stride];
366
6.61G
                b = dst[offset + x + 8 * stride] - dst[offset + x + 7 * stride];
367
6.61G
                c = dst[offset + x + 9 * stride] - dst[offset + x + 8 * stride];
368
369
6.61G
                d = FFABS(b) - ((FFABS(a) + FFABS(c) + 1) >> 1);
370
6.61G
                d = FFMAX(d, 0);
371
6.61G
                if (b < 0)
372
90.3M
                    d = -d;
373
374
6.61G
                if (d == 0)
375
6.43G
                    continue;
376
377
181M
                if (!(top_damage && bottom_damage))
378
30.4M
                    d = d * 16 / 9;
379
380
181M
                if (top_damage) {
381
152M
                    dst[offset + x +  7 * stride] = cm[dst[offset + x +  7 * stride] + ((d * 7) >> 4)];
382
152M
                    dst[offset + x +  6 * stride] = cm[dst[offset + x +  6 * stride] + ((d * 5) >> 4)];
383
152M
                    dst[offset + x +  5 * stride] = cm[dst[offset + x +  5 * stride] + ((d * 3) >> 4)];
384
152M
                    dst[offset + x +  4 * stride] = cm[dst[offset + x +  4 * stride] + ((d * 1) >> 4)];
385
152M
                }
386
181M
                if (bottom_damage) {
387
179M
                    dst[offset + x +  8 * stride] = cm[dst[offset + x +  8 * stride] - ((d * 7) >> 4)];
388
179M
                    dst[offset + x +  9 * stride] = cm[dst[offset + x +  9 * stride] - ((d * 5) >> 4)];
389
179M
                    dst[offset + x + 10 * stride] = cm[dst[offset + x + 10 * stride] - ((d * 3) >> 4)];
390
179M
                    dst[offset + x + 11 * stride] = cm[dst[offset + x + 11 * stride] - ((d * 1) >> 4)];
391
179M
                }
392
181M
            }
393
826M
        }
394
150M
    }
395
1.35M
}
396
397
918M
#define MV_FROZEN    8
398
112M
#define MV_CHANGED   4
399
103M
#define MV_UNCHANGED 2
400
52.0M
#define MV_LISTED    1
401
static av_always_inline void add_blocklist(int (*blocklist)[2], int *blocklist_length, uint8_t *fixed, int mb_x, int mb_y, int mb_xy)
402
814M
{
403
814M
    if (fixed[mb_xy])
404
762M
        return;
405
52.0M
    fixed[mb_xy] = MV_LISTED;
406
52.0M
    blocklist[ *blocklist_length   ][0] = mb_x;
407
52.0M
    blocklist[(*blocklist_length)++][1] = mb_y;
408
52.0M
}
409
410
static void guess_mv(ERContext *s)
411
381k
{
412
381k
    int (*blocklist)[2], (*next_blocklist)[2];
413
381k
    uint8_t *fixed;
414
381k
    const ptrdiff_t mb_stride = s->mb_stride;
415
381k
    const int mb_width  = s->mb_width;
416
381k
    int mb_height = s->mb_height;
417
381k
    int i, num_avail;
418
381k
    int mb_x, mb_y;
419
381k
    ptrdiff_t mot_step, mot_stride;
420
381k
    int blocklist_length, next_blocklist_length;
421
422
381k
    if (s->last_pic.f && s->last_pic.f->data[0])
423
272k
        mb_height = FFMIN(mb_height, (s->last_pic.f->height+15)>>4);
424
381k
    if (s->next_pic.f && s->next_pic.f->data[0])
425
250k
        mb_height = FFMIN(mb_height, (s->next_pic.f->height+15)>>4);
426
427
381k
    blocklist      = (int (*)[2])s->er_temp_buffer;
428
381k
    next_blocklist = blocklist + s->mb_stride * s->mb_height;
429
381k
    fixed          = (uint8_t *)(next_blocklist + s->mb_stride * s->mb_height);
430
431
381k
    set_mv_strides(s, &mot_step, &mot_stride);
432
433
381k
    num_avail = 0;
434
381k
    if (s->last_pic.motion_val[0]) {
435
260k
        if (s->last_pic.tf)
436
88.7k
            ff_thread_await_progress(s->last_pic.tf, mb_height-1, 0);
437
171k
        else
438
171k
            ff_thread_progress_await(s->last_pic.progress, mb_height - 1);
439
260k
    }
440
426M
    for (i = 0; i < mb_width * mb_height; i++) {
441
426M
        const int mb_xy = s->mb_index2xy[i];
442
426M
        int f = 0;
443
426M
        int error = s->error_status_table[mb_xy];
444
445
426M
        if (IS_INTRA(s->cur_pic.mb_type[mb_xy]))
446
139M
            f = MV_FROZEN; // intra // FIXME check
447
426M
        if (!(error & ER_MV_ERROR))
448
32.3M
            f = MV_FROZEN; // inter with undamaged MV
449
450
426M
        fixed[mb_xy] = f;
451
426M
        if (f == MV_FROZEN)
452
164M
            num_avail++;
453
262M
        else if(s->last_pic.f->data[0] && s->last_pic.motion_val[0]){
454
254M
            const int mb_y= mb_xy / s->mb_stride;
455
254M
            const int mb_x= mb_xy % s->mb_stride;
456
254M
            const int mot_index= (mb_x + mb_y*mot_stride) * mot_step;
457
254M
            s->cur_pic.motion_val[0][mot_index][0]= s->last_pic.motion_val[0][mot_index][0];
458
254M
            s->cur_pic.motion_val[0][mot_index][1]= s->last_pic.motion_val[0][mot_index][1];
459
254M
            s->cur_pic.ref_index[0][4*mb_xy]      = s->last_pic.ref_index[0][4*mb_xy];
460
254M
        }
461
426M
    }
462
463
381k
    if ((!(s->avctx->error_concealment&FF_EC_GUESS_MVS)) ||
464
381k
        num_avail <= FFMAX(mb_width, mb_height) / 2) {
465
21.5M
        for (mb_y = 0; mb_y < mb_height; mb_y++) {
466
232M
            for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
467
211M
                const int mb_xy = mb_x + mb_y * s->mb_stride;
468
211M
                int mv_dir = (s->last_pic.f && s->last_pic.f->data[0]) ? MV_DIR_FORWARD : MV_DIR_BACKWARD;
469
470
211M
                if (IS_INTRA(s->cur_pic.mb_type[mb_xy]))
471
41.4k
                    continue;
472
211M
                if (!(s->error_status_table[mb_xy] & ER_MV_ERROR))
473
1.17M
                    continue;
474
475
210M
                s->mv[0][0][0] = 0;
476
210M
                s->mv[0][0][1] = 0;
477
210M
                s->decode_mb(s->opaque, 0, mv_dir, MV_TYPE_16X16, &s->mv,
478
210M
                             mb_x, mb_y, 0, 0);
479
210M
            }
480
21.3M
        }
481
221k
        return;
482
221k
    }
483
484
159k
    blocklist_length = 0;
485
12.9M
    for (mb_y = 0; mb_y < mb_height; mb_y++) {
486
228M
        for (mb_x = 0; mb_x < mb_width; mb_x++) {
487
215M
            const int mb_xy = mb_x + mb_y * mb_stride;
488
215M
            if (fixed[mb_xy] == MV_FROZEN) {
489
163M
                if (mb_x)               add_blocklist(blocklist, &blocklist_length, fixed, mb_x - 1, mb_y, mb_xy - 1);
490
163M
                if (mb_y)               add_blocklist(blocklist, &blocklist_length, fixed, mb_x, mb_y - 1, mb_xy - mb_stride);
491
163M
                if (mb_x+1 < mb_width)  add_blocklist(blocklist, &blocklist_length, fixed, mb_x + 1, mb_y, mb_xy + 1);
492
163M
                if (mb_y+1 < mb_height) add_blocklist(blocklist, &blocklist_length, fixed, mb_x, mb_y + 1, mb_xy + mb_stride);
493
163M
            }
494
215M
        }
495
12.8M
    }
496
497
3.09M
    for (;;) {
498
3.09M
        int changed, pass, none_left;
499
3.09M
        int blocklist_index;
500
501
3.09M
        none_left = 1;
502
3.09M
        changed   = 1;
503
9.74M
        for (pass = 0; (changed || pass < 2) && pass < 10; pass++) {
504
6.65M
            changed = 0;
505
123M
            for (blocklist_index = 0; blocklist_index < blocklist_length; blocklist_index++) {
506
116M
                const int mb_x = blocklist[blocklist_index][0];
507
116M
                const int mb_y = blocklist[blocklist_index][1];
508
116M
                const int mb_xy = mb_x + mb_y * mb_stride;
509
116M
                int mv_predictor[8][2];
510
116M
                int ref[8];
511
116M
                int pred_count;
512
116M
                int j;
513
116M
                int best_score;
514
116M
                int best_pred;
515
116M
                int mot_index;
516
116M
                int prev_x, prev_y, prev_ref;
517
518
116M
                if ((mb_x ^ mb_y ^ pass) & 1)
519
58.6M
                    continue;
520
58.3M
                av_assert2(fixed[mb_xy] != MV_FROZEN);
521
522
523
58.3M
                av_assert1(!IS_INTRA(s->cur_pic.mb_type[mb_xy]));
524
58.3M
                av_assert1(s->last_pic.f && s->last_pic.f->data[0]);
525
526
58.3M
                j = 0;
527
58.3M
                if (mb_x > 0)
528
55.4M
                    j |= fixed[mb_xy - 1];
529
58.3M
                if (mb_x + 1 < mb_width)
530
55.5M
                    j |= fixed[mb_xy + 1];
531
58.3M
                if (mb_y > 0)
532
57.7M
                    j |= fixed[mb_xy - mb_stride];
533
58.3M
                if (mb_y + 1 < mb_height)
534
55.0M
                    j |= fixed[mb_xy + mb_stride];
535
536
58.3M
                av_assert2(j & MV_FROZEN);
537
538
58.3M
                if (!(j & MV_CHANGED) && pass > 1)
539
4.94M
                    continue;
540
541
53.3M
                none_left = 0;
542
53.3M
                pred_count = 0;
543
53.3M
                mot_index  = (mb_x + mb_y * mot_stride) * mot_step;
544
545
53.3M
                if (mb_x > 0 && fixed[mb_xy - 1] > 1) {
546
28.5M
                    mv_predictor[pred_count][0] =
547
28.5M
                        s->cur_pic.motion_val[0][mot_index - mot_step][0];
548
28.5M
                    mv_predictor[pred_count][1] =
549
28.5M
                        s->cur_pic.motion_val[0][mot_index - mot_step][1];
550
28.5M
                    ref[pred_count] =
551
28.5M
                        s->cur_pic.ref_index[0][4 * (mb_xy - 1)];
552
28.5M
                    pred_count++;
553
28.5M
                }
554
53.3M
                if (mb_x + 1 < mb_width && fixed[mb_xy + 1] > 1) {
555
23.3M
                    mv_predictor[pred_count][0] =
556
23.3M
                        s->cur_pic.motion_val[0][mot_index + mot_step][0];
557
23.3M
                    mv_predictor[pred_count][1] =
558
23.3M
                        s->cur_pic.motion_val[0][mot_index + mot_step][1];
559
23.3M
                    ref[pred_count] =
560
23.3M
                        s->cur_pic.ref_index[0][4 * (mb_xy + 1)];
561
23.3M
                    pred_count++;
562
23.3M
                }
563
53.3M
                if (mb_y > 0 && fixed[mb_xy - mb_stride] > 1) {
564
50.6M
                    mv_predictor[pred_count][0] =
565
50.6M
                        s->cur_pic.motion_val[0][mot_index - mot_stride * mot_step][0];
566
50.6M
                    mv_predictor[pred_count][1] =
567
50.6M
                        s->cur_pic.motion_val[0][mot_index - mot_stride * mot_step][1];
568
50.6M
                    ref[pred_count] =
569
50.6M
                        s->cur_pic.ref_index[0][4 * (mb_xy - s->mb_stride)];
570
50.6M
                    pred_count++;
571
50.6M
                }
572
53.3M
                if (mb_y + 1<mb_height && fixed[mb_xy + mb_stride] > 1) {
573
2.40M
                    mv_predictor[pred_count][0] =
574
2.40M
                        s->cur_pic.motion_val[0][mot_index + mot_stride * mot_step][0];
575
2.40M
                    mv_predictor[pred_count][1] =
576
2.40M
                        s->cur_pic.motion_val[0][mot_index + mot_stride * mot_step][1];
577
2.40M
                    ref[pred_count] =
578
2.40M
                        s->cur_pic.ref_index[0][4 * (mb_xy + s->mb_stride)];
579
2.40M
                    pred_count++;
580
2.40M
                }
581
53.3M
                if (pred_count == 0)
582
0
                    continue;
583
584
53.3M
                if (pred_count > 1) {
585
29.4M
                    int sum_x = 0, sum_y = 0, sum_r = 0;
586
29.4M
                    int max_x, max_y, min_x, min_y, max_r, min_r;
587
588
110M
                    for (j = 0; j < pred_count; j++) {
589
80.9M
                        sum_x += mv_predictor[j][0];
590
80.9M
                        sum_y += mv_predictor[j][1];
591
80.9M
                        sum_r += ref[j];
592
80.9M
                        if (j && ref[j] != ref[j - 1])
593
135k
                            goto skip_mean_and_median;
594
80.9M
                    }
595
596
                    /* mean */
597
29.3M
                    mv_predictor[pred_count][0] = sum_x / j;
598
29.3M
                    mv_predictor[pred_count][1] = sum_y / j;
599
29.3M
                             ref[pred_count]    = sum_r / j;
600
601
                    /* median */
602
29.3M
                    if (pred_count >= 3) {
603
21.9M
                        min_y = min_x = min_r =  99999;
604
21.9M
                        max_y = max_x = max_r = -99999;
605
21.9M
                    } else {
606
7.37M
                        min_x = min_y = max_x = max_y = min_r = max_r = 0;
607
7.37M
                    }
608
110M
                    for (j = 0; j < pred_count; j++) {
609
80.6M
                        max_x = FFMAX(max_x, mv_predictor[j][0]);
610
80.6M
                        max_y = FFMAX(max_y, mv_predictor[j][1]);
611
80.6M
                        max_r = FFMAX(max_r, ref[j]);
612
80.6M
                        min_x = FFMIN(min_x, mv_predictor[j][0]);
613
80.6M
                        min_y = FFMIN(min_y, mv_predictor[j][1]);
614
80.6M
                        min_r = FFMIN(min_r, ref[j]);
615
80.6M
                    }
616
29.3M
                    mv_predictor[pred_count + 1][0] = sum_x - max_x - min_x;
617
29.3M
                    mv_predictor[pred_count + 1][1] = sum_y - max_y - min_y;
618
29.3M
                             ref[pred_count + 1]    = sum_r - max_r - min_r;
619
620
29.3M
                    if (pred_count == 4) {
621
31.2k
                        mv_predictor[pred_count + 1][0] /= 2;
622
31.2k
                        mv_predictor[pred_count + 1][1] /= 2;
623
31.2k
                                 ref[pred_count + 1]    /= 2;
624
31.2k
                    }
625
29.3M
                    pred_count += 2;
626
29.3M
                }
627
628
53.3M
skip_mean_and_median:
629
                /* zero MV */
630
53.3M
                mv_predictor[pred_count][0] =
631
53.3M
                mv_predictor[pred_count][1] =
632
53.3M
                         ref[pred_count]    = 0;
633
53.3M
                pred_count++;
634
635
53.3M
                prev_x   = s->cur_pic.motion_val[0][mot_index][0];
636
53.3M
                prev_y   = s->cur_pic.motion_val[0][mot_index][1];
637
53.3M
                prev_ref = s->cur_pic.ref_index[0][4 * mb_xy];
638
639
                /* last MV */
640
53.3M
                mv_predictor[pred_count][0] = prev_x;
641
53.3M
                mv_predictor[pred_count][1] = prev_y;
642
53.3M
                         ref[pred_count]    = prev_ref;
643
53.3M
                pred_count++;
644
645
53.3M
                best_pred = 0;
646
53.3M
                best_score = 256 * 256 * 256 * 64;
647
323M
                for (j = 0; j < pred_count; j++) {
648
270M
                    int *linesize = s->cur_pic.f->linesize;
649
270M
                    int score = 0;
650
270M
                    uint8_t *src = s->cur_pic.f->data[0] +
651
270M
                                   mb_x * 16 + mb_y * 16 * linesize[0];
652
653
270M
                    s->cur_pic.motion_val[0][mot_index][0] =
654
270M
                        s->mv[0][0][0] = mv_predictor[j][0];
655
270M
                    s->cur_pic.motion_val[0][mot_index][1] =
656
270M
                        s->mv[0][0][1] = mv_predictor[j][1];
657
658
                    // predictor intra or otherwise not available
659
270M
                    if (ref[j] < 0)
660
28.3k
                        continue;
661
662
270M
                    s->decode_mb(s->opaque, ref[j], MV_DIR_FORWARD,
663
270M
                                 MV_TYPE_16X16, &s->mv, mb_x, mb_y, 0, 0);
664
665
270M
                    if (mb_x > 0 && fixed[mb_xy - 1] > 1) {
666
191M
                        int k;
667
3.26G
                        for (k = 0; k < 16; k++)
668
3.07G
                            score += FFABS(src[k * linesize[0] - 1] -
669
191M
                                           src[k * linesize[0]]);
670
191M
                    }
671
270M
                    if (mb_x + 1 < mb_width && fixed[mb_xy + 1] > 1) {
672
162M
                        int k;
673
2.75G
                        for (k = 0; k < 16; k++)
674
2.59G
                            score += FFABS(src[k * linesize[0] + 15] -
675
162M
                                           src[k * linesize[0] + 16]);
676
162M
                    }
677
270M
                    if (mb_y > 0 && fixed[mb_xy - mb_stride] > 1) {
678
257M
                        int k;
679
4.36G
                        for (k = 0; k < 16; k++)
680
4.11G
                            score += FFABS(src[k - linesize[0]] - src[k]);
681
257M
                    }
682
270M
                    if (mb_y + 1 < mb_height && fixed[mb_xy + mb_stride] > 1) {
683
12.6M
                        int k;
684
215M
                        for (k = 0; k < 16; k++)
685
202M
                            score += FFABS(src[k + linesize[0] * 15] -
686
12.6M
                                           src[k + linesize[0] * 16]);
687
12.6M
                    }
688
689
270M
                    if (score <= best_score) { // <= will favor the last MV
690
263M
                        best_score = score;
691
263M
                        best_pred  = j;
692
263M
                    }
693
270M
                }
694
53.3M
                s->mv[0][0][0] = mv_predictor[best_pred][0];
695
53.3M
                s->mv[0][0][1] = mv_predictor[best_pred][1];
696
697
171M
                for (i = 0; i < mot_step; i++)
698
398M
                    for (j = 0; j < mot_step; j++) {
699
280M
                        s->cur_pic.motion_val[0][mot_index + i + j * mot_stride][0] = s->mv[0][0][0];
700
280M
                        s->cur_pic.motion_val[0][mot_index + i + j * mot_stride][1] = s->mv[0][0][1];
701
280M
                    }
702
703
53.3M
                s->decode_mb(s->opaque, ref[best_pred], MV_DIR_FORWARD,
704
53.3M
                             MV_TYPE_16X16, &s->mv, mb_x, mb_y, 0, 0);
705
706
707
53.3M
                if (s->mv[0][0][0] != prev_x || s->mv[0][0][1] != prev_y) {
708
1.80M
                    fixed[mb_xy] = MV_CHANGED;
709
1.80M
                    changed++;
710
1.80M
                } else
711
51.5M
                    fixed[mb_xy] = MV_UNCHANGED;
712
53.3M
            }
713
6.65M
        }
714
715
3.09M
        if (none_left)
716
159k
            return;
717
718
2.93M
        next_blocklist_length = 0;
719
720
55.0M
        for (blocklist_index = 0; blocklist_index < blocklist_length; blocklist_index++) {
721
52.0M
            const int mb_x = blocklist[blocklist_index][0];
722
52.0M
            const int mb_y = blocklist[blocklist_index][1];
723
52.0M
            const int mb_xy = mb_x + mb_y * mb_stride;
724
725
52.0M
            if (fixed[mb_xy] & (MV_CHANGED|MV_UNCHANGED|MV_FROZEN)) {
726
52.0M
                fixed[mb_xy] = MV_FROZEN;
727
52.0M
                if (mb_x > 0)
728
49.4M
                    add_blocklist(next_blocklist, &next_blocklist_length, fixed, mb_x - 1, mb_y, mb_xy - 1);
729
52.0M
                if (mb_y > 0)
730
51.5M
                    add_blocklist(next_blocklist, &next_blocklist_length, fixed, mb_x, mb_y - 1, mb_xy - mb_stride);
731
52.0M
                if (mb_x + 1 < mb_width)
732
49.4M
                    add_blocklist(next_blocklist, &next_blocklist_length, fixed, mb_x + 1, mb_y, mb_xy + 1);
733
52.0M
                if (mb_y + 1 < mb_height)
734
49.2M
                    add_blocklist(next_blocklist, &next_blocklist_length, fixed, mb_x, mb_y + 1, mb_xy + mb_stride);
735
52.0M
            }
736
52.0M
        }
737
2.93M
        av_assert0(next_blocklist_length <= mb_height * mb_width);
738
2.93M
        FFSWAP(int , blocklist_length, next_blocklist_length);
739
2.93M
        FFSWAP(void*, blocklist, next_blocklist);
740
2.93M
    }
741
159k
}
742
743
static int is_intra_more_likely(ERContext *s)
744
450k
{
745
450k
    int is_intra_likely, i, j, undamaged_count, skip_amount, mb_x, mb_y;
746
747
450k
    if (!s->last_pic.f || !s->last_pic.f->data[0])
748
115k
        return 1; // no previous frame available -> use spatial prediction
749
750
334k
    if (s->avctx->error_concealment & FF_EC_FAVOR_INTER)
751
0
        return 0;
752
753
334k
    undamaged_count = 0;
754
334M
    for (i = 0; i < s->mb_num; i++) {
755
334M
        const int mb_xy = s->mb_index2xy[i];
756
334M
        const int error = s->error_status_table[mb_xy];
757
334M
        if (!((error & ER_DC_ERROR) && (error & ER_MV_ERROR)))
758
26.9M
            undamaged_count++;
759
334M
    }
760
761
334k
    if (undamaged_count < 5)
762
254k
        return 0; // almost all MBs damaged -> use temporal prediction
763
764
79.9k
    skip_amount     = FFMAX(undamaged_count / 50, 1); // check only up to 50 MBs
765
79.9k
    is_intra_likely = 0;
766
767
79.9k
    j = 0;
768
12.4M
    for (mb_y = 0; mb_y < s->mb_height - 1; mb_y++) {
769
160M
        for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
770
148M
            int error;
771
148M
            const int mb_xy = mb_x + mb_y * s->mb_stride;
772
773
148M
            error = s->error_status_table[mb_xy];
774
148M
            if ((error & ER_DC_ERROR) && (error & ER_MV_ERROR))
775
122M
                continue; // skip damaged
776
777
26.1M
            j++;
778
            // skip a few to speed things up
779
26.1M
            if ((j % skip_amount) != 0)
780
23.3M
                continue;
781
782
2.82M
            if (s->cur_pic.f->pict_type == AV_PICTURE_TYPE_I) {
783
130k
                int *linesize = s->cur_pic.f->linesize;
784
130k
                uint8_t *mb_ptr      = s->cur_pic.f->data[0] +
785
130k
                                       mb_x * 16 + mb_y * 16 * linesize[0];
786
130k
                uint8_t *last_mb_ptr = s->last_pic.f->data[0] +
787
130k
                                       mb_x * 16 + mb_y * 16 * linesize[0];
788
789
130k
                if (s->avctx->codec_id == AV_CODEC_ID_H264) {
790
                    // FIXME
791
117k
                } else {
792
117k
                    ff_thread_progress_await(s->last_pic.progress, mb_y);
793
117k
                }
794
130k
                is_intra_likely += s->sad(NULL, last_mb_ptr, mb_ptr,
795
130k
                                          linesize[0], 16);
796
                // FIXME need await_progress() here
797
130k
                is_intra_likely -= s->sad(NULL, last_mb_ptr,
798
130k
                                          last_mb_ptr + linesize[0] * 16,
799
130k
                                          linesize[0], 16);
800
2.68M
            } else {
801
2.68M
                if (IS_INTRA(s->cur_pic.mb_type[mb_xy]))
802
65.1k
                   is_intra_likely++;
803
2.62M
                else
804
2.62M
                   is_intra_likely--;
805
2.68M
            }
806
2.82M
        }
807
12.3M
    }
808
//      av_log(NULL, AV_LOG_ERROR, "is_intra_likely: %d type:%d\n", is_intra_likely, s->pict_type);
809
79.9k
    return is_intra_likely > 0;
810
334k
}
811
812
void ff_er_frame_start(ERContext *s)
813
6.51M
{
814
6.51M
    if (!s->avctx->error_concealment)
815
4.43M
        return;
816
817
2.08M
    memset(s->error_status_table, ER_MB_ERROR | VP_START | ER_MB_END,
818
2.08M
           s->mb_stride * s->mb_height * sizeof(uint8_t));
819
2.08M
    atomic_init(&s->error_count, 3 * s->mb_num);
820
2.08M
    s->error_occurred = 0;
821
2.08M
}
822
823
static int er_supported(ERContext *s)
824
1.50M
{
825
1.50M
    if (s->avctx->hwaccel ||
826
1.50M
       !s->cur_pic.f                                                  ||
827
1.28M
       s->cur_pic.field_picture
828
1.50M
    )
829
245k
        return 0;
830
1.26M
    return 1;
831
1.50M
}
832
833
/**
834
 * Add a slice.
835
 * @param endx   x component of the last macroblock, can be -1
836
 *               for the last of the previous line
837
 * @param status the status at the end (ER_MV_END, ER_AC_ERROR, ...), it is
838
 *               assumed that no earlier end or error of the same type occurred
839
 */
840
void ff_er_add_slice(ERContext *s, int startx, int starty,
841
                     int endx, int endy, int status)
842
6.20M
{
843
6.20M
    const int start_i  = av_clip(startx + starty * s->mb_width, 0, s->mb_num - 1);
844
6.20M
    const int end_i    = av_clip(endx   + endy   * s->mb_width, 0, s->mb_num);
845
6.20M
    const int start_xy = s->mb_index2xy[start_i];
846
6.20M
    const int end_xy   = s->mb_index2xy[end_i];
847
6.20M
    int mask           = -1;
848
849
6.20M
    if (s->avctx->hwaccel)
850
0
        return;
851
852
6.20M
    if (start_i > end_i || start_xy > end_xy) {
853
14.3k
        av_log(s->avctx, AV_LOG_ERROR,
854
14.3k
               "internal error, slice end before start\n");
855
14.3k
        return;
856
14.3k
    }
857
858
6.18M
    if (!s->avctx->error_concealment)
859
2.98M
        return;
860
861
3.20M
    mask &= ~VP_START;
862
3.20M
    if (status & (ER_AC_ERROR | ER_AC_END)) {
863
3.17M
        mask           &= ~(ER_AC_ERROR | ER_AC_END);
864
3.17M
        atomic_fetch_add(&s->error_count, start_i - end_i - 1);
865
3.17M
    }
866
3.20M
    if (status & (ER_DC_ERROR | ER_DC_END)) {
867
3.18M
        mask           &= ~(ER_DC_ERROR | ER_DC_END);
868
3.18M
        atomic_fetch_add(&s->error_count, start_i - end_i - 1);
869
3.18M
    }
870
3.20M
    if (status & (ER_MV_ERROR | ER_MV_END)) {
871
3.19M
        mask           &= ~(ER_MV_ERROR | ER_MV_END);
872
3.19M
        atomic_fetch_add(&s->error_count, start_i - end_i - 1);
873
3.19M
    }
874
875
3.20M
    if (status & ER_MB_ERROR) {
876
2.31M
        s->error_occurred = 1;
877
2.31M
        atomic_store(&s->error_count, INT_MAX);
878
2.31M
    }
879
880
3.20M
    if (mask == ~0x7F) {
881
3.17M
        memset(&s->error_status_table[start_xy], 0,
882
3.17M
               (end_xy - start_xy) * sizeof(uint8_t));
883
3.17M
    } else {
884
32.0k
        int i;
885
651k
        for (i = start_xy; i < end_xy; i++)
886
619k
            s->error_status_table[i] &= mask;
887
32.0k
    }
888
889
3.20M
    if (end_i == s->mb_num)
890
3.20M
        atomic_store(&s->error_count, INT_MAX);
891
2.99M
    else {
892
2.99M
        s->error_status_table[end_xy] &= mask;
893
2.99M
        s->error_status_table[end_xy] |= status;
894
2.99M
    }
895
896
3.20M
    s->error_status_table[start_xy] |= VP_START;
897
898
3.20M
    if (start_xy > 0 && !(s->avctx->active_thread_type & FF_THREAD_SLICE) &&
899
1.05M
        er_supported(s) && s->avctx->skip_top * s->mb_width < start_i) {
900
811k
        int prev_status = s->error_status_table[s->mb_index2xy[start_i - 1]];
901
902
811k
        prev_status &= ~ VP_START;
903
811k
        if (prev_status != (ER_MV_END | ER_DC_END | ER_AC_END)) {
904
480k
            s->error_occurred = 1;
905
480k
            atomic_store(&s->error_count, INT_MAX);
906
480k
        }
907
811k
    }
908
3.20M
}
909
910
void ff_er_frame_end(ERContext *s, int *decode_error_flags)
911
2.92M
{
912
2.92M
    int *linesize = NULL;
913
2.92M
    int i, mb_x, mb_y, error, error_type, dc_error, mv_error, ac_error;
914
2.92M
    int distance;
915
2.92M
    int threshold_part[4] = { 100, 100, 100 };
916
2.92M
    int threshold = 50;
917
2.92M
    int is_intra_likely;
918
2.92M
    int size = s->b8_stride * 2 * s->mb_height;
919
2.92M
    int guessed_mb_type;
920
921
    /* We do not support ER of field pictures yet,
922
     * though it should not crash if enabled. */
923
2.92M
    if (!s->avctx->error_concealment || !atomic_load(&s->error_count)  ||
924
511k
        s->avctx->lowres                                               ||
925
453k
        !er_supported(s)                                               ||
926
2.92M
        atomic_load(&s->error_count) == 3 * s->mb_width *
927
2.47M
                          (s->avctx->skip_top + s->avctx->skip_bottom)) {
928
2.47M
        return;
929
2.47M
    }
930
451k
    linesize = s->cur_pic.f->linesize;
931
932
451k
    if (   s->avctx->codec_id == AV_CODEC_ID_MPEG2VIDEO
933
11.4k
        && (FFALIGN(s->avctx->height, 16)&16)
934
451k
        && atomic_load(&s->error_count) == 3 * s->mb_width * (s->avctx->skip_top + s->avctx->skip_bottom + 1)) {
935
281k
        for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
936
280k
            int status = s->error_status_table[mb_x + (s->mb_height - 1) * s->mb_stride];
937
280k
            if (status != 0x7F)
938
0
                break;
939
280k
        }
940
941
943
        if (mb_x == s->mb_width) {
942
943
            av_log(s->avctx, AV_LOG_DEBUG, "ignoring last missing slice\n");
943
943
            return;
944
943
        }
945
943
    }
946
947
450k
    if (s->last_pic.f) {
948
334k
        if (s->last_pic.f->width  != s->cur_pic.f->width  ||
949
334k
            s->last_pic.f->height != s->cur_pic.f->height ||
950
334k
            s->last_pic.f->format != s->cur_pic.f->format) {
951
0
            av_log(s->avctx, AV_LOG_WARNING, "Cannot use previous picture in error concealment\n");
952
0
            memset(&s->last_pic, 0, sizeof(s->last_pic));
953
0
        }
954
334k
    }
955
450k
    if (s->next_pic.f) {
956
310k
        if (s->next_pic.f->width  != s->cur_pic.f->width  ||
957
307k
            s->next_pic.f->height != s->cur_pic.f->height ||
958
307k
            s->next_pic.f->format != s->cur_pic.f->format) {
959
3.07k
            av_log(s->avctx, AV_LOG_WARNING, "Cannot use next picture in error concealment\n");
960
3.07k
            memset(&s->next_pic, 0, sizeof(s->next_pic));
961
3.07k
        }
962
310k
    }
963
964
450k
    if (!s->cur_pic.motion_val[0] || !s->cur_pic.ref_index[0]) {
965
20.5k
        av_log(s->avctx, AV_LOG_ERROR, "Warning MVs not available\n");
966
967
61.6k
        for (i = 0; i < 2; i++) {
968
41.0k
            s->ref_index[i]       = av_calloc(s->mb_stride * s->mb_height, 4 * sizeof(uint8_t));
969
41.0k
            s->motion_val_base[i] = av_calloc(size + 4, 2 * sizeof(uint16_t));
970
41.0k
            if (!s->ref_index[i] || !s->motion_val_base[i])
971
0
                goto cleanup;
972
41.0k
            s->cur_pic.ref_index[i]  = s->ref_index[i];
973
41.0k
            s->cur_pic.motion_val[i] = s->motion_val_base[i] + 4;
974
41.0k
        }
975
20.5k
    }
976
977
450k
    if (s->avctx->debug & FF_DEBUG_ER) {
978
0
        for (mb_y = 0; mb_y < s->mb_height; mb_y++) {
979
0
            for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
980
0
                int status = s->error_status_table[mb_x + mb_y * s->mb_stride];
981
982
0
                av_log(s->avctx, AV_LOG_DEBUG, "%2X ", status);
983
0
            }
984
0
            av_log(s->avctx, AV_LOG_DEBUG, "\n");
985
0
        }
986
0
    }
987
988
450k
#if 1
989
    /* handle overlapping slices */
990
1.80M
    for (error_type = 1; error_type <= 3; error_type++) {
991
1.35M
        int end_ok = 0;
992
993
1.39G
        for (i = s->mb_num - 1; i >= 0; i--) {
994
1.39G
            const int mb_xy = s->mb_index2xy[i];
995
1.39G
            int error       = s->error_status_table[mb_xy];
996
997
1.39G
            if (error & (1 << error_type))
998
1.27G
                end_ok = 1;
999
1.39G
            if (error & (8 << error_type))
1000
1.27G
                end_ok = 1;
1001
1002
1.39G
            if (!end_ok)
1003
394k
                s->error_status_table[mb_xy] |= 1 << error_type;
1004
1005
1.39G
            if (error & VP_START)
1006
1.27G
                end_ok = 0;
1007
1.39G
        }
1008
1.35M
    }
1009
450k
#endif
1010
450k
#if 1
1011
    /* handle slices with partitions of different length */
1012
450k
    if (s->partitioned_frame) {
1013
5.05k
        int end_ok = 0;
1014
1015
1.92M
        for (i = s->mb_num - 1; i >= 0; i--) {
1016
1.92M
            const int mb_xy = s->mb_index2xy[i];
1017
1.92M
            int error       = s->error_status_table[mb_xy];
1018
1019
1.92M
            if (error & ER_AC_END)
1020
1.90M
                end_ok = 0;
1021
1.92M
            if ((error & ER_MV_END) ||
1022
297k
                (error & ER_DC_END) ||
1023
20.0k
                (error & ER_AC_ERROR))
1024
1.91M
                end_ok = 1;
1025
1026
1.92M
            if (!end_ok)
1027
911
                s->error_status_table[mb_xy]|= ER_AC_ERROR;
1028
1029
1.92M
            if (error & VP_START)
1030
1.63M
                end_ok = 0;
1031
1.92M
        }
1032
5.05k
    }
1033
450k
#endif
1034
    /* handle missing slices */
1035
450k
    if (s->avctx->err_recognition & AV_EF_EXPLODE) {
1036
101k
        int end_ok = 1;
1037
1038
        // FIXME + 100 hack
1039
76.2M
        for (i = s->mb_num - 2; i >= s->mb_width + 100; i--) {
1040
76.1M
            const int mb_xy = s->mb_index2xy[i];
1041
76.1M
            int error1 = s->error_status_table[mb_xy];
1042
76.1M
            int error2 = s->error_status_table[s->mb_index2xy[i + 1]];
1043
1044
76.1M
            if (error1 & VP_START)
1045
71.2M
                end_ok = 1;
1046
1047
76.1M
            if (error2 == (VP_START | ER_MB_ERROR | ER_MB_END) &&
1048
71.2M
                error1 != (VP_START | ER_MB_ERROR | ER_MB_END) &&
1049
11.8k
                ((error1 & ER_AC_END) || (error1 & ER_DC_END) ||
1050
8.22k
                (error1 & ER_MV_END))) {
1051
                // end & uninit
1052
3.63k
                end_ok = 0;
1053
3.63k
            }
1054
1055
76.1M
            if (!end_ok)
1056
369k
                s->error_status_table[mb_xy] |= ER_MB_ERROR;
1057
76.1M
        }
1058
101k
    }
1059
1060
450k
#if 1
1061
    /* backward mark errors */
1062
450k
    distance = 9999999;
1063
1.80M
    for (error_type = 1; error_type <= 3; error_type++) {
1064
1.39G
        for (i = s->mb_num - 1; i >= 0; i--) {
1065
1.39G
            const int mb_xy = s->mb_index2xy[i];
1066
1.39G
            int       error = s->error_status_table[mb_xy];
1067
1068
1.39G
            if (!s->mbskip_table || !s->mbskip_table[mb_xy]) // FIXME partition specific
1069
1.31G
                distance++;
1070
1.39G
            if (error & (1 << error_type))
1071
1.27G
                distance = 0;
1072
1073
1.39G
            if (s->partitioned_frame) {
1074
5.77M
                if (distance < threshold_part[error_type - 1])
1075
5.60M
                    s->error_status_table[mb_xy] |= 1 << error_type;
1076
1.39G
            } else {
1077
1.39G
                if (distance < threshold)
1078
1.28G
                    s->error_status_table[mb_xy] |= 1 << error_type;
1079
1.39G
            }
1080
1081
1.39G
            if (error & VP_START)
1082
1.27G
                distance = 9999999;
1083
1.39G
        }
1084
1.35M
    }
1085
450k
#endif
1086
1087
    /* forward mark errors */
1088
450k
    error = 0;
1089
466M
    for (i = 0; i < s->mb_num; i++) {
1090
466M
        const int mb_xy = s->mb_index2xy[i];
1091
466M
        int old_error   = s->error_status_table[mb_xy];
1092
1093
466M
        if (old_error & VP_START) {
1094
424M
            error = old_error & ER_MB_ERROR;
1095
424M
        } else {
1096
41.3M
            error |= old_error & ER_MB_ERROR;
1097
41.3M
            s->error_status_table[mb_xy] |= error;
1098
41.3M
        }
1099
466M
    }
1100
450k
#if 1
1101
    /* handle not partitioned case */
1102
450k
    if (!s->partitioned_frame) {
1103
464M
        for (i = 0; i < s->mb_num; i++) {
1104
464M
            const int mb_xy = s->mb_index2xy[i];
1105
464M
            int error = s->error_status_table[mb_xy];
1106
464M
            if (error & ER_MB_ERROR)
1107
428M
                error |= ER_MB_ERROR;
1108
464M
            s->error_status_table[mb_xy] = error;
1109
464M
        }
1110
445k
    }
1111
450k
#endif
1112
1113
450k
    dc_error = ac_error = mv_error = 0;
1114
466M
    for (i = 0; i < s->mb_num; i++) {
1115
466M
        const int mb_xy = s->mb_index2xy[i];
1116
466M
        int error = s->error_status_table[mb_xy];
1117
466M
        if (error & ER_DC_ERROR)
1118
430M
            dc_error++;
1119
466M
        if (error & ER_AC_ERROR)
1120
430M
            ac_error++;
1121
466M
        if (error & ER_MV_ERROR)
1122
430M
            mv_error++;
1123
466M
    }
1124
450k
    av_log(s->avctx, AV_LOG_INFO, "concealing %d DC, %d AC, %d MV errors in %c frame\n",
1125
450k
           dc_error, ac_error, mv_error, av_get_picture_type_char(s->cur_pic.f->pict_type));
1126
1127
450k
    if (decode_error_flags)
1128
209k
        *decode_error_flags |= FF_DECODE_ERROR_CONCEALMENT_ACTIVE;
1129
240k
    else
1130
240k
        s->cur_pic.f->decode_error_flags |= FF_DECODE_ERROR_CONCEALMENT_ACTIVE;
1131
1132
450k
    is_intra_likely = is_intra_more_likely(s);
1133
1134
    /* set unknown mb-type to most likely */
1135
450k
    guessed_mb_type = is_intra_likely ? MB_TYPE_INTRA4x4 :
1136
450k
                         (MB_TYPE_16x16 | (s->avctx->codec_id == AV_CODEC_ID_H264 ? MB_TYPE_L0 : MB_TYPE_FORWARD_MV));
1137
466M
    for (i = 0; i < s->mb_num; i++) {
1138
466M
        const int mb_xy = s->mb_index2xy[i];
1139
466M
        int error = s->error_status_table[mb_xy];
1140
466M
        if (!((error & ER_DC_ERROR) && (error & ER_MV_ERROR)))
1141
35.7M
            continue;
1142
1143
430M
        s->cur_pic.mb_type[mb_xy] = guessed_mb_type;
1144
430M
    }
1145
1146
    // change inter to intra blocks if no reference frames are available
1147
450k
    if (!(s->last_pic.f && s->last_pic.f->data[0]) &&
1148
115k
        !(s->next_pic.f && s->next_pic.f->data[0]))
1149
22.9M
        for (i = 0; i < s->mb_num; i++) {
1150
22.8M
            const int mb_xy = s->mb_index2xy[i];
1151
22.8M
            if (!IS_INTRA(s->cur_pic.mb_type[mb_xy]))
1152
771k
                s->cur_pic.mb_type[mb_xy] = MB_TYPE_INTRA4x4;
1153
22.8M
        }
1154
1155
    /* handle inter blocks with damaged AC */
1156
38.3M
    for (mb_y = 0; mb_y < s->mb_height; mb_y++) {
1157
504M
        for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
1158
466M
            const int mb_xy   = mb_x + mb_y * s->mb_stride;
1159
466M
            const int mb_type = s->cur_pic.mb_type[mb_xy];
1160
466M
            const int dir     = !(s->last_pic.f && s->last_pic.f->data[0]);
1161
466M
            const int mv_dir  = dir ? MV_DIR_BACKWARD : MV_DIR_FORWARD;
1162
466M
            int mv_type;
1163
1164
466M
            int error = s->error_status_table[mb_xy];
1165
1166
466M
            if (IS_INTRA(mb_type))
1167
143M
                continue; // intra
1168
322M
            if (error & ER_MV_ERROR)
1169
294M
                continue; // inter with damaged MV
1170
27.5M
            if (!(error & ER_AC_ERROR))
1171
27.4M
                continue; // undamaged inter
1172
1173
145k
            if (IS_8X8(mb_type)) {
1174
8.87k
                int mb_index = mb_x * 2 + mb_y * 2 * s->b8_stride;
1175
8.87k
                int j;
1176
8.87k
                mv_type = MV_TYPE_8X8;
1177
44.3k
                for (j = 0; j < 4; j++) {
1178
35.5k
                    s->mv[0][j][0] = s->cur_pic.motion_val[dir][mb_index + (j & 1) + (j >> 1) * s->b8_stride][0];
1179
35.5k
                    s->mv[0][j][1] = s->cur_pic.motion_val[dir][mb_index + (j & 1) + (j >> 1) * s->b8_stride][1];
1180
35.5k
                }
1181
136k
            } else {
1182
136k
                mv_type     = MV_TYPE_16X16;
1183
136k
                s->mv[0][0][0] = s->cur_pic.motion_val[dir][mb_x * 2 + mb_y * 2 * s->b8_stride][0];
1184
136k
                s->mv[0][0][1] = s->cur_pic.motion_val[dir][mb_x * 2 + mb_y * 2 * s->b8_stride][1];
1185
136k
            }
1186
1187
145k
            s->decode_mb(s->opaque, 0 /* FIXME H.264 partitioned slices need this set */,
1188
145k
                         mv_dir, mv_type, &s->mv, mb_x, mb_y, 0, 0);
1189
145k
        }
1190
37.9M
    }
1191
1192
    /* guess MVs */
1193
450k
    if (s->cur_pic.f->pict_type == AV_PICTURE_TYPE_B) {
1194
3.81M
        for (mb_y = 0; mb_y < s->mb_height; mb_y++) {
1195
42.7M
            for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
1196
39.0M
                int       xy      = mb_x * 2 + mb_y * 2 * s->b8_stride;
1197
39.0M
                const int mb_xy   = mb_x + mb_y * s->mb_stride;
1198
39.0M
                const int mb_type = s->cur_pic.mb_type[mb_xy];
1199
39.0M
                int mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD;
1200
1201
39.0M
                int error = s->error_status_table[mb_xy];
1202
1203
39.0M
                if (IS_INTRA(mb_type))
1204
4.13M
                    continue;
1205
34.8M
                if (!(error & ER_MV_ERROR))
1206
2.90M
                    continue; // inter with undamaged MV
1207
31.9M
                if (!(error & ER_AC_ERROR))
1208
0
                    continue; // undamaged inter
1209
1210
31.9M
                if (!(s->last_pic.f && s->last_pic.f->data[0]))
1211
0
                    mv_dir &= ~MV_DIR_FORWARD;
1212
31.9M
                if (!(s->next_pic.f && s->next_pic.f->data[0]))
1213
2.31M
                    mv_dir &= ~MV_DIR_BACKWARD;
1214
1215
31.9M
                if (s->pp_time) {
1216
1.33M
                    int time_pp = s->pp_time;
1217
1.33M
                    int time_pb = s->pb_time;
1218
1219
1.33M
                    av_assert0(s->avctx->codec_id != AV_CODEC_ID_H264);
1220
1.33M
                    ff_thread_progress_await(s->next_pic.progress, mb_y);
1221
1222
1.33M
                    s->mv[0][0][0] = s->next_pic.motion_val[0][xy][0] *  time_pb            / time_pp;
1223
1.33M
                    s->mv[0][0][1] = s->next_pic.motion_val[0][xy][1] *  time_pb            / time_pp;
1224
1.33M
                    s->mv[1][0][0] = s->next_pic.motion_val[0][xy][0] * (time_pb - time_pp) / time_pp;
1225
1.33M
                    s->mv[1][0][1] = s->next_pic.motion_val[0][xy][1] * (time_pb - time_pp) / time_pp;
1226
30.6M
                } else {
1227
30.6M
                    s->mv[0][0][0] = 0;
1228
30.6M
                    s->mv[0][0][1] = 0;
1229
30.6M
                    s->mv[1][0][0] = 0;
1230
30.6M
                    s->mv[1][0][1] = 0;
1231
30.6M
                }
1232
1233
31.9M
                s->decode_mb(s->opaque, 0, mv_dir, MV_TYPE_16X16, &s->mv,
1234
31.9M
                             mb_x, mb_y, 0, 0);
1235
31.9M
            }
1236
3.74M
        }
1237
68.7k
    } else
1238
381k
        guess_mv(s);
1239
1240
    /* fill DC for inter blocks */
1241
38.3M
    for (mb_y = 0; mb_y < s->mb_height; mb_y++) {
1242
504M
        for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
1243
466M
            int dc, dcu, dcv, y, n;
1244
466M
            int16_t *dc_ptr;
1245
466M
            uint8_t *dest_y, *dest_cb, *dest_cr;
1246
466M
            const int mb_xy   = mb_x + mb_y * s->mb_stride;
1247
466M
            const int mb_type = s->cur_pic.mb_type[mb_xy];
1248
1249
            // error = s->error_status_table[mb_xy];
1250
1251
466M
            if (IS_INTRA(mb_type) && s->partitioned_frame)
1252
171k
                continue;
1253
            // if (error & ER_MV_ERROR)
1254
            //     continue; // inter data damaged FIXME is this good?
1255
1256
465M
            dest_y  = s->cur_pic.f->data[0] + mb_x * 16 + mb_y * 16 * linesize[0];
1257
465M
            dest_cb = s->cur_pic.f->data[1] + mb_x *  8 + mb_y *  8 * linesize[1];
1258
465M
            dest_cr = s->cur_pic.f->data[2] + mb_x *  8 + mb_y *  8 * linesize[2];
1259
1260
465M
            dc_ptr = &s->dc_val[0][mb_x * 2 + mb_y * 2 * s->b8_stride];
1261
2.32G
            for (n = 0; n < 4; n++) {
1262
1.86G
                dc = 0;
1263
16.7G
                for (y = 0; y < 8; y++) {
1264
14.9G
                    int x;
1265
134G
                    for (x = 0; x < 8; x++)
1266
119G
                       dc += dest_y[x + (n & 1) * 8 +
1267
119G
                             (y + (n >> 1) * 8) * linesize[0]];
1268
14.9G
                }
1269
1.86G
                dc_ptr[(n & 1) + (n >> 1) * s->b8_stride] = (dc + 4) >> 3;
1270
1.86G
            }
1271
1272
465M
            if (!s->cur_pic.f->data[2])
1273
0
                continue;
1274
1275
465M
            dcu = dcv = 0;
1276
4.19G
            for (y = 0; y < 8; y++) {
1277
3.72G
                int x;
1278
33.5G
                for (x = 0; x < 8; x++) {
1279
29.8G
                    dcu += dest_cb[x + y * linesize[1]];
1280
29.8G
                    dcv += dest_cr[x + y * linesize[2]];
1281
29.8G
                }
1282
3.72G
            }
1283
465M
            s->dc_val[1][mb_x + mb_y * s->mb_stride] = (dcu + 4) >> 3;
1284
465M
            s->dc_val[2][mb_x + mb_y * s->mb_stride] = (dcv + 4) >> 3;
1285
465M
        }
1286
37.9M
    }
1287
450k
#if 1
1288
    /* guess DC for damaged blocks */
1289
450k
    guess_dc(s, s->dc_val[0], s->mb_width*2, s->mb_height*2, s->b8_stride, 1);
1290
450k
    guess_dc(s, s->dc_val[1], s->mb_width  , s->mb_height  , s->mb_stride, 0);
1291
450k
    guess_dc(s, s->dc_val[2], s->mb_width  , s->mb_height  , s->mb_stride, 0);
1292
450k
#endif
1293
1294
    /* filter luma DC */
1295
450k
    filter181(s->dc_val[0], s->mb_width * 2, s->mb_height * 2, s->b8_stride);
1296
1297
450k
#if 1
1298
    /* render DC only intra */
1299
38.3M
    for (mb_y = 0; mb_y < s->mb_height; mb_y++) {
1300
504M
        for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
1301
466M
            uint8_t *dest_y, *dest_cb, *dest_cr;
1302
466M
            const int mb_xy   = mb_x + mb_y * s->mb_stride;
1303
466M
            const int mb_type = s->cur_pic.mb_type[mb_xy];
1304
1305
466M
            int error = s->error_status_table[mb_xy];
1306
1307
466M
            if (IS_INTER(mb_type))
1308
311M
                continue;
1309
154M
            if (!(error & ER_AC_ERROR))
1310
18.8M
                continue; // undamaged
1311
1312
135M
            dest_y  = s->cur_pic.f->data[0] + mb_x * 16 + mb_y * 16 * linesize[0];
1313
135M
            dest_cb = s->cur_pic.f->data[1] + mb_x *  8 + mb_y *  8 * linesize[1];
1314
135M
            dest_cr = s->cur_pic.f->data[2] + mb_x *  8 + mb_y *  8 * linesize[2];
1315
135M
            if (!s->cur_pic.f->data[2])
1316
0
                dest_cb = dest_cr = NULL;
1317
1318
135M
            put_dc(s, dest_y, dest_cb, dest_cr, mb_x, mb_y);
1319
135M
        }
1320
37.9M
    }
1321
450k
#endif
1322
1323
450k
    if (s->avctx->error_concealment & FF_EC_DEBLOCK) {
1324
        /* filter horizontal block boundaries */
1325
450k
        h_block_filter(s, s->cur_pic.f->data[0], s->mb_width * 2,
1326
450k
                       s->mb_height * 2, linesize[0], 1);
1327
1328
        /* filter vertical block boundaries */
1329
450k
        v_block_filter(s, s->cur_pic.f->data[0], s->mb_width * 2,
1330
450k
                       s->mb_height * 2, linesize[0], 1);
1331
1332
450k
        if (s->cur_pic.f->data[2]) {
1333
450k
            h_block_filter(s, s->cur_pic.f->data[1], s->mb_width,
1334
450k
                        s->mb_height, linesize[1], 0);
1335
450k
            h_block_filter(s, s->cur_pic.f->data[2], s->mb_width,
1336
450k
                        s->mb_height, linesize[2], 0);
1337
450k
            v_block_filter(s, s->cur_pic.f->data[1], s->mb_width,
1338
450k
                        s->mb_height, linesize[1], 0);
1339
450k
            v_block_filter(s, s->cur_pic.f->data[2], s->mb_width,
1340
450k
                        s->mb_height, linesize[2], 0);
1341
450k
        }
1342
450k
    }
1343
1344
    /* clean a few tables */
1345
466M
    for (i = 0; i < s->mb_num; i++) {
1346
466M
        const int mb_xy = s->mb_index2xy[i];
1347
466M
        int       error = s->error_status_table[mb_xy];
1348
1349
466M
        if (s->mbskip_table && s->cur_pic.f->pict_type != AV_PICTURE_TYPE_B &&
1350
379M
            (error & (ER_DC_ERROR | ER_MV_ERROR | ER_AC_ERROR))) {
1351
350M
            s->mbskip_table[mb_xy] = 0;
1352
350M
        }
1353
466M
        if (s->mbintra_table)
1354
398M
            s->mbintra_table[mb_xy] = 1;
1355
466M
    }
1356
1357
450k
    memset(&s->cur_pic, 0, sizeof(ERPicture));
1358
450k
    memset(&s->last_pic, 0, sizeof(ERPicture));
1359
450k
    memset(&s->next_pic, 0, sizeof(ERPicture));
1360
1361
450k
cleanup:
1362
1.35M
    for (i = 0; i < 2; i++) {
1363
900k
        av_freep(&s->ref_index[i]);
1364
900k
        av_freep(&s->motion_val_base[i]);
1365
900k
        s->cur_pic.ref_index[i]  = NULL;
1366
        s->cur_pic.motion_val[i] = NULL;
1367
900k
    }
1368
450k
}