Merge commit 'e7a44f87d07655ec0cd31c315936931674434340'
authorMichael Niedermayer <michaelni@gmx.at>
Thu, 13 Jun 2013 08:08:50 +0000 (10:08 +0200)
committerMichael Niedermayer <michaelni@gmx.at>
Thu, 13 Jun 2013 08:08:50 +0000 (10:08 +0200)
* commit 'e7a44f87d07655ec0cd31c315936931674434340':
  4xm: refactor fourxm_read_header

Conflicts:
libavformat/4xm.c

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

@@@ -417,10 -395,10 +417,12 @@@ static int decode_p_frame(FourXContext 
      unsigned int bitstream_size, bytestream_size, wordstream_size, extra,
                   bytestream_offset, wordstream_offset;
  
+     src = (uint16_t *)f->last_picture->data[0];
      if (f->version > 1) {
          extra           = 20;
 +        if (length < extra)
 +            return -1;
          bitstream_size  = AV_RL32(buf + 8);
          wordstream_size = AV_RL32(buf + 12);
          bytestream_size = AV_RL32(buf + 16);
@@@ -91,6 -89,96 +89,105 @@@ static int fourxm_probe(AVProbeData *p
      return AVPROBE_SCORE_MAX;
  }
  
+ static int parse_vtrk(AVFormatContext *s,
+                       FourxmDemuxContext *fourxm, uint8_t *buf, int size)
+ {
+     AVStream *st;
+     /* check that there is enough data */
+     if (size != vtrk_SIZE) {
+         return AVERROR_INVALIDDATA;
+     }
+     /* allocate a new AVStream */
+     st = avformat_new_stream(s, NULL);
+     if (!st)
+         return AVERROR(ENOMEM);
+     avpriv_set_pts_info(st, 60, 1, fourxm->fps);
+     fourxm->video_stream_index = st->index;
+     st->codec->codec_type     = AVMEDIA_TYPE_VIDEO;
+     st->codec->codec_id       = AV_CODEC_ID_4XM;
+     st->codec->extradata_size = 4;
+     st->codec->extradata      = av_malloc(4);
+     AV_WL32(st->codec->extradata, AV_RL32(buf + 16));
+     st->codec->width  = AV_RL32(buf + 36);
+     st->codec->height = AV_RL32(buf + 40);
+     return 0;
+ }
+ static int parse_strk(AVFormatContext *s,
+                       FourxmDemuxContext *fourxm, uint8_t *buf, int size)
+ {
+     AVStream *st;
+     int track;
+     /* check that there is enough data */
+     if (size != strk_SIZE)
+         return AVERROR_INVALIDDATA;
+     track = AV_RL32(buf + 8);
++    if ((unsigned)track >= UINT_MAX / sizeof(AudioTrack) - 1) {
++        av_log(s, AV_LOG_ERROR, "current_track too large\n");
++        return AVERROR_INVALIDDATA;
++    }
+     if (track + 1 > fourxm->track_count) {
+         if (av_reallocp_array(&fourxm->tracks, track + 1, sizeof(AudioTrack)))
+             return AVERROR(ENOMEM);
+         memset(&fourxm->tracks[fourxm->track_count], 0,
+                sizeof(AudioTrack) * (track + 1 - fourxm->track_count));
+         fourxm->track_count = track + 1;
+     }
+     fourxm->tracks[track].adpcm       = AV_RL32(buf + 12);
+     fourxm->tracks[track].channels    = AV_RL32(buf + 36);
+     fourxm->tracks[track].sample_rate = AV_RL32(buf + 40);
+     fourxm->tracks[track].bits        = AV_RL32(buf + 44);
+     fourxm->tracks[track].audio_pts   = 0;
+     if (fourxm->tracks[track].channels    <= 0 ||
+         fourxm->tracks[track].sample_rate <= 0 ||
+         fourxm->tracks[track].bits        < 0) {
+         av_log(s, AV_LOG_ERROR, "audio header invalid\n");
+         return AVERROR_INVALIDDATA;
+     }
++    if (!fourxm->tracks[track].adpcm && fourxm->tracks[track].bits<8) {
++        av_log(s, AV_LOG_ERROR, "bits unspecified for non ADPCM\n");
++        return AVERROR_INVALIDDATA;
++    }
++
+     /* allocate a new AVStream */
+     st = avformat_new_stream(s, NULL);
+     if (!st)
+         return AVERROR(ENOMEM);
+     st->id = track;
+     avpriv_set_pts_info(st, 60, 1, fourxm->tracks[track].sample_rate);
+     fourxm->tracks[track].stream_index = st->index;
+     st->codec->codec_type            = AVMEDIA_TYPE_AUDIO;
+     st->codec->codec_tag             = 0;
+     st->codec->channels              = fourxm->tracks[track].channels;
+     st->codec->sample_rate           = fourxm->tracks[track].sample_rate;
+     st->codec->bits_per_coded_sample = fourxm->tracks[track].bits;
+     st->codec->bit_rate              = st->codec->channels *
+                                        st->codec->sample_rate *
+                                        st->codec->bits_per_coded_sample;
+     st->codec->block_align           = st->codec->channels *
+                                        st->codec->bits_per_coded_sample;
+     if (fourxm->tracks[track].adpcm){
+         st->codec->codec_id = AV_CODEC_ID_ADPCM_4XM;
+     } else if (st->codec->bits_per_coded_sample == 8) {
+         st->codec->codec_id = AV_CODEC_ID_PCM_U8;
+     } else
+         st->codec->codec_id = AV_CODEC_ID_PCM_S16LE;
+     return 0;
+ }
  static int fourxm_read_header(AVFormatContext *s)
  {
      AVIOContext *pb = s->pb;
      for (i = 0; i < header_size - 8; i++) {
          fourcc_tag = AV_RL32(&header[i]);
          size       = AV_RL32(&header[i + 4]);
 +        if (size > header_size - i - 8 && (fourcc_tag == vtrk_TAG || fourcc_tag == strk_TAG)) {
 +            av_log(s, AV_LOG_ERROR, "chunk larger than array %d>%d\n", size, header_size - i - 8);
 +            return AVERROR_INVALIDDATA;
 +        }
  
          if (fourcc_tag == std__TAG) {
 +            if (header_size < i + 16) {
 +                av_log(s, AV_LOG_ERROR, "std TAG truncated\n");
 +                return AVERROR_INVALIDDATA;
 +            }
              fourxm->fps = av_int2float(AV_RL32(&header[i + 12]));
          } else if (fourcc_tag == vtrk_TAG) {
-             /* check that there is enough data */
-             if (size != vtrk_SIZE) {
-                 ret = AVERROR_INVALIDDATA;
+             if ((ret = parse_vtrk(s, fourxm, header + i, size)) < 0)
                  goto fail;
-             }
-             fourxm->width  = AV_RL32(&header[i + 36]);
-             fourxm->height = AV_RL32(&header[i + 40]);
-             /* allocate a new AVStream */
-             st = avformat_new_stream(s, NULL);
-             if (!st) {
-                 ret = AVERROR(ENOMEM);
-                 goto fail;
-             }
-             avpriv_set_pts_info(st, 60, 1, fourxm->fps);
-             fourxm->video_stream_index = st->index;
-             st->codec->codec_type     = AVMEDIA_TYPE_VIDEO;
-             st->codec->codec_id       = AV_CODEC_ID_4XM;
-             st->codec->extradata_size = 4;
-             st->codec->extradata      = av_malloc(4);
-             AV_WL32(st->codec->extradata, AV_RL32(&header[i + 16]));
-             st->codec->width  = fourxm->width;
-             st->codec->height = fourxm->height;
  
              i += 8 + size;
          } else if (fourcc_tag == strk_TAG) {