X-Git-Url: http://git.tuebingen.mpg.de/?a=blobdiff_plain;f=mp4.c;h=c77cedd2bd2fb586a715b12c5808f7691bc35c57;hb=8e2a58f85f68077944bb5739f2327353a502ed70;hp=71858305517cac98f2093050749dbadb1d0d94a1;hpb=623699153a7718e29d6571a9fea1b96244813ef9;p=paraslash.git diff --git a/mp4.c b/mp4.c index 71858305..c77cedd2 100644 --- a/mp4.c +++ b/mp4.c @@ -14,7 +14,6 @@ #include "mp4.h" struct mp4_track { - bool is_audio; uint16_t channelCount; uint16_t sampleRate; @@ -26,13 +25,11 @@ struct mp4_track { /* stts */ uint32_t stts_entry_count; uint32_t *stts_sample_count; - uint32_t *stts_sample_delta; /* stsc */ uint32_t stsc_entry_count; uint32_t *stsc_first_chunk; uint32_t *stsc_samples_per_chunk; - uint32_t *stsc_sample_desc_index; /* stsc */ uint32_t stco_entry_count; @@ -57,6 +54,8 @@ struct mp4 { int32_t total_tracks; /* track data */ struct mp4_track *track[MAX_TRACKS]; + /* the first audio track found */ + struct mp4_track *audio_track; /* metadata */ struct mp4_metadata meta; @@ -492,13 +491,11 @@ static int read_stts(struct mp4 *f) return ret; t->stts_sample_count = para_malloc(t->stts_entry_count * sizeof(int32_t)); - t->stts_sample_delta = para_malloc(t->stts_entry_count - * sizeof (int32_t)); for (i = 0; i < t->stts_entry_count; i++) { ret = read_int32(f, &t->stts_sample_count[i]); if (ret <= 0) return ret; - ret = read_int32(f, &t->stts_sample_delta[i]); + ret = read_int32(f, NULL); /* sample delta */ if (ret <= 0) return ret; } @@ -527,9 +524,6 @@ static int read_stsc(struct mp4 *f) t->stsc_first_chunk = para_malloc(t->stsc_entry_count * sizeof(int32_t)); t->stsc_samples_per_chunk = para_malloc(t->stsc_entry_count * sizeof (int32_t)); - t->stsc_sample_desc_index = para_malloc(t->stsc_entry_count * - sizeof (int32_t)); - for (i = 0; i < t->stsc_entry_count; i++) { ret = read_int32(f, &t->stsc_first_chunk[i]); if (ret <= 0) @@ -537,7 +531,7 @@ static int read_stsc(struct mp4 *f) ret = read_int32(f, &t->stsc_samples_per_chunk[i]); if (ret <= 0) return ret; - ret = read_int32(f, &t->stsc_sample_desc_index[i]); + ret = read_int32(f, NULL); /* sample desc index */ if (ret <= 0) return ret; } @@ -647,9 +641,10 @@ static int read_stsd(struct mp4 *f) if (ret <= 0) return ret; skip += size; - t->is_audio = atom_type == ATOM_MP4A; - if (t->is_audio) + if (!f->audio_track && atom_type == ATOM_MP4A) { + f->audio_track = t; read_mp4a(f); + } set_position(f, skip); } return 1; @@ -933,12 +928,16 @@ static int parse_atoms(struct mp4 *f, int meta_only) } else if (atom_type < SUBATOMIC) { ret = parse_sub_atoms(f, size - header_size, meta_only); if (ret <= 0) - return ret; + break; } else { /* skip this atom */ set_position(f, get_position(f) + size - header_size); } } + if (ret < 0) + return ret; + if (!f->audio_track) + return -E_MP4_TRACK; return ret; } @@ -964,10 +963,8 @@ void mp4_close(struct mp4 *f) if (f->track[i]) { free(f->track[i]->stsz_table); free(f->track[i]->stts_sample_count); - free(f->track[i]->stts_sample_delta); free(f->track[i]->stsc_first_chunk); free(f->track[i]->stsc_samples_per_chunk); - free(f->track[i]->stsc_sample_desc_index); free(f->track[i]->stco_chunk_offset); free(f->track[i]); } @@ -980,10 +977,10 @@ void mp4_close(struct mp4 *f) free(f); } -static int32_t chunk_of_sample(const struct mp4 *f, int32_t track, - int32_t sample, int32_t *chunk) +static int32_t chunk_of_sample(const struct mp4 *f, int32_t sample, + int32_t *chunk) { - const struct mp4_track *t = f->track[track]; + const struct mp4_track *t = f->audio_track; uint32_t *fc = t->stsc_first_chunk, *spc = t->stsc_samples_per_chunk; int32_t chunk1, chunk1samples, n, total, i; @@ -1002,51 +999,28 @@ static int32_t chunk_of_sample(const struct mp4 *f, int32_t track, } /** - * Return the number of milliseconds of the given track. + * Return the number of milliseconds of the audio 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_get_total_tracks(). - * - * The function returns zero if the audio file is of zero length or contains a - * corrupt track header. */ -uint64_t mp4_get_duration(const struct mp4 *f, int32_t track) +uint64_t mp4_get_duration(const struct mp4 *f) { - const struct mp4_track *t = f->track[track]; + const struct mp4_track *t = f->audio_track; if (t->timeScale == 0) return 0; return t->duration * 1000 / t->timeScale; } -int32_t mp4_get_total_tracks(const struct mp4 *f) +int mp4_set_sample_position(struct mp4 *f, int32_t sample) { - return f->total_tracks; -} - -/** - * Check whether the given track number corresponds to an audio track. - * - * \param f See \ref mp4_get_duration(). - * \param track See \ref mp4_get_duration(). - * - * Besides audio tracks, an mp4 file may contain video and system tracks. For - * those the function returns false. - */ -bool mp4_is_audio_track(const struct mp4 *f, int32_t track) -{ - return f->track[track]->is_audio; -} - -int mp4_set_sample_position(struct mp4 *f, uint32_t track, int32_t sample) -{ - const struct mp4_track *t = f->track[track]; + const struct mp4_track *t = f->audio_track; int32_t offset, chunk, chunk_sample; uint32_t n, srs; /* sample range size */ - if (sample >= t->stsz_sample_count || track >= f->total_tracks) + if (sample >= t->stsz_sample_count) return -ERRNO_TO_PARA_ERROR(EINVAL); - chunk_sample = chunk_of_sample(f, track, sample, &chunk); + chunk_sample = chunk_of_sample(f, sample, &chunk); if (t->stsz_sample_size > 0) srs = (sample - chunk_sample) * t->stsz_sample_size; else { @@ -1063,33 +1037,33 @@ int mp4_set_sample_position(struct mp4 *f, uint32_t track, int32_t sample) return 1; } -int32_t mp4_get_sample_size(const struct mp4 *f, int track, int sample) +int32_t mp4_get_sample_size(const struct mp4 *f, int sample) { - const struct mp4_track *t = f->track[track]; + const struct mp4_track *t = f->audio_track; if (t->stsz_sample_size != 0) return t->stsz_sample_size; return t->stsz_table[sample]; } -uint32_t mp4_get_sample_rate(const struct mp4 *f, int32_t track) +uint32_t mp4_get_sample_rate(const struct mp4 *f) { - return f->track[track]->sampleRate; + return f->audio_track->sampleRate; } -uint32_t mp4_get_channel_count(const struct mp4 *f, int32_t track) +uint32_t mp4_get_channel_count(const struct mp4 *f) { - return f->track[track]->channelCount; + return f->audio_track->channelCount ; } -int32_t mp4_num_samples(const struct mp4 *f, int32_t track) +int32_t mp4_num_samples(const struct mp4 *f) { + const struct mp4_track *t = f->audio_track; int32_t i; int32_t total = 0; - for (i = 0; i < f->track[track]->stts_entry_count; i++) { - total += f->track[track]->stts_sample_count[i]; - } + for (i = 0; i < t->stts_entry_count; i++) + total += t->stts_sample_count[i]; return total; }