/* parse root atoms */ static int32_t parse_atoms_int (mp4ff_t *f,int meta_only,int stop_on_mdat) { uint64_t size; uint8_t atom_type = 0; uint8_t header_size = 0; int had_valid_atoms = 0; f->file_size = 0; while ((size = mp4ff_atom_read_header(f, &atom_type, &header_size)) != 0) { // FIXME: ATOM_UNKNOWN is returned both when a valid (but unknown) atom is encontered, // and for invalid data. They need to be handled separately. if (atom_type == ATOM_UNKNOWN && !had_valid_atoms && mp4ff_position(f)+size > 100) { return -1; } had_valid_atoms = 1; f->file_size += size; f->last_atom = atom_type; if (atom_type == ATOM_MDAT && f->moov_read) { /* moov atom is before mdat, we can stop reading when mdat is encountered */ /* file position will stay at beginning of mdat data */ if (!stop_on_mdat) { break; } } if (atom_type == ATOM_MOOV && size > header_size) { f->moov_read = 1; f->moov_offset = mp4ff_position(f)-header_size; f->moov_size = size; } /* parse subatoms */ if (meta_only && !need_parse_when_meta_only(atom_type)) { mp4ff_set_position(f, mp4ff_position(f)+size-header_size); } else if (atom_type < SUBATOMIC) { parse_sub_atoms(f, size-header_size,meta_only); } else { /* skip this atom */ mp4ff_set_position(f, mp4ff_position(f)+size-header_size); } } return 0; }
/* parse atoms that are sub atoms of other atoms */ int32_t parse_sub_atoms(mp4ff_t *f, const uint64_t total_size,int meta_only) { uint64_t size; uint8_t atom_type = 0; uint64_t counted_size = 0; uint8_t header_size = 0; while (counted_size < total_size) { size = mp4ff_atom_read_header(f, &atom_type, &header_size); counted_size += size; /* check for end of file */ if (size == 0) break; /* we're starting to read a new track, update index, * so that all data and tables get written in the right place */ if (atom_type == ATOM_TRAK) { mp4ff_track_add(f); } /* parse subatoms */ if (meta_only && !need_parse_when_meta_only(atom_type)) { mp4ff_set_position(f, mp4ff_position(f)+size-header_size); } else if (atom_type < SUBATOMIC) { parse_sub_atoms(f, size-header_size,meta_only); } else { mp4ff_atom_read(f, (uint32_t)size, atom_type); } #if 0 if (atom_type == ATOM_TRAK) { trace ("mp4ff_track_create_chunks_index\n"); mp4ff_track_create_chunks_index (f, f->track[f->total_tracks-1]); trace ("mp4ff_track_create_samples_index\n"); mp4ff_track_create_samples_index (f, f->track[f->total_tracks-1]); } #endif } return 0; }
/* parse root atoms */ int32_t parse_atoms(mp4ff_t *f,int meta_only) { uint64_t size; uint8_t atom_type = 0; uint8_t header_size = 0; f->file_size = 0; while ((size = mp4ff_atom_read_header(f, &atom_type, &header_size)) != 0) { f->file_size += size; f->last_atom = atom_type; if (atom_type == ATOM_MDAT && f->moov_read) { /* moov atom is before mdat, we can stop reading when mdat is encountered */ /* file position will stay at beginning of mdat data */ // break; } if (atom_type == ATOM_MOOV && size > header_size) { f->moov_read = 1; f->moov_offset = mp4ff_position(f)-header_size; f->moov_size = size; } /* parse subatoms */ if (meta_only && !need_parse_when_meta_only(atom_type)) { mp4ff_set_position(f, mp4ff_position(f)+size-header_size); } else if (atom_type < SUBATOMIC) { parse_sub_atoms(f, size-header_size,meta_only); } else { /* skip this atom */ mp4ff_set_position(f, mp4ff_position(f)+size-header_size); } } return 0; }