Merge commit '8d929afd256069aa881f2bf58ef9f0ffce2d6b7e'
authorMichael Niedermayer <michaelni@gmx.at>
Sun, 16 Jun 2013 20:51:56 +0000 (22:51 +0200)
committerMichael Niedermayer <michaelni@gmx.at>
Sun, 16 Jun 2013 20:51:56 +0000 (22:51 +0200)
* commit '8d929afd256069aa881f2bf58ef9f0ffce2d6b7e':
  h264_mp4toannexb_bsf: factor out extradata parsing

Conflicts:
libavcodec/h264_mp4toannexb_bsf.c

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

@@@ -58,6 -58,79 +58,72 @@@ static int alloc_and_copy(uint8_t **pou
      return 0;
  }
  
 -    if (length_size == 3)
 -        return AVERROR(EINVAL);
 -
+ static int h264_extradata_to_annexb(AVCodecContext *avctx, const int padding)
+ {
+     uint16_t unit_size;
+     uint64_t total_size                 = 0;
+     uint8_t *out                        = NULL, unit_nb, sps_done = 0,
+              sps_seen                   = 0, pps_seen = 0;
+     const uint8_t *extradata            = avctx->extradata + 4;
+     static const uint8_t nalu_header[4] = { 0, 0, 0, 1 };
+     int length_size = (*extradata++ & 0x3) + 1; // retrieve length coded size
 -        unit_nb = *extradata++; /* number of pps unit(s) */
 -        sps_done++;
 -
 -        if (unit_nb)
 -            pps_seen = 1;
+     /* retrieve sps and pps unit(s) */
+     unit_nb = *extradata++ & 0x1f; /* number of sps unit(s) */
+     if (!unit_nb) {
 -
++        goto pps;
+     } else {
+         sps_seen = 1;
+     }
+     while (unit_nb--) {
+         void *tmp;
+         unit_size   = AV_RB16(extradata);
+         total_size += unit_size + 4;
+         if (total_size > INT_MAX - padding ||
+             extradata + 2 + unit_size > avctx->extradata +
+             avctx->extradata_size) {
+             av_free(out);
+             return AVERROR(EINVAL);
+         }
+         tmp = av_realloc(out, total_size + padding);
+         if (!tmp) {
+             av_free(out);
+             return AVERROR(ENOMEM);
+         }
+         out = tmp;
+         memcpy(out + total_size - unit_size - 4, nalu_header, 4);
+         memcpy(out + total_size - unit_size, extradata + 2, unit_size);
+         extradata += 2 + unit_size;
++pps:
+         if (!unit_nb && !sps_done++) {
+             unit_nb = *extradata++; /* number of pps unit(s) */
+             if (unit_nb)
+                 pps_seen = 1;
+         }
+     }
+     if (out)
+         memset(out + total_size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
+     if (!sps_seen)
+         av_log(avctx, AV_LOG_WARNING,
+                "Warning: SPS NALU missing or invalid. "
+                "The resulting stream may not play.\n");
+     if (!pps_seen)
+         av_log(avctx, AV_LOG_WARNING,
+                "Warning: PPS NALU missing or invalid. "
+                "The resulting stream may not play.\n");
+     av_free(avctx->extradata);
+     avctx->extradata      = out;
+     avctx->extradata_size = total_size;
+     return length_size;
+ }
  static int h264_mp4toannexb_filter(AVBitStreamFilterContext *bsfc,
                                     AVCodecContext *avctx, const char *args,
                                     uint8_t **poutbuf, int *poutbuf_size,