const void *map;
size_t mapsize;
size_t fpos;
- int32_t track;
struct mp4 *mp4;
struct mp4_callback cb;
};
return 0;
}
-static int32_t aac_afh_get_track(struct mp4 *mp4)
-{
- int32_t i, num_tracks = mp4_get_total_tracks(mp4);
-
- assert(num_tracks >= 0);
- for (i = 0; i < num_tracks; i++)
- if (mp4_is_audio_track(mp4, i))
- return i;
- return -E_MP4_TRACK; /* no audio track */
-}
-
static int aac_afh_open(const void *map, size_t mapsize, void **afh_context)
{
int ret;
c->mp4 = mp4_open_read(&c->cb);
if (!c->mp4)
goto free_ctx;
- ret = aac_afh_get_track(c->mp4);
- if (ret < 0)
- goto close_mp4;
- c->track = ret;
*afh_context = c;
return 0;
-close_mp4:
- mp4_close(c->mp4);
free_ctx:
free(c);
*afh_context = NULL;
size_t offset;
int ret;
- ret = mp4_set_sample_position(c->mp4, c->track, chunk_num);
+ ret = mp4_set_sample_position(c->mp4, chunk_num);
if (ret < 0)
return ret;
offset = c->fpos;
- ss = mp4_get_sample_size(c->mp4, c->track, chunk_num);
+ ss = mp4_get_sample_size(c->mp4, chunk_num);
if (ss <= 0)
return -E_MP4_BAD_SAMPLE;
assert(ss + offset <= c->mapsize);
return ret;
ret = -E_MP4_BAD_SAMPLERATE;
- rv = mp4_get_sample_rate(c->mp4, c->track);
+ rv = mp4_get_sample_rate(c->mp4);
if (rv <= 0)
goto close;
afhi->frequency = rv;
ret = -E_MP4_BAD_CHANNEL_COUNT;
- rv = mp4_get_channel_count(c->mp4, c->track);
+ rv = mp4_get_channel_count(c->mp4);
if (rv <= 0)
goto close;
afhi->channels = rv;
ret = -E_MP4_BAD_SAMPLE_COUNT;
- rv = mp4_num_samples(c->mp4, c->track);
+ rv = mp4_num_samples(c->mp4);
if (rv <= 0)
goto close;
afhi->chunks_total = rv;
break;
afhi->max_chunk_size = PARA_MAX(afhi->max_chunk_size, len);
}
- milliseconds = mp4_get_duration(c->mp4, c->track);
+ milliseconds = mp4_get_duration(c->mp4);
afhi->seconds_total = milliseconds / 1000;
ms2tv(milliseconds / afhi->chunks_total, &afhi->chunk_tv);
if (aac_afh_get_chunk(0, c, &buf, &len) >= 0)
#include "mp4.h"
struct mp4_track {
- bool is_audio;
uint16_t channelCount;
uint16_t sampleRate;
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;
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;
} 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;
}
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;
}
/**
- * 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 {
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;
}
struct mp4; /* opaque */
-int mp4_set_sample_position(struct mp4 *f, uint32_t track, int32_t sample);
-int32_t mp4_get_total_tracks(const struct mp4 *f);
-bool mp4_is_audio_track(const struct mp4 *f, int32_t track);
+int mp4_set_sample_position(struct mp4 *f, int32_t sample);
struct mp4 *mp4_open_read(const struct mp4_callback *cb);
void mp4_close(struct mp4 *f);
-int32_t mp4_get_sample_size(const struct mp4 *f, int track, int sample);
-uint32_t mp4_get_sample_rate(const struct mp4 *f, int32_t track);
-uint32_t mp4_get_channel_count(const struct mp4 * f, int32_t track);
-int32_t mp4_num_samples(const struct mp4 *f, int track);
-uint64_t mp4_get_duration(const struct mp4 *f, int32_t track);
+int32_t mp4_get_sample_size(const struct mp4 *f, int sample);
+uint32_t mp4_get_sample_rate(const struct mp4 *f);
+uint32_t mp4_get_channel_count(const struct mp4 * f);
+int32_t mp4_num_samples(const struct mp4 *f);
+uint64_t mp4_get_duration(const struct mp4 *f);
struct mp4 *mp4_open_meta(const struct mp4_callback *cb);
struct mp4_metadata *mp4_get_meta(struct mp4 *f);