#include "string.h"
#include "mp4.h"
+struct mp4ff_track {
+ int32_t type;
+ int32_t channelCount;
+ int32_t sampleSize;
+ uint16_t sampleRate;
+ int32_t audioType;
+
+ /* stsd */
+ int32_t stsd_entry_count;
+
+ /* stsz */
+ int32_t stsz_sample_size;
+ int32_t stsz_sample_count;
+ int32_t *stsz_table;
+
+ /* stts */
+ int32_t stts_entry_count;
+ int32_t *stts_sample_count;
+ int32_t *stts_sample_delta;
+
+ /* stsc */
+ int32_t stsc_entry_count;
+ int32_t *stsc_first_chunk;
+ int32_t *stsc_samples_per_chunk;
+ int32_t *stsc_sample_desc_index;
+
+ /* stsc */
+ int32_t stco_entry_count;
+ int32_t *stco_chunk_offset;
+
+ /* ctts */
+ int32_t ctts_entry_count;
+ int32_t *ctts_sample_count;
+ int32_t *ctts_sample_offset;
+
+ /* esde */
+ uint8_t *decoderConfig;
+ int32_t decoderConfigLen;
+
+ uint32_t maxBitrate;
+ uint32_t avgBitrate;
+
+ uint32_t timeScale;
+ uint64_t duration;
+};
+
+#define MAX_TRACKS 1024
+
+struct mp4ff {
+ /* stream to read from */
+ struct mp4ff_callback *stream;
+ int64_t current_position;
+
+ uint64_t moov_offset;
+ uint64_t moov_size;
+ uint8_t last_atom;
+ uint64_t file_size;
+ uint32_t error;
+
+ /* mvhd */
+ int32_t time_scale;
+ int32_t duration;
+
+ /* incremental track index while reading the file */
+ int32_t total_tracks;
+
+ /* track data */
+ struct mp4ff_track *track[MAX_TRACKS];
+
+ /* metadata */
+ struct mp4ff_metadata tags;
+};
+
int32_t mp4ff_total_tracks(const struct mp4ff *f)
{
return f->total_tracks;
unsigned error;
};
-#define stricmp strcasecmp
-
static struct membuffer *membuffer_create(void)
{
const unsigned initial_size = 256;
{
unsigned n;
for (n = 0; n < sizeof (ID3v1GenreList) / sizeof (ID3v1GenreList[0]); n++) {
- if (!stricmp(genrestr, ID3v1GenreList[n]))
+ if (!strcasecmp(genrestr, ID3v1GenreList[n]))
return n + 1;
}
return 0;
{
unsigned n;
for (n = 0; n < sizeof (stdmetas) / sizeof (stdmetas[0]); n++) {
- if (!stricmp(name, stdmetas[n].name))
+ if (!strcasecmp(name, stdmetas[n].name))
return stdmetas[n].atom;
}
return 0;
struct membuffer *buf = membuffer_create();
unsigned metaptr;
char *mask = para_calloc(data->count);
- {
- const char *tracknumber_ptr = 0, *totaltracks_ptr = 0;
- const char *discnumber_ptr = 0, *totaldiscs_ptr = 0;
- const char *genre_ptr = 0, *tempo_ptr = 0;
- for (metaptr = 0; metaptr < data->count; metaptr++) {
- struct mp4ff_tag *tag = &data->tags[metaptr];
- if (!stricmp(tag->item, "tracknumber") || !stricmp(tag->item, "track")) {
- if (tracknumber_ptr == 0)
- tracknumber_ptr = tag->value;
- mask[metaptr] = 1;
- } else if (!stricmp(tag->item, "totaltracks")) {
- if (totaltracks_ptr == 0)
- totaltracks_ptr = tag->value;
- mask[metaptr] = 1;
- } else if (!stricmp(tag->item, "discnumber")
- || !stricmp(tag->item, "disc")) {
- if (discnumber_ptr == 0)
- discnumber_ptr = tag->value;
- mask[metaptr] = 1;
- } else if (!stricmp(tag->item, "totaldiscs")) {
- if (totaldiscs_ptr == 0)
- totaldiscs_ptr = tag->value;
- mask[metaptr] = 1;
- } else if (!stricmp(tag->item, "genre")) {
- if (genre_ptr == 0)
- genre_ptr = tag->value;
- mask[metaptr] = 1;
- } else if (!stricmp(tag->item, "tempo")) {
- if (tempo_ptr == 0)
- tempo_ptr = tag->value;
- mask[metaptr] = 1;
- }
-
- }
-
- if (tracknumber_ptr)
- membuffer_write_track_tag(buf, "trkn",
- myatoi(tracknumber_ptr),
- myatoi(totaltracks_ptr));
- if (discnumber_ptr)
- membuffer_write_track_tag(buf, "disk",
- myatoi(discnumber_ptr),
- myatoi(totaldiscs_ptr));
- if (tempo_ptr)
- membuffer_write_int16_tag(buf, "tmpo",
- (uint16_t) myatoi(tempo_ptr));
-
- if (genre_ptr) {
- uint32_t index = meta_genre_to_index(genre_ptr);
- if (index == 0)
- membuffer_write_std_tag(buf, "©gen",
- genre_ptr);
- else
- membuffer_write_int16_tag(buf, "gnre",
- (uint16_t) index);
+ const char *tracknumber_ptr = 0, *totaltracks_ptr = 0;
+ const char *discnumber_ptr = 0, *totaldiscs_ptr = 0;
+ const char *genre_ptr = 0, *tempo_ptr = 0;
+ for (metaptr = 0; metaptr < data->count; metaptr++) {
+ struct mp4ff_tag *tag = &data->tags[metaptr];
+ if (!strcasecmp(tag->item, "tracknumber") || !strcasecmp(tag->item, "track")) {
+ if (tracknumber_ptr == 0)
+ tracknumber_ptr = tag->value;
+ mask[metaptr] = 1;
+ } else if (!strcasecmp(tag->item, "totaltracks")) {
+ if (totaltracks_ptr == 0)
+ totaltracks_ptr = tag->value;
+ mask[metaptr] = 1;
+ } else if (!strcasecmp(tag->item, "discnumber")
+ || !strcasecmp(tag->item, "disc")) {
+ if (discnumber_ptr == 0)
+ discnumber_ptr = tag->value;
+ mask[metaptr] = 1;
+ } else if (!strcasecmp(tag->item, "totaldiscs")) {
+ if (totaldiscs_ptr == 0)
+ totaldiscs_ptr = tag->value;
+ mask[metaptr] = 1;
+ } else if (!strcasecmp(tag->item, "genre")) {
+ if (genre_ptr == 0)
+ genre_ptr = tag->value;
+ mask[metaptr] = 1;
+ } else if (!strcasecmp(tag->item, "tempo")) {
+ if (tempo_ptr == 0)
+ tempo_ptr = tag->value;
+ mask[metaptr] = 1;
}
}
+ if (tracknumber_ptr)
+ membuffer_write_track_tag(buf, "trkn",
+ myatoi(tracknumber_ptr),
+ myatoi(totaltracks_ptr));
+ if (discnumber_ptr)
+ membuffer_write_track_tag(buf, "disk",
+ myatoi(discnumber_ptr),
+ myatoi(totaldiscs_ptr));
+ if (tempo_ptr)
+ membuffer_write_int16_tag(buf, "tmpo", myatoi(tempo_ptr));
+
+ if (genre_ptr) {
+ uint32_t index = meta_genre_to_index(genre_ptr);
+ if (index == 0)
+ membuffer_write_std_tag(buf, "©gen",
+ genre_ptr);
+ else
+ membuffer_write_int16_tag(buf, "gnre", index);
+ }
for (metaptr = 0; metaptr < data->count; metaptr++) {
if (!mask[metaptr]) {
struct mp4ff_tag *tag = &data->tags[metaptr];
uint32_t i;
for (i = 0; i < f->tags.count; i++) {
- if (!stricmp(f->tags.tags[i].item, item)) {
+ if (!strcasecmp(f->tags.tags[i].item, item)) {
*value = para_strdup(f->tags.tags[i].value);
return 1;
}