]> git.sesse.net Git - ffmpeg/commitdiff
Merge commit 'b4d372e091f6b30758db2a43a5a9fe2510ec2b13'
authorMichael Niedermayer <michaelni@gmx.at>
Sat, 8 Mar 2014 23:57:22 +0000 (00:57 +0100)
committerMichael Niedermayer <michaelni@gmx.at>
Sat, 8 Mar 2014 23:59:00 +0000 (00:59 +0100)
* commit 'b4d372e091f6b30758db2a43a5a9fe2510ec2b13':
  rv10: Forward error from rv10_decode_packet

Merged-by: Michael Niedermayer <michaelni@gmx.at>
1  2 
libavcodec/rv10.c

diff --combined libavcodec/rv10.c
index fc3fb722f8d23407907db4d13ca136ee2f7de9dd,51affa876982dc21ce716c7f0cb1c0394ac887da..cf13b9b0c10e69c26d235adf69b95990f8e87b69
@@@ -3,20 -3,20 +3,20 @@@
   * Copyright (c) 2000,2001 Fabrice Bellard
   * Copyright (c) 2002-2004 Michael Niedermayer
   *
 - * This file is part of Libav.
 + * This file is part of FFmpeg.
   *
 - * Libav is free software; you can redistribute it and/or
 + * FFmpeg is free software; you can redistribute it and/or
   * modify it under the terms of the GNU Lesser General Public
   * License as published by the Free Software Foundation; either
   * version 2.1 of the License, or (at your option) any later version.
   *
 - * Libav is distributed in the hope that it will be useful,
 + * FFmpeg is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   * Lesser General Public License for more details.
   *
   * You should have received a copy of the GNU Lesser General Public
 - * License along with Libav; if not, write to the Free Software
 + * License along with FFmpeg; if not, write to the Free Software
   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
   */
  
@@@ -300,10 -300,10 +300,10 @@@ static int rv20_decode_picture_header(R
  {
      MpegEncContext *s = &rv->m;
      int seq, mb_pos, i, ret;
 -    int rpr_bits;
 +    int rpr_max;
  
      i = get_bits(&s->gb, 2);
 -    switch (i) {
 +    switch(i) {
      case 0: s->pict_type = AV_PICTURE_TYPE_I; break;
      case 1: s->pict_type = AV_PICTURE_TYPE_I; break; //hmm ...
      case 2: s->pict_type = AV_PICTURE_TYPE_P; break;
          return AVERROR_INVALIDDATA;
      }
  
 +    if (s->low_delay && s->pict_type == AV_PICTURE_TYPE_B) {
 +        av_log(s->avctx, AV_LOG_ERROR, "low delay B\n");
 +        return -1;
 +    }
      if (s->last_picture_ptr == NULL && s->pict_type == AV_PICTURE_TYPE_B) {
          av_log(s->avctx, AV_LOG_ERROR, "early B-frame\n");
          return AVERROR_INVALIDDATA;
      }
  
      if (RV_GET_MINOR_VER(rv->sub_id) >= 2)
 -        s->loop_filter = get_bits1(&s->gb);
 +        s->loop_filter = get_bits1(&s->gb) && !s->avctx->lowres;
  
      if (RV_GET_MINOR_VER(rv->sub_id) <= 1)
          seq = get_bits(&s->gb, 8) << 7;
      else
          seq = get_bits(&s->gb, 13) << 2;
  
 -    rpr_bits = s->avctx->extradata[1] & 7;
 -    if (rpr_bits) {
 +    rpr_max = s->avctx->extradata[1] & 7;
 +    if (rpr_max) {
          int f, new_w, new_h;
 -        rpr_bits = FFMIN((rpr_bits >> 1) + 1, 3);
 +        int rpr_bits = av_log2(rpr_max) + 1;
  
          f = get_bits(&s->gb, rpr_bits);
  
              new_h = s->orig_height;
          }
          if (new_w != s->width || new_h != s->height) {
 +            AVRational old_aspect = s->avctx->sample_aspect_ratio;
              av_log(s->avctx, AV_LOG_DEBUG,
                     "attempting to change resolution to %dx%d\n", new_w, new_h);
 +            if (av_image_check_size(new_w, new_h, 0, s->avctx) < 0)
 +                return AVERROR_INVALIDDATA;
              ff_MPV_common_end(s);
  
 +            // attempt to keep aspect during typical resolution switches
 +            if (!old_aspect.num)
 +                old_aspect = (AVRational){1, 1};
 +            if (2 * new_w * s->height == new_h * s->width)
 +                s->avctx->sample_aspect_ratio = av_mul_q(old_aspect, (AVRational){2, 1});
 +            if (new_w * s->height == 2 * new_h * s->width)
 +                s->avctx->sample_aspect_ratio = av_mul_q(old_aspect, (AVRational){1, 2});
 +
              ret = ff_set_dimensions(s->avctx, new_w, new_h);
              if (ret < 0)
                  return ret;
          }
  
          if (s->avctx->debug & FF_DEBUG_PICT_INFO) {
 -            av_log(s->avctx, AV_LOG_DEBUG, "F %d/%d\n", f, rpr_bits);
 +            av_log(s->avctx, AV_LOG_DEBUG, "F %d/%d/%d\n", f, rpr_bits, rpr_max);
          }
 -    } else if (av_image_check_size(s->width, s->height, 0, s->avctx) < 0)
 +    }
 +    if (av_image_check_size(s->width, s->height, 0, s->avctx) < 0)
          return AVERROR_INVALIDDATA;
  
      mb_pos = ff_h263_decode_mba(s);
          } else {
              s->time    = seq;
              s->pb_time = s->pp_time - (s->last_non_b_time - s->time);
 -            if (s->pp_time <= s->pb_time ||
 -                s->pp_time <= s->pp_time - s->pb_time || s->pp_time <= 0) {
 -                av_log(s->avctx, AV_LOG_DEBUG, "messed up order, possible "
 -                       "from seeking? skipping current b frame\n");
 -                return FRAME_SKIPPED;
 -            }
 -            ff_mpeg4_init_direct_mv(s);
          }
      }
 +    if (s->pict_type == AV_PICTURE_TYPE_B) {
 +        if (s->pp_time <=s->pb_time || s->pp_time <= s->pp_time - s->pb_time || s->pp_time<=0) {
 +            av_log(s->avctx, AV_LOG_DEBUG,
 +                   "messed up order, possible from seeking? skipping current b frame\n");
 +#define ERROR_SKIP_FRAME -123
 +            return ERROR_SKIP_FRAME;
 +        }
 +        ff_mpeg4_init_direct_mv(s);
 +    }
  
      s->no_rounding = get_bits1(&s->gb);
  
      s->unrestricted_mv = 1;
      s->h263_aic        = s->pict_type == AV_PICTURE_TYPE_I;
      s->modified_quant  = 1;
 -    s->loop_filter     = 1;
 +    if (!s->avctx->lowres)
 +        s->loop_filter = 1;
  
      if (s->avctx->debug & FF_DEBUG_PICT_INFO) {
          av_log(s->avctx, AV_LOG_INFO, "num:%5d x:%2d y:%2d type:%d qscale:%2d rnd:%d\n",
                 seq, s->mb_x, s->mb_y, s->pict_type, s->qscale, s->no_rounding);
      }
  
 -    assert(s->pict_type != AV_PICTURE_TYPE_B || !s->low_delay);
 +    av_assert0(s->pict_type != AV_PICTURE_TYPE_B || !s->low_delay);
  
      return s->mb_width*s->mb_height - mb_pos;
  }
