CAMLprim value ocaml_faad_mp4_open_read_fd(value metaonly, value fd) { CAMLparam2(metaonly, fd); CAMLlocal1(ans); mp4_t *mp = malloc(sizeof(mp4_t)); mp->fd = GET_FD(fd); mp->ff_cb.read = read_cb; mp->read_cb = 0; mp->ff_cb.write = write_cb; mp->write_cb = 0; mp->ff_cb.seek = seek_cb; mp->seek_cb = 0; mp->ff_cb.truncate = trunc_cb; mp->trunc_cb = 0; mp->ff_cb.user_data = mp; caml_enter_blocking_section(); if(Bool_val(metaonly)) mp->ff = mp4ff_open_read_metaonly(&mp->ff_cb); else mp->ff = mp4ff_open_read(&mp->ff_cb); caml_leave_blocking_section(); assert(mp->ff); ans = caml_alloc_custom(&mp4_ops, sizeof(mp4_t*), 1, 0); Mp4_val(ans) = mp; CAMLreturn(ans); }
static void mp4_getSongTitle(char *filename, char **title, int *len) { FILE* mp4file; (*title) = NULL; (*len) = -1; if((mp4file = fopen(filename, "rb"))){ mp4_get_file_type(mp4file); fseek(mp4file, 0, SEEK_SET); if(mp4cfg.file_type == FILE_MP4){ mp4ff_callback_t* mp4cb; mp4ff_t* infile; gint mp4track; mp4cb = getMP4FF_cb(mp4file); if ((infile = mp4ff_open_read_metaonly(mp4cb)) && ((mp4track = getAACTrack(infile)) >= 0)){ (*title) = getMP4title(infile, filename); double track_duration = mp4ff_get_track_duration(infile, mp4track); unsigned long time_scale = mp4ff_time_scale(infile, mp4track); unsigned long length = (track_duration * 1000 / time_scale); (*len) = length; } if(infile) mp4ff_close(infile); if(mp4cb) g_free(mp4cb); } else{ // Check AAC ID3 tag... } fclose(mp4file); } }
CAMLprim value ocaml_faad_mp4_open_read(value metaonly, value read, value write, value seek, value trunc) { CAMLparam4(read, write, seek, trunc); CAMLlocal1(ans); mp4_t *mp = malloc(sizeof(mp4_t)); mp->fd = -1; mp->ff_cb.read = read_cb; mp->read_cb = read; caml_register_global_root(&mp->read_cb); if (Is_block(write)) { mp->ff_cb.write = write_cb; mp->write_cb = Field(write, 0); caml_register_global_root(&mp->write_cb); } else { mp->ff_cb.write = NULL; mp->write_cb = 0; } if (Is_block(seek)) { mp->ff_cb.seek = seek_cb; mp->seek_cb = Field(seek, 0); caml_register_global_root(&mp->seek_cb); } else { mp->ff_cb.seek = NULL; mp->seek_cb = 0; } if (Is_block(trunc)) { mp->ff_cb.truncate = trunc_cb; mp->trunc_cb = Field(trunc, 0); caml_register_global_root(&mp->trunc_cb); } else { mp->ff_cb.truncate = NULL; mp->trunc_cb = 0; } mp->ff_cb.user_data = mp; caml_enter_blocking_section(); if(Bool_val(metaonly)) mp->ff = mp4ff_open_read_metaonly(&mp->ff_cb); else mp->ff = mp4ff_open_read(&mp->ff_cb); caml_leave_blocking_section(); assert(mp->ff); ans = caml_alloc_custom(&mp4_ops, sizeof(mp4_t*), 1, 0); Mp4_val(ans) = mp; CAMLreturn(ans); }