*/
#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"
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) {
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);
}
}
-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)) {
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;
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 */
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;
}
#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;
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);
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
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)
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) {
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;
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);
!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)
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);
#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,
#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,
#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,
.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
#endif
NULL
},
+ .caps_internal = FF_CODEC_CAP_ALLOCATE_PROGRESS,
};
#endif /* CONFIG_VP7_DECODER */