Merge commit 'b3dc260e7fa6f3f852dd5cb7d86763c4b5736714'
authorMichael Niedermayer <michaelni@gmx.at>
Sun, 11 Aug 2013 08:08:48 +0000 (10:08 +0200)
committerMichael Niedermayer <michaelni@gmx.at>
Sun, 11 Aug 2013 08:08:48 +0000 (10:08 +0200)
* commit 'b3dc260e7fa6f3f852dd5cb7d86763c4b5736714':
  h264: return meaningful values

Conflicts:
libavcodec/h264.c

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

@@@ -1400,22 -1364,20 +1400,23 @@@ fail
  static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size,
                              int parse_extradata);
  
 -int ff_h264_decode_extradata(H264Context *h)
 +int ff_h264_decode_extradata(H264Context *h, const uint8_t *buf, int size)
  {
      AVCodecContext *avctx = h->avctx;
+     int ret;
  
 -    if (avctx->extradata[0] == 1) {
 +    if (!buf || size <= 0)
 +        return -1;
 +
 +    if (buf[0] == 1) {
          int i, cnt, nalsize;
 -        unsigned char *p = avctx->extradata;
 +        const unsigned char *p = buf;
  
          h->is_avc = 1;
  
 -        if (avctx->extradata_size < 7) {
 +        if (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 */
          p  += 6;
          for (i = 0; i < cnt; i++) {
              nalsize = AV_RB16(p) + 2;
 -            if (p - avctx->extradata + nalsize > avctx->extradata_size)
 +            if(nalsize > size - (p-buf))
-                 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;
          }
          cnt = *(p++); // Number of pps
          for (i = 0; i < cnt; i++) {
              nalsize = AV_RB16(p) + 2;
 -            if (p - avctx->extradata + nalsize > avctx->extradata_size)
 +            if(nalsize > size - (p-buf))
-                 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;
          }
          // Now store right nal length size, that will be used to parse all other nals
 -        h->nal_length_size = (avctx->extradata[4] & 0x03) + 1;
 +        h->nal_length_size = (buf[4] & 0x03) + 1;
      } else {
          h->is_avc = 0;
-         if (decode_nal_units(h, buf, size, 1) < 0)
-             return -1;
 -        ret = decode_nal_units(h, avctx->extradata, avctx->extradata_size, 1);
++        ret = decode_nal_units(h, buf, size, 1);
+         if (ret < 0)
+             return ret;
      }
 -    return 0;
 +    return size;
  }
  
  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, avctx->extradata, avctx->extradata_size) < 0) {
-         ff_h264_free_context(h);
-         return -1;
+     if (avctx->extradata_size > 0 && avctx->extradata) {
 -       ret = ff_h264_decode_extradata(h);
 -       if (ret < 0)
 -           return ret;
++        ret = ff_h264_decode_extradata(h, avctx->extradata, avctx->extradata_size);
++        if (ret < 0) {
++            ff_h264_free_context(h);
++            return ret;
++        }
      }
  
      if (h->sps.bitstream_restriction_flag &&
@@@ -1690,19 -1632,12 +1697,20 @@@ static int decode_update_thread_context
          h->ref_index_pool    = NULL;
          h->motion_val_pool   = NULL;
  
-         if (ff_h264_alloc_tables(h) < 0) {
 +        if (h1->context_initialized) {
 +        h->context_initialized = 0;
 +
 +        memset(&h->cur_pic, 0, sizeof(h->cur_pic));
 +        avcodec_get_frame_defaults(&h->cur_pic.f);
 +        h->cur_pic.tf.f = &h->cur_pic.f;
 +
+         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;
          }
          context_init(h);
 +        }
  
          for (i = 0; i < 2; i++) {
              h->rbsp_buffer[i]      = NULL;
@@@ -3227,8 -3150,8 +3237,8 @@@ static int decode_slice_header(H264Cont
      if (slice_type > 9) {
          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);
 +               slice_type, h->mb_x, h->mb_y);
-         return -1;
+         return AVERROR_INVALIDDATA;
      }
      if (slice_type > 4) {
          slice_type -= 5;
  
      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");
 +        av_log(h->avctx, AV_LOG_ERROR, "pps_id %d out of range\n", pps_id);
-         return -1;
+         return AVERROR_INVALIDDATA;
      }
      if (!h0->pps_buffers[pps_id]) {
          av_log(h->avctx, AV_LOG_ERROR,
          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)
 +        if ((ret = get_pixel_format(h, 1)) < 0)
              return ret;
          h->avctx->pix_fmt = ret;
  
              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;
 +            if (!h->sps.gaps_in_frame_num_allowed_flag)
 +                for(i=0; i<FF_ARRAY_ELEMS(h->last_pocs); i++)
 +                    h->last_pocs[i] = INT_MIN;
+             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;
          h->list_count   = 0;
          h->ref_count[0] = h->ref_count[1] = 0;
      }
 -
 -    max_refs = h->picture_structure == PICT_FRAME ? 16 : 32;
 -
 -    if (h->ref_count[0] > max_refs || h->ref_count[1] > max_refs) {
 -        av_log(h->avctx, AV_LOG_ERROR, "reference overflow\n");
 -        h->ref_count[0] = h->ref_count[1] = 0;
 -        return AVERROR_INVALIDDATA;
 -    }
 -
 -    if (!default_ref_list_done)
 +    if (slice_type != AV_PICTURE_TYPE_I &&
 +        (h0->current_slice == 0 ||
 +         slice_type != h0->last_slice_type ||
 +         memcmp(h0->last_ref_count, h0->ref_count, sizeof(h0->ref_count)))) {
          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) ||
@@@ -4410,10 -4266,10 +4424,10 @@@ static int decode_slice(struct AVCodecC
                          return 0;
                      } else {
                          er_add_slice(h, h->resync_mb_x, h->resync_mb_y,
 -                                     h->mb_x - 1, h->mb_y,
 +                                     h->mb_x, h->mb_y,
                                       ER_MB_END);
  
-                         return -1;
+                         return AVERROR_INVALIDDATA;
                      }
                  }
              }
@@@ -4497,13 -4348,8 +4512,14 @@@ static int decode_nal_units(H264Contex
      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 idr_cleared=0;
 +    int first_slice = 0;
+     int ret = 0;
  
 +    h->nal_unit_type= 0;
 +
 +    if(!h->slice_context_count)
 +         h->slice_context_count= 1;
      h->max_contexts = h->slice_context_count;
      if (!(avctx->flags2 & CODEC_FLAG2_CHUNKS)) {
          h->current_slice = 0;
                  continue;
  
  again:
 -            /* Ignore every NAL unit type except PPS and SPS during extradata
 +            /* Ignore per frame NAL unit type during extradata
               * parsing. Decoding slices is not possible in codec init
               * with frame-mt */
 -            if (parse_extradata && HAVE_THREADS &&
 -                (h->avctx->active_thread_type & FF_THREAD_FRAME) &&
 -                (hx->nal_unit_type != NAL_PPS &&
 -                 hx->nal_unit_type != NAL_SPS)) {
 -                av_log(avctx, AV_LOG_INFO, "Ignoring NAL unit %d during "
 -                       "extradata parsing\n", hx->nal_unit_type);
 -                hx->nal_unit_type = NAL_FF_IGNORE;
 +            if (parse_extradata) {
 +                switch (hx->nal_unit_type) {
 +                case NAL_IDR_SLICE:
 +                case NAL_SLICE:
 +                case NAL_DPA:
 +                case NAL_DPB:
 +                case NAL_DPC:
 +                case NAL_AUXILIARY_SLICE:
 +                    av_log(h->avctx, AV_LOG_WARNING, "Ignoring NAL %d in global header/extradata\n", hx->nal_unit_type);
 +                    hx->nal_unit_type = NAL_FF_IGNORE;
 +                }
              }
 +
              err = 0;
 +
              switch (hx->nal_unit_type) {
              case NAL_IDR_SLICE:
 -                if (h->nal_unit_type != NAL_IDR_SLICE) {
 +                if (first_slice != 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
 +                if(!idr_cleared)
 +                    idr(h); // FIXME ensure we don't lose some frames if there is reordering
 +                idr_cleared = 1;
              case NAL_SLICE:
                  init_get_bits(&hx->gb, ptr, bit_length);
                  hx->intra_gb_ptr      =
@@@ -4929,19 -4703,18 +4946,19 @@@ not_extra
  
      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;
 +        av_assert0(buf_index <= buf_size);
          goto out;
      }
  
      if (!(avctx->flags2 & CODEC_FLAG2_CHUNKS) && !h->cur_pic_ptr) {
 -        if (avctx->skip_frame >= AVDISCARD_NONREF)
 -            return 0;
 +        if (avctx->skip_frame >= AVDISCARD_NONREF ||
 +            buf_size >= 4 && !memcmp("Q264", buf, 4))
 +            return buf_size;
          av_log(avctx, AV_LOG_ERROR, "no frame!\n");
-         return -1;
+         return AVERROR_INVALIDDATA;
      }
  
      if (!(avctx->flags2 & CODEC_FLAG2_CHUNKS) ||