diff options
Diffstat (limited to 'ffmpeg/libavcodec/error_resilience.c')
| -rw-r--r-- | ffmpeg/libavcodec/error_resilience.c | 56 |
1 files changed, 41 insertions, 15 deletions
diff --git a/ffmpeg/libavcodec/error_resilience.c b/ffmpeg/libavcodec/error_resilience.c index cdd28ab..ebd671a 100644 --- a/ffmpeg/libavcodec/error_resilience.c +++ b/ffmpeg/libavcodec/error_resilience.c @@ -27,11 +27,13 @@ #include <limits.h> +#include "libavutil/internal.h" #include "avcodec.h" #include "error_resilience.h" #include "mpegvideo.h" #include "rectangle.h" #include "thread.h" +#include "version.h" /** * @param stride the number of MVs to get to the next row @@ -236,7 +238,7 @@ static void h_block_filter(ERContext *s, uint8_t *dst, int w, int h, int stride, int is_luma) { int b_x, b_y, mvx_stride, mvy_stride; - uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; + const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; set_mv_strides(s, &mvx_stride, &mvy_stride); mvx_stride >>= is_luma; mvy_stride *= mvx_stride; @@ -304,7 +306,7 @@ static void v_block_filter(ERContext *s, uint8_t *dst, int w, int h, int stride, int is_luma) { int b_x, b_y, mvx_stride, mvy_stride; - uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; + const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; set_mv_strides(s, &mvx_stride, &mvy_stride); mvx_stride >>= is_luma; mvy_stride *= mvx_stride; @@ -698,8 +700,8 @@ static int is_intra_more_likely(ERContext *s) return 0; // almost all MBs damaged -> use temporal prediction // prevent dsp.sad() check, that requires access to the image - if (CONFIG_MPEG_XVMC_DECODER && - s->avctx->xvmc_acceleration && + if (CONFIG_XVMC && + s->avctx->hwaccel && s->avctx->hwaccel->decode_mb && s->cur_pic->f.pict_type == AV_PICTURE_TYPE_I) return 1; @@ -747,13 +749,13 @@ static int is_intra_more_likely(ERContext *s) } } } - // printf("is_intra_likely: %d type:%d\n", is_intra_likely, s->pict_type); +// av_log(NULL, AV_LOG_ERROR, "is_intra_likely: %d type:%d\n", is_intra_likely, s->pict_type); return is_intra_likely > 0; } void ff_er_frame_start(ERContext *s) { - if (!s->avctx->err_recognition) + if (!s->avctx->error_concealment) return; memset(s->error_status_table, ER_MB_ERROR | VP_START | ER_MB_END, @@ -762,6 +764,17 @@ void ff_er_frame_start(ERContext *s) s->error_occurred = 0; } +static int er_supported(ERContext *s) +{ + if(s->avctx->hwaccel && s->avctx->hwaccel->decode_slice || + s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU || + !s->cur_pic || + s->cur_pic->field_picture + ) + return 0; + return 1; +} + /** * Add a slice. * @param endx x component of the last macroblock, can be -1 @@ -778,7 +791,7 @@ void ff_er_add_slice(ERContext *s, int startx, int starty, const int end_xy = s->mb_index2xy[end_i]; int mask = -1; - if (s->avctx->hwaccel) + if (s->avctx->hwaccel && s->avctx->hwaccel->decode_slice) return; if (start_i > end_i || start_xy > end_xy) { @@ -787,7 +800,7 @@ void ff_er_add_slice(ERContext *s, int startx, int starty, return; } - if (!s->avctx->err_recognition) + if (!s->avctx->error_concealment) return; mask &= ~VP_START; @@ -828,7 +841,7 @@ void ff_er_add_slice(ERContext *s, int startx, int starty, s->error_status_table[start_xy] |= VP_START; if (start_xy > 0 && !(s->avctx->active_thread_type & FF_THREAD_SLICE) && - s->avctx->skip_top * s->mb_width < start_i) { + er_supported(s) && s->avctx->skip_top * s->mb_width < start_i) { int prev_status = s->error_status_table[s->mb_index2xy[start_i - 1]]; prev_status &= ~ VP_START; @@ -851,15 +864,28 @@ void ff_er_frame_end(ERContext *s) /* We do not support ER of field pictures yet, * though it should not crash if enabled. */ - if (!s->avctx->err_recognition || s->error_count == 0 || + if (!s->avctx->error_concealment || s->error_count == 0 || s->avctx->lowres || - s->avctx->hwaccel || - s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU || - !s->cur_pic || s->cur_pic->field_picture || + !er_supported(s) || s->error_count == 3 * s->mb_width * (s->avctx->skip_top + s->avctx->skip_bottom)) { return; } + for (mb_x = 0; mb_x < s->mb_width; mb_x++) { + int status = s->error_status_table[mb_x + (s->mb_height - 1) * s->mb_stride]; + if (status != 0x7F) + break; + } + + if ( mb_x == s->mb_width + && s->avctx->codec_id == AV_CODEC_ID_MPEG2VIDEO + && (s->avctx->height&16) + && s->error_count == 3 * s->mb_width * (s->avctx->skip_top + s->avctx->skip_bottom + 1) + ) { + av_log(s->avctx, AV_LOG_DEBUG, "ignoring last missing slice\n"); + return; + } + if (s->last_pic) { if (s->last_pic->f.width != s->cur_pic->f.width || s->last_pic->f.height != s->cur_pic->f.height || @@ -1158,8 +1184,8 @@ void ff_er_frame_end(ERContext *s) } else guess_mv(s); - /* the filters below are not XvMC compatible, skip them */ - if (CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration) + /* the filters below manipulate raw image, skip them */ + if (CONFIG_XVMC && s->avctx->hwaccel && s->avctx->hwaccel->decode_mb) goto ec_clean; /* fill DC for inter blocks */ for (mb_y = 0; mb_y < s->mb_height; mb_y++) { |
