ref: d0d358260cb40bacb324cdc37c426a24a858e6be
parent: 3cb7da83d454c960f48fbb589a7372873a322c5c
author: menno <menno>
date: Sat Dec 13 17:26:56 EST 2003
mp4ff improvements
--- a/common/mp4ff/mp4atom.c
+++ b/common/mp4ff/mp4atom.c
@@ -22,7 +22,7 @@
** Commercial non-GPL licensing of this software is possible.
** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
**
-** $Id: mp4atom.c,v 1.7 2003/12/11 18:32:39 menno Exp $
+** $Id: mp4atom.c,v 1.12 2003/12/23 18:53:24 menno Exp $
**/
#include <stdlib.h>
@@ -156,7 +156,9 @@
return ATOM_GENRE2;
else if (mp4ff_atom_compare(a,b,c,d, 'c','p','i','l'))
return ATOM_COMPILATION;
- else
+ else if (mp4ff_atom_compare(a,b,c,d, 'c','t','t','s'))
+ return ATOM_CTTS;
+ else
return ATOM_UNKNOWN;
}
@@ -213,6 +215,7 @@
static int32_t mp4ff_read_esds(mp4ff_t *f)
{
uint8_t tag;
+ uint32_t temp;
mp4ff_read_char(f); /* version */
mp4ff_read_int24(f); /* flags */
@@ -240,14 +243,11 @@
}
/* read length */
- if (mp4ff_read_mp4_descr_length(f) < 15)
- {
- return 1;
- }
+ temp = mp4ff_read_mp4_descr_length(f);
+ if (temp < 13) return 1;
- /* skip 13 bytes */
- mp4ff_read_char(f);
- mp4ff_read_int32(f);
+ f->track[f->total_tracks - 1]->audioType = mp4ff_read_char(f);
+ mp4ff_read_int32(f);//0x15000414 ????
f->track[f->total_tracks - 1]->maxBitrate = mp4ff_read_int32(f);
f->track[f->total_tracks - 1]->avgBitrate = mp4ff_read_int32(f);
@@ -389,24 +389,68 @@
return 0;
}
-static int32_t mp4ff_read_stts(mp4ff_t *f)
+static int32_t mp4ff_read_ctts(mp4ff_t *f)
{
int32_t i;
+ mp4ff_track_t * p_track = f->track[f->total_tracks - 1];
+ if (p_track->ctts_entry_count) return 0;
+
mp4ff_read_char(f); /* version */
mp4ff_read_int24(f); /* flags */
- f->track[f->total_tracks - 1]->stts_entry_count = mp4ff_read_int32(f);
+ p_track->ctts_entry_count = mp4ff_read_int32(f);
- f->track[f->total_tracks - 1]->stts_sample_count = (int32_t*)malloc(f->track[f->total_tracks - 1]->stts_entry_count * sizeof(int32_t));
- f->track[f->total_tracks - 1]->stts_sample_delta = (int32_t*)malloc(f->track[f->total_tracks - 1]->stts_entry_count * sizeof(int32_t));
+ p_track->ctts_sample_count = (int32_t*)malloc(p_track->ctts_entry_count * sizeof(int32_t));
+ p_track->ctts_sample_offset = (int32_t*)malloc(p_track->ctts_entry_count * sizeof(int32_t));
- for (i = 0; i < f->track[f->total_tracks - 1]->stts_entry_count; i++)
- {
- f->track[f->total_tracks - 1]->stts_sample_count[i] = mp4ff_read_int32(f);
- f->track[f->total_tracks - 1]->stts_sample_delta[i] = mp4ff_read_int32(f);
- }
+ if (p_track->ctts_sample_count == 0 || p_track->ctts_sample_offset == 0)
+ {
+ if (p_track->ctts_sample_count) {free(p_track->ctts_sample_count);p_track->ctts_sample_count=0;}
+ if (p_track->ctts_sample_offset) {free(p_track->ctts_sample_offset);p_track->ctts_sample_offset=0;}
+ p_track->ctts_entry_count = 0;
+ return 0;
+ }
+ else
+ {
+ for (i = 0; i < f->track[f->total_tracks - 1]->ctts_entry_count; i++)
+ {
+ p_track->ctts_sample_count[i] = mp4ff_read_int32(f);
+ p_track->ctts_sample_offset[i] = mp4ff_read_int32(f);
+ }
+ return 1;
+ }
+}
- return 0;
+static int32_t mp4ff_read_stts(mp4ff_t *f)
+{
+ int32_t i;
+ mp4ff_track_t * p_track = f->track[f->total_tracks - 1];
+
+ if (p_track->stts_entry_count) return 0;
+
+ mp4ff_read_char(f); /* version */
+ mp4ff_read_int24(f); /* flags */
+ p_track->stts_entry_count = mp4ff_read_int32(f);
+
+ p_track->stts_sample_count = (int32_t*)malloc(p_track->stts_entry_count * sizeof(int32_t));
+ p_track->stts_sample_delta = (int32_t*)malloc(p_track->stts_entry_count * sizeof(int32_t));
+
+ if (p_track->stts_sample_count == 0 || p_track->stts_sample_delta == 0)
+ {
+ if (p_track->stts_sample_count) {free(p_track->stts_sample_count);p_track->stts_sample_count=0;}
+ if (p_track->stts_sample_delta) {free(p_track->stts_sample_delta);p_track->stts_sample_delta=0;}
+ p_track->stts_entry_count = 0;
+ return 0;
+ }
+ else
+ {
+ for (i = 0; i < f->track[f->total_tracks - 1]->stts_entry_count; i++)
+ {
+ p_track->stts_sample_count[i] = mp4ff_read_int32(f);
+ p_track->stts_sample_delta[i] = mp4ff_read_int32(f);
+ }
+ return 1;
+ }
}
static int32_t mp4ff_read_mvhd(mp4ff_t *f)
@@ -545,6 +589,9 @@
} else if (atom_type == ATOM_STTS) {
/* time to sample box */
mp4ff_read_stts(f);
+ } else if (atom_type == ATOM_CTTS) {
+ /* composition offset box */
+ mp4ff_read_ctts(f);
} else if (atom_type == ATOM_STSC) {
/* sample to chunk box */
mp4ff_read_stsc(f);
@@ -565,10 +612,10 @@
/* iTunes Metadata box */
mp4ff_read_meta(f, size);
#endif
- } else {
- /* skip this atom: not needed for reading */
- mp4ff_set_position(f, dest_position);
}
+
+ mp4ff_set_position(f, dest_position);
+
return 0;
}
--- a/common/mp4ff/mp4ff.c
+++ b/common/mp4ff/mp4ff.c
@@ -22,7 +22,7 @@
** Commercial non-GPL licensing of this software is possible.
** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
**
-** $Id: mp4ff.c,v 1.7 2003/12/11 18:32:39 menno Exp $
+** $Id: mp4ff.c,v 1.8 2003/12/13 22:26:56 menno Exp $
**/
#include <stdlib.h>
@@ -66,6 +66,10 @@
free(ff->track[i]->stco_chunk_offset);
if (ff->track[i]->decoderConfig)
free(ff->track[i]->decoderConfig);
+ if (ff->track[i]->ctts_sample_count)
+ free(ff->track[i]->ctts_sample_count);
+ if (ff->track[i]->ctts_sample_offset)
+ free(ff->track[i]->ctts_sample_offset);
free(ff->track[i]);
}
}
@@ -164,7 +168,97 @@
return 0;
}
+int32_t mp4ff_get_decoder_config(const mp4ff_t *f, const int32_t track,
+ uint8_t** ppBuf, uint32_t* pBufSize)
+{
+ if (track >= f->total_tracks)
+ {
+ *ppBuf = NULL;
+ *pBufSize = 0;
+ return 1;
+ }
+ if (f->track[track]->decoderConfig == NULL || f->track[track]->decoderConfigLen == 0)
+ {
+ *ppBuf = NULL;
+ *pBufSize = 0;
+ } else {
+ *ppBuf = malloc(f->track[track]->decoderConfigLen);
+ if (*ppBuf == NULL)
+ {
+ *pBufSize = 0;
+ return 1;
+ }
+ memcpy(*ppBuf, f->track[track]->decoderConfig, f->track[track]->decoderConfigLen);
+ *pBufSize = f->track[track]->decoderConfigLen;
+ }
+
+ return 0;
+}
+
+int32_t mp4ff_get_track_type(const mp4ff_t *f, const int track)
+{
+ return f->track[track]->type;
+}
+
+int32_t mp4ff_total_tracks(const mp4ff_t *f)
+{
+ return f->total_tracks;
+}
+
+int32_t mp4ff_time_scale(const mp4ff_t *f, const int32_t track)
+{
+ return f->track[track]->timeScale;
+}
+
+uint32_t mp4ff_get_avg_bitrate(const mp4ff_t *f, const int32_t track)
+{
+ return f->track[track]->avgBitrate;
+}
+
+uint32_t mp4ff_get_max_bitrate(const mp4ff_t *f, const int32_t track)
+{
+ return f->track[track]->maxBitrate;
+}
+
+uint64_t mp4ff_get_track_duration(const mp4ff_t *f, const int32_t track)
+{
+ return f->track[track]->duration;
+}
+
+
+int32_t mp4ff_num_samples(const mp4ff_t *f, const int32_t 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];
+ }
+ return total;
+}
+
+
+
+
+uint32_t mp4ff_get_sample_rate(const mp4ff_t *f, const int32_t track)
+{
+ return f->track[track]->sampleRate;
+}
+
+uint32_t mp4ff_get_channel_count(const mp4ff_t * f,const int32_t track)
+{
+ return f->track[track]->channelCount;
+}
+
+uint32_t mp4ff_get_audio_type(const mp4ff_t * f,const int32_t track)
+{
+ return f->track[track]->audioType;
+}
+
+
+
int32_t mp4ff_get_sample_duration(const mp4ff_t *f, const int32_t track, const int32_t sample)
{
int32_t i, co = 0;
@@ -179,7 +273,7 @@
return (int32_t)(-1);
}
-int64_t mp4ff_get_sample_offset(const mp4ff_t *f, const int32_t track, const int32_t sample)
+int64_t mp4ff_get_sample_position(const mp4ff_t *f, const int32_t track, const int32_t sample)
{
int32_t i, co = 0;
int64_t acc = 0;
@@ -201,6 +295,20 @@
return (int64_t)(-1);
}
+int32_t mp4ff_get_sample_offset(const mp4ff_t *f, const int32_t track, const int32_t sample)
+{
+ int32_t i, co = 0;
+
+ for (i = 0; i < f->track[track]->ctts_entry_count; i++)
+ {
+ int32_t delta = f->track[track]->ctts_sample_count[i];
+ if (sample < co + delta)
+ return f->track[track]->ctts_sample_offset[i];
+ co += delta;
+ }
+ return 0;
+}
+
int32_t mp4ff_find_sample(const mp4ff_t *f, const int32_t track, const int64_t offset,int32_t * toskip)
{
int32_t i, co = 0;
@@ -215,7 +323,7 @@
{
int64_t offset_fromstts = offset - offset_total;
if (toskip) *toskip = (int32_t)(offset_fromstts % sample_delta);
- return (int32_t)(offset_fromstts / sample_delta);
+ return co + (int32_t)(offset_fromstts / sample_delta);
}
else
{
@@ -245,71 +353,3 @@
return *bytes;
}
-
-int32_t mp4ff_get_decoder_config(const mp4ff_t *f, const int32_t track,
- uint8_t** ppBuf, uint32_t* pBufSize)
-{
- if (track >= f->total_tracks)
- {
- *ppBuf = NULL;
- *pBufSize = 0;
- return 1;
- }
-
- if (f->track[track]->decoderConfig == NULL || f->track[track]->decoderConfigLen == 0)
- {
- *ppBuf = NULL;
- *pBufSize = 0;
- } else {
- *ppBuf = malloc(f->track[track]->decoderConfigLen);
- if (*ppBuf == NULL)
- {
- *pBufSize = 0;
- return 1;
- }
- memcpy(*ppBuf, f->track[track]->decoderConfig, f->track[track]->decoderConfigLen);
- *pBufSize = f->track[track]->decoderConfigLen;
- }
-
- return 0;
-}
-
-int32_t mp4ff_total_tracks(const mp4ff_t *f)
-{
- return f->total_tracks;
-}
-
-int32_t mp4ff_time_scale(const mp4ff_t *f, const int32_t track)
-{
- return f->track[track]->timeScale;
-}
-
-uint32_t mp4ff_get_avg_bitrate(const mp4ff_t *f, const int32_t track)
-{
- return f->track[track]->avgBitrate;
-}
-
-uint32_t mp4ff_get_max_bitrate(const mp4ff_t *f, const int32_t track)
-{
- return f->track[track]->maxBitrate;
-}
-
-uint64_t mp4ff_get_track_duration(const mp4ff_t *f, const int32_t track)
-{
- return f->track[track]->duration;
-}
-
-
-int32_t mp4ff_num_samples(const mp4ff_t *f, const int32_t 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];
- }
- return total;
-}
-
-
--- a/common/mp4ff/mp4ff.h
+++ b/common/mp4ff/mp4ff.h
@@ -22,7 +22,7 @@
** Commercial non-GPL licensing of this software is possible.
** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
**
-** $Id: mp4ff.h,v 1.10 2003/12/11 18:32:39 menno Exp $
+** $Id: mp4ff.h,v 1.11 2003/12/13 22:26:56 menno Exp $
**/
#ifndef MP4FF_H
@@ -53,12 +53,14 @@
mp4ff_t *mp4ff_open_read(mp4ff_callback_t *f);
void mp4ff_close(mp4ff_t *f);
int32_t mp4ff_get_sample_duration(const mp4ff_t *f, const int32_t track, const int32_t sample);
-int64_t mp4ff_get_sample_offset(const mp4ff_t *f, const int32_t track, const int32_t sample);
+int64_t mp4ff_get_sample_position(const mp4ff_t *f, const int32_t track, const int32_t sample);
+int32_t mp4ff_get_sample_offset(const mp4ff_t *f, const int32_t track, const int32_t sample);
int32_t mp4ff_find_sample(const mp4ff_t *f, const int32_t track, const int64_t offset,int32_t * toskip);
int32_t mp4ff_read_sample(mp4ff_t *f, const int track, const int sample,
unsigned char **audio_buffer, unsigned int *bytes);
int32_t mp4ff_get_decoder_config(const mp4ff_t *f, const int track,
unsigned char** ppBuf, unsigned int* pBufSize);
+int32_t mp4ff_get_track_type(const mp4ff_t *f, const int track);
int32_t mp4ff_total_tracks(const mp4ff_t *f);
int32_t mp4ff_num_samples(const mp4ff_t *f, const int track);
int32_t mp4ff_time_scale(const mp4ff_t *f, const int track);
@@ -66,6 +68,9 @@
uint32_t mp4ff_get_avg_bitrate(const mp4ff_t *f, const int32_t track);
uint32_t mp4ff_get_max_bitrate(const mp4ff_t *f, const int32_t track);
uint64_t mp4ff_get_track_duration(const mp4ff_t *f, const int32_t track); //returns (uint64_t)(-1) if unknown
+uint32_t mp4ff_get_sample_rate(const mp4ff_t *f, const int32_t track);
+uint32_t mp4ff_get_channel_count(const mp4ff_t * f,const int32_t track);
+uint32_t mp4ff_get_audio_type(const mp4ff_t * f,const int32_t track);
/* metadata */
--- a/common/mp4ff/mp4ff_int_types.h
+++ b/common/mp4ff/mp4ff_int_types.h
@@ -1,6 +1,8 @@
#ifndef _MP4FF_INT_TYPES_H_
#define _MP4FF_INT_TYPES_H_
+#ifdef _WIN32
+
typedef char int8_t;
typedef unsigned char uint8_t;
typedef short int16_t;
@@ -8,12 +10,13 @@
typedef long int32_t;
typedef unsigned long uint32_t;
-#ifdef _WIN32
typedef __int64 int64_t;
typedef unsigned __int64 uint64_t;
+
#else
-typedef long long int64_t;
-typedef unsigned long long uint64_t;
+
+#include <stdint.h>
+
#endif
--- a/common/mp4ff/mp4ffint.h
+++ b/common/mp4ff/mp4ffint.h
@@ -22,7 +22,7 @@
** Commercial non-GPL licensing of this software is possible.
** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
**
-** $Id: mp4ffint.h,v 1.4 2003/12/11 18:32:39 menno Exp $
+** $Id: mp4ffint.h,v 1.5 2003/12/13 22:26:56 menno Exp $
**/
#ifndef MP4FF_INTERNAL_H
@@ -67,6 +67,7 @@
#define ATOM_META 148 /* iTunes Metadata box */
#define ATOM_NAME 149 /* iTunes Metadata name box */
#define ATOM_DATA 150 /* iTunes Metadata data box */
+#define ATOM_CTTS 151
#define ATOM_UNKNOWN 255
#define ATOM_FREE ATOM_UNKNOWN
@@ -99,6 +100,10 @@
#include "../../config.h"
#endif
+#ifndef _WIN32
+#define stricmp strcasecmp
+#endif
+
/* file callback structure */
typedef struct
{
@@ -131,6 +136,7 @@
int32_t channelCount;
int32_t sampleSize;
uint16_t sampleRate;
+ int32_t audioType;
/* stsd */
int32_t stsd_entry_count;
@@ -155,6 +161,11 @@
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;
@@ -277,7 +288,8 @@
int32_t parse_atoms(mp4ff_t *f);
int32_t mp4ff_get_sample_duration(const mp4ff_t *f, const int32_t track, const int32_t sample);
-int64_t mp4ff_get_sample_offset(const mp4ff_t *f, const int32_t track, const int32_t sample);
+int64_t mp4ff_get_sample_position(const mp4ff_t *f, const int32_t track, const int32_t sample);
+int32_t mp4ff_get_sample_offset(const mp4ff_t *f, const int32_t track, const int32_t sample);
int32_t mp4ff_find_sample(const mp4ff_t *f, const int32_t track, const int64_t offset,int32_t * toskip);
int32_t mp4ff_read_sample(mp4ff_t *f, const int32_t track, const int32_t sample,
@@ -290,6 +302,7 @@
uint32_t mp4ff_meta_genre_to_index(const char * genrestr);//returns 1-based index, 0 if not found
const char * mp4ff_meta_index_to_genre(uint32_t idx);//returns pointer to static string
+
#ifdef __cplusplus
}
--- a/common/mp4ff/mp4meta.c
+++ b/common/mp4ff/mp4meta.c
@@ -22,7 +22,7 @@
** Commercial non-GPL licensing of this software is possible.
** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
**
-** $Id: mp4meta.c,v 1.4 2003/12/11 18:32:39 menno Exp $
+** $Id: mp4meta.c,v 1.7 2003/12/14 16:47:08 menno Exp $
**/
#ifdef USE_TAGGING
@@ -71,19 +71,8 @@
{
if (!stricmp(tags->tags[i].item, item))
{
- void *backup = (void *)tags->tags[i].value;
- int v_len = strlen(value);
-
- tags->tags[i].value = (char *)realloc(tags->tags[i].value, v_len+1);
- if (!tags->tags[i].value)
- {
- if (backup) free(backup);
- return 0;
- }
-
- memcpy(tags->tags[i].value, value, v_len);
- tags->tags[i].value[v_len] = '\0';
-
+ free(tags->tags[i].value);
+ tags->tags[i].value = strdup(value);
return 1;
}
}
--- a/common/mp4ff/mp4tagupdate.c
+++ b/common/mp4ff/mp4tagupdate.c
@@ -353,9 +353,9 @@
{
uint32_t index = mp4ff_meta_genre_to_index(genre_ptr);
if (index==0)
- membuffer_write_std_tag(buf,"gnre",genre_ptr);
+ membuffer_write_std_tag(buf,"�gen",genre_ptr);
else
- membuffer_write_int16_tag(buf,"�gen",(uint16_t)index);
+ membuffer_write_int16_tag(buf,"gnre",(uint16_t)index);
}
}