@@@ -494,7 -475,7 +494,7 @@@ static av_cold int rv10_decode_init(AVC
  
      if (avctx->debug & FF_DEBUG_PICT_INFO) {
          av_log(avctx, AV_LOG_DEBUG, "ver:%X ver0:%X\n", rv->sub_id,
 -               avctx->extradata_size >= 4 ? ((uint32_t*)avctx->extradata)[0] : -1);
 +               ((uint32_t*)avctx->extradata)[0]);
      }
  
      avctx->pix_fmt = AV_PIX_FMT_YUV420P;
@@@ -541,8 -522,7 +541,8 @@@ static int rv10_decode_packet(AVCodecCo
      else
          mb_count = rv20_decode_picture_header(rv);
      if (mb_count < 0) {
 -        av_log(s->avctx, AV_LOG_ERROR, "HEADER ERROR\n");
 +        if (mb_count != ERROR_SKIP_FRAME)
 +            av_log(s->avctx, AV_LOG_ERROR, "HEADER ERROR\n");
          return AVERROR_INVALIDDATA;
      }
  
          }
      }
  
 +
      av_dlog(avctx, "qscale=%d\n", s->qscale);
  
      /* default quantization values */
@@@ -686,8 -665,6 +686,8 @@@ static int rv10_decode_frame(AVCodecCon
      const uint8_t *slices_hdr = NULL;
  
      av_dlog(avctx, "*****frame %d size=%d\n", avctx->frame_number, buf_size);
 +    s->flags  = avctx->flags;
 +    s->flags2 = avctx->flags2;
  
      /* no supplementary picture */
      if (buf_size == 0) {
              offset + FFMAX(size, size2) > buf_size)
              return AVERROR_INVALIDDATA;
  
-         if (rv10_decode_packet(avctx, buf + offset, size, size2) > 8 * size)
+         if ((ret = rv10_decode_packet(avctx, buf + offset, size, size2)) < 0)
+             return ret;
+         if (ret > 8 * size)
              i++;
      }
  
          if (s->pict_type == AV_PICTURE_TYPE_B || s->low_delay) {
              if ((ret = av_frame_ref(pict, &s->current_picture_ptr->f)) < 0)
                  return ret;
 -            ff_print_debug_info(s, s->current_picture_ptr);
 +            ff_print_debug_info(s, s->current_picture_ptr, pict);
 +            ff_mpv_export_qp_table(s, pict, s->current_picture_ptr, FF_QSCALE_TYPE_MPEG1);
          } else if (s->last_picture_ptr != NULL) {
              if ((ret = av_frame_ref(pict, &s->last_picture_ptr->f)) < 0)
                  return ret;
 -            ff_print_debug_info(s, s->last_picture_ptr);
 +            ff_print_debug_info(s, s->last_picture_ptr, pict);
 +            ff_mpv_export_qp_table(s, pict,s->last_picture_ptr, FF_QSCALE_TYPE_MPEG1);
          }
  
          if (s->last_picture_ptr || s->low_delay) {
@@@ -771,7 -749,6 +774,7 @@@ AVCodec ff_rv10_decoder = 
      .close          = rv10_decode_end,
      .decode         = rv10_decode_frame,
      .capabilities   = CODEC_CAP_DR1,
 +    .max_lowres     = 3,
      .pix_fmts       = ff_pixfmt_list_420,
  };
  
@@@ -786,6 -763,5 +789,6 @@@ AVCodec ff_rv20_decoder = 
      .decode         = rv10_decode_frame,
      .capabilities   = CODEC_CAP_DR1 | CODEC_CAP_DELAY,
      .flush          = ff_mpeg_flush,
 +    .max_lowres     = 3,
      .pix_fmts       = ff_pixfmt_list_420,
  };