]> git.tuebingen.mpg.de Git - paraslash.git/blobdiff - mp4.c
mp4: Simplify sample_range_size().
[paraslash.git] / mp4.c
diff --git a/mp4.c b/mp4.c
index 7b5f4694d5afe93d2b5fb96efa46646d6f967420..89d90c7366431ecaa6a7ee64f306be3c09228833 100644 (file)
--- a/mp4.c
+++ b/mp4.c
@@ -52,11 +52,8 @@ struct mp4 {
        uint8_t last_atom;
        uint64_t file_size;
 
-       uint32_t error;
-
        /* incremental track index while reading the file */
        int32_t total_tracks;
-
        /* track data */
        struct mp4_track *track[MAX_TRACKS];
 
@@ -64,11 +61,6 @@ struct mp4 {
        struct mp4_metadata meta;
 };
 
-int32_t mp4_total_tracks(const struct mp4 *f)
-{
-       return f->total_tracks;
-}
-
 /*
  * Returns -1, 0, or 1 on errors/EOF/success. Partial reads followed by EOF or
  * read errors are treated as errors.
@@ -445,18 +437,6 @@ static int32_t set_position(struct mp4 *f, int64_t position)
        return 0;
 }
 
-static void track_add(struct mp4 *f)
-{
-       f->total_tracks++;
-
-       if (f->total_tracks > MAX_TRACKS) {
-               f->total_tracks = 0;
-               f->error++;
-               return;
-       }
-       f->track[f->total_tracks - 1] = para_calloc(sizeof(struct mp4_track));
-}
-
 static int read_stsz(struct mp4 *f)
 {
        int ret;
@@ -904,16 +884,20 @@ static int parse_sub_atoms(struct mp4 *f, uint64_t total_size, int meta_only)
                if (size == 0)
                        return -1;
                counted_size += size;
-               /* we're starting to read a new track, update index,
-                * so that all data and tables get written in the right place
-                */
-               if (atom_type == ATOM_TRAK)
-                       track_add(f);
+               if (atom_type == ATOM_TRAK) {
+                       if (f->total_tracks >= MAX_TRACKS)
+                               return -1;
+                       f->total_tracks++;
+                       f->track[f->total_tracks - 1] = para_calloc(
+                               sizeof(struct mp4_track));
+               }
                /* parse subatoms */
                if (meta_only && !need_parse_when_meta_only(atom_type)) {
                        set_position(f, get_position(f) + size - header_size);
                } else if (atom_type < SUBATOMIC) {
-                       parse_sub_atoms(f, size - header_size, meta_only);
+                       ret = parse_sub_atoms(f, size - header_size, meta_only);
+                       if (ret <= 0)
+                               return ret;
                } else {
                        ret = atom_read(f, size, atom_type);
                        if (ret <= 0)
@@ -924,7 +908,7 @@ static int parse_sub_atoms(struct mp4 *f, uint64_t total_size, int meta_only)
 }
 
 /* parse root atoms */
-static int32_t parse_atoms(struct mp4 *f, int meta_only)
+static int parse_atoms(struct mp4 *f, int meta_only)
 {
        int ret;
        uint64_t size;
@@ -946,7 +930,9 @@ static int32_t parse_atoms(struct mp4 *f, int meta_only)
                if (meta_only && !need_parse_when_meta_only(atom_type)) {
                        set_position(f, get_position(f) + size - header_size);
                } else if (atom_type < SUBATOMIC) {
-                       parse_sub_atoms(f, size - header_size, meta_only);
+                       ret = parse_sub_atoms(f, size - header_size, meta_only);
+                       if (ret <= 0)
+                               return ret;
                } else {
                        /* skip this atom */
                        set_position(f, get_position(f) + size - header_size);
@@ -957,13 +943,14 @@ static int32_t parse_atoms(struct mp4 *f, int meta_only)
 
 struct mp4 *mp4_open_read(const struct mp4_callback *cb)
 {
+       int ret;
        struct mp4 *f = para_calloc(sizeof(struct mp4));
 
        f->cb = cb;
-       parse_atoms(f, 0);
-       if (f->error) {
+       ret = parse_atoms(f, 0);
+       if (ret < 0) {
                free(f);
-               f = NULL;
+               return NULL;
        }
        return f;
 }
@@ -1059,40 +1046,22 @@ static int32_t sample_range_size(const struct mp4 *f, int32_t track,
                int32_t chunk_sample, int32_t sample)
 {
        int32_t i, total;
-       const struct mp4_track *p_track = f->track[track];
-
-       if (p_track->stsz_sample_size) {
-               return (sample - chunk_sample) * p_track->stsz_sample_size;
-       } else {
-               if (sample >= p_track->stsz_sample_count)
-                       return 0;       //error
-
-               for (i = chunk_sample, total = 0; i < sample; i++) {
-                       total += p_track->stsz_table[i];
-               }
-       }
+       const struct mp4_track *t = f->track[track];
 
+       if (t->stsz_sample_size)
+               return (sample - chunk_sample) * t->stsz_sample_size;
+       if (sample >= t->stsz_sample_count)
+               return 0; /* error */
+       for (i = chunk_sample, total = 0; i < sample; i++)
+               total += t->stsz_table[i];
        return total;
 }
 
-static int32_t sample_to_offset(const struct mp4 *f, int32_t track,
-               int32_t sample)
-{
-       int32_t chunk, chunk_sample, chunk_offset1, chunk_offset2;
-
-       chunk_of_sample(f, track, sample, &chunk_sample, &chunk);
-
-       chunk_offset1 = chunk_to_offset(f, track, chunk);
-       chunk_offset2 = chunk_offset1 + sample_range_size(f,
-               track, chunk_sample, sample);
-       return chunk_offset2;
-}
-
 /**
  * Return the number of milliseconds of the given track.
  *
  * \param f As returned by \ref mp4_open_read(), must not be NULL.
- * \param track Between zero and the value returned by \ref mp4_total_tracks().
+ * \param track Between zero and the value returned by \ref mp4_get_total_tracks().
  *
  * The function returns zero if the audio file is of zero length or contains a
  * corrupt track header.
@@ -1106,6 +1075,11 @@ uint64_t mp4_get_duration(const struct mp4 *f, int32_t track)
        return t->duration * 1000 / t->timeScale;
 }
 
+int32_t mp4_get_total_tracks(const struct mp4 *f)
+{
+       return f->total_tracks;
+}
+
 /**
  * Check whether the given track number corresponds to an audio track.
  *
@@ -1122,7 +1096,11 @@ bool mp4_is_audio_track(const struct mp4 *f, int32_t track)
 
 void mp4_set_sample_position(struct mp4 *f, int32_t track, int32_t sample)
 {
-       int32_t offset = sample_to_offset(f, track, sample);
+       int32_t offset, chunk, chunk_sample;
+
+       chunk_of_sample(f, track, sample, &chunk_sample, &chunk);
+       offset = chunk_to_offset(f, track, chunk)
+               + sample_range_size(f, track, chunk_sample, sample);
        set_position(f, offset);
 }
 
@@ -1158,13 +1136,14 @@ int32_t mp4_num_samples(const struct mp4 *f, int32_t track)
 
 struct mp4 *mp4_open_meta(const struct mp4_callback *cb)
 {
+       int ret;
        struct mp4 *f = para_calloc(sizeof(struct mp4));
 
        f->cb = cb;
-       parse_atoms(f, 1);
-       if (f->error) {
+       ret = parse_atoms(f, 1);
+       if (ret < 0) {
                free(f);
-               f = NULL;
+               return NULL;
        }
        return f;
 }