return 1;
}
-static int parse_root_atoms(struct mp4 *f, bool meta_only)
+static int open_file(const struct mp4_callback *cb, bool meta_only, struct mp4 **result)
{
int ret;
uint64_t size;
- uint8_t atom_type = 0;
- uint8_t header_size = 0;
-
- f->file_size = 0;
+ uint8_t atom_type, header_size;
+ struct mp4 *f = para_calloc(sizeof(*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 (ret <= 0)
break;
}
- if (ret < 0)
- return ret;
+ if (ret < 0) {
+ ret = -E_MP4_OPEN;
+ goto fail;
+ }
+ ret = -E_MP4_TRACK;
if (!f->audio_track)
- return -E_MP4_TRACK;
+ goto fail;
+ *result = f;
+ return 1;
+fail:
+ *result = NULL;
+ free(f);
return ret;
}
-struct mp4 *mp4_open_read(const struct mp4_callback *cb)
+int mp4_open_read(const struct mp4_callback *cb, struct mp4 **result)
{
- int ret;
- struct mp4 *f = para_calloc(sizeof(struct mp4));
-
- f->cb = cb;
- ret = parse_root_atoms(f, false);
- if (ret < 0) {
- free(f);
- return NULL;
- }
- return f;
+ return open_file(cb, false, result);
}
void mp4_close(struct mp4 *f)
return total;
}
-struct mp4 *mp4_open_meta(const struct mp4_callback *cb)
+int mp4_open_meta(const struct mp4_callback *cb, struct mp4 **result)
{
- int ret;
- struct mp4 *f = para_calloc(sizeof(struct mp4));
-
- f->cb = cb;
- ret = parse_root_atoms(f, true);
- if (ret < 0) {
- free(f);
- return NULL;
- }
- return f;
+ return open_file(cb, true, result);
}
/**
membuffer_write(buf, temp, 4);
}
-static void membuffer_write_std_tag(struct membuffer *buf, const char *name,
- const char *value)
-{
- uint32_t len = strlen(value);
- membuffer_write_int32(buf, 8 /* atom header */
- + 8 /* data atom header */
- + 8 /* flags + reserved */
- + len);
- membuffer_write_atom_name(buf, name);
- membuffer_write_int32(buf, 8 /* data atom header */
- + 8 /* flags + reserved */
- + len);
- membuffer_write_atom_name(buf, "data");
- membuffer_write_int32(buf, 1); /* flags */
- membuffer_write_int32(buf, 0); /* reserved */
- membuffer_write(buf, value, len);
-}
-
static unsigned membuffer_get_size(const struct membuffer *buf)
{
return buf->written;
for (n = 0; n < meta->count; n++) {
struct mp4_tag *tag = meta->tags + n;
+ unsigned len = strlen(tag->value);
const char *atom_name;
+
if (!strcasecmp(tag->item, "title"))
atom_name = "\xA9" "nam";
else if (!strcasecmp(tag->item, "artist"))
atom_name = "\xA9" "cmt";
else
assert(false);
- membuffer_write_std_tag(buf, atom_name, tag->value);
+ membuffer_write_int32(buf, 8 /* atom header */
+ + 8 /* data atom header */
+ + 8 /* flags + reserved */
+ + len);
+ membuffer_write_atom_name(buf, atom_name);
+ membuffer_write_int32(buf, 8 /* data atom header */
+ + 8 /* flags + reserved */
+ + len);
+ membuffer_write_atom_name(buf, "data");
+ membuffer_write_int32(buf, 1); /* flags */
+ membuffer_write_int32(buf, 0); /* reserved */
+ membuffer_write(buf, tag->value, len);
}
*out_size = membuffer_get_size(buf);
return membuffer_detach(buf);