On Fri, Dec 12, 2014 at 9:27 PM, Vittorio Giovara <[email protected]> wrote: > Signed-off-by: Vittorio Giovara <[email protected]> > --- > Added checks and used the right type for the offsets. > Vittorio > libavcodec/vp3.c | 62 > +++++++++++++++++++++++++++++++++++++++++--------------- > 1 file changed, 46 insertions(+), 16 deletions(-) > > diff --git a/libavcodec/vp3.c b/libavcodec/vp3.c > index fec8766..8475950 100644 > --- a/libavcodec/vp3.c > +++ b/libavcodec/vp3.c > @@ -171,6 +171,8 @@ typedef struct Vp3DecodeContext { > Vp3Fragment *all_fragments; > int fragment_start[3]; > int data_offset[3]; > + uint8_t offset_x; > + uint8_t offset_y; > > int8_t (*motion_val[2])[2]; > > @@ -1405,14 +1407,14 @@ static void vp3_draw_horiz_band(Vp3DecodeContext *s, > int y) > int offset[AV_NUM_DATA_POINTERS]; > > if (HAVE_THREADS && s->avctx->active_thread_type & FF_THREAD_FRAME) { > - int y_flipped = s->flipped_image ? s->avctx->height - y : y; > + int y_flipped = s->flipped_image ? s->height - y : y; > > /* At the end of the frame, report INT_MAX instead of the height of > * the frame. This makes the other threads' > ff_thread_await_progress() > * calls cheaper, because they don't have to clip their values. */ > ff_thread_report_progress(&s->current_frame, > - y_flipped == s->avctx->height ? INT_MAX > - : y_flipped > - 1, > + y_flipped == s->height ? INT_MAX > + : y_flipped - 1, > 0); > } > > @@ -1424,7 +1426,7 @@ static void vp3_draw_horiz_band(Vp3DecodeContext *s, > int y) > y -= h; > > if (!s->flipped_image) > - y = s->avctx->height - y - h; > + y = s->height - y - h; > > cy = y >> s->chroma_y_shift; > offset[0] = s->current_frame.f->linesize[0] * y; > @@ -1721,8 +1723,8 @@ static av_cold int vp3_decode_init(AVCodecContext > *avctx) > s->version = 1; > > s->avctx = avctx; > - s->width = FFALIGN(avctx->width, 16); > - s->height = FFALIGN(avctx->height, 16); > + s->width = FFALIGN(avctx->coded_width, 16); > + s->height = FFALIGN(avctx->coded_height, 16); > if (avctx->pix_fmt == AV_PIX_FMT_NONE) > avctx->pix_fmt = AV_PIX_FMT_YUV420P; > avctx->chroma_sample_location = AVCHROMA_LOC_CENTER; > @@ -2115,10 +2117,17 @@ static int vp3_decode_frame(AVCodecContext *avctx, > int row = (s->height >> (3 + (i && s->chroma_y_shift))) - 1; > apply_loop_filter(s, i, row, row + 1); > } > - vp3_draw_horiz_band(s, s->avctx->height); > + vp3_draw_horiz_band(s, s->height); > > + /* output frame, offset as needed */ > if ((ret = av_frame_ref(data, s->current_frame.f)) < 0) > return ret; > + for (i = 0; i < 3; i++) { > + AVFrame *dst = data; > + int off = (s->offset_x >> (i && s->chroma_y_shift)) + > + (s->offset_y >> (i && s->chroma_y_shift)) * > dst->linesize[i]; > + dst->data[i] += off; > + } > *got_frame = 1; > > if (!HAVE_THREADS || !(s->avctx->active_thread_type & FF_THREAD_FRAME)) { > @@ -2198,7 +2207,7 @@ static int theora_decode_header(AVCodecContext *avctx, > GetBitContext *gb) > { > Vp3DecodeContext *s = avctx->priv_data; > int visible_width, visible_height, colorspace; > - int offset_x = 0, offset_y = 0; > + uint8_t offset_x = 0, offset_y = 0; > int ret; > AVRational fps, aspect; > > @@ -2226,6 +2235,14 @@ static int theora_decode_header(AVCodecContext *avctx, > GetBitContext *gb) > offset_y = get_bits(gb, 8); /* offset y, from bottom */ > } > > + /* sanity check */ > + if (av_image_check_size(visible_width, visible_height, 0, avctx) < 0 || > + visible_width + offset_x > s->width || > + visible_height + offset_y > s->height) { > + av_log(avctx, AV_LOG_ERROR, "Invalid frame dimensions.\n"); > + return AVERROR_INVALIDDATA; > + } > + > fps.num = get_bits_long(gb, 32); > fps.den = get_bits_long(gb, 32); > if (fps.num && fps.den) { > @@ -2259,16 +2276,29 @@ static int theora_decode_header(AVCodecContext > *avctx, GetBitContext *gb) > skip_bits(gb, 3); /* reserved */ > } > > -// align_get_bits(gb); > - > - if (visible_width <= s->width && visible_width > s->width - 16 && > - visible_height <= s->height && visible_height > s->height - 16 && > - !offset_x && (offset_y == s->height - visible_height)) > - ret = ff_set_dimensions(avctx, visible_width, visible_height); > - else > - ret = ff_set_dimensions(avctx, s->width, s->height); > + ret = ff_set_dimensions(avctx, s->width, s->height); > if (ret < 0) > return ret; > + if (!(avctx->flags2 & CODEC_FLAG2_IGNORE_CROP) && > + (visible_width != s->width || visible_height != s->height)) { > + av_log(s, AV_LOG_DEBUG, "w:%d h:%d x:%d y:%d (%dx%d)\n", > + visible_width, visible_height, offset_x, offset_y, > + s->width, s->height); > + Ok'd by Luca with this log line merged in the "Invalid frame dimensions" log line.
-- Vittorio _______________________________________________ libav-devel mailing list [email protected] https://lists.libav.org/mailman/listinfo/libav-devel
