return lseek(fd, pos, SEEK_SET);
}
-static uint32_t aac_afh_meta_write_cb(void *user_data, void *dest, uint32_t want)
+static ssize_t aac_afh_meta_write_cb(void *user_data, void *dest, size_t count)
{
int fd = *(int *)user_data;
- return write(fd, dest, want);
+ return write(fd, dest, count);
}
static uint32_t aac_afh_meta_truncate_cb(void *user_data)
replace_or_add_tag("album", tags->album, metadata);
replace_or_add_tag("date", tags->year, metadata);
replace_or_add_tag("comment", tags->comment, metadata);
- ret = -E_MP4_META_WRITE;
- if (!mp4_meta_update(mp4))
- goto close;
- ret = 1;
-close:
+ ret = mp4_meta_update(mp4);
mp4_close(mp4);
return ret;
}
PARA_ERROR(MP4_BAD_SAMPLE, "mp4: invalid sample number"), \
PARA_ERROR(MP4_BAD_SAMPLERATE, "mp4: invalid sample rate"), \
PARA_ERROR(MP4_BAD_SAMPLE_COUNT, "mp4: invalid number of samples"), \
- PARA_ERROR(MP4_META_WRITE, "mp4: could not update mp4 metadata"), \
PARA_ERROR(MP4_OPEN, "mp4: open failed"), \
PARA_ERROR(MP4_TRACK, "mp4: no audio track"), \
PARA_ERROR(MP4_MISSING_ATOM, "mp4: essential atom not found"), \
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);
+ }
+ f->current_position += ret;
+ 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 */
+ ret = write_data(f, "free", 4); /* rename old moov to free */
+ if (ret < 0)
+ goto free_moov;
set_position(f, f->file_size); /* write new moov atom at EOF */
} 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)
struct mp4_callback {
- ssize_t (*read)(void *user_data, void *buffer, size_t length);
- uint32_t (*write)(void *udata, void *buffer, uint32_t length);
- uint32_t (*seek)(void *user_data, uint64_t position);
- uint32_t (*truncate)(void *user_data);
- void *user_data;
+ ssize_t (*read)(void *user_data, void *buffer, size_t length);
+ ssize_t (*write)(void *user_data, void *buffer, size_t count);
+ uint32_t (*seek)(void *user_data, uint64_t position);
+ uint32_t (*truncate)(void *user_data);
+ void *user_data;
};
struct mp4_tag {
uint64_t mp4_get_duration(const struct mp4 *f);
int mp4_open_meta(const struct mp4_callback *cb, struct mp4 **result);
struct mp4_metadata *mp4_get_meta(struct mp4 *f);
-int32_t mp4_meta_update(struct mp4 *f);
+int mp4_meta_update(struct mp4 *f);
char *mp4_meta_get_artist(const struct mp4 *f);
char *mp4_meta_get_title(const struct mp4 *f);
char *mp4_meta_get_date(const struct mp4 *f);