struct mp4_track {
bool is_audio;
int32_t channelCount;
- int32_t sampleSize;
uint16_t sampleRate;
- /* stsd */
- int32_t stsd_entry_count;
-
/* stsz */
int32_t stsz_sample_size;
int32_t stsz_sample_count;
int32_t stco_entry_count;
int32_t *stco_chunk_offset;
- uint32_t maxBitrate;
- uint32_t avgBitrate;
-
uint32_t timeScale;
uint64_t duration;
};
#define MAX_TRACKS 1024
struct mp4 {
- /* stream to read from */
- struct mp4_callback *stream;
+ struct mp4_callback *cb;
int64_t current_position;
uint64_t moov_offset;
uint64_t moov_size;
uint8_t last_atom;
uint64_t file_size;
+
+ uint32_t read_error;
uint32_t error;
/* incremental track index while reading the file */
{
int32_t result = 1;
- result = f->stream->read(f->stream->user_data, data, size);
+ result = f->cb->read(f->cb->user_data, data, size);
if (result < size)
- f->stream->read_error++;
+ f->read_error++;
f->current_position += size;
static int32_t set_position(struct mp4 *f, int64_t position)
{
- f->stream->seek(f->stream->user_data, position);
+ f->cb->seek(f->cb->user_data, position);
f->current_position = position;
return 0;
if (t->stsz_sample_size != 0)
return 0;
t->stsz_table = para_malloc(t->stsz_sample_count * sizeof(int32_t));
- for (i = 0; i < t->stsz_sample_count && !f->stream->read_error; i++)
+ for (i = 0; i < t->stsz_sample_count && !f->read_error; i++)
t->stsz_table[i] = read_int32(f);
return 0;
}
t->stts_sample_delta = para_malloc(t->stts_entry_count
* sizeof (int32_t));
/* CVE-2017-9254 */
- for (i = 0; i < t->stts_entry_count && !f->stream->read_error; i++) {
+ for (i = 0; i < t->stts_entry_count && !f->read_error; i++) {
t->stts_sample_count[i] = read_int32(f);
t->stts_sample_delta[i] = read_int32(f);
}
sizeof (int32_t));
/* CVE-2017-9255 */
- for (i = 0; i < t->stsc_entry_count && !f->stream->read_error; i++) {
+ for (i = 0; i < t->stsc_entry_count && !f->read_error; i++) {
t->stsc_first_chunk[i] = read_int32(f);
t->stsc_samples_per_chunk[i] = read_int32(f);
t->stsc_sample_desc_index[i] = read_int32(f);
t->stco_chunk_offset = para_malloc(t->stco_entry_count
* sizeof(int32_t));
/* CVE-2017-9256 */
- for (i = 0; i < t->stco_entry_count && !f->stream->read_error; i++)
+ for (i = 0; i < t->stco_entry_count && !f->read_error; i++)
t->stco_chunk_offset[i] = read_int32(f);
return 0;
}
read_int32(f); /* reserved */
t->channelCount = read_int16(f);
- t->sampleSize = read_int16(f);
+ read_int16(f);
read_int16(f);
read_int16(f);
static int32_t read_stsd(struct mp4 *f)
{
- int32_t i;
+ int32_t i, entry_count;
uint8_t header_size = 0;
struct mp4_track *t;
read_char(f); /* version */
read_int24(f); /* flags */
- t->stsd_entry_count = read_int32(f);
+ entry_count = read_int32(f);
/* CVE-2017-9253 */
- for (i = 0; i < t->stsd_entry_count && !f->stream->read_error; i++) {
+ for (i = 0; i < entry_count && !f->read_error; i++) {
uint64_t skip = get_position(f);
uint64_t size;
uint8_t atom_type = 0;
for (
sumsize = 0;
- sumsize < size && !f->stream->read_error; /* CVE-2017-9222 */
+ sumsize < size && !f->read_error; /* CVE-2017-9222 */
set_position(f, destpos), sumsize += subsize
) {
subsize = atom_read_header(f, &atom_type, &header_size);
uint8_t header_size = 0;
f->file_size = 0;
- f->stream->read_error = 0;
+ f->read_error = 0;
while ((size =
atom_read_header(f, &atom_type, &header_size)) != 0) {
return 0;
}
-struct mp4 *mp4_open_read(struct mp4_callback *f)
+struct mp4 *mp4_open_read(struct mp4_callback *cb)
{
- struct mp4 *ff = para_calloc(sizeof(struct mp4));
+ struct mp4 *f = para_calloc(sizeof(struct mp4));
- ff->stream = f;
-
- parse_atoms(ff, 0);
-
- if (ff->error) {
- free(ff);
- ff = NULL;
+ f->cb = cb;
+ parse_atoms(f, 0);
+ if (f->error) {
+ free(f);
+ f = NULL;
}
-
- return ff;
+ return f;
}
static int32_t tag_delete(struct mp4_metadata *tags)
return 0;
}
-void mp4_close(struct mp4 *ff)
+void mp4_close(struct mp4 *f)
{
int32_t i;
- for (i = 0; i < ff->total_tracks; i++) {
- if (ff->track[i]) {
- free(ff->track[i]->stsz_table);
- free(ff->track[i]->stts_sample_count);
- free(ff->track[i]->stts_sample_delta);
- free(ff->track[i]->stsc_first_chunk);
- free(ff->track[i]->stsc_samples_per_chunk);
- free(ff->track[i]->stsc_sample_desc_index);
- free(ff->track[i]->stco_chunk_offset);
- free(ff->track[i]);
+ for (i = 0; i < f->total_tracks; i++) {
+ 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]);
}
}
- tag_delete(&(ff->tags));
- free(ff);
+ tag_delete(&(f->tags));
+ free(f);
}
static int32_t chunk_of_sample(const struct mp4 *f, int32_t track,
return total;
}
-struct mp4 *mp4_open_meta(struct mp4_callback *f)
+struct mp4 *mp4_open_meta(struct mp4_callback *cb)
{
- struct mp4 *ff = para_calloc(sizeof(struct mp4));
-
- ff->stream = f;
+ struct mp4 *f = para_calloc(sizeof(struct mp4));
- parse_atoms(ff, 1);
-
- if (ff->error) {
- free(ff);
- ff = NULL;
+ f->cb = cb;
+ parse_atoms(f, 1);
+ if (f->error) {
+ free(f);
+ f = NULL;
}
-
- return ff;
+ return f;
}
int32_t mp4_meta_get_num_items(const struct mp4 *f)
{
int32_t result = 1;
- result = f->stream->write(f->stream->user_data, data, size);
+ result = f->cb->write(f->cb->user_data, data, size);
f->current_position += size;
return write_data(f, temp, sizeof(temp));
}
-static int32_t truncate_stream(struct mp4 *f)
-{
- return f->stream->truncate(f->stream->user_data);
-}
-
-int32_t mp4_meta_update(struct mp4_callback *f, const struct mp4_metadata *data)
+int32_t mp4_meta_update(struct mp4_callback *cb, const struct mp4_metadata *data)
{
void *new_moov_data;
uint32_t new_moov_size;
- struct mp4 *ff = para_calloc(sizeof(struct mp4));
- ff->stream = f;
- set_position(ff, 0);
-
- parse_atoms(ff, 1);
-
- if (!modify_moov(ff, data, &new_moov_data, &new_moov_size)) {
- mp4_close(ff);
+ struct mp4 *f = para_calloc(sizeof(struct mp4));
+ f->cb = cb;
+ set_position(f, 0);
+ parse_atoms(f, 1);
+ if (!modify_moov(f, data, &new_moov_data, &new_moov_size)) {
+ mp4_close(f);
return 0;
}
/* copy moov atom to end of the file */
- if (ff->last_atom != ATOM_MOOV) {
+ if (f->last_atom != ATOM_MOOV) {
char *free_data = "free";
/* rename old moov to free */
- set_position(ff, ff->moov_offset + 4);
- write_data(ff, free_data, 4);
+ set_position(f, f->moov_offset + 4);
+ write_data(f, free_data, 4);
- set_position(ff, ff->file_size);
- write_int32(ff, new_moov_size + 8);
- write_data(ff, "moov", 4);
- write_data(ff, new_moov_data, new_moov_size);
+ set_position(f, f->file_size);
+ write_int32(f, new_moov_size + 8);
+ write_data(f, "moov", 4);
+ write_data(f, new_moov_data, new_moov_size);
} else {
- set_position(ff, ff->moov_offset);
- write_int32(ff, new_moov_size + 8);
- write_data(ff, "moov", 4);
- write_data(ff, new_moov_data, new_moov_size);
+ set_position(f, f->moov_offset);
+ write_int32(f, new_moov_size + 8);
+ write_data(f, "moov", 4);
+ write_data(f, new_moov_data, new_moov_size);
}
-
- truncate_stream(ff);
-
- mp4_close(ff);
+ cb->truncate(cb->user_data);
+ mp4_close(f);
return 1;
}