X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fvp8.c;h=b964d2fd2df0cb98bba590fd7b4f706ab44b8801;hb=1ab74bc19354aedfb9afe71515952254753a75cc;hp=3adfeac3d94493b54ce84c92bef499a46cb4178e;hpb=ef71ef5f30ddf1cd61e46628a04608892caf76d2;p=ffmpeg diff --git a/libavcodec/vp8.c b/libavcodec/vp8.c index 3adfeac3d94..b964d2fd2df 100644 --- a/libavcodec/vp8.c +++ b/libavcodec/vp8.c @@ -25,9 +25,10 @@ */ #include "libavutil/imgutils.h" +#include "libavutil/mem_internal.h" #include "avcodec.h" -#include "hwaccel.h" +#include "hwconfig.h" #include "internal.h" #include "mathops.h" #include "rectangle.h" @@ -187,7 +188,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 +197,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 +505,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 +548,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 +662,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 +697,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 +2275,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,7 +2292,11 @@ 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; + for (mb_x = 0; mb_x < s->mb_width; mb_x++, mb_xy++, mb++) { + if (vpX_rac_is_end(&s->c)) { + return AVERROR_INVALIDDATA; + } if (mb_y == 0) AV_WN32A((mb - s->mb_width - 1)->intra4x4_pred_mode_top, DC_PRED * 0x01010101); @@ -2295,18 +2309,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 +2379,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 +2410,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) { @@ -2607,7 +2622,7 @@ static int vp8_decode_mb_row_sliced(AVCodecContext *avctx, void *tdata, static av_always_inline int vp78_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, - AVPacket *avpkt, int is_vp7) + const AVPacket *avpkt, int is_vp7) { VP8Context *s = avctx->priv_data; int ret, i, referenced, num_jobs; @@ -2704,7 +2719,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 +2757,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 +2857,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 +2898,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, @@ -2936,7 +2938,7 @@ static int vp8_decode_update_thread_context(AVCodecContext *dst, #endif /* CONFIG_VP8_DECODER */ #if CONFIG_VP7_DECODER -AVCodec ff_vp7_decoder = { +const AVCodec ff_vp7_decoder = { .name = "vp7", .long_name = NULL_IF_CONFIG_SMALL("On2 VP7"), .type = AVMEDIA_TYPE_VIDEO, @@ -2951,7 +2953,7 @@ AVCodec ff_vp7_decoder = { #endif /* CONFIG_VP7_DECODER */ #if CONFIG_VP8_DECODER -AVCodec ff_vp8_decoder = { +const AVCodec ff_vp8_decoder = { .name = "vp8", .long_name = NULL_IF_CONFIG_SMALL("On2 VP8"), .type = AVMEDIA_TYPE_VIDEO, @@ -2963,9 +2965,8 @@ 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*[]) { + .hw_configs = (const AVCodecHWConfigInternal *const []) { #if CONFIG_VP8_VAAPI_HWACCEL HWACCEL_VAAPI(vp8), #endif @@ -2974,5 +2975,6 @@ AVCodec ff_vp8_decoder = { #endif NULL }, + .caps_internal = FF_CODEC_CAP_ALLOCATE_PROGRESS, }; #endif /* CONFIG_VP7_DECODER */