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