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

Reply via email to