Merge commit 'e7a44f87d07655ec0cd31c315936931674434340'
[ffmpeg.git] / libavformat / 4xm.c
index e147a93..a11ce0e 100644 (file)
@@ -72,8 +72,6 @@ typedef struct AudioTrack {
 } AudioTrack;
 
 typedef struct FourxmDemuxContext {
-    int width;
-    int height;
     int video_stream_index;
     int track_count;
     AudioTrack *tracks;
@@ -91,6 +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;
@@ -100,7 +197,6 @@ static int fourxm_read_header(AVFormatContext *s)
     FourxmDemuxContext *fourxm = s->priv_data;
     unsigned char *header;
     int i, ret;
-    AVStream *st;
 
     fourxm->track_count = 0;
     fourxm->tracks      = NULL;
@@ -140,104 +236,15 @@ static int fourxm_read_header(AVFormatContext *s)
             }
             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) {
-            int current_track;
-            /* check that there is enough data */
-            if (size != strk_SIZE) {
-                ret= AVERROR_INVALIDDATA;
-                goto fail;
-            }
-            current_track = AV_RL32(&header[i + 8]);
-            if((unsigned)current_track >= UINT_MAX / sizeof(AudioTrack) - 1){
-                av_log(s, AV_LOG_ERROR, "current_track too large\n");
-                ret = AVERROR_INVALIDDATA;
-                goto fail;
-            }
-            if (current_track + 1 > fourxm->track_count) {
-                fourxm->tracks = av_realloc_f(fourxm->tracks,
-                                              sizeof(AudioTrack),
-                                              current_track + 1);
-                if (!fourxm->tracks) {
-                    ret = AVERROR(ENOMEM);
-                    goto fail;
-                }
-                memset(&fourxm->tracks[fourxm->track_count], 0,
-                       sizeof(AudioTrack) * (current_track + 1 - fourxm->track_count));
-                fourxm->track_count = current_track + 1;
-            }
-            fourxm->tracks[current_track].adpcm       = AV_RL32(&header[i + 12]);
-            fourxm->tracks[current_track].channels    = AV_RL32(&header[i + 36]);
-            fourxm->tracks[current_track].sample_rate = AV_RL32(&header[i + 40]);
-            fourxm->tracks[current_track].bits        = AV_RL32(&header[i + 44]);
-            fourxm->tracks[current_track].audio_pts   = 0;
-            if (fourxm->tracks[current_track].channels    <= 0 ||
-                fourxm->tracks[current_track].sample_rate <= 0 ||
-                fourxm->tracks[current_track].bits        < 0) {
-                av_log(s, AV_LOG_ERROR, "audio header invalid\n");
-                ret = AVERROR_INVALIDDATA;
+            if ((ret = parse_strk(s, fourxm, header + i, size)) < 0)
                 goto fail;
-            }
-            if(!fourxm->tracks[current_track].adpcm && fourxm->tracks[current_track].bits<8){
-                av_log(s, AV_LOG_ERROR, "bits unspecified for non ADPCM\n");
-                ret = AVERROR_INVALIDDATA;
-                goto fail;
-            }
-            i += 8 + size;
-
-            /* allocate a new AVStream */
-            st = avformat_new_stream(s, NULL);
-            if (!st) {
-                ret = AVERROR(ENOMEM);
-                goto fail;
-            }
 
-            st->id = current_track;
-            avpriv_set_pts_info(st, 60, 1,
-                                fourxm->tracks[current_track].sample_rate);
-
-            fourxm->tracks[current_track].stream_index = st->index;
-
-            st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
-            st->codec->codec_tag = 0;
-            st->codec->channels              = fourxm->tracks[current_track].channels;
-            st->codec->sample_rate           = fourxm->tracks[current_track].sample_rate;
-            st->codec->bits_per_coded_sample = fourxm->tracks[current_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[current_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;
+            i += 8 + size;
         }
     }