struct mp4 {
const struct mp4_callback *cb;
- int64_t current_position;
uint64_t moov_offset;
uint64_t moov_size;
uint32_t udta_size;
uint8_t last_atom;
- uint64_t file_size;
-
/* incremental track index while reading the file */
int32_t total_tracks;
/* track data */
/* regard EAGAIN as an error as reads should be blocking. */
if (ret <= 0)
return ret < 0? -1 : 0;
- f->current_position += ret;
size -= ret;
}
return 1;
return 1;
}
-static int64_t get_position(const struct mp4 *f)
+static off_t get_position(const struct mp4 *f)
{
- return f->current_position;
+ return f->cb->seek(f->cb->user_data, 0, SEEK_CUR);
}
-static int32_t set_position(struct mp4 *f, int64_t position)
+static void set_position(struct mp4 *f, off_t position)
{
- f->cb->seek(f->cb->user_data, position);
- f->current_position = position;
-
- return 0;
+ f->cb->seek(f->cb->user_data, position, SEEK_SET);
}
static int read_stsz(struct mp4 *f)
f->cb = cb;
while ((ret = atom_read_header(f, &atom_type, &header_size, &size)) > 0) {
- f->file_size += size;
f->last_atom = atom_type;
if (atom_type != ATOM_MOOV || size <= header_size) { /* skip */
set_position(f, get_position(f) + size - header_size);
return out_buffer;
}
-static int32_t write_data(struct mp4 *f, void *data, uint32_t size)
+static int write_data(struct mp4 *f, void *data, size_t size)
{
- int32_t result = 1;
-
- result = f->cb->write(f->cb->user_data, data, size);
-
- f->current_position += size;
-
- return result;
+ while (size > 0) {
+ ssize_t ret = f->cb->write(f->cb->user_data, data, size);
+ if (ret < 0) {
+ if (errno == EINTR)
+ continue;
+ return -ERRNO_TO_PARA_ERROR(errno);
+ }
+ size -= ret;
+ }
+ return 1;
}
-int32_t mp4_meta_update(struct mp4 *f)
+int mp4_meta_update(struct mp4 *f)
{
void *new_moov_data;
uint32_t new_moov_size;
- uint8_t buf[4];
+ uint8_t buf[8] = "----moov";
+ int ret;
set_position(f, 0);
new_moov_data = modify_moov(f, &new_moov_size);
}
if (f->last_atom != ATOM_MOOV) {
set_position(f, f->moov_offset + 4);
- write_data(f, "free", 4); /* rename old moov to free */
- set_position(f, f->file_size); /* write new moov atom at EOF */
+ ret = write_data(f, "free", 4); /* rename old moov to free */
+ if (ret < 0)
+ goto free_moov;
+ /* write new moov atom at EOF */
+ f->cb->seek(f->cb->user_data, 0, SEEK_END);
} else /* overwrite old moov atom */
set_position(f, f->moov_offset);
write_u32_be(buf, new_moov_size + 8);
- write_data(f, buf, 4);
- write_data(f, "moov", 4);
- write_data(f, new_moov_data, new_moov_size);
- free(new_moov_data);
+ ret = write_data(f, buf, sizeof(buf));
+ if (ret < 0)
+ goto free_moov;
+ ret = write_data(f, new_moov_data, new_moov_size);
+ if (ret < 0)
+ goto free_moov;
f->cb->truncate(f->cb->user_data);
- return 1;
+ ret = 1;
+free_moov:
+ free(new_moov_data);
+ return ret;
}
static char *meta_find_by_name(const struct mp4 *f, const char *item)