On Tue, Jul 30, 2013 at 12:00 PM, Vittorio Giovara
<[email protected]> wrote:
> ---
> Resend taking into account Luca and Diego's comments.
>
>  libavcodec/h264.c |  198 
> ++++++++++++++++++++++++++++++-----------------------
>  1 file changed, 113 insertions(+), 85 deletions(-)
>
> diff --git a/libavcodec/h264.c b/libavcodec/h264.c
> index 2dccb87..effd6d9 100644
> --- a/libavcodec/h264.c
> +++ b/libavcodec/h264.c
> @@ -415,7 +415,7 @@ int ff_h264_check_intra4x4_pred_mode(H264Context *h)
>                  av_log(h->avctx, AV_LOG_ERROR,
>                         "top block unavailable for requested intra4x4 mode %d 
> at %d %d\n",
>                         status, h->mb_x, h->mb_y);
> -                return -1;
> +                return status;

Status is not an AVERROR code, it'll just be -1, so
AVERROR_INVALIDDATA seems more appropriate?

>              } else if (status) {
>                  h->intra4x4_pred_mode_cache[scan8[0] + i] = status;
>              }
> @@ -431,7 +431,7 @@ int ff_h264_check_intra4x4_pred_mode(H264Context *h)
>                      av_log(h->avctx, AV_LOG_ERROR,
>                             "left block unavailable for requested intra4x4 
> mode %d at %d %d\n",
>                             status, h->mb_x, h->mb_y);
> -                    return -1;
> +                    return status;
>                  } else if (status) {
>                      h->intra4x4_pred_mode_cache[scan8[0] + 8 * i] = status;
>                  }
> @@ -454,7 +454,7 @@ int ff_h264_check_intra_pred_mode(H264Context *h, int 
> mode, int is_chroma)
>          av_log(h->avctx, AV_LOG_ERROR,
>                 "out of range intra chroma pred mode at %d %d\n",
>                 h->mb_x, h->mb_y);
> -        return -1;
> +        return AVERROR_INVALIDDATA;
>      }
>
>      if (!(h->top_samples_available & 0x8000)) {
> @@ -463,7 +463,7 @@ int ff_h264_check_intra_pred_mode(H264Context *h, int 
> mode, int is_chroma)
>              av_log(h->avctx, AV_LOG_ERROR,
>                     "top block unavailable for requested intra mode at %d 
> %d\n",
>                     h->mb_x, h->mb_y);
> -            return -1;
> +            return AVERROR_INVALIDDATA;
>          }
>      }
>
> @@ -479,7 +479,7 @@ int ff_h264_check_intra_pred_mode(H264Context *h, int 
> mode, int is_chroma)
>              av_log(h->avctx, AV_LOG_ERROR,
>                     "left block unavailable for requested intra mode at %d 
> %d\n",
>                     h->mb_x, h->mb_y);
> -            return -1;
> +            return AVERROR_INVALIDDATA;
>          }
>      }
>
> @@ -1260,7 +1260,7 @@ int ff_h264_alloc_tables(H264Context *h)
>
>  fail:
>      free_tables(h, 1);
> -    return -1;
> +    return AVERROR(ENOMEM);
>  }
>
>  /**
> @@ -1359,7 +1359,7 @@ static int context_init(H264Context *h)
>      return 0;
>
>  fail:
> -    return -1; // free_tables will clean up for us
> +    return AVERROR(ENOMEM); // free_tables will clean up for us
>  }
>
>  static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size,
> @@ -1368,6 +1368,7 @@ static int decode_nal_units(H264Context *h, const 
> uint8_t *buf, int buf_size,
>  int ff_h264_decode_extradata(H264Context *h)
>  {
>      AVCodecContext *avctx = h->avctx;
> +    int ret;
>
>      if (avctx->extradata[0] == 1) {
>          int i, cnt, nalsize;
> @@ -1377,7 +1378,7 @@ int ff_h264_decode_extradata(H264Context *h)
>
>          if (avctx->extradata_size < 7) {
>              av_log(avctx, AV_LOG_ERROR, "avcC too short\n");
> -            return -1;
> +            return AVERROR_INVALIDDATA;
>          }
>          /* sps and pps in the avcC always have length coded with 2 bytes,
>           * so put a fake nal_length_size = 2 while parsing them */
> @@ -1388,11 +1389,12 @@ int ff_h264_decode_extradata(H264Context *h)
>          for (i = 0; i < cnt; i++) {
>              nalsize = AV_RB16(p) + 2;
>              if (p - avctx->extradata + nalsize > avctx->extradata_size)
> -                return -1;
> -            if (decode_nal_units(h, p, nalsize, 1) < 0) {
> +                return AVERROR_INVALIDDATA;
> +            ret = decode_nal_units(h, p, nalsize, 1);
> +            if (ret < 0) {
>                  av_log(avctx, AV_LOG_ERROR,
>                         "Decoding sps %d from avcC failed\n", i);
> -                return -1;
> +                return ret;
>              }
>              p += nalsize;
>          }
> @@ -1401,11 +1403,12 @@ int ff_h264_decode_extradata(H264Context *h)
>          for (i = 0; i < cnt; i++) {
>              nalsize = AV_RB16(p) + 2;
>              if (p - avctx->extradata + nalsize > avctx->extradata_size)
> -                return -1;
> -            if (decode_nal_units(h, p, nalsize, 1) < 0) {
> +                return AVERROR_INVALIDDATA;
> +            ret = decode_nal_units(h, p, nalsize, 1);
> +            if (ret < 0) {
>                  av_log(avctx, AV_LOG_ERROR,
>                         "Decoding pps %d from avcC failed\n", i);
> -                return -1;
> +                return ret;
>              }
>              p += nalsize;
>          }
> @@ -1413,8 +1416,9 @@ int ff_h264_decode_extradata(H264Context *h)
>          h->nal_length_size = (avctx->extradata[4] & 0x03) + 1;
>      } else {
>          h->is_avc = 0;
> -        if (decode_nal_units(h, avctx->extradata, avctx->extradata_size, 1) 
> < 0)
> -            return -1;
> +        ret = decode_nal_units(h, avctx->extradata, avctx->extradata_size, 
> 1);
> +        if (ret < 0)
> +            return ret;
>      }
>      return 0;
>  }
> @@ -1423,6 +1427,7 @@ av_cold int ff_h264_decode_init(AVCodecContext *avctx)
>  {
>      H264Context *h = avctx->priv_data;
>      int i;
> +    int ret;
>
>      h->avctx = avctx;
>
> @@ -1474,9 +1479,11 @@ av_cold int ff_h264_decode_init(AVCodecContext *avctx)
>          avctx->ticks_per_frame = 2;
>      }
>
> -    if (avctx->extradata_size > 0 && avctx->extradata &&
> -        ff_h264_decode_extradata(h))
> -        return -1;
> +    if (avctx->extradata_size > 0 && avctx->extradata) {
> +       ret = ff_h264_decode_extradata(h);
> +       if (ret < 0)
> +           return ret;
> +    }
>
>      if (h->sps.bitstream_restriction_flag &&
>          h->avctx->has_b_frames < h->sps.num_reorder_frames) {
> @@ -1626,11 +1633,16 @@ static int 
> decode_update_thread_context(AVCodecContext *dst,
>          h->ref_index_pool    = NULL;
>          h->motion_val_pool   = NULL;
>
> -        if (ff_h264_alloc_tables(h) < 0) {
> +        ret = ff_h264_alloc_tables(h);
> +        if (ret < 0) {
>              av_log(dst, AV_LOG_ERROR, "Could not allocate memory for 
> h264\n");
> -            return AVERROR(ENOMEM);
> +            return ret;
> +        }
> +        ret = context_init(h);
> +        if (ret < 0) {
> +            av_log(dst, AV_LOG_ERROR, "context_init() failed.\n");
> +            return ret;
>          }
> -        context_init(h);
>
>          for (i = 0; i < 2; i++) {
>              h->rbsp_buffer[i]      = NULL;
> @@ -2763,7 +2775,7 @@ static void init_scan_tables(H264Context *h)
>  static int field_end(H264Context *h, int in_setup)
>  {
>      AVCodecContext *const avctx = h->avctx;
> -    int err = 0;
> +    int err, ret = 0;
>      h->mb_y = 0;
>
>      if (!in_setup && !h->droppable)
> @@ -2776,7 +2788,7 @@ static int field_end(H264Context *h, int in_setup)
>
>      if (in_setup || !(avctx->active_thread_type & FF_THREAD_FRAME)) {
>          if (!h->droppable) {
> -            err = ff_h264_execute_ref_pic_marking(h, h->mmco, h->mmco_index);
> +            ret = ff_h264_execute_ref_pic_marking(h, h->mmco, h->mmco_index);
>              h->prev_poc_msb = h->poc_msb;
>              h->prev_poc_lsb = h->poc_lsb;
>          }
> @@ -2786,7 +2798,8 @@ static int field_end(H264Context *h, int in_setup)
>      }
>
>      if (avctx->hwaccel) {
> -        if (avctx->hwaccel->end_frame(avctx) < 0)
> +        err = avctx->hwaccel->end_frame(avctx);
> +        if (err < 0)
>              av_log(avctx, AV_LOG_ERROR,
>                     "hardware accelerator failed to decode picture\n");

This change seems unnecessary, as the return value is not used for anything.
In addition, you can skip the additional "ret" variable and keep using
"err" when err is not being clobbered here.

>      }
> @@ -2817,7 +2830,7 @@ static int field_end(H264Context *h, int in_setup)
>
>      h->current_slice = 0;
>
> -    return err;
> +    return ret;
>  }
>
>  /**
> @@ -3019,7 +3032,7 @@ static int h264_slice_header_init(H264Context *h, int 
> reinit)
>      int nb_slices = (HAVE_THREADS &&
>                       h->avctx->active_thread_type & FF_THREAD_SLICE) ?
>                      h->avctx->thread_count : 1;
> -    int i;
> +    int i, ret;
>
>      h->avctx->sample_aspect_ratio = h->sps.sar;
>      av_assert0(h->avctx->sample_aspect_ratio.den);
> @@ -3042,10 +3055,11 @@ static int h264_slice_header_init(H264Context *h, int 
> reinit)
>      h->prev_interlaced_frame = 1;
>
>      init_scan_tables(h);
> -    if (ff_h264_alloc_tables(h) < 0) {
> +    ret = ff_h264_alloc_tables(h);
> +    if (ret < 0) {
>          av_log(h->avctx, AV_LOG_ERROR,
>                 "Could not allocate memory for h264\n");
> -        return AVERROR(ENOMEM);
> +        return ret;
>      }
>
>      if (nb_slices > MAX_THREADS || (nb_slices > h->mb_height && 
> h->mb_height)) {
> @@ -3061,9 +3075,10 @@ static int h264_slice_header_init(H264Context *h, int 
> reinit)
>      h->slice_context_count = nb_slices;
>
>      if (!HAVE_THREADS || !(h->avctx->active_thread_type & FF_THREAD_SLICE)) {
> -        if (context_init(h) < 0) {
> +        ret = context_init(h);
> +        if (ret < 0) {
>              av_log(h->avctx, AV_LOG_ERROR, "context_init() failed.\n");
> -            return -1;
> +            return ret;
>          }
>      } else {
>          for (i = 1; i < h->slice_context_count; i++) {
> @@ -3102,9 +3117,9 @@ static int h264_slice_header_init(H264Context *h, int 
> reinit)
>          }
>
>          for (i = 0; i < h->slice_context_count; i++)
> -            if (context_init(h->thread_context[i]) < 0) {
> +            if ((ret = context_init(h->thread_context[i])) < 0) {
>                  av_log(h->avctx, AV_LOG_ERROR, "context_init() failed.\n");
> -                return -1;
> +                return ret;
>              }
>      }
>
> @@ -3158,7 +3173,7 @@ static int decode_slice_header(H264Context *h, 
> H264Context *h0)
>          av_log(h->avctx, AV_LOG_ERROR,
>                 "slice type too large (%d) at %d %d\n",
>                 h->slice_type, h->mb_x, h->mb_y);
> -        return -1;
> +        return AVERROR_INVALIDDATA;
>      }
>      if (slice_type > 4) {
>          slice_type -= 5;
> @@ -3180,13 +3195,13 @@ static int decode_slice_header(H264Context *h, 
> H264Context *h0)
>      pps_id = get_ue_golomb(&h->gb);
>      if (pps_id >= MAX_PPS_COUNT) {
>          av_log(h->avctx, AV_LOG_ERROR, "pps_id out of range\n");
> -        return -1;
> +        return AVERROR_INVALIDDATA;
>      }
>      if (!h0->pps_buffers[pps_id]) {
>          av_log(h->avctx, AV_LOG_ERROR,
>                 "non-existing PPS %u referenced\n",
>                 pps_id);
> -        return -1;
> +        return AVERROR_INVALIDDATA;
>      }
>      h->pps = *h0->pps_buffers[pps_id];
>
> @@ -3194,7 +3209,7 @@ static int decode_slice_header(H264Context *h, 
> H264Context *h0)
>          av_log(h->avctx, AV_LOG_ERROR,
>                 "non-existing SPS %u referenced\n",
>                 h->pps.sps_id);
> -        return -1;
> +        return AVERROR_INVALIDDATA;
>      }
>
>      if (h->pps.sps_id != h->current_sps_id ||
> @@ -3279,7 +3294,7 @@ static int decode_slice_header(H264Context *h, 
> H264Context *h0)
>          if (h != h0) {
>              av_log(h->avctx, AV_LOG_ERROR,
>                     "Cannot (re-)initialize context during parallel 
> decoding.\n");
> -            return -1;
> +            return AVERROR_PATCHWELCOME;
>          }
>
>          if ((ret = get_pixel_format(h)) < 0)
> @@ -3407,19 +3422,20 @@ static int decode_slice_header(H264Context *h, 
> H264Context *h0)
>              Picture *prev = h->short_ref_count ? h->short_ref[0] : NULL;
>              av_log(h->avctx, AV_LOG_DEBUG, "Frame num gap %d %d\n",
>                     h->frame_num, h->prev_frame_num);
> -            if (h264_frame_start(h) < 0)
> -                return -1;
> +            ret = h264_frame_start(h);
> +            if (ret < 0)
> +                return ret;
>              h->prev_frame_num++;
>              h->prev_frame_num        %= 1 << h->sps.log2_max_frame_num;
>              h->cur_pic_ptr->frame_num = h->prev_frame_num;
>              ff_thread_report_progress(&h->cur_pic_ptr->tf, INT_MAX, 0);
>              ff_thread_report_progress(&h->cur_pic_ptr->tf, INT_MAX, 1);
> -            if ((ret = ff_generate_sliding_window_mmcos(h, 1)) < 0 &&
> -                h->avctx->err_recognition & AV_EF_EXPLODE)
> +            ret = ff_generate_sliding_window_mmcos(h, 1);
> +            if (ret < 0 && h->avctx->err_recognition & AV_EF_EXPLODE)
> +                return ret;
> +            ret = ff_h264_execute_ref_pic_marking(h, h->mmco, h->mmco_index);
> +            if (ret < 0 && (h->avctx->err_recognition & AV_EF_EXPLODE))
>                  return ret;
> -            if (ff_h264_execute_ref_pic_marking(h, h->mmco, h->mmco_index) < 
> 0 &&
> -                (h->avctx->err_recognition & AV_EF_EXPLODE))
> -                return AVERROR_INVALIDDATA;
>              /* Error concealment: If a ref is missing, copy the previous ref
>               * in its place.
>               * FIXME: Avoiding a memcpy would be nice, but ref handling makes
> @@ -3491,7 +3507,7 @@ static int decode_slice_header(H264Context *h, 
> H264Context *h0)
>      if (first_mb_in_slice << FIELD_OR_MBAFF_PICTURE(h) >= h->mb_num ||
>          first_mb_in_slice >= h->mb_num) {
>          av_log(h->avctx, AV_LOG_ERROR, "first_mb_in_slice overflow\n");
> -        return -1;
> +        return AVERROR_INVALIDDATA;
>      }
>      h->resync_mb_x = h->mb_x =  first_mb_in_slice % h->mb_width;
>      h->resync_mb_y = h->mb_y = (first_mb_in_slice / h->mb_width) <<
> @@ -3570,10 +3586,12 @@ static int decode_slice_header(H264Context *h, 
> H264Context *h0)
>      if (!default_ref_list_done)
>          ff_h264_fill_default_ref_list(h);
>
> -    if (h->slice_type_nos != AV_PICTURE_TYPE_I &&
> -        ff_h264_decode_ref_pic_list_reordering(h) < 0) {
> -        h->ref_count[1] = h->ref_count[0] = 0;
> -        return -1;
> +    if (h->slice_type_nos != AV_PICTURE_TYPE_I) {
> +       ret = ff_h264_decode_ref_pic_list_reordering(h);
> +       if (ret < 0) {
> +           h->ref_count[1] = h->ref_count[0] = 0;
> +           return ret;
> +       }
>      }
>
>      if ((h->pps.weighted_pred && h->slice_type_nos == AV_PICTURE_TYPE_P) ||
> @@ -3596,12 +3614,13 @@ static int decode_slice_header(H264Context *h, 
> H264Context *h0)
>      // or h->mmco, which will cause ref list mix-ups and decoding errors
>      // further down the line. This may break decoding if the first slice is
>      // corrupt, thus we only do this if frame-mt is enabled.
> -    if (h->nal_ref_idc &&
> -        ff_h264_decode_ref_pic_marking(h0, &h->gb,
> -                                       !(h->avctx->active_thread_type & 
> FF_THREAD_FRAME) ||
> -                                       h0->current_slice == 0) < 0 &&
> -        (h->avctx->err_recognition & AV_EF_EXPLODE))
> -        return AVERROR_INVALIDDATA;
> +    if (h->nal_ref_idc) {
> +        ret = ff_h264_decode_ref_pic_marking(h0, &h->gb,
> +                                             !(h->avctx->active_thread_type 
> & FF_THREAD_FRAME) ||
> +                                             h0->current_slice == 0);
> +        if (ret < 0 && (h->avctx->err_recognition & AV_EF_EXPLODE))
> +            return AVERROR_INVALIDDATA;
> +    }
>
>      if (FRAME_MBAFF(h)) {
>          ff_h264_fill_mbaff_ref_list(h);
> @@ -3620,7 +3639,7 @@ static int decode_slice_header(H264Context *h, 
> H264Context *h0)
>          tmp = get_ue_golomb_31(&h->gb);
>          if (tmp > 2) {
>              av_log(h->avctx, AV_LOG_ERROR, "cabac_init_idc overflow\n");
> -            return -1;
> +            return AVERROR_INVALIDDATA;
>          }
>          h->cabac_init_idc = tmp;
>      }
> @@ -3629,7 +3648,7 @@ static int decode_slice_header(H264Context *h, 
> H264Context *h0)
>      tmp = h->pps.init_qp + get_se_golomb(&h->gb);
>      if (tmp > 51 + 6 * (h->sps.bit_depth_luma - 8)) {
>          av_log(h->avctx, AV_LOG_ERROR, "QP %u out of range\n", tmp);
> -        return -1;
> +        return AVERROR_INVALIDDATA;
>      }
>      h->qscale       = tmp;
>      h->chroma_qp[0] = get_chroma_qp(h, 0, h->qscale);
> @@ -3649,7 +3668,7 @@ static int decode_slice_header(H264Context *h, 
> H264Context *h0)
>          if (tmp > 2) {
>              av_log(h->avctx, AV_LOG_ERROR,
>                     "deblocking_filter_idc %u out of range\n", tmp);
> -            return -1;
> +            return AVERROR_INVALIDDATA;
>          }
>          h->deblocking_filter = tmp;
>          if (h->deblocking_filter < 2)
> @@ -3663,7 +3682,7 @@ static int decode_slice_header(H264Context *h, 
> H264Context *h0)
>                  av_log(h->avctx, AV_LOG_ERROR,
>                         "deblocking filter parameters %d %d out of range\n",
>                         h->slice_alpha_c0_offset, h->slice_beta_offset);
> -                return -1;
> +                return AVERROR_INVALIDDATA;
>              }
>          }
>      }
> @@ -3781,7 +3800,7 @@ int ff_h264_get_slice_type(const H264Context *h)
>      case AV_PICTURE_TYPE_SI:
>          return 4;
>      default:
> -        return -1;
> +        return AVERROR_INVALIDDATA;
>      }
>  }
>
> @@ -4022,6 +4041,7 @@ static void loop_filter(H264Context *h, int start_x, 
> int end_x)
>      const int old_slice_type = h->slice_type;
>      const int pixel_shift    = h->pixel_shift;
>      const int block_h        = 16 >> h->chroma_y_shift;
> +    int ret;
>
>      if (h->deblocking_filter) {
>          for (mb_x = start_x; mb_x < end_x; mb_x++)
> @@ -4062,7 +4082,8 @@ static void loop_filter(H264Context *h, int start_x, 
> int end_x)
>                  }
>                  backup_mb_border(h, dest_y, dest_cb, dest_cr, linesize,
>                                   uvlinesize, 0);
> -                if (fill_filter_caches(h, mb_type))
> +                ret = fill_filter_caches(h, mb_type);
> +                if (ret)
>                      continue;

Since the value is also not used for anything, is this really the better way?

>                  h->chroma_qp[0] = get_chroma_qp(h, 0, 
> h->cur_pic.qscale_table[mb_xy]);
>                  h->chroma_qp[1] = get_chroma_qp(h, 1, 
> h->cur_pic.qscale_table[mb_xy]);
> @@ -4142,6 +4163,7 @@ static int decode_slice(struct AVCodecContext *avctx, 
> void *arg)
>  {
>      H264Context *h = *(void **)arg;
>      int lf_x_start = h->mb_x;
> +    int ret;
>
>      h->mb_skip_run = -1;
>
> @@ -4162,9 +4184,9 @@ static int decode_slice(struct AVCodecContext *avctx, 
> void *arg)
>          ff_h264_init_cabac_states(h);
>
>          for (;;) {
> -            // START_TIMER
> -            int ret = ff_h264_decode_mb_cabac(h);
>              int eos;
> +            // START_TIMER
> +            ret = ff_h264_decode_mb_cabac(h);
>              // STOP_TIMER("decode_mb_cabac")
>
>              if (ret >= 0)
> @@ -4197,7 +4219,7 @@ static int decode_slice(struct AVCodecContext *avctx, 
> void *arg)
>                         h->cabac.bytestream_end - h->cabac.bytestream);
>                  er_add_slice(h, h->resync_mb_x, h->resync_mb_y, h->mb_x,
>                               h->mb_y, ER_MB_ERROR);
> -                return -1;
> +                return AVERROR_INVALIDDATA;
>              }
>
>              if (++h->mb_x >= h->mb_width) {
> @@ -4224,7 +4246,7 @@ static int decode_slice(struct AVCodecContext *avctx, 
> void *arg)
>          }
>      } else {
>          for (;;) {
> -            int ret = ff_h264_decode_mb_cavlc(h);
> +            ret = ff_h264_decode_mb_cavlc(h);
>
>              if (ret >= 0)
>                  ff_h264_hl_decode_mb(h);
> @@ -4244,7 +4266,7 @@ static int decode_slice(struct AVCodecContext *avctx, 
> void *arg)
>                         "error while decoding MB %d %d\n", h->mb_x, h->mb_y);
>                  er_add_slice(h, h->resync_mb_x, h->resync_mb_y, h->mb_x,
>                               h->mb_y, ER_MB_ERROR);
> -                return -1;
> +                return ret;
>              }
>
>              if (++h->mb_x >= h->mb_width) {
> @@ -4261,12 +4283,13 @@ static int decode_slice(struct AVCodecContext *avctx, 
> void *arg)
>                      tprintf(h->avctx, "slice end %d %d\n",
>                              get_bits_count(&h->gb), h->gb.size_in_bits);
>
> -                    if (get_bits_left(&h->gb) == 0) {
> +                    ret = get_bits_left(&h->gb);
> +                    if (ret == 0) {
>                          er_add_slice(h, h->resync_mb_x, h->resync_mb_y,
>                                       h->mb_x - 1, h->mb_y,
>                                       ER_MB_END);
>
> -                        return 0;
> +                        return ret;
>                      } else {
>                          er_add_slice(h, h->resync_mb_x, h->resync_mb_y,
>                                       h->mb_x - 1, h->mb_y,
> @@ -4277,17 +4300,20 @@ static int decode_slice(struct AVCodecContext *avctx, 
> void *arg)
>                  }
>              }
>
> -            if (get_bits_left(&h->gb) <= 0 && h->mb_skip_run <= 0) {
> -                tprintf(h->avctx, "slice end %d %d\n",
> -                        get_bits_count(&h->gb), h->gb.size_in_bits);
> -                if (get_bits_left(&h->gb) == 0) {
> +            ret = get_bits_left(&h->gb);
> +            if (ret <= 0 && h->mb_skip_run <= 0) {
> +                ret = get_bits_count(&h->gb);
> +                tprintf(h->avctx, "slice end %d %d\n", ret, 
> h->gb.size_in_bits);
> +
> +                ret = get_bits_left(&h->gb);
> +                if (ret == 0) {
>                      er_add_slice(h, h->resync_mb_x, h->resync_mb_y,
>                                   h->mb_x - 1, h->mb_y,
>                                   ER_MB_END);
>                      if (h->mb_x > lf_x_start)
>                          loop_filter(h, lf_x_start, h->mb_x);
>
> -                    return 0;
> +                    return ret;
>                  } else {
>                      er_add_slice(h, h->resync_mb_x, h->resync_mb_y, h->mb_x,
>                                   h->mb_y, ER_MB_ERROR);
> @@ -4351,6 +4377,7 @@ static int decode_nal_units(H264Context *h, const 
> uint8_t *buf, int buf_size,
>      int pass = !(avctx->active_thread_type & FF_THREAD_FRAME);
>      int nals_needed = 0; ///< number of NALs that need decoding before the 
> next frame thread starts
>      int nal_index;
> +    int ret = 0;
>
>      h->max_contexts = h->slice_context_count;
>      if (!(avctx->flags2 & CODEC_FLAG2_CHUNKS)) {
> @@ -4409,7 +4436,7 @@ static int decode_nal_units(H264Context *h, const 
> uint8_t *buf, int buf_size,
>              ptr = ff_h264_decode_nal(hx, buf + buf_index, &dst_length,
>                                       &consumed, next_avc - buf_index);
>              if (ptr == NULL || dst_length < 0) {
> -                buf_index = -1;
> +                ret = -1;
>                  goto end;
>              }
>              i = buf_index + consumed;
> @@ -4452,7 +4479,8 @@ static int decode_nal_units(H264Context *h, const 
> uint8_t *buf, int buf_size,
>                  case NAL_IDR_SLICE:
>                  case NAL_SLICE:
>                      init_get_bits(&hx->gb, ptr, bit_length);
> -                    if (!get_ue_golomb(&hx->gb))
> +                    ret = get_ue_golomb(&hx->gb);
> +                    if (ret == 0)
>                          nals_needed = nal_index;
>                  }
>                  continue;
> @@ -4480,7 +4508,7 @@ again:
>                  if (h->nal_unit_type != NAL_IDR_SLICE) {
>                      av_log(h->avctx, AV_LOG_ERROR,
>                             "Invalid mix of idr and non-idr slices\n");
> -                    buf_index = -1;
> +                    ret = -1;
>                      goto end;
>                  }
>                  idr(h); // FIXME ensure we don't lose some frames if there 
> is reordering
> @@ -4570,8 +4598,8 @@ again:
>                  break;
>              case NAL_SPS:
>                  init_get_bits(&h->gb, ptr, bit_length);
> -                if (ff_h264_decode_seq_parameter_set(h) < 0 &&
> -                    h->is_avc && (nalsize != consumed) && nalsize) {
> +                ret = ff_h264_decode_seq_parameter_set(h);
> +                if (ret < 0 && h->is_avc && (nalsize != consumed) && 
> nalsize) {
>                      av_log(h->avctx, AV_LOG_DEBUG,
>                             "SPS decoding failure, trying again with the 
> complete NAL\n");
>                      init_get_bits(&h->gb, buf + buf_index + 1 - consumed,
> @@ -4579,10 +4607,10 @@ again:
>                      ff_h264_decode_seq_parameter_set(h);
>                  }
>
> -                if (h264_set_parameter_from_sps(h) < 0) {
> -                    buf_index = -1;
> +                ret = h264_set_parameter_from_sps(h);
> +                if (ret < 0)
>                      goto end;
> -                }
> +
>                  break;
>              case NAL_PPS:
>                  init_get_bits(&h->gb, ptr, bit_length);
> @@ -4631,7 +4659,7 @@ end:
>                                    h->picture_structure == PICT_BOTTOM_FIELD);
>      }
>
> -    return buf_index;
> +    return (ret < 0) ? ret : buf_index;
>  }
>
>  /**
> @@ -4715,7 +4743,7 @@ out:
>
>      buf_index = decode_nal_units(h, buf, buf_size, 0);
>      if (buf_index < 0)
> -        return -1;
> +        return AVERROR_INVALIDDATA;
>
>      if (!h->cur_pic_ptr && h->nal_unit_type == NAL_END_SEQUENCE) {
>          buf_size = 0;
> @@ -4726,7 +4754,7 @@ out:
>          if (avctx->skip_frame >= AVDISCARD_NONREF)
>              return 0;
>          av_log(avctx, AV_LOG_ERROR, "no frame!\n");
> -        return -1;
> +        return AVERROR_INVALIDDATA;
>      }
>
>      if (!(avctx->flags2 & CODEC_FLAG2_CHUNKS) ||
> --
> 1.7.9.5
>
> _______________________________________________
> libav-devel mailing list
> [email protected]
> https://lists.libav.org/mailman/listinfo/libav-devel
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to