annotate ffmpeg/libavcodec/error_resilience.c @ 13:844d341cf643 tip

Back up before ISMIR
author Yading Song <yading.song@eecs.qmul.ac.uk>
date Thu, 31 Oct 2013 13:17:06 +0000
parents 6840f77b83aa
children
rev   line source
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 }