X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fvp8.c;h=d5d133540a660a288cf476ca8d9117551fe6d712;hb=f1700bd8bb983bb3b56c3a1f8b9078cb62a44f65;hp=3adfeac3d94493b54ce84c92bef499a46cb4178e;hpb=fb4a12cda4033f2f3d3d1039739f6e0e6f9afb82;p=ffmpeg diff --git a/libavcodec/vp8.c b/libavcodec/vp8.c index 3adfeac3d94..d5d133540a6 100644 --- a/libavcodec/vp8.c +++ b/libavcodec/vp8.c @@ -27,7 +27,7 @@ #include "libavutil/imgutils.h" #include "avcodec.h" -#include "hwaccel.h" +#include "hwconfig.h" #include "internal.h" #include "mathops.h" #include "rectangle.h" @@ -187,7 +187,7 @@ static av_always_inline int update_dimensions(VP8Context *s, int width, int height, int is_vp7) { AVCodecContext *avctx = s->avctx; - int i, ret; + int i, ret, dim_reset = 0; if (width != s->avctx->width || ((width+15)/16 != s->mb_width || (height+15)/16 != s->mb_height) && s->macroblocks_base || height != s->avctx->height) { @@ -196,9 +196,12 @@ int update_dimensions(VP8Context *s, int width, int height, int is_vp7) ret = ff_set_dimensions(s->avctx, width, height); if (ret < 0) return ret; + + dim_reset = (s->macroblocks_base != NULL); } - if (!s->actually_webp && !is_vp7) { + if ((s->pix_fmt == AV_PIX_FMT_NONE || dim_reset) && + !s->actually_webp && !is_vp7) { s->pix_fmt = get_pixel_format(s); if (s->pix_fmt < 0) return AVERROR(EINVAL); @@ -501,10 +504,8 @@ static void fade(uint8_t *dst, ptrdiff_t dst_linesize, } } -static int vp7_fade_frame(VP8Context *s, VP56RangeCoder *c) +static int vp7_fade_frame(VP8Context *s, int alpha, int beta) { - int alpha = (int8_t) vp8_rac_get_uint(c, 8); - int beta = (int8_t) vp8_rac_get_uint(c, 8); int ret; if (!s->keyframe && (alpha || beta)) { @@ -546,6 +547,8 @@ static int vp7_decode_frame_header(VP8Context *s, const uint8_t *buf, int buf_si int part1_size, hscale, vscale, i, j, ret; int width = s->avctx->width; int height = s->avctx->height; + int alpha = 0; + int beta = 0; if (buf_size < 4) { return AVERROR_INVALIDDATA; @@ -658,12 +661,12 @@ static int vp7_decode_frame_header(VP8Context *s, const uint8_t *buf, int buf_si s->fade_present = vp8_rac_get(c); } - if (c->end <= c->buffer && c->bits >= 0) + if (vpX_rac_is_end(c)) return AVERROR_INVALIDDATA; /* E. Fading information for previous frame */ if (s->fade_present && vp8_rac_get(c)) { - if ((ret = vp7_fade_frame(s ,c)) < 0) - return ret; + alpha = (int8_t) vp8_rac_get_uint(c, 8); + beta = (int8_t) vp8_rac_get_uint(c, 8); } /* F. Loop filter type */ @@ -693,6 +696,12 @@ static int vp7_decode_frame_header(VP8Context *s, const uint8_t *buf, int buf_si vp78_update_pred16x16_pred8x8_mvc_probabilities(s, VP7_MVC_SIZE); } + if (vpX_rac_is_end(c)) + return AVERROR_INVALIDDATA; + + if ((ret = vp7_fade_frame(s, alpha, beta)) < 0) + return ret; + return 0; } @@ -2265,7 +2274,7 @@ void filter_mb_simple(VP8Context *s, uint8_t *dst, VP8FilterStrength *f, #define MARGIN (16 << 2) static av_always_inline -void vp78_decode_mv_mb_modes(AVCodecContext *avctx, VP8Frame *curframe, +int vp78_decode_mv_mb_modes(AVCodecContext *avctx, VP8Frame *curframe, VP8Frame *prev_frame, int is_vp7) { VP8Context *s = avctx->priv_data; @@ -2282,6 +2291,10 @@ void vp78_decode_mv_mb_modes(AVCodecContext *avctx, VP8Frame *curframe, s->mv_bounds.mv_min.x = -MARGIN; s->mv_bounds.mv_max.x = ((s->mb_width - 1) << 6) + MARGIN; + + if (vpX_rac_is_end(&s->c)) { + return AVERROR_INVALIDDATA; + } for (mb_x = 0; mb_x < s->mb_width; mb_x++, mb_xy++, mb++) { if (mb_y == 0) AV_WN32A((mb - s->mb_width - 1)->intra4x4_pred_mode_top, @@ -2295,18 +2308,19 @@ void vp78_decode_mv_mb_modes(AVCodecContext *avctx, VP8Frame *curframe, s->mv_bounds.mv_min.y -= 64; s->mv_bounds.mv_max.y -= 64; } + return 0; } -static void vp7_decode_mv_mb_modes(AVCodecContext *avctx, VP8Frame *cur_frame, +static int vp7_decode_mv_mb_modes(AVCodecContext *avctx, VP8Frame *cur_frame, VP8Frame *prev_frame) { - vp78_decode_mv_mb_modes(avctx, cur_frame, prev_frame, IS_VP7); + return vp78_decode_mv_mb_modes(avctx, cur_frame, prev_frame, IS_VP7); } -static void vp8_decode_mv_mb_modes(AVCodecContext *avctx, VP8Frame *cur_frame, +static int vp8_decode_mv_mb_modes(AVCodecContext *avctx, VP8Frame *cur_frame, VP8Frame *prev_frame) { - vp78_decode_mv_mb_modes(avctx, cur_frame, prev_frame, IS_VP8); + return vp78_decode_mv_mb_modes(avctx, cur_frame, prev_frame, IS_VP8); } #if HAVE_THREADS @@ -2364,7 +2378,7 @@ static av_always_inline int decode_mb_row_no_filter(AVCodecContext *avctx, void curframe->tf.f->data[2] + 8 * mb_y * s->uvlinesize }; - if (c->end <= c->buffer && c->bits >= 0) + if (vpX_rac_is_end(c)) return AVERROR_INVALIDDATA; if (mb_y == 0) @@ -2395,7 +2409,7 @@ static av_always_inline int decode_mb_row_no_filter(AVCodecContext *avctx, void td->mv_bounds.mv_max.x = ((s->mb_width - 1) << 6) + MARGIN; for (mb_x = 0; mb_x < s->mb_width; mb_x++, mb_xy++, mb++) { - if (c->end <= c->buffer && c->bits >= 0) + if (vpX_rac_is_end(c)) return AVERROR_INVALIDDATA; // Wait for previous thread to read mb_x+2, and reach mb_y-1. if (prev_td != td) { @@ -2704,7 +2718,8 @@ int vp78_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, s->next_framep[VP56_FRAME_CURRENT] = curframe; - ff_thread_finish_setup(avctx); + if (avctx->codec->update_thread_context) + ff_thread_finish_setup(avctx); if (avctx->hwaccel) { ret = avctx->hwaccel->start_frame(avctx, avpkt->data, avpkt->size); @@ -2741,9 +2756,11 @@ int vp78_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, !s->segmentation.update_map) ff_thread_await_progress(&prev_frame->tf, 1, 0); if (is_vp7) - vp7_decode_mv_mb_modes(avctx, curframe, prev_frame); + ret = vp7_decode_mv_mb_modes(avctx, curframe, prev_frame); else - vp8_decode_mv_mb_modes(avctx, curframe, prev_frame); + ret = vp8_decode_mv_mb_modes(avctx, curframe, prev_frame); + if (ret < 0) + goto err; } if (avctx->active_thread_type == FF_THREAD_FRAME) @@ -2839,7 +2856,6 @@ int vp78_decode_init(AVCodecContext *avctx, int is_vp7) s->vp7 = avctx->codec->id == AV_CODEC_ID_VP7; s->pix_fmt = AV_PIX_FMT_NONE; avctx->pix_fmt = AV_PIX_FMT_YUV420P; - avctx->internal->allocate_progress = 1; ff_videodsp_init(&s->vdsp, 8); @@ -2881,21 +2897,6 @@ av_cold int ff_vp8_decode_init(AVCodecContext *avctx) #if CONFIG_VP8_DECODER #if HAVE_THREADS -static av_cold int vp8_decode_init_thread_copy(AVCodecContext *avctx) -{ - VP8Context *s = avctx->priv_data; - int ret; - - s->avctx = avctx; - - if ((ret = vp8_init_frames(s)) < 0) { - ff_vp8_decode_free(avctx); - return ret; - } - - return 0; -} - #define REBASE(pic) ((pic) ? (pic) - &s_src->frames[0] + &s->frames[0] : NULL) static int vp8_decode_update_thread_context(AVCodecContext *dst, @@ -2963,7 +2964,6 @@ AVCodec ff_vp8_decoder = { .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS | AV_CODEC_CAP_SLICE_THREADS, .flush = vp8_decode_flush, - .init_thread_copy = ONLY_IF_THREADS_ENABLED(vp8_decode_init_thread_copy), .update_thread_context = ONLY_IF_THREADS_ENABLED(vp8_decode_update_thread_context), .hw_configs = (const AVCodecHWConfigInternal*[]) { #if CONFIG_VP8_VAAPI_HWACCEL @@ -2974,5 +2974,6 @@ AVCodec ff_vp8_decoder = { #endif NULL }, + .caps_internal = FF_CODEC_CAP_ALLOCATE_PROGRESS, }; #endif /* CONFIG_VP7_DECODER */